@dhis2/app-service-data 3.17.0-beta.4 → 3.18.0-beta.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/README.md
CHANGED
|
@@ -9,3 +9,107 @@ This library is intended for use with the [DHIS2 Application Platform](https://g
|
|
|
9
9
|
This package is internal to `@dhis2/app-runtime` and generally should not be installed independently.
|
|
10
10
|
|
|
11
11
|
See [the docs](https://developers.dhis2.org/docs/app-runtime/getting-started) for more.
|
|
12
|
+
|
|
13
|
+
## TypeScript — typed query responses
|
|
14
|
+
|
|
15
|
+
`useDataQuery` infers the response type automatically from the query object. The default map covers all DHIS2 v43 metadata endpoints. Three patterns are supported:
|
|
16
|
+
|
|
17
|
+
### 1. Default — v43 types, fully inferred
|
|
18
|
+
|
|
19
|
+
Pass the query `as const` so TypeScript can see the literal resource name and field list. No type annotation needed.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { useDataQuery } from '@dhis2/app-runtime'
|
|
23
|
+
|
|
24
|
+
const { data } = useDataQuery({
|
|
25
|
+
dataElements: {
|
|
26
|
+
resource: 'dataElements',
|
|
27
|
+
params: { fields: ['id', 'name', 'valueType'] as const },
|
|
28
|
+
},
|
|
29
|
+
} as const)
|
|
30
|
+
|
|
31
|
+
// data?.dataElements.pager.page → number
|
|
32
|
+
// data?.dataElements.dataElements[0].id → string | undefined
|
|
33
|
+
// data?.dataElements.dataElements[0].valueType → ValueType (enum, not just string)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`as const` on the fields array is what allows TypeScript to narrow the element type. Without it the response type is broader but still valid. Without `as const` on the outer object, resource names are not captured as literals and field narrowing is skipped entirely.
|
|
37
|
+
|
|
38
|
+
### 2. Targeting a specific DHIS2 API version
|
|
39
|
+
|
|
40
|
+
If the target instance runs an older DHIS2 version, build the result type from that version's paths. `paths` comes from the version-specific entry point; `DeriveResourceTypeMap` and `InferQueryResult` are version-agnostic and always come from `@dhis2/api-types/utils`:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { useDataQuery } from '@dhis2/app-runtime'
|
|
44
|
+
import type { paths } from '@dhis2/api-types/v42'
|
|
45
|
+
import type {
|
|
46
|
+
DeriveResourceTypeMap,
|
|
47
|
+
InferQueryResult,
|
|
48
|
+
} from '@dhis2/api-types/utils'
|
|
49
|
+
|
|
50
|
+
const query = {
|
|
51
|
+
dataElements: {
|
|
52
|
+
resource: 'dataElements',
|
|
53
|
+
params: { fields: ['id', 'name', 'valueType'] as const },
|
|
54
|
+
},
|
|
55
|
+
} as const
|
|
56
|
+
|
|
57
|
+
type Result = InferQueryResult<typeof query, DeriveResourceTypeMap<paths>>
|
|
58
|
+
|
|
59
|
+
const { data } = useDataQuery<typeof query, Result>(query)
|
|
60
|
+
// data?.dataElements.dataElements[0].valueType → v42's ValueType
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`@dhis2/api-types/v40`, `/v41`, `/v42`, and `/v43` are all available.
|
|
64
|
+
|
|
65
|
+
### 3. Overriding the inferred type
|
|
66
|
+
|
|
67
|
+
Pass an explicit result type as the second generic to opt out of inference entirely — useful for custom endpoints or when the inferred type needs to be shaped differently:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { useDataQuery } from '@dhis2/app-runtime'
|
|
71
|
+
|
|
72
|
+
type MyResult = {
|
|
73
|
+
dataElements: {
|
|
74
|
+
pager: {
|
|
75
|
+
page: number
|
|
76
|
+
pageCount: number
|
|
77
|
+
total: number
|
|
78
|
+
pageSize: number
|
|
79
|
+
}
|
|
80
|
+
dataElements: Array<{ id: string; name: string; valueType: string }>
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const { data } = useDataQuery<typeof query, MyResult>(query)
|
|
85
|
+
// data?.dataElements.dataElements[0] → { id: string; name: string; valueType: string }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Tracker resources
|
|
89
|
+
|
|
90
|
+
Tracker endpoints (`tracker/enrollments`, `tracker/trackedEntities`, etc.) resolve to `unknown` with the default map because the spec types their responses opaquely. Extend the map manually to cover them:
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { useDataQuery } from '@dhis2/app-runtime'
|
|
94
|
+
import type { paths, TrackerEnrollment } from '@dhis2/api-types'
|
|
95
|
+
import type {
|
|
96
|
+
DeriveResourceTypeMap,
|
|
97
|
+
InferQueryResult,
|
|
98
|
+
} from '@dhis2/api-types/utils'
|
|
99
|
+
|
|
100
|
+
type TrackerMap = DeriveResourceTypeMap<paths> & {
|
|
101
|
+
'tracker/enrollments': TrackerEnrollment
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const query = {
|
|
105
|
+
enrollments: {
|
|
106
|
+
resource: 'tracker/enrollments',
|
|
107
|
+
params: { fields: ['enrollment', 'status'] as const },
|
|
108
|
+
},
|
|
109
|
+
} as const
|
|
110
|
+
|
|
111
|
+
type Result = InferQueryResult<typeof query, TrackerMap>
|
|
112
|
+
|
|
113
|
+
const { data } = useDataQuery<typeof query, Result>(query)
|
|
114
|
+
// data?.enrollments.enrollments[0].status → EnrollmentStatus
|
|
115
|
+
```
|
|
@@ -9,6 +9,10 @@ var _react = require("react");
|
|
|
9
9
|
var _mergeAndCompareVariables = require("./mergeAndCompareVariables");
|
|
10
10
|
var _useDataEngine = require("./useDataEngine");
|
|
11
11
|
var _useStaticInput = require("./useStaticInput");
|
|
12
|
+
// Pre-compute the default resource→item map once from the latest API version's paths type.
|
|
13
|
+
// Consumers targeting an older DHIS2 version can pass an explicit TResult built with
|
|
14
|
+
// InferQueryResult<typeof query, DeriveResourceTypeMap<v4xPaths>> as the second generic.
|
|
15
|
+
|
|
12
16
|
const useDataQuery = (query, {
|
|
13
17
|
onComplete: userOnSuccess,
|
|
14
18
|
onError: userOnError,
|
|
@@ -3,6 +3,11 @@ import { useState, useRef, useCallback, useDebugValue } from 'react';
|
|
|
3
3
|
import { mergeAndCompareVariables } from './mergeAndCompareVariables';
|
|
4
4
|
import { useDataEngine } from './useDataEngine';
|
|
5
5
|
import { useStaticInput } from './useStaticInput';
|
|
6
|
+
|
|
7
|
+
// Pre-compute the default resource→item map once from the latest API version's paths type.
|
|
8
|
+
// Consumers targeting an older DHIS2 version can pass an explicit TResult built with
|
|
9
|
+
// InferQueryResult<typeof query, DeriveResourceTypeMap<v4xPaths>> as the second generic.
|
|
10
|
+
|
|
6
11
|
export const useDataQuery = (query, {
|
|
7
12
|
onComplete: userOnSuccess,
|
|
8
13
|
onError: userOnError,
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { paths } from '@dhis2/api-types';
|
|
2
|
+
import type { DeriveResourceTypeMap, InferQueryResult } from '@dhis2/api-types/utils';
|
|
3
|
+
import type { Query, QueryOptions } from '@dhis2/data-engine';
|
|
2
4
|
import type { QueryRenderInput } from '../../types';
|
|
3
|
-
|
|
5
|
+
type DefaultMap = DeriveResourceTypeMap<paths>;
|
|
6
|
+
export declare const useDataQuery: <Q extends Query, TResult = InferQueryResult<Q, DefaultMap>>(query: Q, { onComplete: userOnSuccess, onError: userOnError, variables: initialVariables, lazy: initialLazy, }?: QueryOptions<TResult>) => QueryRenderInput<TResult>;
|
|
7
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhis2/app-service-data",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.0-beta.1",
|
|
4
4
|
"main": "./build/cjs/index.js",
|
|
5
5
|
"module": "./build/es/index.js",
|
|
6
6
|
"types": "./build/types/index.d.ts",
|
|
@@ -33,12 +33,13 @@
|
|
|
33
33
|
"coverage": "yarn test --coverage"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@dhis2/api-types": "^43.0.0-beta.a48b417",
|
|
36
37
|
"@tanstack/react-query": "^4.36.1",
|
|
37
38
|
"prop-types": "^15.7.2"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
|
-
"@dhis2/app-service-config": "3.
|
|
41
|
-
"@dhis2/data-engine": "3.
|
|
41
|
+
"@dhis2/app-service-config": "3.18.0-beta.1",
|
|
42
|
+
"@dhis2/data-engine": "3.18.0-beta.1",
|
|
42
43
|
"react": "^16.8.6 || ^18",
|
|
43
44
|
"react-dom": "^16.8.6 || ^18"
|
|
44
45
|
}
|