@shko.online/dataverse-odata 0.1.0 → 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 (100) hide show
  1. package/.babelrc.js +160 -160
  2. package/.releaserc.yaml +23 -0
  3. package/CHANGELOG.md +13 -0
  4. package/README.md +3 -0
  5. package/lib/cjs/getExpandFromParser.js +16 -16
  6. package/lib/cjs/getFetchXmlFromParser.js +14 -7
  7. package/lib/cjs/getOrderByFromParser.js +44 -0
  8. package/lib/cjs/getSelectFromParser.js +4 -4
  9. package/lib/cjs/getTopFromParser.js +10 -6
  10. package/lib/cjs/getXQueryFromParser.js +35 -0
  11. package/lib/cjs/index.js +42 -0
  12. package/lib/cjs/parseOData.js +16 -4
  13. package/lib/cjs/validateNotEmpty.js +17 -0
  14. package/lib/esm/getExpandFromParser.js +16 -16
  15. package/lib/esm/getFetchXmlFromParser.js +14 -7
  16. package/lib/esm/getOrderByFromParser.js +37 -0
  17. package/lib/esm/getSelectFromParser.js +4 -4
  18. package/lib/esm/getTopFromParser.js +11 -6
  19. package/lib/esm/getXQueryFromParser.js +28 -0
  20. package/lib/esm/index.js +6 -0
  21. package/lib/esm/parseOData.js +17 -4
  22. package/lib/esm/validateNotEmpty.js +10 -0
  23. package/lib/modern/getExpandFromParser.js +16 -16
  24. package/lib/modern/getFetchXmlFromParser.js +14 -7
  25. package/lib/modern/getOrderByFromParser.js +38 -0
  26. package/lib/modern/getSelectFromParser.js +4 -4
  27. package/lib/modern/getTopFromParser.js +11 -6
  28. package/lib/modern/getXQueryFromParser.js +28 -0
  29. package/lib/modern/index.js +6 -0
  30. package/lib/modern/parseOData.js +17 -4
  31. package/lib/modern/validateNotEmpty.js +10 -0
  32. package/lib/ts3.4/getExpandFromParser.d.ts +2 -2
  33. package/lib/ts3.4/getFetchXmlFromParser.d.ts +2 -2
  34. package/lib/ts3.4/getOrderByFromParser.d.ts +7 -0
  35. package/lib/ts3.4/getSelectFromParser.d.ts +2 -2
  36. package/lib/ts3.4/getTopFromParser.d.ts +2 -2
  37. package/lib/ts3.4/getXQueryFromParser.d.ts +8 -0
  38. package/lib/ts3.4/index.d.ts +6 -0
  39. package/lib/ts3.4/parseOData.d.ts +5 -0
  40. package/lib/ts3.4/validateNotEmpty.d.ts +3 -0
  41. package/lib/ts3.9/getExpandFromParser.d.ts +6 -6
  42. package/lib/ts3.9/getExpandFromParser.d.ts.map +1 -1
  43. package/lib/ts3.9/getFetchXmlFromParser.d.ts +6 -6
  44. package/lib/ts3.9/getFetchXmlFromParser.d.ts.map +1 -1
  45. package/lib/ts3.9/getOrderByFromParser.d.ts +7 -0
  46. package/lib/ts3.9/getOrderByFromParser.d.ts.map +1 -0
  47. package/lib/ts3.9/getSelectFromParser.d.ts +6 -6
  48. package/lib/ts3.9/getSelectFromParser.d.ts.map +1 -1
  49. package/lib/ts3.9/getTopFromParser.d.ts +6 -6
  50. package/lib/ts3.9/getTopFromParser.d.ts.map +1 -1
  51. package/lib/ts3.9/getXQueryFromParser.d.ts +8 -0
  52. package/lib/ts3.9/getXQueryFromParser.d.ts.map +1 -0
  53. package/lib/ts3.9/index.d.ts +10 -4
  54. package/lib/ts3.9/index.d.ts.map +1 -1
  55. package/lib/ts3.9/parseOData.d.ts +7 -2
  56. package/lib/ts3.9/parseOData.d.ts.map +1 -1
  57. package/lib/ts3.9/validateNotEmpty.d.ts +3 -0
  58. package/lib/ts3.9/validateNotEmpty.d.ts.map +1 -0
  59. package/package.json +13 -8
  60. package/src/OData.types.d.ts +136 -61
  61. package/src/getExpandFromParser.ts +106 -105
  62. package/src/getFetchXmlFromParser.ts +56 -48
  63. package/src/getOrderByFromParser.ts +42 -0
  64. package/src/getSelectFromParser.ts +13 -13
  65. package/src/getTopFromParser.ts +31 -27
  66. package/src/getXQueryFromParser.ts +34 -0
  67. package/src/index.ts +24 -16
  68. package/src/parseOData.ts +36 -23
  69. package/src/validateNotEmpty.ts +12 -0
  70. package/tsconfig.build.json +8 -8
  71. package/tsconfig.json +35 -35
  72. package/jest.config.ts +0 -12
  73. package/lib/getExpandFromParser.d.ts +0 -7
  74. package/lib/getExpandFromParser.d.ts.map +0 -1
  75. package/lib/getExpandFromParser.js +0 -97
  76. package/lib/getExpandFromParser.js.map +0 -1
  77. package/lib/getFetchXmlFromParser.d.ts +0 -7
  78. package/lib/getFetchXmlFromParser.d.ts.map +0 -1
  79. package/lib/getFetchXmlFromParser.js +0 -41
  80. package/lib/getFetchXmlFromParser.js.map +0 -1
  81. package/lib/getSelectFromParser.d.ts +0 -7
  82. package/lib/getSelectFromParser.d.ts.map +0 -1
  83. package/lib/getSelectFromParser.js +0 -12
  84. package/lib/getSelectFromParser.js.map +0 -1
  85. package/lib/getTopFromParser.d.ts +0 -7
  86. package/lib/getTopFromParser.d.ts.map +0 -1
  87. package/lib/getTopFromParser.js +0 -27
  88. package/lib/getTopFromParser.js.map +0 -1
  89. package/lib/index.d.ts +0 -5
  90. package/lib/index.d.ts.map +0 -1
  91. package/lib/index.js +0 -4
  92. package/lib/index.js.map +0 -1
  93. package/lib/parseOData.d.ts +0 -3
  94. package/lib/parseOData.d.ts.map +0 -1
  95. package/lib/parseOData.js +0 -22
  96. package/lib/parseOData.js.map +0 -1
  97. package/tests/OData-Parser.$expand.test.ts +0 -39
  98. package/tests/OData-Parser.$top.test.ts +0 -36
  99. package/tests/OData-Parser.fetchXml.test.ts +0 -62
  100. package/tests/OData-Parser.test.ts +0 -17
