@mapcreator/api 0.0.0-co-edit.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +86 -0
  3. package/cjs/api/apiCommon.d.ts +7 -0
  4. package/cjs/api/apiCommon.d.ts.map +1 -0
  5. package/cjs/api/apiCommon.js +31 -0
  6. package/cjs/api/apiCommon.js.map +1 -0
  7. package/cjs/api/choropleth.d.ts +138 -0
  8. package/cjs/api/choropleth.d.ts.map +1 -0
  9. package/cjs/api/choropleth.js +41 -0
  10. package/cjs/api/choropleth.js.map +1 -0
  11. package/cjs/api/color.d.ts +16 -0
  12. package/cjs/api/color.d.ts.map +1 -0
  13. package/cjs/api/color.js +8 -0
  14. package/cjs/api/color.js.map +1 -0
  15. package/cjs/api/dimension.d.ts +25 -0
  16. package/cjs/api/dimension.d.ts.map +1 -0
  17. package/cjs/api/dimension.js +14 -0
  18. package/cjs/api/dimension.js.map +1 -0
  19. package/cjs/api/dimensionSet.d.ts +15 -0
  20. package/cjs/api/dimensionSet.d.ts.map +1 -0
  21. package/cjs/api/dimensionSet.js +7 -0
  22. package/cjs/api/dimensionSet.js.map +1 -0
  23. package/cjs/api/feature.d.ts +16 -0
  24. package/cjs/api/feature.d.ts.map +1 -0
  25. package/cjs/api/feature.js +8 -0
  26. package/cjs/api/feature.js.map +1 -0
  27. package/cjs/api/font.d.ts +32 -0
  28. package/cjs/api/font.d.ts.map +1 -0
  29. package/cjs/api/font.js +15 -0
  30. package/cjs/api/font.js.map +1 -0
  31. package/cjs/api/fontFamily.d.ts +17 -0
  32. package/cjs/api/fontFamily.d.ts.map +1 -0
  33. package/cjs/api/fontFamily.js +17 -0
  34. package/cjs/api/fontFamily.js.map +1 -0
  35. package/cjs/api/geocode.d.ts +10 -0
  36. package/cjs/api/geocode.d.ts.map +1 -0
  37. package/cjs/api/geocode.js +9 -0
  38. package/cjs/api/geocode.js.map +1 -0
  39. package/cjs/api/highlight.d.ts +41 -0
  40. package/cjs/api/highlight.d.ts.map +1 -0
  41. package/cjs/api/highlight.js +25 -0
  42. package/cjs/api/highlight.js.map +1 -0
  43. package/cjs/api/insetMap.d.ts +37 -0
  44. package/cjs/api/insetMap.d.ts.map +1 -0
  45. package/cjs/api/insetMap.js +47 -0
  46. package/cjs/api/insetMap.js.map +1 -0
  47. package/cjs/api/job.d.ts +45 -0
  48. package/cjs/api/job.d.ts.map +1 -0
  49. package/cjs/api/job.js +77 -0
  50. package/cjs/api/job.js.map +1 -0
  51. package/cjs/api/jobResult.d.ts +40 -0
  52. package/cjs/api/jobResult.d.ts.map +1 -0
  53. package/cjs/api/jobResult.js +35 -0
  54. package/cjs/api/jobResult.js.map +1 -0
  55. package/cjs/api/jobRevision.d.ts +76 -0
  56. package/cjs/api/jobRevision.d.ts.map +1 -0
  57. package/cjs/api/jobRevision.js +126 -0
  58. package/cjs/api/jobRevision.js.map +1 -0
  59. package/cjs/api/jobShare.d.ts +26 -0
  60. package/cjs/api/jobShare.d.ts.map +1 -0
  61. package/cjs/api/jobShare.js +9 -0
  62. package/cjs/api/jobShare.js.map +1 -0
  63. package/cjs/api/jobType.d.ts +17 -0
  64. package/cjs/api/jobType.d.ts.map +1 -0
  65. package/cjs/api/jobType.js +11 -0
  66. package/cjs/api/jobType.js.map +1 -0
  67. package/cjs/api/language.d.ts +17 -0
  68. package/cjs/api/language.d.ts.map +1 -0
  69. package/cjs/api/language.js +3 -0
  70. package/cjs/api/language.js.map +1 -0
  71. package/cjs/api/layer.d.ts +26 -0
  72. package/cjs/api/layer.d.ts.map +1 -0
  73. package/cjs/api/layer.js +14 -0
  74. package/cjs/api/layer.js.map +1 -0
  75. package/cjs/api/layerFaq.d.ts +27 -0
  76. package/cjs/api/layerFaq.d.ts.map +1 -0
  77. package/cjs/api/layerFaq.js +16 -0
  78. package/cjs/api/layerFaq.js.map +1 -0
  79. package/cjs/api/layerGroup.d.ts +16 -0
  80. package/cjs/api/layerGroup.d.ts.map +1 -0
  81. package/cjs/api/layerGroup.js +36 -0
  82. package/cjs/api/layerGroup.js.map +1 -0
  83. package/cjs/api/mapstyleSet.d.ts +32 -0
  84. package/cjs/api/mapstyleSet.d.ts.map +1 -0
  85. package/cjs/api/mapstyleSet.js +28 -0
  86. package/cjs/api/mapstyleSet.js.map +1 -0
  87. package/cjs/api/message.d.ts +32 -0
  88. package/cjs/api/message.d.ts.map +1 -0
  89. package/cjs/api/message.js +37 -0
  90. package/cjs/api/message.js.map +1 -0
  91. package/cjs/api/organisation.d.ts +41 -0
  92. package/cjs/api/organisation.d.ts.map +1 -0
  93. package/cjs/api/organisation.js +41 -0
  94. package/cjs/api/organisation.js.map +1 -0
  95. package/cjs/api/resources.d.ts +65 -0
  96. package/cjs/api/resources.d.ts.map +1 -0
  97. package/cjs/api/resources.js +61 -0
  98. package/cjs/api/resources.js.map +1 -0
  99. package/cjs/api/svg.d.ts +21 -0
  100. package/cjs/api/svg.d.ts.map +1 -0
  101. package/cjs/api/svg.js +15 -0
  102. package/cjs/api/svg.js.map +1 -0
  103. package/cjs/api/svgSet.d.ts +22 -0
  104. package/cjs/api/svgSet.d.ts.map +1 -0
  105. package/cjs/api/svgSet.js +25 -0
  106. package/cjs/api/svgSet.js.map +1 -0
  107. package/cjs/api/user.d.ts +129 -0
  108. package/cjs/api/user.d.ts.map +1 -0
  109. package/cjs/api/user.js +145 -0
  110. package/cjs/api/user.js.map +1 -0
  111. package/cjs/index.d.ts +28 -0
  112. package/cjs/index.d.ts.map +1 -0
  113. package/cjs/index.js +53 -0
  114. package/cjs/index.js.map +1 -0
  115. package/cjs/oauth.d.ts +31 -0
  116. package/cjs/oauth.d.ts.map +1 -0
  117. package/cjs/oauth.js +76 -0
  118. package/cjs/oauth.js.map +1 -0
  119. package/cjs/utils.d.ts +72 -0
  120. package/cjs/utils.d.ts.map +1 -0
  121. package/cjs/utils.js +220 -0
  122. package/cjs/utils.js.map +1 -0
  123. package/esm/api/apiCommon.d.ts +7 -0
  124. package/esm/api/apiCommon.d.ts.map +1 -0
  125. package/esm/api/apiCommon.js +28 -0
  126. package/esm/api/apiCommon.js.map +1 -0
  127. package/esm/api/choropleth.d.ts +138 -0
  128. package/esm/api/choropleth.d.ts.map +1 -0
  129. package/esm/api/choropleth.js +34 -0
  130. package/esm/api/choropleth.js.map +1 -0
  131. package/esm/api/color.d.ts +16 -0
  132. package/esm/api/color.d.ts.map +1 -0
  133. package/esm/api/color.js +5 -0
  134. package/esm/api/color.js.map +1 -0
  135. package/esm/api/dimension.d.ts +25 -0
  136. package/esm/api/dimension.d.ts.map +1 -0
  137. package/esm/api/dimension.js +11 -0
  138. package/esm/api/dimension.js.map +1 -0
  139. package/esm/api/dimensionSet.d.ts +15 -0
  140. package/esm/api/dimensionSet.d.ts.map +1 -0
  141. package/esm/api/dimensionSet.js +4 -0
  142. package/esm/api/dimensionSet.js.map +1 -0
  143. package/esm/api/feature.d.ts +16 -0
  144. package/esm/api/feature.d.ts.map +1 -0
  145. package/esm/api/feature.js +5 -0
  146. package/esm/api/feature.js.map +1 -0
  147. package/esm/api/font.d.ts +32 -0
  148. package/esm/api/font.d.ts.map +1 -0
  149. package/esm/api/font.js +11 -0
  150. package/esm/api/font.js.map +1 -0
  151. package/esm/api/fontFamily.d.ts +17 -0
  152. package/esm/api/fontFamily.d.ts.map +1 -0
  153. package/esm/api/fontFamily.js +13 -0
  154. package/esm/api/fontFamily.js.map +1 -0
  155. package/esm/api/geocode.d.ts +10 -0
  156. package/esm/api/geocode.d.ts.map +1 -0
  157. package/esm/api/geocode.js +6 -0
  158. package/esm/api/geocode.js.map +1 -0
  159. package/esm/api/highlight.d.ts +41 -0
  160. package/esm/api/highlight.d.ts.map +1 -0
  161. package/esm/api/highlight.js +21 -0
  162. package/esm/api/highlight.js.map +1 -0
  163. package/esm/api/insetMap.d.ts +37 -0
  164. package/esm/api/insetMap.d.ts.map +1 -0
  165. package/esm/api/insetMap.js +42 -0
  166. package/esm/api/insetMap.js.map +1 -0
  167. package/esm/api/job.d.ts +45 -0
  168. package/esm/api/job.d.ts.map +1 -0
  169. package/esm/api/job.js +64 -0
  170. package/esm/api/job.js.map +1 -0
  171. package/esm/api/jobResult.d.ts +40 -0
  172. package/esm/api/jobResult.d.ts.map +1 -0
  173. package/esm/api/jobResult.js +30 -0
  174. package/esm/api/jobResult.js.map +1 -0
  175. package/esm/api/jobRevision.d.ts +76 -0
  176. package/esm/api/jobRevision.d.ts.map +1 -0
  177. package/esm/api/jobRevision.js +114 -0
  178. package/esm/api/jobRevision.js.map +1 -0
  179. package/esm/api/jobShare.d.ts +26 -0
  180. package/esm/api/jobShare.d.ts.map +1 -0
  181. package/esm/api/jobShare.js +6 -0
  182. package/esm/api/jobShare.js.map +1 -0
  183. package/esm/api/jobType.d.ts +17 -0
  184. package/esm/api/jobType.d.ts.map +1 -0
  185. package/esm/api/jobType.js +8 -0
  186. package/esm/api/jobType.js.map +1 -0
  187. package/esm/api/language.d.ts +17 -0
  188. package/esm/api/language.d.ts.map +1 -0
  189. package/esm/api/language.js +2 -0
  190. package/esm/api/language.js.map +1 -0
  191. package/esm/api/layer.d.ts +26 -0
  192. package/esm/api/layer.d.ts.map +1 -0
  193. package/esm/api/layer.js +11 -0
  194. package/esm/api/layer.js.map +1 -0
  195. package/esm/api/layerFaq.d.ts +27 -0
  196. package/esm/api/layerFaq.d.ts.map +1 -0
  197. package/esm/api/layerFaq.js +12 -0
  198. package/esm/api/layerFaq.js.map +1 -0
  199. package/esm/api/layerGroup.d.ts +16 -0
  200. package/esm/api/layerGroup.d.ts.map +1 -0
  201. package/esm/api/layerGroup.js +33 -0
  202. package/esm/api/layerGroup.js.map +1 -0
  203. package/esm/api/mapstyleSet.d.ts +32 -0
  204. package/esm/api/mapstyleSet.d.ts.map +1 -0
  205. package/esm/api/mapstyleSet.js +24 -0
  206. package/esm/api/mapstyleSet.js.map +1 -0
  207. package/esm/api/message.d.ts +32 -0
  208. package/esm/api/message.d.ts.map +1 -0
  209. package/esm/api/message.js +32 -0
  210. package/esm/api/message.js.map +1 -0
  211. package/esm/api/organisation.d.ts +41 -0
  212. package/esm/api/organisation.d.ts.map +1 -0
  213. package/esm/api/organisation.js +35 -0
  214. package/esm/api/organisation.js.map +1 -0
  215. package/esm/api/resources.d.ts +65 -0
  216. package/esm/api/resources.d.ts.map +1 -0
  217. package/esm/api/resources.js +55 -0
  218. package/esm/api/resources.js.map +1 -0
  219. package/esm/api/svg.d.ts +21 -0
  220. package/esm/api/svg.d.ts.map +1 -0
  221. package/esm/api/svg.js +11 -0
  222. package/esm/api/svg.js.map +1 -0
  223. package/esm/api/svgSet.d.ts +22 -0
  224. package/esm/api/svgSet.d.ts.map +1 -0
  225. package/esm/api/svgSet.js +21 -0
  226. package/esm/api/svgSet.js.map +1 -0
  227. package/esm/api/user.d.ts +129 -0
  228. package/esm/api/user.d.ts.map +1 -0
  229. package/esm/api/user.js +126 -0
  230. package/esm/api/user.js.map +1 -0
  231. package/esm/index.d.ts +28 -0
  232. package/esm/index.d.ts.map +1 -0
  233. package/esm/index.js +28 -0
  234. package/esm/index.js.map +1 -0
  235. package/esm/oauth.d.ts +31 -0
  236. package/esm/oauth.d.ts.map +1 -0
  237. package/esm/oauth.js +68 -0
  238. package/esm/oauth.js.map +1 -0
  239. package/esm/utils.d.ts +72 -0
  240. package/esm/utils.d.ts.map +1 -0
  241. package/esm/utils.js +206 -0
  242. package/esm/utils.js.map +1 -0
  243. package/package.json +80 -0
  244. package/src/README.md +126 -0
  245. package/src/api/apiCommon.ts +70 -0
  246. package/src/api/choropleth.ts +228 -0
  247. package/src/api/color.ts +22 -0
  248. package/src/api/dimension.ts +44 -0
  249. package/src/api/dimensionSet.ts +20 -0
  250. package/src/api/feature.ts +22 -0
  251. package/src/api/font.ts +57 -0
  252. package/src/api/fontFamily.ts +43 -0
  253. package/src/api/geocode.ts +17 -0
  254. package/src/api/highlight.ts +87 -0
  255. package/src/api/insetMap.ts +95 -0
  256. package/src/api/job.ts +139 -0
  257. package/src/api/jobResult.ts +95 -0
  258. package/src/api/jobRevision.ts +281 -0
  259. package/src/api/jobShare.ts +35 -0
  260. package/src/api/jobType.ts +26 -0
  261. package/src/api/language.ts +19 -0
  262. package/src/api/layer.ts +38 -0
  263. package/src/api/layerFaq.ts +53 -0
  264. package/src/api/layerGroup.ts +69 -0
  265. package/src/api/mapstyleSet.ts +70 -0
  266. package/src/api/message.ts +80 -0
  267. package/src/api/organisation.ts +96 -0
  268. package/src/api/resources.ts +153 -0
  269. package/src/api/svg.ts +33 -0
  270. package/src/api/svgSet.ts +56 -0
  271. package/src/api/user.ts +327 -0
  272. package/src/index.ts +44 -0
  273. package/src/oauth.ts +90 -0
  274. package/src/utils.ts +342 -0
