@dhis2/app-service-data 3.8.0 → 3.10.0-alpha.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/build/cjs/__tests__/integration.test.js +16 -10
- package/build/cjs/__tests__/mutations.test.js +8 -5
- package/build/cjs/engine/DataEngine.js +14 -12
- package/build/cjs/engine/helpers/resolveDynamicQuery.js +14 -11
- package/build/cjs/engine/helpers/resolveDynamicQuery.test.js +23 -14
- package/build/cjs/engine/helpers/validate.js +6 -4
- package/build/cjs/engine/helpers/validate.test.js +74 -15
- package/build/cjs/engine/types/FetchError.js +6 -5
- package/build/cjs/engine/types/InvalidQueryError.js +1 -1
- package/build/cjs/index.js +10 -10
- package/build/cjs/links/CustomDataLink.js +8 -6
- package/build/cjs/links/CustomDataLink.test.js +2 -2
- package/build/cjs/links/RestAPILink/fetchData.js +3 -2
- package/build/cjs/links/RestAPILink/fetchData.test.js +1 -1
- package/build/cjs/links/RestAPILink/metadataResources.js +1 -1
- package/build/cjs/links/RestAPILink/path.js +5 -1
- package/build/cjs/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.js +29 -16
- package/build/cjs/links/RestAPILink/queryToRequestOptions/requestContentType.js +9 -6
- package/build/cjs/links/RestAPILink/queryToRequestOptions/requestContentType.test.js +2 -2
- package/build/cjs/links/RestAPILink/queryToRequestOptions/textPlainMatchers.js +51 -33
- package/build/cjs/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.js +6 -3
- package/build/cjs/links/RestAPILink/queryToRequestOptions.js +1 -1
- package/build/cjs/links/RestAPILink/queryToRequestOptions.test.js +56 -6
- package/build/cjs/links/RestAPILink/queryToResourcePath.js +14 -6
- package/build/cjs/links/RestAPILink/queryToResourcePath.test.js +16 -16
- package/build/cjs/links/RestAPILink/validateQuery.test.js +12 -12
- package/build/cjs/links/RestAPILink.js +4 -3
- package/build/cjs/react/components/CustomDataProvider.js +7 -6
- package/build/cjs/react/components/DataMutation.js +8 -7
- package/build/cjs/react/components/DataProvider.js +1 -1
- package/build/cjs/react/components/DataQuery.js +9 -8
- package/build/cjs/react/context/defaultContext.test.js +10 -2
- package/build/cjs/react/hooks/stableVariablesHash.js +1 -2
- package/build/cjs/react/hooks/stableVariablesHash.test.js +6 -6
- package/build/cjs/react/hooks/useDataMutation.js +7 -6
- package/build/cjs/react/hooks/useDataMutation.test.js +70 -43
- package/build/cjs/react/hooks/useDataQuery.js +13 -9
- package/build/cjs/react/hooks/useDataQuery.test.js +259 -162
- package/build/cjs/react/hooks/useQueryExecutor.js +11 -9
- package/build/cjs/react/hooks/useQueryExecutor.test.js +16 -12
- package/build/cjs/react/hooks/useStaticInput.js +7 -6
- package/build/cjs/react/hooks/useStaticInput.test.js +44 -25
- package/build/cjs/react/index.js +6 -6
- package/build/es/__tests__/integration.test.js +16 -10
- package/build/es/__tests__/mutations.test.js +8 -5
- package/build/es/engine/DataEngine.js +14 -12
- package/build/es/engine/helpers/resolveDynamicQuery.js +14 -11
- package/build/es/engine/helpers/resolveDynamicQuery.test.js +23 -14
- package/build/es/engine/helpers/validate.js +6 -4
- package/build/es/engine/helpers/validate.test.js +74 -15
- package/build/es/engine/types/FetchError.js +6 -5
- package/build/es/engine/types/InvalidQueryError.js +1 -1
- package/build/es/links/CustomDataLink.js +8 -6
- package/build/es/links/CustomDataLink.test.js +2 -2
- package/build/es/links/RestAPILink/fetchData.js +3 -2
- package/build/es/links/RestAPILink/fetchData.test.js +1 -1
- package/build/es/links/RestAPILink/path.js +5 -1
- package/build/es/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.js +28 -15
- package/build/es/links/RestAPILink/queryToRequestOptions/requestContentType.js +8 -5
- package/build/es/links/RestAPILink/queryToRequestOptions/requestContentType.test.js +2 -2
- package/build/es/links/RestAPILink/queryToRequestOptions/textPlainMatchers.js +50 -32
- package/build/es/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.js +6 -3
- package/build/es/links/RestAPILink/queryToRequestOptions.js +1 -1
- package/build/es/links/RestAPILink/queryToRequestOptions.test.js +56 -6
- package/build/es/links/RestAPILink/queryToResourcePath.js +14 -6
- package/build/es/links/RestAPILink/queryToResourcePath.test.js +16 -16
- package/build/es/links/RestAPILink/validateQuery.test.js +12 -12
- package/build/es/links/RestAPILink.js +4 -3
- package/build/es/react/components/CustomDataProvider.js +7 -6
- package/build/es/react/components/DataMutation.js +8 -7
- package/build/es/react/components/DataQuery.js +9 -8
- package/build/es/react/context/defaultContext.test.js +10 -2
- package/build/es/react/hooks/stableVariablesHash.js +1 -2
- package/build/es/react/hooks/stableVariablesHash.test.js +6 -6
- package/build/es/react/hooks/useDataMutation.js +7 -6
- package/build/es/react/hooks/useDataMutation.test.js +70 -43
- package/build/es/react/hooks/useDataQuery.js +13 -9
- package/build/es/react/hooks/useDataQuery.test.js +259 -162
- package/build/es/react/hooks/useQueryExecutor.js +11 -9
- package/build/es/react/hooks/useQueryExecutor.test.js +16 -12
- package/build/es/react/hooks/useStaticInput.js +7 -6
- package/build/es/react/hooks/useStaticInput.test.js +44 -25
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.requestHeadersForContentType = exports.requestContentType = exports.requestBodyForContentType = void 0;
|
|
7
7
|
|
|
8
8
|
var multipartFormDataMatchers = _interopRequireWildcard(require("./multipartFormDataMatchers"));
|
|
9
9
|
|
|
@@ -25,10 +25,11 @@ const convertData = (data, initialValue) => {
|
|
|
25
25
|
const dataEntries = Object.entries(data);
|
|
26
26
|
|
|
27
27
|
if (dataEntries.length === 0) {
|
|
28
|
-
throw new Error(
|
|
28
|
+
throw new Error(`Could not convert data to ${initialValue.constructor.name}: object does not have own enumerable string-keyed properties`);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
return dataEntries.reduce((convertedData,
|
|
31
|
+
return dataEntries.reduce((convertedData, _ref) => {
|
|
32
|
+
let [key, value] = _ref;
|
|
32
33
|
convertedData.append(key, value);
|
|
33
34
|
return convertedData;
|
|
34
35
|
}, initialValue);
|
|
@@ -79,9 +80,11 @@ const requestHeadersForContentType = contentType => {
|
|
|
79
80
|
|
|
80
81
|
exports.requestHeadersForContentType = requestHeadersForContentType;
|
|
81
82
|
|
|
82
|
-
const requestBodyForContentType = (contentType, {
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
const requestBodyForContentType = (contentType, _ref2) => {
|
|
84
|
+
let {
|
|
85
|
+
data
|
|
86
|
+
} = _ref2;
|
|
87
|
+
|
|
85
88
|
if (typeof data === 'undefined') {
|
|
86
89
|
return undefined;
|
|
87
90
|
}
|
|
@@ -88,7 +88,7 @@ describe('requestBodyForContentType', () => {
|
|
|
88
88
|
type: 'text/plain'
|
|
89
89
|
})
|
|
90
90
|
});
|
|
91
|
-
}).toThrowErrorMatchingInlineSnapshot("
|
|
91
|
+
}).toThrowErrorMatchingInlineSnapshot(`"Could not convert data to FormData: object does not have own enumerable string-keyed properties"`);
|
|
92
92
|
});
|
|
93
93
|
it('converts to URLSearchParams if contentType is "application/x-www-form-urlencoded"', () => {
|
|
94
94
|
const data = {
|
|
@@ -109,7 +109,7 @@ describe('requestBodyForContentType', () => {
|
|
|
109
109
|
type: 'text/plain'
|
|
110
110
|
})
|
|
111
111
|
});
|
|
112
|
-
}).toThrowErrorMatchingInlineSnapshot("
|
|
112
|
+
}).toThrowErrorMatchingInlineSnapshot(`"Could not convert data to URLSearchParams: object does not have own enumerable string-keyed properties"`);
|
|
113
113
|
});
|
|
114
114
|
it('returns the data as received if contentType is "text/plain"', () => {
|
|
115
115
|
const data = 'Something';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.isUpdateInterpretation = exports.isReplyToMessageConversation = exports.isMetadataPackageInstallation = exports.isInterpretationCommentUpdate = exports.isExpressionDescriptionValidation = exports.isCreateInterpretation = exports.isCreateFeedbackMessage = exports.isCommentOnInterpretation = exports.isAddOrUpdateSystemOrUserSetting = exports.addOrUpdateConfigurationProperty = void 0;
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
9
|
* Requests that expect a "text/plain" Content-Type have been collected by scanning
|
|
@@ -16,9 +16,10 @@ exports.isExpressionDescriptionValidation = exports.isMetadataPackageInstallatio
|
|
|
16
16
|
* "create" mutation-objects, we will have to include additional checks below.
|
|
17
17
|
*/
|
|
18
18
|
// POST to `messageConversations/${id}` (reply to a messagConversation)
|
|
19
|
-
const isReplyToMessageConversation = (type, {
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const isReplyToMessageConversation = (type, _ref) => {
|
|
20
|
+
let {
|
|
21
|
+
resource
|
|
22
|
+
} = _ref;
|
|
22
23
|
const pattern = /^messageConversations\/[a-zA-Z0-9]{11}$/;
|
|
23
24
|
return type === 'create' && pattern.test(resource);
|
|
24
25
|
}; // POST to 'messageConversations/feedback' (create a feedback message)
|
|
@@ -26,16 +27,20 @@ const isReplyToMessageConversation = (type, {
|
|
|
26
27
|
|
|
27
28
|
exports.isReplyToMessageConversation = isReplyToMessageConversation;
|
|
28
29
|
|
|
29
|
-
const isCreateFeedbackMessage = (type, {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const isCreateFeedbackMessage = (type, _ref2) => {
|
|
31
|
+
let {
|
|
32
|
+
resource
|
|
33
|
+
} = _ref2;
|
|
34
|
+
return type === 'create' && resource === 'messageConversations/feedback';
|
|
35
|
+
}; // POST `interpretations/${objectType}/${id}` (add an interpretation to a visualization)
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
exports.isCreateFeedbackMessage = isCreateFeedbackMessage;
|
|
35
39
|
|
|
36
|
-
const isCreateInterpretation = (type, {
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
const isCreateInterpretation = (type, _ref3) => {
|
|
41
|
+
let {
|
|
42
|
+
resource
|
|
43
|
+
} = _ref3;
|
|
39
44
|
const pattern = /^interpretations\/(?:reportTable|chart|visualization|map|eventVisualization|eventReport|eventChart|dataSetReport)\/[a-zA-Z0-9]{11}$/;
|
|
40
45
|
return type === 'create' && pattern.test(resource);
|
|
41
46
|
}; // PUT to `interpretations/${id}` (update an interpretation)
|
|
@@ -43,10 +48,12 @@ const isCreateInterpretation = (type, {
|
|
|
43
48
|
|
|
44
49
|
exports.isCreateInterpretation = isCreateInterpretation;
|
|
45
50
|
|
|
46
|
-
const isUpdateInterpretation = (type, {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
const isUpdateInterpretation = (type, _ref4) => {
|
|
52
|
+
let {
|
|
53
|
+
resource,
|
|
54
|
+
id
|
|
55
|
+
} = _ref4;
|
|
56
|
+
|
|
50
57
|
if (type !== 'replace') {
|
|
51
58
|
return false;
|
|
52
59
|
}
|
|
@@ -66,9 +73,10 @@ const isUpdateInterpretation = (type, {
|
|
|
66
73
|
|
|
67
74
|
exports.isUpdateInterpretation = isUpdateInterpretation;
|
|
68
75
|
|
|
69
|
-
const isCommentOnInterpretation = (type, {
|
|
70
|
-
|
|
71
|
-
|
|
76
|
+
const isCommentOnInterpretation = (type, _ref5) => {
|
|
77
|
+
let {
|
|
78
|
+
resource
|
|
79
|
+
} = _ref5;
|
|
72
80
|
const pattern = /^interpretations\/[a-zA-Z0-9]{11}\/comments$/;
|
|
73
81
|
return type === 'create' && pattern.test(resource);
|
|
74
82
|
}; // PUT to `interpretations/${interpretationId}/comments/${commentId}`
|
|
@@ -77,10 +85,12 @@ const isCommentOnInterpretation = (type, {
|
|
|
77
85
|
|
|
78
86
|
exports.isCommentOnInterpretation = isCommentOnInterpretation;
|
|
79
87
|
|
|
80
|
-
const isInterpretationCommentUpdate = (type, {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
const isInterpretationCommentUpdate = (type, _ref6) => {
|
|
89
|
+
let {
|
|
90
|
+
resource,
|
|
91
|
+
id
|
|
92
|
+
} = _ref6;
|
|
93
|
+
|
|
84
94
|
if (type !== 'replace') {
|
|
85
95
|
return false;
|
|
86
96
|
}
|
|
@@ -100,9 +110,10 @@ const isInterpretationCommentUpdate = (type, {
|
|
|
100
110
|
|
|
101
111
|
exports.isInterpretationCommentUpdate = isInterpretationCommentUpdate;
|
|
102
112
|
|
|
103
|
-
const isAddOrUpdateSystemOrUserSetting = (type, {
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
const isAddOrUpdateSystemOrUserSetting = (type, _ref7) => {
|
|
114
|
+
let {
|
|
115
|
+
resource
|
|
116
|
+
} = _ref7;
|
|
106
117
|
// At least 4 chars because the all start with 'key' (i.e. keyStyle)
|
|
107
118
|
const pattern = /^(?:systemSettings|userSettings)\/[a-zA-Z]{4,}$/;
|
|
108
119
|
return type === 'create' && pattern.test(resource);
|
|
@@ -112,9 +123,10 @@ const isAddOrUpdateSystemOrUserSetting = (type, {
|
|
|
112
123
|
|
|
113
124
|
exports.isAddOrUpdateSystemOrUserSetting = isAddOrUpdateSystemOrUserSetting;
|
|
114
125
|
|
|
115
|
-
const addOrUpdateConfigurationProperty = (type, {
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
const addOrUpdateConfigurationProperty = (type, _ref8) => {
|
|
127
|
+
let {
|
|
128
|
+
resource
|
|
129
|
+
} = _ref8;
|
|
118
130
|
// NOTE: The corsWhitelist property does expect "application/json"
|
|
119
131
|
const pattern = /^(configuration)\/([a-zA-Z]{1,50})$/;
|
|
120
132
|
const match = resource.match(pattern);
|
|
@@ -124,15 +136,21 @@ const addOrUpdateConfigurationProperty = (type, {
|
|
|
124
136
|
|
|
125
137
|
exports.addOrUpdateConfigurationProperty = addOrUpdateConfigurationProperty;
|
|
126
138
|
|
|
127
|
-
const isMetadataPackageInstallation = (type, {
|
|
128
|
-
|
|
129
|
-
|
|
139
|
+
const isMetadataPackageInstallation = (type, _ref9) => {
|
|
140
|
+
let {
|
|
141
|
+
resource
|
|
142
|
+
} = _ref9;
|
|
143
|
+
return type === 'create' && resource === 'synchronization/metadataPull';
|
|
144
|
+
}; // POST to 'indicaators/expression/description' (validate an expression)
|
|
130
145
|
|
|
131
146
|
|
|
132
147
|
exports.isMetadataPackageInstallation = isMetadataPackageInstallation;
|
|
133
148
|
|
|
134
|
-
const isExpressionDescriptionValidation = (type, {
|
|
135
|
-
|
|
136
|
-
|
|
149
|
+
const isExpressionDescriptionValidation = (type, _ref10) => {
|
|
150
|
+
let {
|
|
151
|
+
resource
|
|
152
|
+
} = _ref10;
|
|
153
|
+
return type === 'create' && resource === 'indicators/expression/description';
|
|
154
|
+
};
|
|
137
155
|
|
|
138
156
|
exports.isExpressionDescriptionValidation = isExpressionDescriptionValidation;
|
|
@@ -6,8 +6,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.isSvgConversion = void 0;
|
|
7
7
|
|
|
8
8
|
// POST to convert an SVG file
|
|
9
|
-
const isSvgConversion = (type, {
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const isSvgConversion = (type, _ref) => {
|
|
10
|
+
let {
|
|
11
|
+
resource
|
|
12
|
+
} = _ref;
|
|
13
|
+
return type === 'create' && (resource === 'svg.png' || resource === 'svg.pdf');
|
|
14
|
+
};
|
|
12
15
|
|
|
13
16
|
exports.isSvgConversion = isSvgConversion;
|
|
@@ -7,7 +7,14 @@ describe('queryToRequestOptions', () => {
|
|
|
7
7
|
const options = (0, _queryToRequestOptions.queryToRequestOptions)('read', {
|
|
8
8
|
resource: 'test'
|
|
9
9
|
});
|
|
10
|
-
expect(options).toMatchInlineSnapshot(
|
|
10
|
+
expect(options).toMatchInlineSnapshot(`
|
|
11
|
+
Object {
|
|
12
|
+
"body": undefined,
|
|
13
|
+
"headers": undefined,
|
|
14
|
+
"method": "GET",
|
|
15
|
+
"signal": undefined,
|
|
16
|
+
}
|
|
17
|
+
`);
|
|
11
18
|
});
|
|
12
19
|
it('should return a valid Fetch option object for create request', () => {
|
|
13
20
|
const options = (0, _queryToRequestOptions.queryToRequestOptions)('create', {
|
|
@@ -17,7 +24,16 @@ describe('queryToRequestOptions', () => {
|
|
|
17
24
|
foo: 'bar'
|
|
18
25
|
}
|
|
19
26
|
});
|
|
20
|
-
expect(options).toMatchInlineSnapshot(
|
|
27
|
+
expect(options).toMatchInlineSnapshot(`
|
|
28
|
+
Object {
|
|
29
|
+
"body": "{\\"answer\\":42,\\"foo\\":\\"bar\\"}",
|
|
30
|
+
"headers": Object {
|
|
31
|
+
"Content-Type": "application/json",
|
|
32
|
+
},
|
|
33
|
+
"method": "POST",
|
|
34
|
+
"signal": undefined,
|
|
35
|
+
}
|
|
36
|
+
`);
|
|
21
37
|
});
|
|
22
38
|
it('should return a valid Fetch option object for update request', () => {
|
|
23
39
|
const options = (0, _queryToRequestOptions.queryToRequestOptions)('update', {
|
|
@@ -27,7 +43,16 @@ describe('queryToRequestOptions', () => {
|
|
|
27
43
|
foo: 'bar'
|
|
28
44
|
}
|
|
29
45
|
});
|
|
30
|
-
expect(options).toMatchInlineSnapshot(
|
|
46
|
+
expect(options).toMatchInlineSnapshot(`
|
|
47
|
+
Object {
|
|
48
|
+
"body": "{\\"answer\\":42,\\"foo\\":\\"bar\\"}",
|
|
49
|
+
"headers": Object {
|
|
50
|
+
"Content-Type": "application/json",
|
|
51
|
+
},
|
|
52
|
+
"method": "PATCH",
|
|
53
|
+
"signal": undefined,
|
|
54
|
+
}
|
|
55
|
+
`);
|
|
31
56
|
});
|
|
32
57
|
it('should return a valid Fetch option object for json-patch request', () => {
|
|
33
58
|
const options = (0, _queryToRequestOptions.queryToRequestOptions)('json-patch', {
|
|
@@ -37,7 +62,16 @@ describe('queryToRequestOptions', () => {
|
|
|
37
62
|
foo: 'bar'
|
|
38
63
|
}
|
|
39
64
|
});
|
|
40
|
-
expect(options).toMatchInlineSnapshot(
|
|
65
|
+
expect(options).toMatchInlineSnapshot(`
|
|
66
|
+
Object {
|
|
67
|
+
"body": "{\\"answer\\":42,\\"foo\\":\\"bar\\"}",
|
|
68
|
+
"headers": Object {
|
|
69
|
+
"Content-Type": "application/json-patch+json",
|
|
70
|
+
},
|
|
71
|
+
"method": "PATCH",
|
|
72
|
+
"signal": undefined,
|
|
73
|
+
}
|
|
74
|
+
`);
|
|
41
75
|
});
|
|
42
76
|
it('should return a valid Fetch option object for replace request', () => {
|
|
43
77
|
const options = (0, _queryToRequestOptions.queryToRequestOptions)('replace', {
|
|
@@ -47,12 +81,28 @@ describe('queryToRequestOptions', () => {
|
|
|
47
81
|
foo: 'bar'
|
|
48
82
|
}
|
|
49
83
|
});
|
|
50
|
-
expect(options).toMatchInlineSnapshot(
|
|
84
|
+
expect(options).toMatchInlineSnapshot(`
|
|
85
|
+
Object {
|
|
86
|
+
"body": "{\\"answer\\":42,\\"foo\\":\\"bar\\"}",
|
|
87
|
+
"headers": Object {
|
|
88
|
+
"Content-Type": "application/json",
|
|
89
|
+
},
|
|
90
|
+
"method": "PUT",
|
|
91
|
+
"signal": undefined,
|
|
92
|
+
}
|
|
93
|
+
`);
|
|
51
94
|
});
|
|
52
95
|
it('should return a valid Fetch option object for delete request', () => {
|
|
53
96
|
const options = (0, _queryToRequestOptions.queryToRequestOptions)('delete', {
|
|
54
97
|
resource: 'test'
|
|
55
98
|
});
|
|
56
|
-
expect(options).toMatchInlineSnapshot(
|
|
99
|
+
expect(options).toMatchInlineSnapshot(`
|
|
100
|
+
Object {
|
|
101
|
+
"body": undefined,
|
|
102
|
+
"headers": undefined,
|
|
103
|
+
"method": "DELETE",
|
|
104
|
+
"signal": undefined,
|
|
105
|
+
}
|
|
106
|
+
`);
|
|
57
107
|
});
|
|
58
108
|
});
|
|
@@ -51,17 +51,20 @@ const queryParametersMapToArray = params => Object.keys(params).reduce((out, key
|
|
|
51
51
|
|
|
52
52
|
const queryParametersToQueryString = params => {
|
|
53
53
|
const expandedParams = queryParametersMapToArray(params);
|
|
54
|
-
return expandedParams.map(({
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
return expandedParams.map((_ref) => {
|
|
55
|
+
let {
|
|
56
|
+
key,
|
|
57
|
+
value
|
|
58
|
+
} = _ref;
|
|
59
|
+
return `${encodeURIComponent(key)}=${encodeQueryParameter(value)}`;
|
|
60
|
+
}).join('&');
|
|
58
61
|
};
|
|
59
62
|
|
|
60
63
|
const actionPrefix = 'action::';
|
|
61
64
|
|
|
62
65
|
const isAction = resource => resource.startsWith(actionPrefix);
|
|
63
66
|
|
|
64
|
-
const makeActionPath = resource => (0, _path.joinPath)('dhis-web-commons',
|
|
67
|
+
const makeActionPath = resource => (0, _path.joinPath)('dhis-web-commons', `${resource.substr(actionPrefix.length)}.action`);
|
|
65
68
|
|
|
66
69
|
const skipApiVersion = (resource, config) => {
|
|
67
70
|
if (resource === 'tracker' || resource.startsWith('tracker/')) {
|
|
@@ -70,6 +73,11 @@ const skipApiVersion = (resource, config) => {
|
|
|
70
73
|
if (!((_config$serverVersion = config.serverVersion) !== null && _config$serverVersion !== void 0 && _config$serverVersion.minor) || ((_config$serverVersion2 = config.serverVersion) === null || _config$serverVersion2 === void 0 ? void 0 : _config$serverVersion2.minor) < 38) {
|
|
71
74
|
return true;
|
|
72
75
|
}
|
|
76
|
+
} // The `/api/ping` endpoint is unversioned
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
if (resource === 'ping') {
|
|
80
|
+
return true;
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
return false;
|
|
@@ -86,7 +94,7 @@ const queryToResourcePath = (link, query, type) => {
|
|
|
86
94
|
(0, _validateQuery.validateResourceQuery)(query, type);
|
|
87
95
|
|
|
88
96
|
if (Object.keys(params).length) {
|
|
89
|
-
return
|
|
97
|
+
return `${base}?${queryParametersToQueryString(params)}`;
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
return base;
|
|
@@ -17,7 +17,7 @@ const defaultConfig = {
|
|
|
17
17
|
};
|
|
18
18
|
const link = createLink(defaultConfig);
|
|
19
19
|
const apiPath = link.versionedApiPath;
|
|
20
|
-
const actionPrefix =
|
|
20
|
+
const actionPrefix = `dhis-web-commons/`;
|
|
21
21
|
const actionPostfix = '.action';
|
|
22
22
|
describe('queryToResourcePath', () => {
|
|
23
23
|
describe('action', () => {
|
|
@@ -25,7 +25,7 @@ describe('queryToResourcePath', () => {
|
|
|
25
25
|
const query = {
|
|
26
26
|
resource: 'action::test'
|
|
27
27
|
};
|
|
28
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
28
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${actionPrefix}test${actionPostfix}`);
|
|
29
29
|
});
|
|
30
30
|
it('should return action URL with a simple querystring if query parameters are passed', () => {
|
|
31
31
|
const query = {
|
|
@@ -34,7 +34,7 @@ describe('queryToResourcePath', () => {
|
|
|
34
34
|
key: 'value'
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
37
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${actionPrefix}test${actionPostfix}?key=value`);
|
|
38
38
|
});
|
|
39
39
|
});
|
|
40
40
|
describe('resource with dot', () => {
|
|
@@ -42,14 +42,14 @@ describe('queryToResourcePath', () => {
|
|
|
42
42
|
const query = {
|
|
43
43
|
resource: 'svg.pdf'
|
|
44
44
|
};
|
|
45
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
45
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/svg.pdf`);
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
it('should return resource url with no querystring if not query parameters are passed', () => {
|
|
49
49
|
const query = {
|
|
50
50
|
resource: 'test'
|
|
51
51
|
};
|
|
52
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
52
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test`);
|
|
53
53
|
});
|
|
54
54
|
it('should return resource url and singular parameter separated by ?', () => {
|
|
55
55
|
const query = {
|
|
@@ -58,7 +58,7 @@ describe('queryToResourcePath', () => {
|
|
|
58
58
|
key: 'value'
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
61
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?key=value`);
|
|
62
62
|
});
|
|
63
63
|
it('should return resource url and multiple parameters separated by ? and &', () => {
|
|
64
64
|
const query = {
|
|
@@ -68,7 +68,7 @@ describe('queryToResourcePath', () => {
|
|
|
68
68
|
param: 'value2'
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
71
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?key=value¶m=value2`);
|
|
72
72
|
});
|
|
73
73
|
it('should url encode special characters in query keys', () => {
|
|
74
74
|
const query = {
|
|
@@ -77,7 +77,7 @@ describe('queryToResourcePath', () => {
|
|
|
77
77
|
'key=42&val': 'value'
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
80
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?key%3D42%26val=value`);
|
|
81
81
|
});
|
|
82
82
|
it('should url encode special characters in string parameters', () => {
|
|
83
83
|
const query = {
|
|
@@ -87,7 +87,7 @@ describe('queryToResourcePath', () => {
|
|
|
87
87
|
param: 'value2&& 53'
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
90
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?key=value%3F%3D42¶m=value2%26%26%2053`);
|
|
91
91
|
});
|
|
92
92
|
it('should support numeric (integer and float) parameters', () => {
|
|
93
93
|
const query = {
|
|
@@ -97,7 +97,7 @@ describe('queryToResourcePath', () => {
|
|
|
97
97
|
param: 193.75
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
100
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?key=42¶m=193.75`);
|
|
101
101
|
});
|
|
102
102
|
it('should support boolean parameters', () => {
|
|
103
103
|
const query = {
|
|
@@ -107,7 +107,7 @@ describe('queryToResourcePath', () => {
|
|
|
107
107
|
someflag: true
|
|
108
108
|
}
|
|
109
109
|
};
|
|
110
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
110
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?key=42&someflag=true`);
|
|
111
111
|
});
|
|
112
112
|
it('should join array parameters with commas', () => {
|
|
113
113
|
const query = {
|
|
@@ -116,7 +116,7 @@ describe('queryToResourcePath', () => {
|
|
|
116
116
|
key: ['asdf', 123]
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
119
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?key=asdf,123`);
|
|
120
120
|
});
|
|
121
121
|
it('should include multiple filter parameters when array of filters provided', () => {
|
|
122
122
|
const query = {
|
|
@@ -125,7 +125,7 @@ describe('queryToResourcePath', () => {
|
|
|
125
125
|
filter: ['asdf', 123]
|
|
126
126
|
}
|
|
127
127
|
};
|
|
128
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
128
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${apiPath}/test?filter=asdf&filter=123`);
|
|
129
129
|
});
|
|
130
130
|
it('should NOT YET support name-aliased parameters', () => {
|
|
131
131
|
const query = {
|
|
@@ -151,13 +151,13 @@ describe('queryToResourcePath', () => {
|
|
|
151
151
|
const query = {
|
|
152
152
|
resource: 'tracker'
|
|
153
153
|
};
|
|
154
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
154
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${link.unversionedApiPath}/tracker`);
|
|
155
155
|
});
|
|
156
156
|
it('should return an unversioned endpoint sub-resources of the new tracker importer (in version 2.37)', () => {
|
|
157
157
|
const query = {
|
|
158
158
|
resource: 'tracker/test'
|
|
159
159
|
};
|
|
160
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(
|
|
160
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(link, query, 'read')).toBe(`${link.unversionedApiPath}/tracker/test`);
|
|
161
161
|
});
|
|
162
162
|
it('should return a VERSIONED endpoint for the new tracker importer (in version 2.38)', () => {
|
|
163
163
|
const query = {
|
|
@@ -170,6 +170,6 @@ describe('queryToResourcePath', () => {
|
|
|
170
170
|
patch: 0
|
|
171
171
|
}
|
|
172
172
|
};
|
|
173
|
-
expect((0, _queryToResourcePath.queryToResourcePath)(createLink(v38config), query, 'read')).toBe(
|
|
173
|
+
expect((0, _queryToResourcePath.queryToResourcePath)(createLink(v38config), query, 'read')).toBe(`${link.versionedApiPath}/tracker`);
|
|
174
174
|
});
|
|
175
175
|
});
|
|
@@ -110,7 +110,7 @@ describe('validateQuery', () => {
|
|
|
110
110
|
}
|
|
111
111
|
}, 'read')).toBe(false);
|
|
112
112
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
113
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
113
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should not use wildcard or dynamic field groups"`);
|
|
114
114
|
process.env.NODE_ENV = 'test';
|
|
115
115
|
});
|
|
116
116
|
it('Should detect missing fields', () => {
|
|
@@ -120,7 +120,7 @@ describe('validateQuery', () => {
|
|
|
120
120
|
resource: 'mapViews'
|
|
121
121
|
}, 'read')).toBe(false);
|
|
122
122
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
123
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
123
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should always specify fields to return"`);
|
|
124
124
|
process.env.NODE_ENV = 'test';
|
|
125
125
|
});
|
|
126
126
|
it('Should detect paging false', () => {
|
|
@@ -134,7 +134,7 @@ describe('validateQuery', () => {
|
|
|
134
134
|
}
|
|
135
135
|
}, 'read')).toBe(false);
|
|
136
136
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
137
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
137
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries with paging=false are deprecated and should not be used!"`);
|
|
138
138
|
expect((0, _validateQuery.validateResourceQuery)({
|
|
139
139
|
resource: 'optionSets',
|
|
140
140
|
params: {
|
|
@@ -143,7 +143,7 @@ describe('validateQuery', () => {
|
|
|
143
143
|
}
|
|
144
144
|
}, 'read')).toBe(false);
|
|
145
145
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
146
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
146
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries with paging=false are deprecated and should not be used!"`);
|
|
147
147
|
process.env.NODE_ENV = 'test';
|
|
148
148
|
});
|
|
149
149
|
it('Should detect wildcard fields', () => {
|
|
@@ -156,7 +156,7 @@ describe('validateQuery', () => {
|
|
|
156
156
|
}
|
|
157
157
|
}, 'read')).toBe(false);
|
|
158
158
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
159
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
159
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should not use wildcard or dynamic field groups"`);
|
|
160
160
|
expect((0, _validateQuery.validateResourceQuery)({
|
|
161
161
|
resource: 'organisationUnits',
|
|
162
162
|
params: {
|
|
@@ -164,7 +164,7 @@ describe('validateQuery', () => {
|
|
|
164
164
|
}
|
|
165
165
|
}, 'read')).toBe(false);
|
|
166
166
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
167
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
167
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should not use wildcard or dynamic field groups"`);
|
|
168
168
|
expect((0, _validateQuery.validateResourceQuery)({
|
|
169
169
|
resource: 'organisationUnitGroups',
|
|
170
170
|
params: {
|
|
@@ -172,7 +172,7 @@ describe('validateQuery', () => {
|
|
|
172
172
|
}
|
|
173
173
|
}, 'read')).toBe(false);
|
|
174
174
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
175
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
175
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should not use wildcard or dynamic field groups"`);
|
|
176
176
|
expect((0, _validateQuery.validateResourceQuery)({
|
|
177
177
|
resource: 'dashboards',
|
|
178
178
|
params: {
|
|
@@ -180,7 +180,7 @@ describe('validateQuery', () => {
|
|
|
180
180
|
}
|
|
181
181
|
}, 'read')).toBe(false);
|
|
182
182
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
183
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
183
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should not use wildcard or dynamic field groups"`);
|
|
184
184
|
process.env.NODE_ENV = 'test';
|
|
185
185
|
});
|
|
186
186
|
it('Should warn for multiple errors in one query', () => {
|
|
@@ -194,8 +194,8 @@ describe('validateQuery', () => {
|
|
|
194
194
|
}
|
|
195
195
|
}, 'read')).toBe(false);
|
|
196
196
|
expect(warn).toHaveBeenCalledTimes(2);
|
|
197
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
198
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
197
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries with paging=false are deprecated and should not be used!"`);
|
|
198
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should not use wildcard or dynamic field groups"`);
|
|
199
199
|
expect((0, _validateQuery.validateResourceQuery)({
|
|
200
200
|
resource: 'dashboardItems',
|
|
201
201
|
params: {
|
|
@@ -203,8 +203,8 @@ describe('validateQuery', () => {
|
|
|
203
203
|
}
|
|
204
204
|
}, 'read')).toBe(false);
|
|
205
205
|
expect(warn).toHaveBeenCalledTimes(2);
|
|
206
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
207
|
-
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot("
|
|
206
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries with paging=false are deprecated and should not be used!"`);
|
|
207
|
+
expect(warn.mock.calls.shift()[0]).toMatchInlineSnapshot(`"Data queries should always specify fields to return"`);
|
|
208
208
|
process.env.NODE_ENV = 'test';
|
|
209
209
|
});
|
|
210
210
|
});
|
|
@@ -32,9 +32,10 @@ class RestAPILink {
|
|
|
32
32
|
return (0, _fetchData.fetchData)((0, _path.joinPath)(this.config.baseUrl, path), options);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
executeResourceQuery(type, query, {
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
executeResourceQuery(type, query, _ref) {
|
|
36
|
+
let {
|
|
37
|
+
signal
|
|
38
|
+
} = _ref;
|
|
38
39
|
return this.fetch((0, _queryToResourcePath.queryToResourcePath)(this, query, type), (0, _queryToRequestOptions.queryToRequestOptions)(type, query, signal));
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -19,12 +19,13 @@ var _DataProvider = require("./DataProvider");
|
|
|
19
19
|
|
|
20
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
21
|
|
|
22
|
-
const CustomDataProvider = ({
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
const CustomDataProvider = (_ref) => {
|
|
23
|
+
let {
|
|
24
|
+
children,
|
|
25
|
+
data,
|
|
26
|
+
options,
|
|
27
|
+
queryClientOptions = _DataProvider.queryClientOptions
|
|
28
|
+
} = _ref;
|
|
28
29
|
const link = new _links.CustomDataLink(data, options);
|
|
29
30
|
const engine = new _engine.DataEngine(link);
|
|
30
31
|
const queryClient = new _reactQuery.QueryClient(queryClientOptions);
|