@mapcreator/api 5.0.0-alpha.77 → 5.0.0-alpha.78
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/LICENSE +29 -29
- package/README.md +86 -86
- package/cjs/api/choropleth.d.ts +7 -71
- package/cjs/api/choropleth.d.ts.map +1 -1
- package/cjs/api/choropleth.js +17 -26
- package/cjs/api/choropleth.js.map +1 -1
- package/esm/api/choropleth.d.ts +7 -71
- package/esm/api/choropleth.d.ts.map +1 -1
- package/esm/api/choropleth.js +16 -23
- package/esm/api/choropleth.js.map +1 -1
- package/package.json +80 -80
- package/src/README.md +126 -126
- package/src/api/choropleth.ts +47 -129
package/LICENSE
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
BSD 3-Clause License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024, Mapcreator
|
|
4
|
-
All rights reserved.
|
|
5
|
-
|
|
6
|
-
Redistribution and use in source and binary forms, with or without
|
|
7
|
-
modification, are permitted provided that the following conditions are met:
|
|
8
|
-
|
|
9
|
-
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
-
list of conditions and the following disclaimer.
|
|
11
|
-
|
|
12
|
-
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
-
this list of conditions and the following disclaimer in the documentation
|
|
14
|
-
and/or other materials provided with the distribution.
|
|
15
|
-
|
|
16
|
-
* Neither the name of the copyright holder nor the names of its
|
|
17
|
-
contributors may be used to endorse or promote products derived from
|
|
18
|
-
this software without specific prior written permission.
|
|
19
|
-
|
|
20
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024, Mapcreator
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
# Mapcreator Javascript API
|
|
2
|
-
|
|
3
|
-
The Mapcreator API is a powerful mapping service built for our front-end applications. This library is released to
|
|
4
|
-
provide a painless way of talking to the api using Javascript. See the LICENSE file for licensing information. Api
|
|
5
|
-
tokens can be granted through support requests.
|
|
6
|
-
|
|
7
|
-
## Table of contents
|
|
8
|
-
|
|
9
|
-
* [Installation](#installation)
|
|
10
|
-
* [Quick start](#quick-start)
|
|
11
|
-
* [Common usage](#common-usage)
|
|
12
|
-
* [Publishing](#publishing)
|
|
13
|
-
|
|
14
|
-
### Installation
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install @mapcreator/api --save
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
### Quick start
|
|
21
|
-
|
|
22
|
-
```javascript
|
|
23
|
-
import { authenticate, initImplicitFlow } from '@mapcreator/api/oauth';
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* You need to initialize the authentication module.
|
|
27
|
-
* This is an important step that should be completed as soon as possible after general application init.
|
|
28
|
-
*
|
|
29
|
-
* @param {string} apiUrl - Full API URL, like 'https://api.mapcreator.io'
|
|
30
|
-
* @param {string} clientId - OAuth client id, issued for particular application
|
|
31
|
-
* @param {string} [redirectUrl] - Callback URL, typically your application URL
|
|
32
|
-
* @param {string[]} [scopes] - A list of required scopes, like ['mapcreator']
|
|
33
|
-
*/
|
|
34
|
-
initImplicitFlow(
|
|
35
|
-
import.meta.env.VITE_API_HOST,
|
|
36
|
-
import.meta.env.VITE_API_CLIENT_ID,
|
|
37
|
-
import.meta.env.VITE_API_REDIRECT_URL,
|
|
38
|
-
['mapcreator'],
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
// ...
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* The subsequent command should lead to two scenarios.
|
|
45
|
-
* If the initialization function was able to obtain the token from the local storage or from the address bar,
|
|
46
|
-
* then this command is NO-OP. If the token is not found or has expired, then a redirect will be made to the
|
|
47
|
-
* authentication page (the application will unload), but when it redirects back again (see the parameter above),
|
|
48
|
-
* this method won't do anything and the application will be able to continue its work.
|
|
49
|
-
*/
|
|
50
|
-
authenticate();
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Common usage
|
|
54
|
-
|
|
55
|
-
The library exports independent methods for accessing the API. The recommended pattern for importing and using methods
|
|
56
|
-
looks like this:
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
import { updateJob } from '@mapcreator/api/job';
|
|
60
|
-
|
|
61
|
-
await updateJob(someJobId, newJobTitle);
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
You can also import methods by specifying only the package name, but this results in the use of a common file with
|
|
65
|
-
re-exports and can negatively affect the size of the resulting code if you do not need some parts of the API.
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
import { type LayerFaq, listLayerFaqs } from '@mapcreator/api';
|
|
69
|
-
|
|
70
|
-
const layerFaqs: LayerFaq = await listLayerFaqs();
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
TypeScript types are also exposed, and you can use them whenever needed.
|
|
74
|
-
|
|
75
|
-
Please consult the contents of the library. All API access files (they are located in `api` sub-folder and each file
|
|
76
|
-
generally describes methods for accessing specific entity) describe both the API type and the data type returned
|
|
77
|
-
to the application. We sincerely hope this helps you make your app development easier.
|
|
78
|
-
|
|
79
|
-
## Publishing
|
|
80
|
-
```shell
|
|
81
|
-
npm version patch # minor | major
|
|
82
|
-
npm publish
|
|
83
|
-
```
|
|
84
|
-
Until the contents of the package are stabilized, it is suggested to use the scheme with the **alpha** or **beta**
|
|
85
|
-
suffixes. And therefore the call to the first command should be replaced by manual modification of the `package.json`
|
|
86
|
-
and `package-lock.json` files (will need to change in three places).
|
|
1
|
+
# Mapcreator Javascript API
|
|
2
|
+
|
|
3
|
+
The Mapcreator API is a powerful mapping service built for our front-end applications. This library is released to
|
|
4
|
+
provide a painless way of talking to the api using Javascript. See the LICENSE file for licensing information. Api
|
|
5
|
+
tokens can be granted through support requests.
|
|
6
|
+
|
|
7
|
+
## Table of contents
|
|
8
|
+
|
|
9
|
+
* [Installation](#installation)
|
|
10
|
+
* [Quick start](#quick-start)
|
|
11
|
+
* [Common usage](#common-usage)
|
|
12
|
+
* [Publishing](#publishing)
|
|
13
|
+
|
|
14
|
+
### Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @mapcreator/api --save
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Quick start
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import { authenticate, initImplicitFlow } from '@mapcreator/api/oauth';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* You need to initialize the authentication module.
|
|
27
|
+
* This is an important step that should be completed as soon as possible after general application init.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} apiUrl - Full API URL, like 'https://api.mapcreator.io'
|
|
30
|
+
* @param {string} clientId - OAuth client id, issued for particular application
|
|
31
|
+
* @param {string} [redirectUrl] - Callback URL, typically your application URL
|
|
32
|
+
* @param {string[]} [scopes] - A list of required scopes, like ['mapcreator']
|
|
33
|
+
*/
|
|
34
|
+
initImplicitFlow(
|
|
35
|
+
import.meta.env.VITE_API_HOST,
|
|
36
|
+
import.meta.env.VITE_API_CLIENT_ID,
|
|
37
|
+
import.meta.env.VITE_API_REDIRECT_URL,
|
|
38
|
+
['mapcreator'],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// ...
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The subsequent command should lead to two scenarios.
|
|
45
|
+
* If the initialization function was able to obtain the token from the local storage or from the address bar,
|
|
46
|
+
* then this command is NO-OP. If the token is not found or has expired, then a redirect will be made to the
|
|
47
|
+
* authentication page (the application will unload), but when it redirects back again (see the parameter above),
|
|
48
|
+
* this method won't do anything and the application will be able to continue its work.
|
|
49
|
+
*/
|
|
50
|
+
authenticate();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Common usage
|
|
54
|
+
|
|
55
|
+
The library exports independent methods for accessing the API. The recommended pattern for importing and using methods
|
|
56
|
+
looks like this:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { updateJob } from '@mapcreator/api/job';
|
|
60
|
+
|
|
61
|
+
await updateJob(someJobId, newJobTitle);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
You can also import methods by specifying only the package name, but this results in the use of a common file with
|
|
65
|
+
re-exports and can negatively affect the size of the resulting code if you do not need some parts of the API.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { type LayerFaq, listLayerFaqs } from '@mapcreator/api';
|
|
69
|
+
|
|
70
|
+
const layerFaqs: LayerFaq = await listLayerFaqs();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
TypeScript types are also exposed, and you can use them whenever needed.
|
|
74
|
+
|
|
75
|
+
Please consult the contents of the library. All API access files (they are located in `api` sub-folder and each file
|
|
76
|
+
generally describes methods for accessing specific entity) describe both the API type and the data type returned
|
|
77
|
+
to the application. We sincerely hope this helps you make your app development easier.
|
|
78
|
+
|
|
79
|
+
## Publishing
|
|
80
|
+
```shell
|
|
81
|
+
npm version patch # minor | major
|
|
82
|
+
npm publish
|
|
83
|
+
```
|
|
84
|
+
Until the contents of the package are stabilized, it is suggested to use the scheme with the **alpha** or **beta**
|
|
85
|
+
suffixes. And therefore the call to the first command should be replaced by manual modification of the `package.json`
|
|
86
|
+
and `package-lock.json` files (will need to change in three places).
|
package/cjs/api/choropleth.d.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import { type ApiError, type ApiSuccess,
|
|
2
|
-
import type { RequireAtLeastOne } from 'type-fest';
|
|
1
|
+
import { type ApiError, type ApiSuccess, Flatten, Revivers } from '../utils.js';
|
|
3
2
|
import type { Polygon } from 'geojson';
|
|
4
|
-
|
|
5
|
-
data: {
|
|
6
|
-
bounding_box: string;
|
|
7
|
-
};
|
|
8
|
-
} & Omit<ApiSuccess, 'data'> | ApiError, {
|
|
9
|
-
boundingBox: Polygon;
|
|
10
|
-
}>;
|
|
3
|
+
import { RequireAtLeastOne } from 'type-fest';
|
|
11
4
|
export type ApiSearchPoint = {
|
|
12
5
|
lat: number;
|
|
13
6
|
lng: number;
|
|
@@ -24,35 +17,18 @@ type SingleOrGroupedAreaBase = {
|
|
|
24
17
|
subtitle: string;
|
|
25
18
|
svgPreview: string;
|
|
26
19
|
boundingBox: Polygon;
|
|
27
|
-
isGroup: boolean;
|
|
28
|
-
properties: Record<string, string> | null;
|
|
29
20
|
};
|
|
30
|
-
export type GroupedArea = SingleOrGroupedAreaBase
|
|
21
|
+
export type GroupedArea = SingleOrGroupedAreaBase & {
|
|
22
|
+
isGroup: true;
|
|
23
|
+
};
|
|
31
24
|
export type SingleArea = SingleOrGroupedAreaBase & {
|
|
25
|
+
isGroup: false;
|
|
32
26
|
vectorSource: string;
|
|
33
27
|
sourceLayer: string;
|
|
34
28
|
featureId: number;
|
|
29
|
+
properties: Record<string, string>;
|
|
35
30
|
};
|
|
36
31
|
export type SingleOrGroupedArea = SingleArea | GroupedArea;
|
|
37
|
-
export type ApiSingleOrGroupedArea = {
|
|
38
|
-
data: {
|
|
39
|
-
id: number;
|
|
40
|
-
title: string;
|
|
41
|
-
subtitle: string;
|
|
42
|
-
svg_preview: string;
|
|
43
|
-
bounding_box: string;
|
|
44
|
-
is_group: boolean;
|
|
45
|
-
vector_source: string | null;
|
|
46
|
-
source_layer: string | null;
|
|
47
|
-
feature_id: number | null;
|
|
48
|
-
properties: string | null;
|
|
49
|
-
};
|
|
50
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
51
|
-
export type ApiSingleOrGroupedAreaData = Flatten<Exclude<ApiSingleOrGroupedArea, ApiError>['data']>;
|
|
52
|
-
export declare const singleOrGroupedAreaRevivers: Revivers<ApiSingleOrGroupedArea, SingleOrGroupedArea>;
|
|
53
|
-
/**
|
|
54
|
-
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
55
|
-
*/
|
|
56
32
|
export declare function searchSingleOrGroupedAreas(language: string, search: RequireAtLeastOne<{
|
|
57
33
|
searchBounds?: ApiSearchBounds;
|
|
58
34
|
query?: string;
|
|
@@ -81,45 +57,5 @@ type ApiGroupedAreaChild = {
|
|
|
81
57
|
export type ApiGroupedAreaChildData = Flatten<Exclude<ApiGroupedAreaChild, ApiError>['data']>;
|
|
82
58
|
export declare const groupedAreaChildRevivers: Revivers<ApiGroupedAreaChild, GroupedAreaChild>;
|
|
83
59
|
export declare function groupedAreaChildren(groupId: number, language: string): Promise<GroupedAreaChild[]>;
|
|
84
|
-
export type MatchedGroup = {
|
|
85
|
-
id: number;
|
|
86
|
-
sml: number;
|
|
87
|
-
childrenCount: number;
|
|
88
|
-
boundingBox: Polygon;
|
|
89
|
-
matchField: string;
|
|
90
|
-
property: string;
|
|
91
|
-
name: string;
|
|
92
|
-
};
|
|
93
|
-
export type ApiMatchedGroup = {
|
|
94
|
-
data: {
|
|
95
|
-
id: number;
|
|
96
|
-
sml: number;
|
|
97
|
-
children_count: number;
|
|
98
|
-
bounding_box: string;
|
|
99
|
-
match_field: string;
|
|
100
|
-
property: string;
|
|
101
|
-
name: string;
|
|
102
|
-
};
|
|
103
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
104
|
-
export type ApiMatchedGroupData = Flatten<Exclude<ApiMatchedGroup, ApiError>['data']>;
|
|
105
|
-
export declare function getGroupsByDataSample(sample: Record<string, string[]>, language: string): Promise<MatchedGroup[]>;
|
|
106
|
-
export type BoundPolygon = {
|
|
107
|
-
index: number;
|
|
108
|
-
id: number;
|
|
109
|
-
sml: number;
|
|
110
|
-
name: string;
|
|
111
|
-
inputName: string;
|
|
112
|
-
};
|
|
113
|
-
export type ApiBoundPolygon = {
|
|
114
|
-
data: {
|
|
115
|
-
index: number;
|
|
116
|
-
id: number;
|
|
117
|
-
sml: number;
|
|
118
|
-
name: string;
|
|
119
|
-
input_name: string;
|
|
120
|
-
};
|
|
121
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
122
|
-
export type ApiBoundPolygonData = Flatten<Exclude<ApiBoundPolygon, ApiError>['data']>;
|
|
123
|
-
export declare function getBoundPolygons(groupId: number, property: string, data: string[], language: string): Promise<BoundPolygon[]>;
|
|
124
60
|
export {};
|
|
125
61
|
//# sourceMappingURL=choropleth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choropleth.d.ts","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"choropleth.d.ts","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,OAAO,EAAE,QAAQ,EAA4B,MAAM,aAAa,CAAC;AAC1G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAmBF,KAAK,uBAAuB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAGF,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG;IAClD,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAGF,MAAM,MAAM,UAAU,GAAG,uBAAuB,GAAG;IACjD,OAAO,EAAE,KAAK,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,WAAW,CAAC;AAE3D,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,CAAC;IACxB,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B,CAAC,EACF,IAAI,GAAE,SAAS,GAAG,OAAO,GAAG,MAAe,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAwBhC;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC;AAExC,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE9F,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,mBAAmB,EAAE,gBAAgB,CAGpF,CAAC;AAEF,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAWxG"}
|
package/cjs/api/choropleth.js
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.groupedAreaChildRevivers =
|
|
3
|
+
exports.groupedAreaChildRevivers = void 0;
|
|
4
4
|
exports.searchSingleOrGroupedAreas = searchSingleOrGroupedAreas;
|
|
5
5
|
exports.groupedAreaChildren = groupedAreaChildren;
|
|
6
|
-
exports.getGroupsByDataSample = getGroupsByDataSample;
|
|
7
|
-
exports.getBoundPolygons = getBoundPolygons;
|
|
8
6
|
const utils_js_1 = require("../utils.js");
|
|
9
|
-
exports.boundingBoxRevivers = {
|
|
10
|
-
boundingBox: (data) => JSON.parse(data.bounding_box),
|
|
11
|
-
};
|
|
12
|
-
exports.singleOrGroupedAreaRevivers = Object.assign(Object.assign({}, exports.boundingBoxRevivers), { properties: (data) => (data.properties != null ? JSON.parse(data.properties) : null) });
|
|
13
|
-
/**
|
|
14
|
-
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
15
|
-
*/
|
|
16
7
|
async function searchSingleOrGroupedAreas(language, search, mode = 'both') {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
/**
|
|
9
|
+
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
10
|
+
*/
|
|
11
|
+
return (0, utils_js_1.request)(`/v1/choropleth/polygons/search?${(0, utils_js_1.getSearchParams)(Object.assign(Object.assign(Object.assign(Object.assign({ language }, search.searchBounds), (search.query && { query: search.query })), (search.searchPoint && { point: search.searchPoint })), { mode }))}`).then(result => {
|
|
12
|
+
result.forEach(elem => {
|
|
13
|
+
elem.boundingBox = JSON.parse(elem.boundingBox);
|
|
14
|
+
if (!elem.isGroup) {
|
|
15
|
+
elem.properties = JSON.parse(elem.properties);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return result;
|
|
19
|
+
});
|
|
22
20
|
}
|
|
23
|
-
exports.groupedAreaChildRevivers =
|
|
21
|
+
exports.groupedAreaChildRevivers = {
|
|
22
|
+
boundingBox: (data) => JSON.parse(data.bounding_box),
|
|
23
|
+
properties: (data) => JSON.parse(data.properties),
|
|
24
|
+
};
|
|
24
25
|
async function groupedAreaChildren(groupId, language) {
|
|
25
26
|
const pathname = `/v1/choropleth/groups/${groupId}/children-optimized`;
|
|
26
27
|
const query = (0, utils_js_1.getSearchParams)({ language });
|
|
@@ -28,14 +29,4 @@ async function groupedAreaChildren(groupId, language) {
|
|
|
28
29
|
const options = { revivers: exports.groupedAreaChildRevivers };
|
|
29
30
|
return (0, utils_js_1.request)(path, null, null, options);
|
|
30
31
|
}
|
|
31
|
-
async function getGroupsByDataSample(sample, language) {
|
|
32
|
-
const path = `/v1/choropleth/groups/sample`;
|
|
33
|
-
const options = { revivers: exports.boundingBoxRevivers };
|
|
34
|
-
return (0, utils_js_1.request)(path, { sample, language }, null, options);
|
|
35
|
-
}
|
|
36
|
-
async function getBoundPolygons(groupId, property, data, language) {
|
|
37
|
-
const path = `/v1/choropleth/groups/bind`;
|
|
38
|
-
const body = { group_id: groupId, property, data, language };
|
|
39
|
-
return (0, utils_js_1.request)(path, body);
|
|
40
|
-
}
|
|
41
32
|
//# sourceMappingURL=choropleth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choropleth.js","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"choropleth.js","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":";;;AAyDA,gEAgCC;AA+BD,kDAWC;AAnID,0CAA0G;AAyDnG,KAAK,UAAU,0BAA0B,CAC9C,QAAgB,EAChB,MAIE,EACF,OAAqC,MAAM;IAE3C;;OAEG;IACH,OAAO,IAAA,kBAAO,EACZ,kCAAkC,IAAA,0BAAe,4DAC/C,QAAQ,IACL,MAAM,CAAC,YAAY,GACnB,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,GACzC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,KACxD,IAAI,IACJ,EAAE,CACL,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACd,MAAM,CAAC,OAAO,CACZ,IAAI,CAAC,EAAE;YACL,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAgC,CAAY,CAAC;YAChF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAA+B,CAA2B,CAAC;YAC/F,CAAC;QACH,CAAC,CACF,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AA0BY,QAAA,wBAAwB,GAAoD;IACvF,WAAW,EAAE,CAAC,IAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAY;IACxF,UAAU,EAAE,CAAC,IAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAA2B;CACrG,CAAC;AAEK,KAAK,UAAU,mBAAmB,CAAC,OAAe,EAAE,QAAgB;IACzE,MAAM,QAAQ,GAAG,yBAAyB,OAAO,qBAAqB,CAAC;IACvE,MAAM,KAAK,GAAG,IAAA,0BAAe,EAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,gCAAwB,EAAE,CAAC;IAMvD,OAAO,IAAA,kBAAO,EAAgD,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3F,CAAC"}
|
package/esm/api/choropleth.d.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import { type ApiError, type ApiSuccess,
|
|
2
|
-
import type { RequireAtLeastOne } from 'type-fest';
|
|
1
|
+
import { type ApiError, type ApiSuccess, Flatten, Revivers } from '../utils.js';
|
|
3
2
|
import type { Polygon } from 'geojson';
|
|
4
|
-
|
|
5
|
-
data: {
|
|
6
|
-
bounding_box: string;
|
|
7
|
-
};
|
|
8
|
-
} & Omit<ApiSuccess, 'data'> | ApiError, {
|
|
9
|
-
boundingBox: Polygon;
|
|
10
|
-
}>;
|
|
3
|
+
import { RequireAtLeastOne } from 'type-fest';
|
|
11
4
|
export type ApiSearchPoint = {
|
|
12
5
|
lat: number;
|
|
13
6
|
lng: number;
|
|
@@ -24,35 +17,18 @@ type SingleOrGroupedAreaBase = {
|
|
|
24
17
|
subtitle: string;
|
|
25
18
|
svgPreview: string;
|
|
26
19
|
boundingBox: Polygon;
|
|
27
|
-
isGroup: boolean;
|
|
28
|
-
properties: Record<string, string> | null;
|
|
29
20
|
};
|
|
30
|
-
export type GroupedArea = SingleOrGroupedAreaBase
|
|
21
|
+
export type GroupedArea = SingleOrGroupedAreaBase & {
|
|
22
|
+
isGroup: true;
|
|
23
|
+
};
|
|
31
24
|
export type SingleArea = SingleOrGroupedAreaBase & {
|
|
25
|
+
isGroup: false;
|
|
32
26
|
vectorSource: string;
|
|
33
27
|
sourceLayer: string;
|
|
34
28
|
featureId: number;
|
|
29
|
+
properties: Record<string, string>;
|
|
35
30
|
};
|
|
36
31
|
export type SingleOrGroupedArea = SingleArea | GroupedArea;
|
|
37
|
-
export type ApiSingleOrGroupedArea = {
|
|
38
|
-
data: {
|
|
39
|
-
id: number;
|
|
40
|
-
title: string;
|
|
41
|
-
subtitle: string;
|
|
42
|
-
svg_preview: string;
|
|
43
|
-
bounding_box: string;
|
|
44
|
-
is_group: boolean;
|
|
45
|
-
vector_source: string | null;
|
|
46
|
-
source_layer: string | null;
|
|
47
|
-
feature_id: number | null;
|
|
48
|
-
properties: string | null;
|
|
49
|
-
};
|
|
50
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
51
|
-
export type ApiSingleOrGroupedAreaData = Flatten<Exclude<ApiSingleOrGroupedArea, ApiError>['data']>;
|
|
52
|
-
export declare const singleOrGroupedAreaRevivers: Revivers<ApiSingleOrGroupedArea, SingleOrGroupedArea>;
|
|
53
|
-
/**
|
|
54
|
-
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
55
|
-
*/
|
|
56
32
|
export declare function searchSingleOrGroupedAreas(language: string, search: RequireAtLeastOne<{
|
|
57
33
|
searchBounds?: ApiSearchBounds;
|
|
58
34
|
query?: string;
|
|
@@ -81,45 +57,5 @@ type ApiGroupedAreaChild = {
|
|
|
81
57
|
export type ApiGroupedAreaChildData = Flatten<Exclude<ApiGroupedAreaChild, ApiError>['data']>;
|
|
82
58
|
export declare const groupedAreaChildRevivers: Revivers<ApiGroupedAreaChild, GroupedAreaChild>;
|
|
83
59
|
export declare function groupedAreaChildren(groupId: number, language: string): Promise<GroupedAreaChild[]>;
|
|
84
|
-
export type MatchedGroup = {
|
|
85
|
-
id: number;
|
|
86
|
-
sml: number;
|
|
87
|
-
childrenCount: number;
|
|
88
|
-
boundingBox: Polygon;
|
|
89
|
-
matchField: string;
|
|
90
|
-
property: string;
|
|
91
|
-
name: string;
|
|
92
|
-
};
|
|
93
|
-
export type ApiMatchedGroup = {
|
|
94
|
-
data: {
|
|
95
|
-
id: number;
|
|
96
|
-
sml: number;
|
|
97
|
-
children_count: number;
|
|
98
|
-
bounding_box: string;
|
|
99
|
-
match_field: string;
|
|
100
|
-
property: string;
|
|
101
|
-
name: string;
|
|
102
|
-
};
|
|
103
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
104
|
-
export type ApiMatchedGroupData = Flatten<Exclude<ApiMatchedGroup, ApiError>['data']>;
|
|
105
|
-
export declare function getGroupsByDataSample(sample: Record<string, string[]>, language: string): Promise<MatchedGroup[]>;
|
|
106
|
-
export type BoundPolygon = {
|
|
107
|
-
index: number;
|
|
108
|
-
id: number;
|
|
109
|
-
sml: number;
|
|
110
|
-
name: string;
|
|
111
|
-
inputName: string;
|
|
112
|
-
};
|
|
113
|
-
export type ApiBoundPolygon = {
|
|
114
|
-
data: {
|
|
115
|
-
index: number;
|
|
116
|
-
id: number;
|
|
117
|
-
sml: number;
|
|
118
|
-
name: string;
|
|
119
|
-
input_name: string;
|
|
120
|
-
};
|
|
121
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
122
|
-
export type ApiBoundPolygonData = Flatten<Exclude<ApiBoundPolygon, ApiError>['data']>;
|
|
123
|
-
export declare function getBoundPolygons(groupId: number, property: string, data: string[], language: string): Promise<BoundPolygon[]>;
|
|
124
60
|
export {};
|
|
125
61
|
//# sourceMappingURL=choropleth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choropleth.d.ts","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"choropleth.d.ts","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,OAAO,EAAE,QAAQ,EAA4B,MAAM,aAAa,CAAC;AAC1G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAmBF,KAAK,uBAAuB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAGF,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG;IAClD,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAGF,MAAM,MAAM,UAAU,GAAG,uBAAuB,GAAG;IACjD,OAAO,EAAE,KAAK,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,WAAW,CAAC;AAE3D,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,CAAC;IACxB,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B,CAAC,EACF,IAAI,GAAE,SAAS,GAAG,OAAO,GAAG,MAAe,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAwBhC;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC;AAExC,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE9F,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,mBAAmB,EAAE,gBAAgB,CAGpF,CAAC;AAEF,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAWxG"}
|
package/esm/api/choropleth.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { getSearchParams, request } from '../utils.js';
|
|
2
|
-
export const boundingBoxRevivers = {
|
|
3
|
-
boundingBox: (data) => JSON.parse(data.bounding_box),
|
|
4
|
-
};
|
|
5
|
-
export const singleOrGroupedAreaRevivers = Object.assign(Object.assign({}, boundingBoxRevivers), { properties: (data) => (data.properties != null ? JSON.parse(data.properties) : null) });
|
|
6
|
-
/**
|
|
7
|
-
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
8
|
-
*/
|
|
9
2
|
export async function searchSingleOrGroupedAreas(language, search, mode = 'both') {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
/**
|
|
4
|
+
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
5
|
+
*/
|
|
6
|
+
return request(`/v1/choropleth/polygons/search?${getSearchParams(Object.assign(Object.assign(Object.assign(Object.assign({ language }, search.searchBounds), (search.query && { query: search.query })), (search.searchPoint && { point: search.searchPoint })), { mode }))}`).then(result => {
|
|
7
|
+
result.forEach(elem => {
|
|
8
|
+
elem.boundingBox = JSON.parse(elem.boundingBox);
|
|
9
|
+
if (!elem.isGroup) {
|
|
10
|
+
elem.properties = JSON.parse(elem.properties);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
return result;
|
|
14
|
+
});
|
|
15
15
|
}
|
|
16
|
-
export const groupedAreaChildRevivers =
|
|
16
|
+
export const groupedAreaChildRevivers = {
|
|
17
|
+
boundingBox: (data) => JSON.parse(data.bounding_box),
|
|
18
|
+
properties: (data) => JSON.parse(data.properties),
|
|
19
|
+
};
|
|
17
20
|
export async function groupedAreaChildren(groupId, language) {
|
|
18
21
|
const pathname = `/v1/choropleth/groups/${groupId}/children-optimized`;
|
|
19
22
|
const query = getSearchParams({ language });
|
|
@@ -21,14 +24,4 @@ export async function groupedAreaChildren(groupId, language) {
|
|
|
21
24
|
const options = { revivers: groupedAreaChildRevivers };
|
|
22
25
|
return request(path, null, null, options);
|
|
23
26
|
}
|
|
24
|
-
export async function getGroupsByDataSample(sample, language) {
|
|
25
|
-
const path = `/v1/choropleth/groups/sample`;
|
|
26
|
-
const options = { revivers: boundingBoxRevivers };
|
|
27
|
-
return request(path, { sample, language }, null, options);
|
|
28
|
-
}
|
|
29
|
-
export async function getBoundPolygons(groupId, property, data, language) {
|
|
30
|
-
const path = `/v1/choropleth/groups/bind`;
|
|
31
|
-
const body = { group_id: groupId, property, data, language };
|
|
32
|
-
return request(path, body);
|
|
33
|
-
}
|
|
34
27
|
//# sourceMappingURL=choropleth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choropleth.js","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"choropleth.js","sourceRoot":"","sources":["../../src/api/choropleth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqD,eAAe,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAyD1G,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,QAAgB,EAChB,MAIE,EACF,OAAqC,MAAM;IAE3C;;OAEG;IACH,OAAO,OAAO,CACZ,kCAAkC,eAAe,2DAC/C,QAAQ,IACL,MAAM,CAAC,YAAY,GACnB,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,GACzC,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,KACxD,IAAI,IACJ,EAAE,CACL,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACd,MAAM,CAAC,OAAO,CACZ,IAAI,CAAC,EAAE;YACL,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAgC,CAAY,CAAC;YAChF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAA+B,CAA2B,CAAC;YAC/F,CAAC;QACH,CAAC,CACF,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AA0BD,MAAM,CAAC,MAAM,wBAAwB,GAAoD;IACvF,WAAW,EAAE,CAAC,IAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAY;IACxF,UAAU,EAAE,CAAC,IAA6B,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAA2B;CACrG,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe,EAAE,QAAgB;IACzE,MAAM,QAAQ,GAAG,yBAAyB,OAAO,qBAAqB,CAAC;IACvE,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,wBAAwB,EAAE,CAAC;IAMvD,OAAO,OAAO,CAAgD,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3F,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mapcreator/api",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
4
|
-
"description": "Mapcreator JavaScript API",
|
|
5
|
-
"license": "BSD-3-Clause",
|
|
6
|
-
"main": "./cjs/index.js",
|
|
7
|
-
"types": "./cjs/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./esm/index.d.ts",
|
|
11
|
-
"import": "./esm/index.js",
|
|
12
|
-
"require": "./cjs/index.js"
|
|
13
|
-
},
|
|
14
|
-
"./oauth": {
|
|
15
|
-
"types": "./esm/oauth.d.ts",
|
|
16
|
-
"import": "./esm/oauth.js",
|
|
17
|
-
"require": "./cjs/oauth.js"
|
|
18
|
-
},
|
|
19
|
-
"./oauth.js": {
|
|
20
|
-
"types": "./esm/oauth.d.ts",
|
|
21
|
-
"import": "./esm/oauth.js",
|
|
22
|
-
"require": "./cjs/oauth.js"
|
|
23
|
-
},
|
|
24
|
-
"./utils": {
|
|
25
|
-
"types": "./esm/utils.d.ts",
|
|
26
|
-
"import": "./esm/utils.js",
|
|
27
|
-
"require": "./cjs/utils.js"
|
|
28
|
-
},
|
|
29
|
-
"./utils.js": {
|
|
30
|
-
"types": "./esm/utils.d.ts",
|
|
31
|
-
"import": "./esm/utils.js",
|
|
32
|
-
"require": "./cjs/utils.js"
|
|
33
|
-
},
|
|
34
|
-
"./package.json": "./package.json",
|
|
35
|
-
"./*": {
|
|
36
|
-
"types": "./esm/api/*.d.ts",
|
|
37
|
-
"import": "./esm/api/*.js",
|
|
38
|
-
"require": "./cjs/api/*.js"
|
|
39
|
-
},
|
|
40
|
-
"./*.js": {
|
|
41
|
-
"types": "./esm/api/*.d.ts",
|
|
42
|
-
"import": "./esm/api/*.js",
|
|
43
|
-
"require": "./cjs/api/*.js"
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
"scripts": {
|
|
47
|
-
"build": "tsc --outDir esm && tsc -m commonjs --outDir cjs",
|
|
48
|
-
"clean": "npx rimraf esm/ cjs/",
|
|
49
|
-
"lint": "eslint --ext .ts src",
|
|
50
|
-
"prepublishOnly": "npm run lint && npm run clean && npm run build",
|
|
51
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
52
|
-
},
|
|
53
|
-
"repository": {
|
|
54
|
-
"type": "git",
|
|
55
|
-
"url": "git+https://gitlab.com/mapcreator/api-wrapper.git"
|
|
56
|
-
},
|
|
57
|
-
"publishConfig": {
|
|
58
|
-
"registry": "https://registry.npmjs.org/"
|
|
59
|
-
},
|
|
60
|
-
"files": [
|
|
61
|
-
"cjs",
|
|
62
|
-
"esm",
|
|
63
|
-
"src"
|
|
64
|
-
],
|
|
65
|
-
"bugs": {
|
|
66
|
-
"url": "https://gitlab.com/mapcreator/api-wrapper/issues"
|
|
67
|
-
},
|
|
68
|
-
"homepage": "https://gitlab.com/mapcreator/api-wrapper#readme",
|
|
69
|
-
"dependencies": {
|
|
70
|
-
"@types/geojson": "^7946.0.14",
|
|
71
|
-
"type-fest": "^4.10"
|
|
72
|
-
},
|
|
73
|
-
"devDependencies": {
|
|
74
|
-
"@stylistic/eslint-plugin": "~1.5",
|
|
75
|
-
"@typescript-eslint/eslint-plugin": "~6.15",
|
|
76
|
-
"@typescript-eslint/parser": "~6.15",
|
|
77
|
-
"eslint": "~8.57",
|
|
78
|
-
"typescript": "~5.8.3"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@mapcreator/api",
|
|
3
|
+
"version": "5.0.0-alpha.78",
|
|
4
|
+
"description": "Mapcreator JavaScript API",
|
|
5
|
+
"license": "BSD-3-Clause",
|
|
6
|
+
"main": "./cjs/index.js",
|
|
7
|
+
"types": "./cjs/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./esm/index.d.ts",
|
|
11
|
+
"import": "./esm/index.js",
|
|
12
|
+
"require": "./cjs/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./oauth": {
|
|
15
|
+
"types": "./esm/oauth.d.ts",
|
|
16
|
+
"import": "./esm/oauth.js",
|
|
17
|
+
"require": "./cjs/oauth.js"
|
|
18
|
+
},
|
|
19
|
+
"./oauth.js": {
|
|
20
|
+
"types": "./esm/oauth.d.ts",
|
|
21
|
+
"import": "./esm/oauth.js",
|
|
22
|
+
"require": "./cjs/oauth.js"
|
|
23
|
+
},
|
|
24
|
+
"./utils": {
|
|
25
|
+
"types": "./esm/utils.d.ts",
|
|
26
|
+
"import": "./esm/utils.js",
|
|
27
|
+
"require": "./cjs/utils.js"
|
|
28
|
+
},
|
|
29
|
+
"./utils.js": {
|
|
30
|
+
"types": "./esm/utils.d.ts",
|
|
31
|
+
"import": "./esm/utils.js",
|
|
32
|
+
"require": "./cjs/utils.js"
|
|
33
|
+
},
|
|
34
|
+
"./package.json": "./package.json",
|
|
35
|
+
"./*": {
|
|
36
|
+
"types": "./esm/api/*.d.ts",
|
|
37
|
+
"import": "./esm/api/*.js",
|
|
38
|
+
"require": "./cjs/api/*.js"
|
|
39
|
+
},
|
|
40
|
+
"./*.js": {
|
|
41
|
+
"types": "./esm/api/*.d.ts",
|
|
42
|
+
"import": "./esm/api/*.js",
|
|
43
|
+
"require": "./cjs/api/*.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc --outDir esm && tsc -m commonjs --outDir cjs",
|
|
48
|
+
"clean": "npx rimraf esm/ cjs/",
|
|
49
|
+
"lint": "eslint --ext .ts src",
|
|
50
|
+
"prepublishOnly": "npm run lint && npm run clean && npm run build",
|
|
51
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
52
|
+
},
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "git+https://gitlab.com/mapcreator/api-wrapper.git"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"registry": "https://registry.npmjs.org/"
|
|
59
|
+
},
|
|
60
|
+
"files": [
|
|
61
|
+
"cjs",
|
|
62
|
+
"esm",
|
|
63
|
+
"src"
|
|
64
|
+
],
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://gitlab.com/mapcreator/api-wrapper/issues"
|
|
67
|
+
},
|
|
68
|
+
"homepage": "https://gitlab.com/mapcreator/api-wrapper#readme",
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@types/geojson": "^7946.0.14",
|
|
71
|
+
"type-fest": "^4.10"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@stylistic/eslint-plugin": "~1.5",
|
|
75
|
+
"@typescript-eslint/eslint-plugin": "~6.15",
|
|
76
|
+
"@typescript-eslint/parser": "~6.15",
|
|
77
|
+
"eslint": "~8.57",
|
|
78
|
+
"typescript": "~5.8.3"
|
|
79
|
+
}
|
|
80
|
+
}
|
package/src/README.md
CHANGED
|
@@ -1,126 +1,126 @@
|
|
|
1
|
-
### Used type system
|
|
2
|
-
|
|
3
|
-
We use type declarations for both the data coming over the wire and the data used by the application. In general, these types differ only in the presence of additional fields in the data arriving over the network (like `created_at`), and used naming convention. Data over the network uses the so-called snake case.
|
|
4
|
-
|
|
5
|
-
All in all, we can use TypeScript's native mechanisms to convert one type to another and fully define just one type:
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
import type { CamelCasedProperties } from 'type-fest';
|
|
9
|
-
|
|
10
|
-
type ApiType =
|
|
11
|
-
| ({
|
|
12
|
-
data: {
|
|
13
|
-
prop: unknown;
|
|
14
|
-
} & ApiCommonData;
|
|
15
|
-
} & Omit<ApiSuccess, 'data'>)
|
|
16
|
-
| ApiError;
|
|
17
|
-
|
|
18
|
-
type AppType = CamelCasedProperties<Omit<Exclude<ApiType, ApiError>['data'], keyof ApiCommonData>>;
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
or in reverse order:
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
import type { SnakeCasedProperties } from 'type-fest';
|
|
25
|
-
|
|
26
|
-
type AppType = {
|
|
27
|
-
prop: unknown;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
type ApiType =
|
|
31
|
-
| ({
|
|
32
|
-
data: SnakeCasedProperties<AppType> & ApiCommonData;
|
|
33
|
-
} & Omit<ApiSuccess, 'data'>)
|
|
34
|
-
| ApiError;
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
But the decision was made not to do this, since it may be more difficult for the developer to make the conversion in their head than to see it in front of their eyes.
|
|
38
|
-
|
|
39
|
-
### Using a `request()`
|
|
40
|
-
|
|
41
|
-
The function has the following signature:
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
async function request<I extends ApiCommon, O extends Record<string, unknown> | string>(
|
|
45
|
-
path: string,
|
|
46
|
-
body?: XMLHttpRequestBodyInit | Record<string | number, unknown> | null,
|
|
47
|
-
extraHeaders?: Record<string, string> | null,
|
|
48
|
-
extraOptions?: ExtraOptions<I, O>,
|
|
49
|
-
): Promise<O | O[]> { /* ... */ }
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Let's take it step by step.
|
|
53
|
-
|
|
54
|
-
`I extends ApiCommon` - represents the type of data we receive over the network.
|
|
55
|
-
|
|
56
|
-
`O extends Record<string, unknown> | string` - represents the data type that will be used in the application.
|
|
57
|
-
|
|
58
|
-
Ideally you should describe and convey both types. This will help to check the data types in the arguments passed.
|
|
59
|
-
See current data types for an example.
|
|
60
|
-
|
|
61
|
-
`path: string` - the path to the resource, must include the API version, but must not include the schema or authority.
|
|
62
|
-
Example: `/v1/jobs/12345`
|
|
63
|
-
|
|
64
|
-
`body?: XMLHttpRequestBodyInit | Record<string | number, unknown> | null` - any meaningful body type. In general,
|
|
65
|
-
the presence of an JSON object is assumed (or the absence of one for methods that only request data), but you can
|
|
66
|
-
also pass `Blob`, `FormData`, `URLSearchParams` or just `ArrayBuffer`. The required content type will be added to
|
|
67
|
-
the headers automatically.
|
|
68
|
-
|
|
69
|
-
`extraHeaders?: Record<string, string> | null` - the object with additional headers.
|
|
70
|
-
|
|
71
|
-
`extraOptions?: ExtraOptions<I, O>` - where `ExtraOptions<I, O>` is defined like this:
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
interface ExtraOptions<I extends ApiCommon, O extends Record<string, unknown> | string> {
|
|
75
|
-
method?: 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
76
|
-
revivers?: O extends Record<string, unknown> ? Revivers<I, O> : never;
|
|
77
|
-
sendNull?: boolean;
|
|
78
|
-
withMeta?: boolean;
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Most fields are self-explanatory.
|
|
83
|
-
|
|
84
|
-
`sendNull` can be used if you really want to pass `null` as body content.
|
|
85
|
-
|
|
86
|
-
`revivers` is used to specify an object that can modify the behavior of the internal handler of data coming over
|
|
87
|
-
the network. Let's take a closer look at this moment.
|
|
88
|
-
|
|
89
|
-
#### Revivers
|
|
90
|
-
|
|
91
|
-
By default, the `request()` function does the following things with data coming over the network:
|
|
92
|
-
|
|
93
|
-
- It removes `created_at`, `updated_at`, `deleted_at` fields from the output objects.
|
|
94
|
-
- It preserves all the remaining fields but converts their names into camelCase.
|
|
95
|
-
|
|
96
|
-
When passing an object with revivers you can a couple of things:
|
|
97
|
-
|
|
98
|
-
- You can list the fields that you want **to exclude** from the result object. To do this, the field must be assigned an
|
|
99
|
-
`undefined` value.
|
|
100
|
-
- You can **add** new fields or **modify** the type of existing ones. To do this, you need to pass a function as a field
|
|
101
|
-
value, which will receive the original object as input.
|
|
102
|
-
|
|
103
|
-
Example:
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
const jobRevivers: Revivers<ApiJob, Job> = {
|
|
107
|
-
user_id: undefined,
|
|
108
|
-
description: undefined,
|
|
109
|
-
share_token: undefined,
|
|
110
|
-
autosave_preview_path: undefined,
|
|
111
|
-
job_folder_id: undefined,
|
|
112
|
-
|
|
113
|
-
jobTypeId: () => 9,
|
|
114
|
-
createdAt: (data: ApiJobData) => data.created_at as string,
|
|
115
|
-
previewPath: (data: ApiJobData) => data.autosave_preview_path ?? undefined,
|
|
116
|
-
};
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
`user_id`, `description`, `share_token`, `autosave_preview_path`, `job_folder_id` fields will be excluded from the
|
|
120
|
-
result object.
|
|
121
|
-
|
|
122
|
-
`jobTypeId` will be always **9**.
|
|
123
|
-
|
|
124
|
-
`createdAt` will be returned (please note that that field is excluded by default)
|
|
125
|
-
|
|
126
|
-
`previewPath` - some actions will be performed with the source data.
|
|
1
|
+
### Used type system
|
|
2
|
+
|
|
3
|
+
We use type declarations for both the data coming over the wire and the data used by the application. In general, these types differ only in the presence of additional fields in the data arriving over the network (like `created_at`), and used naming convention. Data over the network uses the so-called snake case.
|
|
4
|
+
|
|
5
|
+
All in all, we can use TypeScript's native mechanisms to convert one type to another and fully define just one type:
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import type { CamelCasedProperties } from 'type-fest';
|
|
9
|
+
|
|
10
|
+
type ApiType =
|
|
11
|
+
| ({
|
|
12
|
+
data: {
|
|
13
|
+
prop: unknown;
|
|
14
|
+
} & ApiCommonData;
|
|
15
|
+
} & Omit<ApiSuccess, 'data'>)
|
|
16
|
+
| ApiError;
|
|
17
|
+
|
|
18
|
+
type AppType = CamelCasedProperties<Omit<Exclude<ApiType, ApiError>['data'], keyof ApiCommonData>>;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
or in reverse order:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import type { SnakeCasedProperties } from 'type-fest';
|
|
25
|
+
|
|
26
|
+
type AppType = {
|
|
27
|
+
prop: unknown;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type ApiType =
|
|
31
|
+
| ({
|
|
32
|
+
data: SnakeCasedProperties<AppType> & ApiCommonData;
|
|
33
|
+
} & Omit<ApiSuccess, 'data'>)
|
|
34
|
+
| ApiError;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
But the decision was made not to do this, since it may be more difficult for the developer to make the conversion in their head than to see it in front of their eyes.
|
|
38
|
+
|
|
39
|
+
### Using a `request()`
|
|
40
|
+
|
|
41
|
+
The function has the following signature:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
async function request<I extends ApiCommon, O extends Record<string, unknown> | string>(
|
|
45
|
+
path: string,
|
|
46
|
+
body?: XMLHttpRequestBodyInit | Record<string | number, unknown> | null,
|
|
47
|
+
extraHeaders?: Record<string, string> | null,
|
|
48
|
+
extraOptions?: ExtraOptions<I, O>,
|
|
49
|
+
): Promise<O | O[]> { /* ... */ }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Let's take it step by step.
|
|
53
|
+
|
|
54
|
+
`I extends ApiCommon` - represents the type of data we receive over the network.
|
|
55
|
+
|
|
56
|
+
`O extends Record<string, unknown> | string` - represents the data type that will be used in the application.
|
|
57
|
+
|
|
58
|
+
Ideally you should describe and convey both types. This will help to check the data types in the arguments passed.
|
|
59
|
+
See current data types for an example.
|
|
60
|
+
|
|
61
|
+
`path: string` - the path to the resource, must include the API version, but must not include the schema or authority.
|
|
62
|
+
Example: `/v1/jobs/12345`
|
|
63
|
+
|
|
64
|
+
`body?: XMLHttpRequestBodyInit | Record<string | number, unknown> | null` - any meaningful body type. In general,
|
|
65
|
+
the presence of an JSON object is assumed (or the absence of one for methods that only request data), but you can
|
|
66
|
+
also pass `Blob`, `FormData`, `URLSearchParams` or just `ArrayBuffer`. The required content type will be added to
|
|
67
|
+
the headers automatically.
|
|
68
|
+
|
|
69
|
+
`extraHeaders?: Record<string, string> | null` - the object with additional headers.
|
|
70
|
+
|
|
71
|
+
`extraOptions?: ExtraOptions<I, O>` - where `ExtraOptions<I, O>` is defined like this:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface ExtraOptions<I extends ApiCommon, O extends Record<string, unknown> | string> {
|
|
75
|
+
method?: 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
76
|
+
revivers?: O extends Record<string, unknown> ? Revivers<I, O> : never;
|
|
77
|
+
sendNull?: boolean;
|
|
78
|
+
withMeta?: boolean;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Most fields are self-explanatory.
|
|
83
|
+
|
|
84
|
+
`sendNull` can be used if you really want to pass `null` as body content.
|
|
85
|
+
|
|
86
|
+
`revivers` is used to specify an object that can modify the behavior of the internal handler of data coming over
|
|
87
|
+
the network. Let's take a closer look at this moment.
|
|
88
|
+
|
|
89
|
+
#### Revivers
|
|
90
|
+
|
|
91
|
+
By default, the `request()` function does the following things with data coming over the network:
|
|
92
|
+
|
|
93
|
+
- It removes `created_at`, `updated_at`, `deleted_at` fields from the output objects.
|
|
94
|
+
- It preserves all the remaining fields but converts their names into camelCase.
|
|
95
|
+
|
|
96
|
+
When passing an object with revivers you can a couple of things:
|
|
97
|
+
|
|
98
|
+
- You can list the fields that you want **to exclude** from the result object. To do this, the field must be assigned an
|
|
99
|
+
`undefined` value.
|
|
100
|
+
- You can **add** new fields or **modify** the type of existing ones. To do this, you need to pass a function as a field
|
|
101
|
+
value, which will receive the original object as input.
|
|
102
|
+
|
|
103
|
+
Example:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const jobRevivers: Revivers<ApiJob, Job> = {
|
|
107
|
+
user_id: undefined,
|
|
108
|
+
description: undefined,
|
|
109
|
+
share_token: undefined,
|
|
110
|
+
autosave_preview_path: undefined,
|
|
111
|
+
job_folder_id: undefined,
|
|
112
|
+
|
|
113
|
+
jobTypeId: () => 9,
|
|
114
|
+
createdAt: (data: ApiJobData) => data.created_at as string,
|
|
115
|
+
previewPath: (data: ApiJobData) => data.autosave_preview_path ?? undefined,
|
|
116
|
+
};
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`user_id`, `description`, `share_token`, `autosave_preview_path`, `job_folder_id` fields will be excluded from the
|
|
120
|
+
result object.
|
|
121
|
+
|
|
122
|
+
`jobTypeId` will be always **9**.
|
|
123
|
+
|
|
124
|
+
`createdAt` will be returned (please note that that field is excluded by default)
|
|
125
|
+
|
|
126
|
+
`previewPath` - some actions will be performed with the source data.
|
package/src/api/choropleth.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import { type ApiError, type ApiSuccess,
|
|
2
|
-
|
|
3
|
-
import type { RequireAtLeastOne } from 'type-fest';
|
|
1
|
+
import { type ApiError, type ApiSuccess, Flatten, Revivers, getSearchParams, request } from '../utils.js';
|
|
4
2
|
import type { Polygon } from 'geojson';
|
|
5
|
-
|
|
6
|
-
export const boundingBoxRevivers: Revivers<
|
|
7
|
-
{ data: { bounding_box: string } } & Omit<ApiSuccess, 'data'> | ApiError,
|
|
8
|
-
{ boundingBox: Polygon }
|
|
9
|
-
> = {
|
|
10
|
-
boundingBox: (data: { bounding_box: string }) => JSON.parse(data.bounding_box) as Polygon,
|
|
11
|
-
};
|
|
3
|
+
import { RequireAtLeastOne } from 'type-fest';
|
|
12
4
|
|
|
13
5
|
export type ApiSearchPoint = {
|
|
14
6
|
lat: number;
|
|
@@ -22,54 +14,47 @@ export type ApiSearchBounds = {
|
|
|
22
14
|
max_lng: number;
|
|
23
15
|
};
|
|
24
16
|
|
|
17
|
+
type ApiSingleOrGroupedArea = {
|
|
18
|
+
id: number;
|
|
19
|
+
title: string;
|
|
20
|
+
subtitle: string;
|
|
21
|
+
svg_preview: string;
|
|
22
|
+
bounding_box: string;
|
|
23
|
+
is_group: boolean;
|
|
24
|
+
vector_source: string | null;
|
|
25
|
+
source_layer: string | null;
|
|
26
|
+
feature_id: number | null;
|
|
27
|
+
properties: Record<string, string> | null;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type ApiSingleOrGroupedAreaArray = {
|
|
31
|
+
data: ApiSingleOrGroupedArea[];
|
|
32
|
+
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
33
|
+
|
|
25
34
|
type SingleOrGroupedAreaBase = {
|
|
26
35
|
id: number;
|
|
27
36
|
title: string;
|
|
28
37
|
subtitle: string;
|
|
29
38
|
svgPreview: string;
|
|
30
39
|
boundingBox: Polygon;
|
|
31
|
-
isGroup: boolean;
|
|
32
|
-
properties: Record<string, string> | null;
|
|
33
40
|
};
|
|
34
41
|
|
|
35
42
|
// TODO don't export this once search on click is out
|
|
36
|
-
export type GroupedArea = SingleOrGroupedAreaBase
|
|
43
|
+
export type GroupedArea = SingleOrGroupedAreaBase & {
|
|
44
|
+
isGroup: true;
|
|
45
|
+
};
|
|
37
46
|
|
|
38
47
|
// TODO don't export this once search on click is out
|
|
39
48
|
export type SingleArea = SingleOrGroupedAreaBase & {
|
|
49
|
+
isGroup: false;
|
|
40
50
|
vectorSource: string;
|
|
41
51
|
sourceLayer: string;
|
|
42
52
|
featureId: number;
|
|
53
|
+
properties: Record<string, string>;
|
|
43
54
|
};
|
|
44
55
|
|
|
45
56
|
export type SingleOrGroupedArea = SingleArea | GroupedArea;
|
|
46
57
|
|
|
47
|
-
export type ApiSingleOrGroupedArea = {
|
|
48
|
-
data: {
|
|
49
|
-
id: number;
|
|
50
|
-
title: string;
|
|
51
|
-
subtitle: string;
|
|
52
|
-
svg_preview: string;
|
|
53
|
-
bounding_box: string;
|
|
54
|
-
is_group: boolean;
|
|
55
|
-
vector_source: string | null;
|
|
56
|
-
source_layer: string | null;
|
|
57
|
-
feature_id: number | null;
|
|
58
|
-
properties: string | null;
|
|
59
|
-
};
|
|
60
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
61
|
-
|
|
62
|
-
export type ApiSingleOrGroupedAreaData = Flatten<Exclude<ApiSingleOrGroupedArea, ApiError>['data']>;
|
|
63
|
-
|
|
64
|
-
export const singleOrGroupedAreaRevivers: Revivers<ApiSingleOrGroupedArea, SingleOrGroupedArea> = {
|
|
65
|
-
...boundingBoxRevivers,
|
|
66
|
-
properties: (data: ApiSingleOrGroupedAreaData) =>
|
|
67
|
-
(data.properties != null ? JSON.parse(data.properties) as Record<string, string> : null),
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
72
|
-
*/
|
|
73
58
|
export async function searchSingleOrGroupedAreas(
|
|
74
59
|
language: string,
|
|
75
60
|
search: RequireAtLeastOne<{
|
|
@@ -79,22 +64,29 @@ export async function searchSingleOrGroupedAreas(
|
|
|
79
64
|
}>,
|
|
80
65
|
mode: 'polygon' | 'group' | 'both' = 'both',
|
|
81
66
|
): Promise<SingleOrGroupedArea[]> {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
67
|
+
/**
|
|
68
|
+
* TODO When SAGA search on click is implemented, remove mode and make searchBounds required
|
|
69
|
+
*/
|
|
70
|
+
return request<ApiSingleOrGroupedAreaArray, SingleOrGroupedArea>(
|
|
71
|
+
`/v1/choropleth/polygons/search?${getSearchParams({
|
|
72
|
+
language,
|
|
73
|
+
...search.searchBounds,
|
|
74
|
+
...(search.query && { query: search.query }),
|
|
75
|
+
...(search.searchPoint && { point: search.searchPoint }),
|
|
76
|
+
mode,
|
|
77
|
+
})}`,
|
|
78
|
+
).then(result => {
|
|
79
|
+
result.forEach(
|
|
80
|
+
elem => {
|
|
81
|
+
elem.boundingBox = JSON.parse(elem.boundingBox as unknown as string) as Polygon;
|
|
82
|
+
if (!elem.isGroup) {
|
|
83
|
+
elem.properties = JSON.parse(elem.properties as unknown as string) as Record<string, string>;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
return result;
|
|
89
89
|
});
|
|
90
|
-
const path = `${pathname}?${query}`;
|
|
91
|
-
const options = { revivers: singleOrGroupedAreaRevivers };
|
|
92
|
-
|
|
93
|
-
type ApiSingleOrGroupedAreaArray = {
|
|
94
|
-
data: ApiSingleOrGroupedAreaData[];
|
|
95
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
96
|
-
|
|
97
|
-
return request<ApiSingleOrGroupedAreaArray, SingleOrGroupedArea>(path, null, null, options);
|
|
98
90
|
}
|
|
99
91
|
|
|
100
92
|
export type GroupedAreaChild = {
|
|
@@ -122,7 +114,7 @@ type ApiGroupedAreaChild = {
|
|
|
122
114
|
export type ApiGroupedAreaChildData = Flatten<Exclude<ApiGroupedAreaChild, ApiError>['data']>;
|
|
123
115
|
|
|
124
116
|
export const groupedAreaChildRevivers: Revivers<ApiGroupedAreaChild, GroupedAreaChild> = {
|
|
125
|
-
|
|
117
|
+
boundingBox: (data: ApiGroupedAreaChildData) => JSON.parse(data.bounding_box) as Polygon,
|
|
126
118
|
properties: (data: ApiGroupedAreaChildData) => JSON.parse(data.properties) as Record<string, string>,
|
|
127
119
|
};
|
|
128
120
|
|
|
@@ -138,77 +130,3 @@ export async function groupedAreaChildren(groupId: number, language: string): Pr
|
|
|
138
130
|
|
|
139
131
|
return request<ApiApiGroupedAreaChildArray, GroupedAreaChild>(path, null, null, options);
|
|
140
132
|
}
|
|
141
|
-
|
|
142
|
-
export type MatchedGroup = {
|
|
143
|
-
id: number;
|
|
144
|
-
sml: number;
|
|
145
|
-
childrenCount: number;
|
|
146
|
-
boundingBox: Polygon;
|
|
147
|
-
matchField: string;
|
|
148
|
-
property: string;
|
|
149
|
-
name: string;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
export type ApiMatchedGroup = {
|
|
153
|
-
data: {
|
|
154
|
-
id: number;
|
|
155
|
-
sml: number;
|
|
156
|
-
children_count: number;
|
|
157
|
-
bounding_box: string;
|
|
158
|
-
match_field: string;
|
|
159
|
-
property: string;
|
|
160
|
-
name: string;
|
|
161
|
-
};
|
|
162
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
163
|
-
|
|
164
|
-
export type ApiMatchedGroupData = Flatten<Exclude<ApiMatchedGroup, ApiError>['data']>;
|
|
165
|
-
|
|
166
|
-
export async function getGroupsByDataSample(
|
|
167
|
-
sample: Record<string, string[]>,
|
|
168
|
-
language: string,
|
|
169
|
-
): Promise<MatchedGroup[]> {
|
|
170
|
-
const path = `/v1/choropleth/groups/sample`;
|
|
171
|
-
const options = { revivers: boundingBoxRevivers };
|
|
172
|
-
|
|
173
|
-
type ApiMatchedGroupArray = {
|
|
174
|
-
data: ApiMatchedGroupData[];
|
|
175
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
176
|
-
|
|
177
|
-
return request<ApiMatchedGroupArray, MatchedGroup>(path, { sample, language }, null, options);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export type BoundPolygon = {
|
|
181
|
-
index: number;
|
|
182
|
-
id: number;
|
|
183
|
-
sml: number;
|
|
184
|
-
name: string;
|
|
185
|
-
inputName: string;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
export type ApiBoundPolygon = {
|
|
189
|
-
data: {
|
|
190
|
-
index: number;
|
|
191
|
-
id: number;
|
|
192
|
-
sml: number;
|
|
193
|
-
name: string;
|
|
194
|
-
input_name: string;
|
|
195
|
-
};
|
|
196
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
197
|
-
|
|
198
|
-
export type ApiBoundPolygonData = Flatten<Exclude<ApiBoundPolygon, ApiError>['data']>;
|
|
199
|
-
|
|
200
|
-
export async function getBoundPolygons(
|
|
201
|
-
groupId: number,
|
|
202
|
-
property: string,
|
|
203
|
-
data: string[],
|
|
204
|
-
language: string,
|
|
205
|
-
): Promise<BoundPolygon[]> {
|
|
206
|
-
const path = `/v1/choropleth/groups/bind`;
|
|
207
|
-
const body = { group_id: groupId, property, data, language };
|
|
208
|
-
|
|
209
|
-
type ApiBoundPolygonArray = {
|
|
210
|
-
data: ApiBoundPolygonData[];
|
|
211
|
-
} & Omit<ApiSuccess, 'data'> | ApiError;
|
|
212
|
-
|
|
213
|
-
return request<ApiBoundPolygonArray, BoundPolygon>(path, body);
|
|
214
|
-
}
|