package/src/README.md ADDED
@@ -0,0 +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.
@@ -0,0 +1,70 @@
1
+ import { type ApiJobData, type Job, jobRevivers } from './job.js';
2
+ import {
3
+ APIMeta,
4
+ type ApiError,
5
+ type ApiSuccess,
6
+ type Revivers,
7
+ defaultListHeader,
8
+ getSearchParams,
9
+ request,
10
+ } from '../utils.js';
11
+
12
+ export interface JobSearchResult {
13
+ pageCount: number;
14
+ data: Job[];
15
+ }
16
+
17
+ export async function listJobs(
18
+ pathname: string,
19
+ title: string,
20
+ page: number,
21
+ searchOptions?: Record<string, unknown>,
22
+ ): Promise<JobSearchResult> {
23
+ const defaultSearchOptions = {
24
+ sort: '-updated',
25
+ only_downloaded: false,
26
+ };
27
+
28
+ const search = { ...defaultSearchOptions, ...searchOptions };
29
+
30
+ const query = getSearchParams({
31
+ only_with_revisions: true,
32
+ search: {
33
+ job_type_id: '9',
34
+ ...(title.length > 0 && { title: `~:${title}` }),
35
+ },
36
+ ...search,
37
+ });
38
+
39
+ const path = `${pathname}?${query}`;
40
+
41
+ const headers = {
42
+ ...defaultListHeader,
43
+ 'X-Page': `${page}`,
44
+ };
45
+ const options = {
46
+ revivers: jobRevivers as Revivers<ApiJobArray, Job>,
47
+ withMeta: true,
48
+ };
49
+
50
+ type ApiJobArray = {
51
+ data: ApiJobData[];
52
+ } & Omit<ApiSuccess, 'data'> | ApiError;
53
+
54
+ const result = (await request<ApiJobArray, Job>(path, null, headers, options).catch(
55
+ (error: Error) => {
56
+ if (error instanceof APIMeta) {
57
+ const { data, headers, status } = error as APIMeta<ApiJobArray, Job>;
58
+
59
+ return { data, headers, status };
60
+ }
61
+
62
+ throw error;
63
+ },
64
+ )) as APIMeta<ApiJobArray, Job>;
65
+
66
+ return {
67
+ data: result.data,
68
+ pageCount: Number(result.headers.get('X-Paginate-Pages')),
69
+ };
70
+ }
@@ -0,0 +1,228 @@
1
+ import { type ApiError, type ApiSuccess, type Flatten, type Revivers, getSearchParams, request } from '../utils.js';
2
+
3
+ import type { RequireAtLeastOne } from 'type-fest';
4
+ 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
+ };
12
+
13
+ export type ApiSearchPoint = {
14
+ lat: number;
15
+ lng: number;
16
+ };
17
+
18
+ export type ApiSearchBounds = {
19
+ min_lat: number;
20
+ min_lng: number;
21
+ max_lat: number;
22
+ max_lng: number;
23
+ };
24
+
25
+ type SingleOrGroupedAreaBase = {
26
+ id: number;
27
+ title: string;
28
+ subtitle: string;
29
+ svgPreview: string;
30
+ boundingBox: Polygon;
31
+ };
32
+
33
+ // TODO don't export this once search on click is out
34
+ export type GroupedArea = SingleOrGroupedAreaBase & {
35
+ isGroup: true;
36
+ };
37
+
38
+ // TODO don't export this once search on click is out
39
+ export type SingleArea = SingleOrGroupedAreaBase & {
40
+ isGroup: false;
41
+ properties: Record<string, string>;
42
+ vectorSource: string;
43
+ sourceLayer: string;
44
+ featureId: number;
45
+ };
46
+
47
+ export type SingleOrGroupedArea = {
48
+ id: number;
49
+ title: string;
50
+ subtitle: string;
51
+ svgPreview: string;
52
+ boundingBox: Polygon;
53
+ isGroup: boolean;
54
+ properties: Record<string, string> | null;
55
+ vectorSource: string | null;
56
+ sourceLayer: string | null;
57
+ featureId: number | null;
58
+ };
59
+
60
+ export type ApiSingleOrGroupedArea = {
61
+ data: {
62
+ id: number;
63
+ title: string;
64
+ subtitle: string;
65
+ svg_preview: string;
66
+ bounding_box: string;
67
+ is_group: boolean;
68
+ properties: string | null;
69
+ vector_source: string | null;
70
+ source_layer: string | null;
71
+ feature_id: number | null;
72
+ };
73
+ } & Omit<ApiSuccess, 'data'> | ApiError;
74
+
75
+ export type ApiSingleOrGroupedAreaData = Flatten<Exclude<ApiSingleOrGroupedArea, ApiError>['data']>;
76
+
77
+ export const singleOrGroupedAreaRevivers: Revivers<ApiSingleOrGroupedArea, SingleOrGroupedArea> = {
78
+ ...boundingBoxRevivers,
79
+ properties: (data: ApiSingleOrGroupedAreaData) =>
80
+ (data.properties != null ? JSON.parse(data.properties) as Record<string, string> : null),
81
+ };
82
+
83
+ /**
84
+ * TODO When SAGA search on click is implemented, remove mode and make searchBounds required
85
+ */
86
+ export async function searchSingleOrGroupedAreas(
87
+ language: string,
88
+ search: RequireAtLeastOne<{
89
+ searchBounds?: ApiSearchBounds;
90
+ query?: string;
91
+ searchPoint?: ApiSearchPoint;
92
+ }>,
93
+ mode: 'polygon' | 'group' | 'both' = 'both',
94
+ ): Promise<SingleOrGroupedArea[]> {
95
+ const pathname = '/v1/choropleth/polygons/search';
96
+ const query = getSearchParams({
97
+ language,
98
+ ...search.searchBounds,
99
+ ...(search.query && { query: search.query }),
100
+ ...(search.searchPoint && { point: search.searchPoint }),
101
+ mode,
102
+ });
103
+ const path = `${pathname}?${query}`;
104
+ const options = { revivers: singleOrGroupedAreaRevivers };
105
+
106
+ type ApiSingleOrGroupedAreaArray = {
107
+ data: ApiSingleOrGroupedAreaData[];
108
+ } & Omit<ApiSuccess, 'data'> | ApiError;
109
+
110
+ return request<ApiSingleOrGroupedAreaArray, SingleOrGroupedArea>(path, null, null, options);
111
+ }
112
+
113
+ export type GroupedAreaChild = {
114
+ id: number;
115
+ title: string;
116
+ vectorSource: string;
117
+ sourceLayer: string;
118
+ featureId: number;
119
+ boundingBox: Polygon;
120
+ properties: Record<string, string>;
121
+ };
122
+
123
+ type ApiGroupedAreaChild = {
124
+ data: {
125
+ id: number;
126
+ title: string;
127
+ vector_source: string;
128
+ source_layer: string;
129
+ feature_id: number;
130
+ bounding_box: string;
131
+ properties: string;
132
+ };
133
+ } & Omit<ApiSuccess, 'data'> | ApiError;
134
+
135
+ export type ApiGroupedAreaChildData = Flatten<Exclude<ApiGroupedAreaChild, ApiError>['data']>;
136
+
137
+ export const groupedAreaChildRevivers: Revivers<ApiGroupedAreaChild, GroupedAreaChild> = {
138
+ ...boundingBoxRevivers,
139
+ properties: (data: ApiGroupedAreaChildData) => JSON.parse(data.properties) as Record<string, string>,
140
+ };
141
+
142
+ export async function groupedAreaChildren(groupId: number, language: string): Promise<GroupedAreaChild[]> {
143
+ const pathname = `/v1/choropleth/groups/${groupId}/children-optimized`;
144
+ const query = getSearchParams({ language });
145
+ const path = `${pathname}?${query}`;
146
+ const options = { revivers: groupedAreaChildRevivers };
147
+
148
+ type ApiGroupedAreaChildArray = {
149
+ data: ApiGroupedAreaChildData[];
150
+ } & Omit<ApiSuccess, 'data'> | ApiError;
151
+
152
+ return request<ApiGroupedAreaChildArray, GroupedAreaChild>(path, null, null, options);
153
+ }
154
+
155
+ export type MatchedGroup = {
156
+ id: number;
157
+ sml: number;
158
+ childrenCount: number;
159
+ matchField: string;
160
+ boundingBox: Polygon;
161
+ property: string;
162
+ name: string;
163
+ };
164
+
165
+ export type ApiMatchedGroup = {
166
+ data: {
167
+ id: number;
168
+ sml: number;
169
+ children_count: number;
170
+ match_field: string;
171
+ bounding_box: string;
172
+ property: string;
173
+ name: string;
174
+ };
175
+ } & Omit<ApiSuccess, 'data'> | ApiError;
176
+
177
+ export type ApiMatchedGroupData = Flatten<Exclude<ApiMatchedGroup, ApiError>['data']>;
178
+
179
+ export async function getGroupsByDataSample(
180
+ sample: Record<string, string[]>,
181
+ language: string,
182
+ rowCount: number,
183
+ ): Promise<MatchedGroup[]> {
184
+ const path = `/v1/choropleth/groups/sample`;
185
+ const options = { revivers: boundingBoxRevivers };
186
+
187
+ type ApiMatchedGroupArray = {
188
+ data: ApiMatchedGroupData[];
189
+ } & Omit<ApiSuccess, 'data'> | ApiError;
190
+
191
+ return request<ApiMatchedGroupArray, MatchedGroup>(path, { sample, language, row_count: rowCount }, null, options);
192
+ }
193
+
194
+ export type BoundPolygon = {
195
+ index: number;
196
+ inputName: string;
197
+ id: number;
198
+ sml: number;
199
+ name: string;
200
+ };
201
+
202
+ export type ApiBoundPolygon = {
203
+ data: {
204
+ index: number;
205
+ input_name: string;
206
+ id: number;
207
+ sml: number;
208
+ name: string;
209
+ };
210
+ } & Omit<ApiSuccess, 'data'> | ApiError;
211
+
212
+ export type ApiBoundPolygonData = Flatten<Exclude<ApiBoundPolygon, ApiError>['data']>;
213
+
214
+ export async function getBoundPolygons(
215
+ groupId: number,
216
+ property: string,
217
+ data: string[],
218
+ language: string,
219
+ ): Promise<BoundPolygon[]> {
220
+ const path = `/v1/choropleth/groups/bind`;
221
+ const body = { group_id: groupId, property, data, language };
222
+
223
+ type ApiBoundPolygonArray = {
224
+ data: ApiBoundPolygonData[];
225
+ } & Omit<ApiSuccess, 'data'> | ApiError;
226
+
227
+ return request<ApiBoundPolygonArray, BoundPolygon>(path, body);
228
+ }
@@ -0,0 +1,22 @@
1
+ import type { ApiCommonData, ApiError, ApiSuccess, Flatten, Revivers } from '../utils.js';
2
+
3
+ export type Color = {
4
+ id: number;
5
+ hex: string;
6
+ };
7
+
8
+ export type ApiColor = {
9
+ data: {
10
+ id: number; // The color id (sortable)
11
+ name: string; // The name of the color (searchable, sortable)
12
+ hex: string; // The hex value of the color (searchable, sortable)
13
+ order?: number; // TODO: not present in API specification!
14
+ } & ApiCommonData;
15
+ } & Omit<ApiSuccess, 'data'> | ApiError;
16
+
17
+ export type ApiColorData = Flatten<Exclude<ApiColor, ApiError>['data']>;
18
+
19
+ export const colorRevivers: Revivers<ApiColor, Color> = {
20
+ name: undefined,
21
+ order: undefined,
22
+ };
@@ -0,0 +1,44 @@
1
+ import type { ApiCommonData, ApiError, ApiSuccess, Flatten, Revivers } from '../utils.js';
2
+
3
+ export type OutputUnit =
4
+ | 'millimeter'
5
+ | 'centimeter'
6
+ | 'inch'
7
+ | 'pixel'
8
+ | 'pica';
9
+
10
+ export type Dimension = {
11
+ id: number;
12
+ dimensionSetId: number;
13
+ name: string;
14
+ width: number;
15
+ height: number;
16
+ dpi: number;
17
+ unit: OutputUnit;
18
+ };
19
+
20
+ export type ApiDimension = {
21
+ data: {
22
+ id: number; // The dimension id (sortable)
23
+ dimension_set_id: number; // The id of the dimension set
24
+ name: string; // The name of dimension (searchable, sortable)
25
+ width: number; // The width of the dimension (searchable, sortable)
26
+ height: number; // The height of the dimension (searchable, sortable)
27
+ dpi: number; // The dpi of the dimension
28
+ unit: string; // The unit of this dimension
29
+ } & ApiCommonData;
30
+ } & Omit<ApiSuccess, 'data'> | ApiError;
31
+
32
+ export type ApiDimensionData = Flatten<Exclude<ApiDimension, ApiError>['data']>;
33
+
34
+ const keyToUnit: { [key: string]: OutputUnit } = {
35
+ MM: 'millimeter',
36
+ CM: 'centimeter',
37
+ IN: 'inch',
38
+ PX: 'pixel',
39
+ PICA: 'pica',
40
+ };
41
+
42
+ export const dimensionRevivers: Revivers<ApiDimension, Dimension> = {
43
+ unit: (data: ApiDimensionData) => keyToUnit[data.unit],
44
+ };
@@ -0,0 +1,20 @@
1
+ import type { ApiCommonData, ApiError, ApiSuccess, Flatten, Revivers } from '../utils.js';
2
+
3
+ export type DimensionSet = {
4
+ id: number;
5
+ name: string;
6
+ };
7
+
8
+ export type ApiDimensionSet = {
9
+ data: {
10
+ id: number; // The dimension set id (sortable)
11
+ name: string; // The dimension set name (searchable, sortable)
12
+ order?: number; // TODO: not present in API specification!
13
+ } & ApiCommonData;
14
+ } & Omit<ApiSuccess, 'data'> | ApiError;
15
+
16
+ export type ApiDimensionSetData = Flatten<Exclude<ApiDimensionSet, ApiError>['data']>;
17
+
18
+ export const dimensionSetRevivers: Revivers<ApiDimensionSet, DimensionSet> = {
19
+ order: undefined,
20
+ };
@@ -0,0 +1,22 @@
1
+ import type { ApiCommonData, ApiError, ApiSuccess, Flatten, Revivers } from '../utils.js';
2
+
3
+ export type Feature = {
4
+ id: number;
5
+ name: string;
6
+ };
7
+
8
+ export type ApiFeature = {
9
+ data: {
10
+ id: number; // The feature id
11
+ name: string; // The feature name (searchable, sortable)
12
+ description: string; // The description of the feature (searchable, sortable)
13
+ order?: number; // TODO: not present in API specification!
14
+ } & ApiCommonData;
15
+ } & Omit<ApiSuccess, 'data'> | ApiError;
16
+
17
+ export type ApiFeatureData = Flatten<Exclude<ApiFeature, ApiError>['data']>;
18
+
19
+ export const featureRevivers: Revivers<ApiFeature, Feature> = {
20
+ description: undefined,
21
+ order: undefined,
22
+ };
@@ -0,0 +1,57 @@
1
+ import {
2
+ type ApiCommonData,
3
+ type ApiError,
4
+ type ApiSuccess,
5
+ type Flatten,
6
+ type Revivers,
7
+ getSearchParams,
8
+ request,
9
+ } from '../utils.js';
10
+
11
+ export type Font = {
12
+ id: number;
13
+ fontFamilyId: number;
14
+ name: string;
15
+ label: string;
16
+ weight: number;
17
+ style: string;
18
+ stretch: string;
19
+ };
20
+
21
+ export type ApiFont = {
22
+ data: {
23
+ id: number; // The id of the font (sortable)
24
+ font_family_id: number; // The id of the font family
25
+ name: string; // The name of the font (searchable, sortable)
26
+ style: string; // The font style (searchable, sortable)
27
+ stretch: string; // The font stretch (searchable, sortable)
28
+ weight: number; // The font weight (searchable, sortable)
29
+ label: string; // The label of the font (searchable, sortable)
30
+ order?: number; // TODO: not present in API specification!
31
+ } & ApiCommonData;
32
+ } & Omit<ApiSuccess, 'data'> | ApiError;
33
+
34
+ export type ApiFontData = Flatten<Exclude<ApiFont, ApiError>['data']>;
35
+
36
+ type FontSearchOptions = {
37
+ family?: string;
38
+ style?: string;
39
+ weight?: string;
40
+ };
41
+
42
+ export const fontRevivers: Revivers<ApiFont, Font> = {
43
+ order: undefined,
44
+ };
45
+
46
+ export async function getFonts(searchOptions: FontSearchOptions): Promise<Font[] | Font> {
47
+ const pathname = `/v1/fonts/search`;
48
+ const query = getSearchParams(searchOptions);
49
+
50
+ const path = `${pathname}?${query}`;
51
+
52
+ type ApiFontArray = {
53
+ data: ApiFontData[];
54
+ } & Omit<ApiSuccess, 'data'> | ApiError;
55
+
56
+ return request<ApiFontArray, Font>(path);
57
+ }
@@ -0,0 +1,43 @@
1
+ import { type ApiFontData, type Font, fontRevivers } from './font.js';
2
+ import {
3
+ type ApiCommonData,
4
+ type ApiError,
5
+ type ApiSuccess,
6
+ type Flatten,
7
+ type Revivers,
8
+ defaultListHeader,
9
+ getSearchParams,
10
+ request,
11
+ } from '../utils.js';
12
+
13
+ export type FontFamily = {
14
+ id: number;
15
+ name: string;
16
+ };
17
+
18
+ export type ApiFontFamily = {
19
+ data: {
20
+ id: number; // The id of the font family (sortable)
21
+ name: string; // The name of the font family (searchable, sortable)
22
+ order?: number; // TODO: not present in API specification!
23
+ } & ApiCommonData;
24
+ } & Omit<ApiSuccess, 'data'> | ApiError;
25
+
26
+ export type ApiFontFamilyData = Flatten<Exclude<ApiFontFamily, ApiError>['data']>;
27
+
28
+ export const fontFamilyRevivers: Revivers<ApiFontFamily, FontFamily> = {
29
+ order: undefined,
30
+ };
31
+
32
+ export async function listFontFamilyFonts(fontFamilyId: number): Promise<Font[]> {
33
+ const pathname = `/v1/fonts/families/${fontFamilyId}/items`;
34
+ const query = getSearchParams({ sort: 'order' });
35
+ const path = `${pathname}?${query}`;
36
+ const options = { revivers: fontRevivers };
37
+
38
+ type ApiFontArray = {
39
+ data: ApiFontData[];
40
+ } & Omit<ApiSuccess, 'data'> | ApiError;
41
+
42
+ return request<ApiFontArray, Font>(path, null, defaultListHeader, options);
43
+ }
@@ -0,0 +1,17 @@
1
+ import { type ApiError, type ApiSuccess, request } from '../utils.js';
2
+
3
+ export type GeocodeResult = {
4
+ index: number;
5
+ lat: number | undefined;
6
+ lng: number | undefined;
7
+ };
8
+
9
+ export async function bulkGeocode(addresses: Array<{ index: number; address: string }>): Promise<GeocodeResult[]> {
10
+ const pathname = `/v1/geocode`;
11
+
12
+ type GeocodeResultArray = {
13
+ data: GeocodeResult[];
14
+ } & Omit<ApiSuccess, 'data'> | ApiError;
15
+
16
+ return request<GeocodeResultArray, GeocodeResult>(pathname, { items: addresses });
17
+ }