@mapcreator/api 5.0.0-alpha.72 → 5.0.0-alpha.73

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.
@@ -1,422 +1,126 @@
1
- import {
2
- APIMeta,
3
- type ApiCommonData,
4
- type ApiError,
5
- type ApiSuccess,
6
- type Flatten,
7
- defaultListHeader,
8
- ensureArray,
9
- getSearchParams,
10
- request,
11
- toAppType,
12
- } from '../utils.js';
13
- import type { FeatureCollection, Polygon } from 'geojson';
14
- import type { SnakeCase } from 'type-fest';
1
+ import { type ApiError, type ApiSuccess, getSearchParams, request } from '../utils.js';
2
+ import type { Polygon } from 'geojson';
3
+ import { RequireAtLeastOne } from 'type-fest';
15
4
 
16
- type FieldName = 'id' | 'name' | 'description' | 'previewJson' | 'previewPath';
17
-
18
- const processGroupData = (group: GroupChoropleth): GroupChoropleth => ({
19
- ...group,
20
- ...group.nativeParentTranslation && { nativeParentTranslation: toAppType(group.nativeParentTranslation) },
21
- ...group.nativeRelationTranslation && { nativeRelationTranslation: toAppType(group.nativeRelationTranslation) },
22
- ...group.englishParentTranslation && { englishParentTranslation: toAppType(group.englishParentTranslation) },
23
- ...group.englishRelationTranslation && { englishRelationTranslation: toAppType(group.englishRelationTranslation) },
24
- ...group.parentTranslations && { parentTranslations: ensureArray(group.parentTranslations).map(toAppType) },
25
- ...group.relationTranslations && { relationTranslations: ensureArray(group.relationTranslations).map(toAppType) },
26
- });
27
-
28
- const processPolygonData = (polygon: PolygonChoropleth): PolygonChoropleth => ({
29
- ...polygon,
30
- ...polygon.parentGroups && { parentGroups: ensureArray(polygon.parentGroups).map(toAppType).map(processGroupData) },
31
- ...polygon.nativeTranslation && { nativeTranslation: toAppType(polygon.nativeTranslation) },
32
- ...polygon.englishTranslation && { englishTranslation: toAppType(polygon.englishTranslation) },
33
- ...polygon.translations && { translations: ensureArray(polygon.translations).map(toAppType) },
34
- });
35
-
36
- export type PartialVectorChoropleth = Pick<VectorChoropleth, FieldName>;
37
-
38
- export type VectorChoropleth = {
39
- id: number;
40
- name: string;
41
- description: string;
42
- previewPath: string | null;
43
- previewJson: FeatureCollection | null;
44
-
45
- vectorSetUrl: string;
46
- sourceLayerName: string;
47
-
48
- lngMin: number;
49
- lngMax: number;
50
- latMin: number;
51
- latMax: number;
52
-
53
- keys: string[];
54
- properties: Array<Record<string, unknown>>;
5
+ export type ApiSearchPoint = {
6
+ lat: number;
7
+ lng: number;
55
8
  };
56
9
 
57
- export type ApiVectorChoropleth = {
58
- data: {
59
- id: number;
60
- name: string;
61
- description: string;
62
- preview_path: string | null;
63
- preview_json: FeatureCollection | null;
64
-
65
- vector_set_url: string;
66
- source_layer_name: string;
67
-
68
- lng_min: number;
69
- lng_max: number;
70
- lat_min: number;
71
- lat_max: number;
72
-
73
- keys: string[];
74
- properties: Array<Record<string, unknown>>;
75
- } & ApiCommonData;
76
- } & Omit<ApiSuccess, 'data'> | ApiError;
77
-
78
- export type ApiVectorChoroplethData = Flatten<Exclude<ApiVectorChoropleth, ApiError>['data']>;
79
-
80
- export async function listVectorChoropleths(name: string): Promise<PartialVectorChoropleth[]> {
81
- const pathname = `/v1/choropleths/vector`;
82
- const query = getSearchParams({ search: { name } });
83
- const path = `${pathname}?${query}`;
84
-
85
- // Only request first 50 results
86
- const headers = { ...defaultListHeader };
87
- const options = { withMeta: true };
88
-
89
- type ApiVectorChoroplethArray = {
90
- data: Array<Pick<ApiVectorChoroplethData, SnakeCase<FieldName>>>;
91
- } & Omit<ApiSuccess, 'data'> | ApiError;
92
-
93
- return request<ApiVectorChoroplethArray, PartialVectorChoropleth>(path, null, headers, options)
94
- .catch((error: Error) => {
95
- if (error instanceof APIMeta) {
96
- return (error as APIMeta<ApiVectorChoroplethArray, PartialVectorChoropleth>).data;
97
- }
98
-
99
- throw error;
100
- });
101
- }
102
-
103
- export async function getVectorChoropleth(choroplethId: number): Promise<VectorChoropleth> {
104
- const path = `/v1/choropleths/vector/${choroplethId}`;
105
-
106
- return request<ApiVectorChoropleth, VectorChoropleth>(path);
107
- }
108
-
109
- export type SearchBounds = {
10
+ export type ApiSearchBounds = {
110
11
  min_lat: number;
111
12
  min_lng: number;
112
13
  max_lat: number;
113
14
  max_lng: number;
114
15
  };
115
16
 
116
- export type PolygonChoropleth = {
117
- sml: string;
17
+ type ApiSingleOrGroupedArea = {
118
18
  id: number;
119
- vectorSource: string;
120
- sourceLayer: string;
121
- featureId: number;
122
- svgPreview: string;
123
- previewPath: string;
124
- allowSingle: boolean;
125
- properties: Record<string, unknown>;
126
- boundingBox: Polygon;
127
- restrictedOwnership: number[] | null;
128
- linkId: number | null;
129
- cloning: boolean;
130
- nativeTranslation: {
131
- polygonId: number;
132
- name: string;
133
- };
134
- englishTranslation?: {
135
- polygonId: number;
136
- name: string;
137
- };
138
- translations?: Array<{
139
- polygonId: number;
140
- language: string;
141
- name: string;
142
- }>;
143
- parentGroups: GroupChoropleth[];
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;
144
28
  };
145
29
 
146
- export type ApiPolygonChoropleth = {
147
- data: {
148
- sml: string;
149
- id: number;
150
- vector_source: string;
151
- source_layer: string;
152
- feature_id: number;
153
- svg_preview: string;
154
- preview_path: string;
155
- allow_single: boolean;
156
- properties: Record<string, unknown>;
157
- bounding_box: Polygon;
158
- restricted_ownership: number[] | null;
159
- link_id: number | null;
160
- cloning: boolean;
161
- native_translation: {
162
- polygon_id: number;
163
- name: string;
164
- };
165
- english_translation?: {
166
- polygon_id: number;
167
- name: string;
168
- };
169
- translations?: Array<{
170
- polygon_id: number;
171
- language: string;
172
- name: string;
173
- }>;
174
- parent_groups: ApiGroupChoroplethData[];
175
- } & ApiCommonData;
30
+ type ApiSingleOrGroupedAreaArray = {
31
+ data: ApiSingleOrGroupedArea[];
176
32
  } & Omit<ApiSuccess, 'data'> | ApiError;
177
33
 
178
- export type ApiPolygonChoroplethData = Flatten<Exclude<ApiPolygonChoropleth, ApiError>['data']>;
179
-
180
- export async function listPolygonChoropleths(
181
- name: string,
182
- languages: string[],
183
- searchBounds?: SearchBounds,
184
- withParentGroups = false,
185
- ): Promise<PolygonChoropleth[]> {
186
- const pathname = `/v1/choropleth/polygons`;
187
- const query = getSearchParams(
188
- {
189
- search: { name, allow_single: true },
190
- with_parent_groups: withParentGroups,
191
- languages,
192
- ...searchBounds,
193
- },
194
- );
195
- const path = `${pathname}?${query}`;
196
-
197
- // Only request first 50 results
198
- const headers = { ...defaultListHeader };
199
- const options = { withMeta: true };
200
-
201
- type ApiPolygonChoroplethArray = {
202
- data: ApiPolygonChoroplethData[];
203
- } & Omit<ApiSuccess, 'data'> | ApiError;
204
-
205
- return request<ApiPolygonChoroplethArray, PolygonChoropleth>(path, null, headers, options)
206
- .catch((error: Error) => {
207
- if (error instanceof APIMeta) {
208
- return (error as APIMeta<ApiPolygonChoroplethArray, PolygonChoropleth>).data;
209
- }
210
-
211
- throw error;
212
- })
213
- .then(result => result.map(processPolygonData));
214
- }
215
-
216
- export type GroupChoropleth = {
34
+ type SingleOrGroupedAreaBase = {
217
35
  id: number;
218
- polygonId: number;
219
- relationId: number;
220
- childrenCount: number;
221
- sml?: string;
36
+ title: string;
37
+ subtitle: string;
222
38
  svgPreview: string;
223
- previewPath: string;
224
- uniqueProperties: string[];
225
39
  boundingBox: Polygon;
226
- partialProperties: string[];
227
- restrictedOwnership: number[] | null;
228
- linkId: number | null;
229
- cloning: boolean;
230
- laravelThroughKey?: number;
231
- nativeParentTranslation: {
232
- polygonId: number;
233
- name: string;
234
- laravelThroughKey: number;
235
- };
236
- nativeRelationTranslation: {
237
- relationId: number;
238
- name: string;
239
- laravelThroughKey: number;
240
- };
241
- englishParentTranslation?: {
242
- polygonId: number;
243
- name: string;
244
- laravelThroughKey: number;
245
- };
246
- englishRelationTranslation?: {
247
- relationId: number;
248
- name: string;
249
- laravelThroughKey: number;
250
- };
251
- parentTranslations?: Array<{
252
- polygonId: number;
253
- name: string;
254
- language: string;
255
- laravelThroughKey: number;
256
- }>;
257
- relationTranslations?: Array<{
258
- relationId: number;
259
- name: string;
260
- language: string;
261
- laravelThroughKey: number;
262
- }>;
263
40
  };
264
41
 
265
- export type ApiGroupChoropleth = {
266
- data: {
267
- id: number;
268
- polygon_id: number;
269
- relation_id: number;
270
- children_count: number;
271
- sml?: number;
272
- svg_preview: string;
273
- preview_path: string;
274
- unique_properties: string[];
275
- bounding_box: Polygon;
276
- partial_properties: string[];
277
- restricted_ownership: number[] | null;
278
- link_id: number | null;
279
- cloning: boolean;
280
- laravel_through_key?: number;
281
- native_parent_translation: {
282
- polygon_id: number;
283
- name: string;
284
- laravel_through_key: number;
285
- };
286
- native_relation_translation: {
287
- relation_id: number;
288
- name: string;
289
- laravel_through_key: number;
290
- };
291
- english_parent_translation?: {
292
- polygon_id: number;
293
- name: string;
294
- laravel_through_key: number;
295
- };
296
- english_relation_translation?: {
297
- relation_id: number;
298
- name: string;
299
- laravel_through_key: number;
300
- };
301
- parent_translations?: Array<{
302
- polygon_id: number;
303
- name: string;
304
- language: string;
305
- laravel_through_key: number;
306
- }>;
307
- relation_translations?: Array<{
308
- relation_id: number;
309
- name: string;
310
- language: string;
311
- laravel_through_key: number;
312
- }>;
313
- } & ApiCommonData;
314
- } & Omit<ApiSuccess, 'data'> | ApiError;
315
-
316
- export type ApiGroupChoroplethData = Flatten<Exclude<ApiGroupChoropleth, ApiError>['data']>;
317
-
318
- export async function listGroupChoropleths(
319
- name: string,
320
- languages: string[],
321
- searchBounds?: SearchBounds,
322
- ): Promise<GroupChoropleth[]> {
323
- const pathname = `/v1/choropleth/groups`;
324
- const query = getSearchParams({ search: { name }, languages, ...searchBounds });
325
- const path = `${pathname}?${query}`;
326
-
327
- // Only request first 50 results
328
- const headers = { ...defaultListHeader };
329
- const options = { withMeta: true };
330
-
331
- type ApiGroupChoroplethArray = {
332
- data: ApiGroupChoroplethData[];
333
- } & Omit<ApiSuccess, 'data'> | ApiError;
334
-
335
- return request<ApiGroupChoroplethArray, GroupChoropleth>(path, null, headers, options)
336
- .catch((error: Error) => {
337
- if (error instanceof APIMeta) {
338
- return (error as APIMeta<ApiGroupChoroplethArray, GroupChoropleth>).data;
339
- }
340
-
341
- throw error;
342
- })
343
- .then(result => result.map(processGroupData));
344
- }
345
-
346
- export async function listChildrenGroupChoropleths(
347
- groupId: number,
348
- languages: string[],
349
- ): Promise<PolygonChoropleth[]> {
350
- const pathname = `/v1/choropleth/groups/${groupId}/children`;
351
- const query = getSearchParams({ languages });
352
- const path = `${pathname}?${query}`;
353
-
354
- type ApiPolygonChoroplethArray = {
355
- data: ApiPolygonChoroplethData[];
356
- } & Omit<ApiSuccess, 'data'> | ApiError;
357
-
358
- return request<ApiPolygonChoroplethArray, PolygonChoropleth>(path).then(polygons => polygons.map(processPolygonData));
359
- }
360
-
361
- export type MatchedGroup = {
362
- id: number;
363
- sml: number;
364
- childrenCount: number;
365
- matchField: string;
366
- property: string;
367
- name: string;
42
+ // TODO don't export this once search on click is out
43
+ export type GroupedArea = SingleOrGroupedAreaBase & {
44
+ isGroup: true;
368
45
  };
369
46
 
370
- export type ApiMatchedGroup = {
371
- id: number;
372
- sml: number;
373
- children_count: number;
374
- match_field: string;
375
- property: string;
376
- name: string;
47
+ // TODO don't export this once search on click is out
48
+ export type SingleArea = SingleOrGroupedAreaBase & {
49
+ isGroup: false;
50
+ vectorSource: string;
51
+ sourceLayer: string;
52
+ featureId: number;
53
+ properties: Record<string, string>;
377
54
  };
378
55
 
379
- export async function getGroupsByDataSample(
380
- sample: Record<string, string[]>,
381
- language: string,
382
- ): Promise<MatchedGroup[]> {
383
- const path = `/v1/choropleth/groups/sample`;
384
-
385
- type ApiMatchedGroupArray = {
386
- data: ApiMatchedGroup[];
387
- } & Omit<ApiSuccess, 'data'> | ApiError;
56
+ export type SingleOrGroupedArea = SingleArea | GroupedArea;
388
57
 
389
- return request<ApiMatchedGroupArray, MatchedGroup>(path, { sample, language });
58
+ export async function searchSingleOrGroupedAreas(
59
+ language: string,
60
+ search: RequireAtLeastOne<{
61
+ searchBounds?: ApiSearchBounds;
62
+ query?: string;
63
+ searchPoint?: ApiSearchPoint;
64
+ }>,
65
+ mode: 'polygon' | 'group' | 'both' = 'both',
66
+ ): Promise<SingleOrGroupedArea[]> {
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
+ });
390
90
  }
391
91
 
392
- export type BoundPolygon = {
393
- index: number;
92
+ type ApiGroupedAreaChild = {
394
93
  id: number;
395
- sml: number;
396
- name: string;
397
- inputName: string;
94
+ title: string;
95
+ vector_source: string;
96
+ source_layer: string;
97
+ feature_id: number;
98
+ properties: Record<string, string>;
398
99
  };
399
100
 
400
- export type ApiBoundPolygon = {
401
- index: number;
101
+ type ApiGroupedAreaChildArray = {
102
+ data: ApiGroupedAreaChild[];
103
+ } & Omit<ApiSuccess, 'data'> | ApiError;
104
+
105
+ export type GroupedAreaChild = {
402
106
  id: number;
403
- sml: number;
404
- name: string;
405
- input_name: string;
107
+ title: string;
108
+ vectorSource: string;
109
+ sourceLayer: string;
110
+ featureId: number;
111
+ properties: Record<string, string>;
406
112
  };
407
113
 
408
- export async function getBoundPolygons(
409
- groupId: number,
410
- property: string,
411
- data: string[],
412
- language: string,
413
- ): Promise<BoundPolygon[]> {
414
- const path = `/v1/choropleth/groups/bind`;
415
- const postBody = { group_id: groupId, property, data, language };
416
-
417
- type ApiBoundPolygonArray = {
418
- data: ApiBoundPolygon[];
419
- } & Omit<ApiSuccess, 'data'> | ApiError;
114
+ export async function groupedAreaChildren(groupId: number, language: string): Promise<GroupedAreaChild[]> {
115
+ return request<ApiGroupedAreaChildArray, GroupedAreaChild>(
116
+ `/v1/choropleth/groups/${groupId}/children-optimized?${getSearchParams({ language })}`,
117
+ ).then(result => {
118
+ result.forEach(
119
+ elem => {
120
+ elem.properties = JSON.parse(elem.properties as unknown as string) as Record<string, string>;
121
+ }
122
+ );
420
123
 
421
- return request<ApiBoundPolygonArray, BoundPolygon>(path, postBody);
124
+ return result;
125
+ });
422
126
  }