@@ -1,105 +1,106 @@
1
- import type { ODataError, ODataExpand, ODataExpandQuery, ODataQuery } from './OData.types';
2
- import { getSelectFromParser } from './getSelectFromParser';
3
-
4
- /**
5
- * Parses the $expand query
6
- * @returns Returns true when the parse has an error
7
- */
8
- export const getExpandFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
9
- const $expand = parser.get('$expand');
10
- if ($expand !== null) {
11
- result.$expand = {};
12
-
13
- if (extractExpand($expand, result)) {
14
- return true;
15
- }
16
- }
17
- return false;
18
- };
19
-
20
- const extractExpand = (value: string, $expand: ODataExpand & ODataError) => {
21
- const match = value.match(/^\s*(\w(\w|\d|_)*)\s*(,|\()?\s*/);
22
- if (
23
- match === null ||
24
- (match[0].length < value.length && match[3] === null) ||
25
- (match[0].length === value.length && match[3] !== undefined)
26
- ) {
27
- $expand.error = {
28
- code: '0x0',
29
- message: 'invalid expand expression',
30
- };
31
- return true;
32
- }
33
- let matchSeparator = match[3];
34
- let matchLength = match[0].length;
35
- if (matchSeparator !== '(') {
36
- if ($expand.$expand !== undefined) {
37
- $expand.$expand[match[1]] = { $select: [] };
38
- }
39
- } else {
40
- const { index, error } = getClosingBracket(value.substring(matchLength));
41
- if (error) {
42
- $expand.error = {
43
- code: '0x0',
44
- message: error,
45
- };
46
- return true;
47
- }
48
-
49
- if ($expand.$expand !== undefined) {
50
- const innerExpand = {} as ODataExpandQuery & ODataError;
51
- const parser = new URLSearchParams('?' + value.substring(matchLength, matchLength + index));
52
- if (getSelectFromParser(parser, innerExpand)) {
53
- $expand.error = innerExpand.error;
54
- return true;
55
- }
56
- if (getExpandFromParser(parser, innerExpand)) {
57
- $expand.error = innerExpand.error;
58
- return true;
59
- }
60
- if (innerExpand.$expand === undefined && innerExpand.$select === undefined) {
61
- $expand.error = { code: '0x0', message: 'Empty expand' };
62
- return true;
63
- }
64
- $expand.$expand[match[1]] = innerExpand;
65
- }
66
-
67
- matchLength = matchLength + index;
68
- const secondMatch = value.substring(matchLength + 1).match(/\s*(,?)\s*d/);
69
- if (secondMatch !== null) {
70
- matchLength = matchLength + secondMatch[0].length;
71
- if (secondMatch[1] !== null) {
72
- matchSeparator = ',';
73
- }
74
- }
75
- }
76
-
77
- if (matchSeparator === ',') {
78
- if (extractExpand(value.substring(matchLength), $expand)) {
79
- return true;
80
- }
81
- }
82
-
83
- return false;
84
- };
85
-
86
- const getClosingBracket = (value: string): { index: number; error?: string } => {
87
- let depth = 1;
88
- let startAt = 0;
89
- while (depth > 0) {
90
- const match = value.substring(startAt).match(/\(|\)/);
91
- if (match === null) {
92
- return { error: 'no closing bracket found', index: -1 };
93
- }
94
- if (match[0] === ')') {
95
- depth -= 1;
96
- if (depth === 0) {
97
- return { index: match.index || 0 };
98
- }
99
- } else {
100
- depth += 1;
101
- }
102
- startAt = (match.index || 0) + 1;
103
- }
104
- return { error: 'no closing bracket found', index: -1 };
105
- };
1
+ import type { ODataError, ODataExpand, ODataExpandQuery, ODataQuery } from './OData.types';
2
+
3
+ import { getSelectFromParser } from './getSelectFromParser';
4
+
5
+ /**
6
+ * Parses the {@link ODataExpand.$expand $expand} query
7
+ * @returns Returns `false` when the parse has an error
8
+ */
9
+ export const getExpandFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
10
+ const $expand = parser.get('$expand');
11
+ if ($expand !== null) {
12
+ result.$expand = {};
13
+
14
+ if (!extractExpand($expand, result)) {
15
+ return false;
16
+ }
17
+ }
18
+ return true;
19
+ };
20
+
21
+ const extractExpand = (value: string, $expand: ODataExpand & ODataError) => {
22
+ const match = value.match(/^\s*(\w(\w|\d|_)*)\s*(,|\()?\s*/);
23
+ if (
24
+ match === null ||
25
+ (match[0].length < value.length && match[3] === null) ||
26
+ (match[0].length === value.length && match[3] !== undefined)
27
+ ) {
28
+ $expand.error = {
29
+ code: '0x0',
30
+ message: 'invalid expand expression',
31
+ };
32
+ return false;
33
+ }
34
+ let matchSeparator = match[3];
35
+ let matchLength = match[0].length;
36
+ if (matchSeparator !== '(') {
37
+ if ($expand.$expand !== undefined) {
38
+ $expand.$expand[match[1]] = { $select: [] };
39
+ }
40
+ } else {
41
+ const { index, error } = getClosingBracket(value.substring(matchLength));
42
+ if (error) {
43
+ $expand.error = {
44
+ code: '0x0',
45
+ message: error,
46
+ };
47
+ return false;
48
+ }
49
+
50
+ if ($expand.$expand !== undefined) {
51
+ const innerExpand = {} as ODataExpandQuery & ODataError;
52
+ const parser = new URLSearchParams('?' + value.substring(matchLength, matchLength + index));
53
+ if (!getSelectFromParser(parser, innerExpand)) {
54
+ $expand.error = innerExpand.error;
55
+ return false;
56
+ }
57
+ if (!getExpandFromParser(parser, innerExpand)) {
58
+ $expand.error = innerExpand.error;
59
+ return false;
60
+ }
61
+ if (innerExpand.$expand === undefined && innerExpand.$select === undefined) {
62
+ $expand.error = { code: '0x0', message: 'Empty expand' };
63
+ return false;
64
+ }
65
+ $expand.$expand[match[1]] = innerExpand;
66
+ }
67
+
68
+ matchLength = matchLength + index;
69
+ const secondMatch = value.substring(matchLength + 1).match(/\s*(,?)\s*d/);
70
+ if (secondMatch !== null) {
71
+ matchLength = matchLength + secondMatch[0].length;
72
+ if (secondMatch[1] !== null) {
73
+ matchSeparator = ',';
74
+ }
75
+ }
76
+ }
77
+
78
+ if (matchSeparator === ',') {
79
+ if (!extractExpand(value.substring(matchLength), $expand)) {
80
+ return false;
81
+ }
82
+ }
83
+
84
+ return true;
85
+ };
86
+
87
+ const getClosingBracket = (value: string): { index: number; error?: string } => {
88
+ let depth = 1;
89
+ let startAt = 0;
90
+ while (depth > 0) {
91
+ const match = value.substring(startAt).match(/\(|\)/);
92
+ if (match === null) {
93
+ return { error: 'no closing bracket found', index: -1 };
94
+ }
95
+ if (match[0] === ')') {
96
+ depth -= 1;
97
+ if (depth === 0) {
98
+ return { index: match.index || 0 };
99
+ }
100
+ } else {
101
+ depth += 1;
102
+ }
103
+ startAt = (match.index || 0) + 1;
104
+ }
105
+ return { error: 'no closing bracket found', index: -1 };
106
+ };
@@ -1,48 +1,56 @@
1
- import type { ODataQuery } from './OData.types';
2
-
3
- /**
4
- * Parses the $fetchXml query
5
- * @returns Returns true when the parse has an error
6
- */
7
- export const getFetchXmlFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
8
- const fetchXml = parser.get('fetchXml');
9
- if (fetchXml !== null) {
10
- const serializer = new DOMParser();
11
- const fetchXmlDocument = serializer.parseFromString(fetchXml, 'text/xml');
12
- if (fetchXmlDocument.documentElement.tagName === 'parsererror') {
13
- result.error = {
14
- code: '0x80040201',
15
- message: 'Invalid XML.',
16
- };
17
- return true;
18
- }
19
- const entity = fetchXmlDocument
20
- .evaluate('fetch/entity', fetchXmlDocument, null, XPathResult.ANY_TYPE, null)
21
- .iterateNext() as Element;
22
- if (fetchXmlDocument.documentElement.children.length != 1 || !entity || !entity.getAttribute('name')) {
23
- result.error = {
24
- code: '0x80041102',
25
- message: 'Entity Name was not specified in FetchXml String.',
26
- };
27
- return true;
28
- }
29
- const invalidAttribute = fetchXmlDocument
30
- .evaluate(
31
- 'fetch/entity/*[not(self::filter or self::order or self::link-entity or self::attribute or self::all-attributes or self::no-attrs)]',
32
- fetchXmlDocument,
33
- null,
34
- XPathResult.ANY_TYPE,
35
- null,
36
- )
37
- .iterateNext() as Element;
38
- if (invalidAttribute) {
39
- result.error = {
40
- code: '0x8004111c',
41
- message: `Invalid Child Node, valid nodes are filter, order, link-entity, attribute, all-attributes, no-attrs. NodeName = ${invalidAttribute.tagName} NodeXml = ${invalidAttribute.outerHTML}`,
42
- };
43
- return true;
44
- }
45
- result.fetchXml = fetchXmlDocument;
46
- }
47
- return false;
48
- };
1
+ import type { ODataQuery, ODataFetch } from './OData.types';
2
+
3
+ /**
4
+ * Parses the {@link ODataFetch.fetchXml fetchXml} query
5
+ * @returns Returns `false` when the parse has an error
6
+ */
7
+ export const getFetchXmlFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
8
+ const fetchXml = parser.get('fetchXml');
9
+ if (fetchXml !== null) {
10
+ if (fetchXml === '') {
11
+ result.error = {
12
+ code: '0x80040203',
13
+ message: 'Expected non-empty string.',
14
+ };
15
+ return false;
16
+ }
17
+
18
+ const serializer = new DOMParser();
19
+ const fetchXmlDocument = serializer.parseFromString(fetchXml, 'text/xml');
20
+ if (fetchXmlDocument.documentElement.tagName === 'parsererror') {
21
+ result.error = {
22
+ code: '0x80040201',
23
+ message: 'Invalid XML.',
24
+ };
25
+ return false;
26
+ }
27
+ const entity = fetchXmlDocument
28
+ .evaluate('fetch/entity', fetchXmlDocument, null, XPathResult.ANY_TYPE, null)
29
+ .iterateNext() as Element;
30
+ if (fetchXmlDocument.documentElement.children.length != 1 || !entity || !entity.getAttribute('name')) {
31
+ result.error = {
32
+ code: '0x80041102',
33
+ message: 'Entity Name was not specified in FetchXml String.',
34
+ };
35
+ return false;
36
+ }
37
+ const invalidAttribute = fetchXmlDocument
38
+ .evaluate(
39
+ 'fetch/entity/*[not(self::filter or self::order or self::link-entity or self::attribute or self::all-attributes or self::no-attrs)]',
40
+ fetchXmlDocument,
41
+ null,
42
+ XPathResult.ANY_TYPE,
43
+ null,
44
+ )
45
+ .iterateNext() as Element;
46
+ if (invalidAttribute) {
47
+ result.error = {
48
+ code: '0x8004111c',
49
+ message: `Invalid Child Node, valid nodes are filter, order, link-entity, attribute, all-attributes, no-attrs. NodeName = ${invalidAttribute.tagName} NodeXml = ${invalidAttribute.outerHTML}`,
50
+ };
51
+ return false;
52
+ }
53
+ result.fetchXml = fetchXmlDocument;
54
+ }
55
+ return true;
56
+ };
@@ -0,0 +1,42 @@
1
+ import type { ODataQuery, ODataOrderBy } from './OData.types';
2
+ import { validateNotEmpty } from './validateNotEmpty';
3
+
4
+ const edmProperty = /\w{1-255}/gi;
5
+
6
+ /**
7
+ * Parses the {@link ODataOrderBy.$orderby $orderby} query
8
+ * @returns Returns `false` when the parse has an error
9
+ */
10
+ export const getOrderByFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
11
+ let $orderby = parser.get('$orderby');
12
+ if ($orderby !== null) {
13
+ if (!validateNotEmpty('$orderby', $orderby, result)) {
14
+ return false;
15
+ }
16
+ $orderby = $orderby.trimEnd();
17
+ const orderByArray: ODataOrderBy['$orderby'] = [];
18
+ for (let i = 0; i < $orderby.length; i++) {
19
+ if (false /* syntax error */) {
20
+ result.error = {
21
+ code: '0x0',
22
+ message: `Syntax error at position ${i} in '${$orderby}'.`,
23
+ };
24
+
25
+ return false;
26
+ }
27
+ }
28
+
29
+ orderByArray.forEach((orderBy) => {
30
+ if (!orderBy.column?.match(edmProperty)) {
31
+ result.error = {
32
+ code: '0x80060888',
33
+ message: 'Order By Property must be of type EdmProperty',
34
+ };
35
+ return false;
36
+ }
37
+ });
38
+
39
+ result.$orderby = orderByArray;
40
+ }
41
+ return true;
42
+ };
@@ -1,13 +1,13 @@
1
- import type { ODataQuery } from './OData.types';
2
-
3
- /**
4
- * Parses the $select query
5
- * @returns Returns true when the parse has an error
6
- */
7
- export const getSelectFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
8
- const $select = parser.get('$select');
9
- if ($select !== null) {
10
- result.$select = $select.split(',');
11
- }
12
- return false;
13
- };
1
+ import type { ODataQuery, ODataSelect } from './OData.types';
2
+
3
+ /**
4
+ * Parses the {@link ODataSelect.$select $select} query
5
+ * @returns Returns `false` when the parse has an error
6
+ */
7
+ export const getSelectFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
8
+ const $select = parser.get('$select');
9
+ if ($select !== null) {
10
+ result.$select = $select.split(',');
11
+ }
12
+ return true;
13
+ };
@@ -1,27 +1,31 @@
1
- import type { ODataQuery } from './OData.types';
2
-
3
- /**
4
- * Parses the $top query
5
- * @returns Returns true when the parse has an error
6
- */
7
- export const getTopFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
8
- const $topValue = parser.get('$top');
9
- if ($topValue !== null) {
10
- let $top;
11
- if (!$topValue.match(/^\d+$/) || ($top = parseInt($topValue)) < 0) {
12
- result.error = {
13
- code: '0x0',
14
- message: `Invalid value '${$topValue}' for $top query option found. The $top query option requires a non-negative integer value.`,
15
- };
16
- return true;
17
- } else if ($top === 0) {
18
- result.error = {
19
- code: '0x0',
20
- message: `Invalid value for $top query option.`,
21
- };
22
- return true;
23
- }
24
- result.$top = $top;
25
- }
26
- return false;
27
- };
1
+ import type { ODataQuery, ODataTop } from './OData.types';
2
+ import { validateNotEmpty } from './validateNotEmpty';
3
+
4
+ /**
5
+ * Parses the {@link ODataTop.$top $top} query
6
+ * @returns Returns `false` when the parse has an error
7
+ */
8
+ export const getTopFromParser = (parser: URLSearchParams, result: ODataQuery): boolean => {
9
+ const $topValue = parser.get('$top');
10
+ if ($topValue !== null) {
11
+ if (!validateNotEmpty('$orderby', $topValue, result)) {
12
+ return false;
13
+ }
14
+ let $top: number;
15
+ if (!$topValue.match(/^\d+$/) || ($top = parseInt($topValue)) < 0) {
16
+ result.error = {
17
+ code: '0x0',
18
+ message: `Invalid value '${$topValue}' for $top query option found. The $top query option requires a non-negative integer value.`,
19
+ };
20
+ return false;
21
+ } else if ($top === 0) {
22
+ result.error = {
23
+ code: '0x0',
24
+ message: `Invalid value for $top query option.`,
25
+ };
26
+ return false;
27
+ }
28
+ result.$top = $top;
29
+ }
30
+ return true;
31
+ };
@@ -0,0 +1,34 @@
1
+ import type { ODataQuery, ODataSavedQuery, ODataUserQuery } from './OData.types';
2
+
3
+ const guidRegex = /[0-9A-F]{8}\-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/gi;
4
+
5
+ /**
6
+ * Parses the {@link ODataSavedQuery.savedQuery savedQuery} or
7
+ * {@link ODataUserQuery.userQuery userQuery} query
8
+ * @returns Returns `false` when the parse has an error
9
+ */
10
+ export const getXQueryFromParser = (
11
+ X: 'savedQuery' | 'userQuery',
12
+ parser: URLSearchParams,
13
+ result: ODataQuery,
14
+ ): boolean => {
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
+ };
package/src/index.ts CHANGED
@@ -1,16 +1,24 @@
1
- export type {
2
- BinaryOperator,
3
- ODataError,
4
- ODataExpand,
5
- ODataExpandQuery,
6
- ODataFetch,
7
- ODataFilter,
8
- ODataQuery,
9
- ODataSelect,
10
- ODataTop,
11
- StandardOperator,
12
- StandardOperators,
13
- } from './OData.types';
14
- export { parseOData } from './parseOData';
15
- import { parseOData } from './parseOData';
16
- export default parseOData;
1
+ export type {
2
+ BinaryOperator,
3
+ ODataError,
4
+ ODataExpand,
5
+ ODataExpandQuery,
6
+ ODataFetch,
7
+ ODataFilter,
8
+ ODataQuery,
9
+ ODataSelect,
10
+ ODataTop,
11
+ StandardOperator,
12
+ StandardOperators,
13
+ } from './OData.types';
14
+
15
+ export { getExpandFromParser } from './getExpandFromParser';
16
+ export { getFetchXmlFromParser } from './getFetchXmlFromParser';
17
+ export { getOrderByFromParser } from './getOrderByFromParser';
18
+ export { getSelectFromParser } from './getSelectFromParser';
19
+ export { getTopFromParser } from './getTopFromParser';
20
+ export { getXQueryFromParser } from './getXQueryFromParser';
21
+
22
+ export { parseOData } from './parseOData';
23
+ import { parseOData } from './parseOData';
24
+ export default parseOData;
package/src/parseOData.ts CHANGED
@@ -1,23 +1,36 @@
1
- import type { ODataQuery } from './OData.types';
2
- import { getTopFromParser } from './getTopFromParser';
3
- import { getSelectFromParser } from './getSelectFromParser';
4
- import { getExpandFromParser } from './getExpandFromParser';
5
- import { getFetchXmlFromParser } from './getFetchXmlFromParser';
6
-
7
- export const parseOData = (query: string) => {
8
- const parser = new URLSearchParams(query);
9
- const result = {} as ODataQuery;
10
- if (getExpandFromParser(parser, result)) {
11
- return result;
12
- }
13
- if (getSelectFromParser(parser, result)) {
14
- return result;
15
- }
16
- if (getTopFromParser(parser, result)) {
17
- return result;
18
- }
19
- if (getFetchXmlFromParser(parser, result)) {
20
- return result;
21
- }
22
- return result;
23
- };
1
+ import type { ODataQuery } from './OData.types';
2
+
3
+ import { getTopFromParser } from './getTopFromParser';
4
+ import { getSelectFromParser } from './getSelectFromParser';
5
+ import { getExpandFromParser } from './getExpandFromParser';
6
+ import { getFetchXmlFromParser } from './getFetchXmlFromParser';
7
+ import { getXQueryFromParser } from './getXQueryFromParser';
8
+
9
+ /**
10
+ * parses the OData query and applies some Dataverse validations
11
+ * @param query The OData query
12
+ * @returns The parsed OData query
13
+ */
14
+ export const parseOData = (query: string) => {
15
+ const parser = new URLSearchParams(query);
16
+ const result = {} as ODataQuery;
17
+ if (!getExpandFromParser(parser, result)) {
18
+ return result;
19
+ }
20
+ if (!getSelectFromParser(parser, result)) {
21
+ return result;
22
+ }
23
+ if (!getTopFromParser(parser, result)) {
24
+ return result;
25
+ }
26
+ if (!getFetchXmlFromParser(parser, result)) {
27
+ return result;
28
+ }
29
+ if (!getXQueryFromParser('savedQuery', parser, result)) {
30
+ return result;
31
+ }
32
+ if (!getXQueryFromParser('userQuery', parser, result)) {
33
+ return result;
34
+ }
35
+ return result;
36
+ };
@@ -0,0 +1,12 @@
1
+ import type { ODataQuery } from './OData.types';
2
+
3
+ export const validateNotEmpty = (query: string, value: string, result: ODataQuery) => {
4
+ if (!value.trim()) {
5
+ result.error = {
6
+ code: '0x0',
7
+ message: `The value for OData query '${query}' cannot be empty.`,
8
+ };
9
+ return false;
10
+ }
11
+ return true;
12
+ };
@@ -1,9 +1,9 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "exclude": [
4
- "tests",
5
- "lib",
6
- "node_modules",
7
- "jest.config.ts"
8
- ]
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "exclude": [
4
+ "tests",
5
+ "lib",
6
+ "node_modules",
7
+ "jest.config.ts"
8
+ ]
9
9
  }