@opengeoweb/api 19.1.0 → 19.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/README.md ADDED
@@ -0,0 +1,224 @@
1
+ ![current version](https://img.shields.io/badge/dynamic/json?color=blue&label=version&query=version&url=https://gitlab.com/opengeoweb/opengeoweb/raw/master/libs/api/package.json)
2
+ ![coverage](https://gitlab.com/opengeoweb/opengeoweb/badges/master/coverage.svg?job=test-api)
3
+
4
+ # content
5
+
6
+ - [api](#api)
7
+ - [Running unit tests](#running-unit-tests)
8
+ - [Setup the api](#setup-the-api)
9
+ - [1. Define a type for the api.](#1-define-a-type-for-the-api)
10
+ - [2. Define routes for your api.](#2-define-routes-for-your-api)
11
+ - [3. Create a createApi method to initiate the api](#3-create-a-createapi-method-to-initiate-the-api)
12
+ - [4. Define a baseURL inside config.json](#4-define-a-baseurl-inside-configjson)
13
+ - [5. Define a `fakeApi`.](#5-define-a--fakeapi-)
14
+ - [How to use the api](#how-to-use-the-api)
15
+ - [Use api inside app for production (api.ts)](#use-api-inside-app-for-production--apits-)
16
+ - [Use (fake)api inside libs for storybook](#use--fake-api-inside-libs-for-storybook)
17
+ - [Use the `useApiContext` to access the api or fakeApi](#use-the--useapicontext--to-access-the-api-or-fakeapi)
18
+
19
+ <small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
20
+
21
+ # Api
22
+
23
+ This library was generated with [Nx](https://nx.dev). The api lib makes it possible to use `ApiProvider` to wrap your components and make the `api` accessible by using the `useApiContext` hook.
24
+
25
+ ## Running unit tests
26
+
27
+ Run `nx test api` to execute the unit tests via [Jest](https://jestjs.io).
28
+
29
+ ## Setup the api
30
+
31
+ ### 1. Define a type for the api.
32
+
33
+ Create a file called `api`, and create a type for the api. This should be a type that returns promises. Example:
34
+
35
+ ```
36
+ // api.ts
37
+ export type AppApi = {
38
+ getInitialPresets: (
39
+ config: ConfigType,
40
+ ) => Promise<{ data: InitialAppPreset }>;
41
+ getScreenPresets: (
42
+ config: ConfigType,
43
+ ) => Promise<{ data: WorkspacePreset[] }>;
44
+ getBeVersion: () => Promise<{ data: { version: string } }>;
45
+ };
46
+ ```
47
+
48
+ ### 2. Define routes for your api.
49
+
50
+ This should be a method that returns the routes. Example:
51
+
52
+ ```
53
+ // api.ts
54
+ const getApiRoutes = (axiosInstance: AxiosInstance): AppApi => ({
55
+ getInitialPresets: (
56
+ formData: FormData,
57
+ ): Promise<{ data: InitialAppPreset }> => {
58
+ return axiosInstance.get('/getInitialPresetsUrl', formData);
59
+ },
60
+ getScreenPresets: (
61
+ formData: FormData,
62
+ ): Promise<{ data: WorkspacePreset[] }> => {
63
+ return axiosInstance.get('/getScreenPresets', formData);
64
+ },
65
+ getBeVersion: (): Promise<{ data: { version: string } }> => {
66
+ return axiosInstance.get('/version');
67
+ },
68
+ });
69
+ ```
70
+
71
+ ### 3. Create a createApi method to initiate the api
72
+
73
+ At GeoWeb we use `axios` to do request to apis. Since we also need authentication, we can't use our defined api directly, so create a small helper method to combine the axiosInstance with our api:
74
+
75
+ ```
76
+ // api.ts
77
+ import { createApiInstance } from '@opengeoweb/api';
78
+
79
+ export const createApi = ({
80
+ url: string,
81
+ appURL: string,
82
+ auth: Credentials,
83
+ setAuth: (cred: Credentials) => void,
84
+ authTokenURL: string,
85
+ authClientId: string,
86
+ }): AppApi => {
87
+ const axiosInstance = createApiInstance(
88
+ url,
89
+ appURL,
90
+ auth,
91
+ setAuth,
92
+ authTokenURL,
93
+ authClientId,
94
+ );
95
+
96
+ return getApiRoutes(axiosInstance);
97
+ };
98
+
99
+ ```
100
+
101
+ ### 4. Define a baseURL inside config.json
102
+
103
+ Your api needs a baseURL in order to work. Add this key to the config.json. Be aware, this involves more changes in other repositories. Example:
104
+
105
+ ```
106
+ // config.json
107
+ {
108
+ ...
109
+ "GW_MY_NEW_TEST_API_URL": 'https://mynewapi.com/v3'
110
+ }
111
+ ```
112
+
113
+ ### 5. Define a `fakeApi`.
114
+
115
+ Since storybook can't handle authenthication we need to mock the api with dummy data locally. It's also nice for testing functionality out without to have the geoweb app running. Create a new file called `fakeApi`, and add the same apiRoutes but let it return dummy data. Example:
116
+
117
+ ```
118
+ // fakeApi.ts
119
+ export const createFakeApi = (): AppApi => {
120
+ const api = {
121
+ // dummy calls
122
+ getInitialPresets: (): Promise<{ data: InitialAppPreset }> =>
123
+ Promise.resolve({
124
+ data: defaultInitialPresets as InitialAppPreset,
125
+ }),
126
+ getScreenPresets: (): Promise<{
127
+ data: WorkspacePreset[];
128
+ }> =>
129
+ Promise.resolve({
130
+ data: defaultScreenPresets as WorkspacePreset[],
131
+ }),
132
+ getBeVersion: (): Promise<{ data: { version: string } }> =>
133
+ Promise.resolve({ data: { version: 'version 1.0.1' } }),
134
+ };
135
+
136
+ return api;
137
+ };
138
+ ```
139
+
140
+ Also create a `createApi` method. Since we're not doing real requests with axios with this, we won't need it and use the `fakeAxiosInstance`. Example:
141
+
142
+ ```
143
+ // fakeApi.ts
144
+ import { createFakeApiInstance } from '@opengeoweb/api';
145
+ export const createApi = (): TafApi => {
146
+ const instance = createFakeApiInstance();
147
+ return getApiRoutes(instance);
148
+ };
149
+ ```
150
+
151
+ ## How to use the api
152
+
153
+ If you follow the steps above, you end up with 2 new files (api.ts and fakeApi.ts) and a new config key for the json.
154
+
155
+ #### Use api inside app for production (api.ts)
156
+
157
+ If you want to try the api out with real data, you should do this inside the `app`. First, wrap the component which needs the api with the ApiProvider, and pass the `createApi` method from the api:
158
+
159
+ ```
160
+ // app/geoweb/components/MyNewModule
161
+ <ApiProvider
162
+ baseURL={config.GW_MY_NEW_TEST_API_URL}
163
+ appURL={config.GW_APP_URL}
164
+ auth={auth}
165
+ onSetAuth={onSetAuth}
166
+ createApi={createApi} // coming fron api.ts
167
+ authTokenURL={config.GW_AUTH_TOKEN_URL}
168
+ authClientId={config.GW_AUTH_CLIENT_ID}
169
+ >
170
+ <ErrorBoundary>
171
+ <MyNewModule />
172
+ </ErrorBoundary>
173
+ </ApiProvider>
174
+ ```
175
+
176
+ The `baseURL` should get the url you've defined earlier. The `createApi` should pass the `createApi` method we've defined. The rest of the props you can pass from the props of geoweb.
177
+
178
+ #### Use (fake)api inside libs for storybook
179
+
180
+ If you want to try the api out with fake data, you should do this inside storybook. First, wrap the component which needs the api with the ApiProvider. and pass the `createApi` method from the fakeApi:
181
+
182
+ ```
183
+ // libs/myNewLib/src/lib/MyNewLibDemo.stories.tsx
184
+ <ApiProvider
185
+ createApi={createApi} // coming fron fakeApi.ts
186
+ >
187
+ <ErrorBoundary>
188
+ <MyNewModule />
189
+ </ErrorBoundary>
190
+ </ApiProvider>
191
+ ```
192
+
193
+ #### Use the `useApiContext` inside a component to access the api or fakeApi
194
+
195
+ Inside your component you can use the `useApiContext` to access the defined routes. Please note that the `ApiProvider` needs to be used around one of the parent components for this to work. Any story or tests should therefore also be wrapped:
196
+
197
+ ```
198
+ const MyComponent: React.FC = () => {
199
+ const { api } = useApiContext<AppApi>();
200
+ const [initialPresets, setInitialPresets] = React.useState<InitialAppPreset>([]);
201
+
202
+ React.useEffect(()=> {
203
+ const intitialPresets = await api.getInitialPresets(myFormvalues);
204
+ setInitialAppPresets(intitialPresets);
205
+ }, []);
206
+
207
+ return <>initialPresets.map(preset => preset.name)</>
208
+ };
209
+
210
+ export const StoryBookExample = (): React.ReactElement => (
211
+ <ApiProvider
212
+ createApi={createApi} // coming fron fakeApi.ts
213
+ >
214
+ <ErrorBoundary>
215
+ <MyComponent />
216
+ </ErrorBoundary>
217
+ </ApiProvider>
218
+ );
219
+
220
+ ```
221
+
222
+ ### TypeScript Documentation
223
+
224
+ - [TypeScript Docs](https://opengeoweb.gitlab.io/opengeoweb/typescript-docs/api/)
@@ -0,0 +1 @@
1
+ export * from "./src/index";
@@ -0,0 +1,588 @@
1
+ import { useAuthenticationContext } from '@opengeoweb/authentication';
2
+ export * from '@opengeoweb/authentication';
3
+ import { useQuery, QueryClientProvider } from '@tanstack/react-query';
4
+ import { omit } from 'lodash';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+ import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
7
+ import React from 'react';
8
+ import { QueryClient, keepPreviousData } from '@tanstack/query-core';
9
+
10
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
11
+ try {
12
+ var i = n[a](c),
13
+ u = i.value;
14
+ } catch (n) {
15
+ return void e(n);
16
+ }
17
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
18
+ }
19
+ function _asyncToGenerator(n) {
20
+ return function () {
21
+ var t = this,
22
+ e = arguments;
23
+ return new Promise(function (r, o) {
24
+ var a = n.apply(t, e);
25
+ function _next(n) {
26
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
27
+ }
28
+ function _throw(n) {
29
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
30
+ }
31
+ _next(void 0);
32
+ });
33
+ };
34
+ }
35
+ function _regenerator() {
36
+ /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
37
+ var e,
38
+ t,
39
+ r = "function" == typeof Symbol ? Symbol : {},
40
+ n = r.iterator || "@@iterator",
41
+ o = r.toStringTag || "@@toStringTag";
42
+ function i(r, n, o, i) {
43
+ var c = n && n.prototype instanceof Generator ? n : Generator,
44
+ u = Object.create(c.prototype);
45
+ return _regeneratorDefine(u, "_invoke", function (r, n, o) {
46
+ var i,
47
+ c,
48
+ u,
49
+ f = 0,
50
+ p = o || [],
51
+ y = false,
52
+ G = {
53
+ p: 0,
54
+ n: 0,
55
+ v: e,
56
+ a: d,
57
+ f: d.bind(e, 4),
58
+ d: function (t, r) {
59
+ return i = t, c = 0, u = e, G.n = r, a;
60
+ }
61
+ };
62
+ function d(r, n) {
63
+ for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) {
64
+ var o,
65
+ i = p[t],
66
+ d = G.p,
67
+ l = i[2];
68
+ r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0));
69
+ }
70
+ if (o || r > 1) return a;
71
+ throw y = true, n;
72
+ }
73
+ return function (o, p, l) {
74
+ if (f > 1) throw TypeError("Generator is already running");
75
+ for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) {
76
+ i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u);
77
+ try {
78
+ if (f = 2, i) {
79
+ if (c || (o = "next"), t = i[o]) {
80
+ if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object");
81
+ if (!t.done) return t;
82
+ u = t.value, c < 2 && (c = 0);
83
+ } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1);
84
+ i = e;
85
+ } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break;
86
+ } catch (t) {
87
+ i = e, c = 1, u = t;
88
+ } finally {
89
+ f = 1;
90
+ }
91
+ }
92
+ return {
93
+ value: t,
94
+ done: y
95
+ };
96
+ };
97
+ }(r, o, i), true), u;
98
+ }
99
+ var a = {};
100
+ function Generator() {}
101
+ function GeneratorFunction() {}
102
+ function GeneratorFunctionPrototype() {}
103
+ t = Object.getPrototypeOf;
104
+ var c = [][n] ? t(t([][n]())) : (_regeneratorDefine(t = {}, n, function () {
105
+ return this;
106
+ }), t),
107
+ u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c);
108
+ function f(e) {
109
+ return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e;
110
+ }
111
+ return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine(u), _regeneratorDefine(u, o, "Generator"), _regeneratorDefine(u, n, function () {
112
+ return this;
113
+ }), _regeneratorDefine(u, "toString", function () {
114
+ return "[object Generator]";
115
+ }), (_regenerator = function () {
116
+ return {
117
+ w: i,
118
+ m: f
119
+ };
120
+ })();
121
+ }
122
+ function _regeneratorDefine(e, r, n, t) {
123
+ var i = Object.defineProperty;
124
+ try {
125
+ i({}, "", {});
126
+ } catch (e) {
127
+ i = 0;
128
+ }
129
+ _regeneratorDefine = function (e, r, n, t) {
130
+ function o(r, n) {
131
+ _regeneratorDefine(e, r, function (e) {
132
+ return this._invoke(r, n, e);
133
+ });
134
+ }
135
+ r ? i ? i(e, r, {
136
+ value: n,
137
+ enumerable: !t,
138
+ configurable: !t,
139
+ writable: !t
140
+ }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2));
141
+ }, _regeneratorDefine(e, r, n, t);
142
+ }
143
+
144
+ var getHeaders = function getHeaders(auth) {
145
+ return omit({
146
+ 'Content-Type': 'application/json',
147
+ Authorization: "Bearer " + (auth == null ? void 0 : auth.token),
148
+ Accept: 'application/json'
149
+ }, auth ? [] : ['Authorization']);
150
+ };
151
+ var withJsonFormat = function withJsonFormat(url) {
152
+ var urlObj = new URL(url);
153
+ urlObj.searchParams.set('f', 'json');
154
+ return urlObj.toString();
155
+ };
156
+ // This function has a copy in libs/webmap-react/src/lib/edr-layer-api/api.ts. This cannot be used there due to circular dependency
157
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
158
+ var handleResponse = /*#__PURE__*/function () {
159
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(response) {
160
+ return _regenerator().w(function (_context) {
161
+ while (1) switch (_context.n) {
162
+ case 0:
163
+ if (!response.ok) {
164
+ _context.n = 1;
165
+ break;
166
+ }
167
+ return _context.a(2, response.json().then(function (json) {
168
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
169
+ return json != null ? json : response.headers;
170
+ })["catch"](function () {
171
+ // No JSON response
172
+ }));
173
+ case 1:
174
+ return _context.a(2, response.json()["catch"](function () {
175
+ // Couldn't parse the JSON
176
+ throw new Error("" + response.status);
177
+ }).then(function (json) {
178
+ // Got valid JSON with error response, use it
179
+ if (json) {
180
+ var message = json.message;
181
+ if (message) {
182
+ throw new Error(message, {
183
+ cause: response.status
184
+ });
185
+ }
186
+ var result = JSON.stringify(json);
187
+ throw new Error(result);
188
+ }
189
+ throw new Error("" + response.status);
190
+ }));
191
+ }
192
+ }, _callee);
193
+ }));
194
+ return function handleResponse(_x) {
195
+ return _ref.apply(this, arguments);
196
+ };
197
+ }();
198
+ var useAuthQuery = function useAuthQuery(queryKey, _queryFn, disabled, refetchInterval) {
199
+ if (disabled === void 0) {
200
+ disabled = false;
201
+ }
202
+ if (refetchInterval === void 0) {
203
+ refetchInterval = false;
204
+ }
205
+ var _useAuthenticationCon = useAuthenticationContext(),
206
+ auth = _useAuthenticationCon.auth;
207
+ var enabled = !!auth && !disabled;
208
+ return useQuery({
209
+ queryKey: queryKey,
210
+ queryFn: function () {
211
+ var _queryFn2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
212
+ return _regenerator().w(function (_context2) {
213
+ while (1) switch (_context2.n) {
214
+ case 0:
215
+ return _context2.a(2, _queryFn(auth));
216
+ }
217
+ }, _callee2);
218
+ }));
219
+ function queryFn() {
220
+ return _queryFn2.apply(this, arguments);
221
+ }
222
+ return queryFn;
223
+ }(),
224
+ enabled: enabled,
225
+ refetchInterval: refetchInterval
226
+ });
227
+ };
228
+ var optimisticUpdate = function optimisticUpdate(updatedQueryKey, queryClient, _optimisticUpdate, errorCallback) {
229
+ return {
230
+ onMutate: function () {
231
+ var _onMutate = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(variables) {
232
+ var oldData;
233
+ return _regenerator().w(function (_context3) {
234
+ while (1) switch (_context3.n) {
235
+ case 0:
236
+ void queryClient.cancelQueries({
237
+ queryKey: updatedQueryKey
238
+ });
239
+ oldData = queryClient.getQueryData(updatedQueryKey);
240
+ if (variables.id) {
241
+ queryClient.setQueryData(updatedQueryKey, function (old) {
242
+ return old == null ? void 0 : old.map(function (item) {
243
+ return item.id === variables.id ? _optimisticUpdate(item, variables) : item;
244
+ });
245
+ });
246
+ }
247
+ return _context3.a(2, {
248
+ oldData: oldData
249
+ });
250
+ }
251
+ }, _callee3);
252
+ }));
253
+ function onMutate(_x2) {
254
+ return _onMutate.apply(this, arguments);
255
+ }
256
+ return onMutate;
257
+ }(),
258
+ onError: function onError(err, _, context) {
259
+ if (context != null && context.oldData) {
260
+ queryClient.setQueryData(updatedQueryKey, context == null ? void 0 : context.oldData);
261
+ }
262
+ if (errorCallback) {
263
+ errorCallback(err);
264
+ }
265
+ }
266
+ };
267
+ };
268
+
269
+ /* *
270
+ * Licensed under the Apache License, Version 2.0 (the "License");
271
+ * you may not use this file except in compliance with the License.
272
+ * You may obtain a copy of the License at
273
+ *
274
+ * http://www.apache.org/licenses/LICENSE-2.0
275
+ *
276
+ * Unless required by applicable law or agreed to in writing, software
277
+ * distributed under the License is distributed on an "AS IS" BASIS,
278
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
279
+ * See the License for the specific language governing permissions and
280
+ * limitations under the License.
281
+ *
282
+ * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
283
+ * Copyright 2025 - Finnish Meteorological Institute (FMI)
284
+ * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
285
+ * */
286
+ var wait = /*#__PURE__*/function () {
287
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(delayDuration) {
288
+ return _regenerator().w(function (_context) {
289
+ while (1) switch (_context.n) {
290
+ case 0:
291
+ return _context.a(2, new Promise(function (resolve) {
292
+ setTimeout(resolve, delayDuration);
293
+ }));
294
+ }
295
+ }, _callee);
296
+ }));
297
+ return function wait(_x) {
298
+ return _ref.apply(this, arguments);
299
+ };
300
+ }();
301
+ var makeMockApiCall = function makeMockApiCall(response, responseInit, delayDuration) {
302
+ if (delayDuration === void 0) {
303
+ delayDuration = 0;
304
+ }
305
+ if (delayDuration) {
306
+ return jest.fn().mockImplementation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
307
+ return _regenerator().w(function (_context2) {
308
+ while (1) switch (_context2.n) {
309
+ case 0:
310
+ _context2.n = 1;
311
+ return wait(delayDuration);
312
+ case 1:
313
+ return _context2.a(2, Response.json(response, responseInit));
314
+ }
315
+ }, _callee2);
316
+ })));
317
+ }
318
+ return jest.fn().mockImplementation(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
319
+ return _regenerator().w(function (_context3) {
320
+ while (1) switch (_context3.n) {
321
+ case 0:
322
+ return _context3.a(2, Promise.resolve(Response.json(response, responseInit)));
323
+ }
324
+ }, _callee3);
325
+ })));
326
+ };
327
+
328
+ /* *
329
+ * Licensed under the Apache License, Version 2.0 (the "License");
330
+ * you may not use this file except in compliance with the License.
331
+ * You may obtain a copy of the License at
332
+ *
333
+ * http://www.apache.org/licenses/LICENSE-2.0
334
+ *
335
+ * Unless required by applicable law or agreed to in writing, software
336
+ * distributed under the License is distributed on an "AS IS" BASIS,
337
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
338
+ * See the License for the specific language governing permissions and
339
+ * limitations under the License.
340
+ *
341
+ * Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
342
+ * Copyright 2024 - Finnish Meteorological Institute (FMI)
343
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
344
+ * */
345
+ /**
346
+ * ProductStatus is returned by the backend. The backend fills in this property.
347
+ * For the backend, it should only need to store 'DRAFT' | 'PUBLISHED' | 'CANCELLED' in its DB.
348
+ * The backend should derive and return the status 'EXPIRED' from the product properties.
349
+ *
350
+ * Note: ProductStatus from the backend should be refreshed regularly to display status updates. */
351
+ var ProductStatus;
352
+ (function (ProductStatus) {
353
+ ProductStatus["DRAFT"] = "DRAFT";
354
+ ProductStatus["PUBLISHED"] = "PUBLISHED";
355
+ ProductStatus["RENEWED"] = "RENEWED";
356
+ ProductStatus["CANCELLED"] = "CANCELLED";
357
+ ProductStatus["EXPIRED"] = "EXPIRED";
358
+ ProductStatus["DISCARDED"] = "DISCARDED";
359
+ })(ProductStatus || (ProductStatus = {}));
360
+ var LevelUnits;
361
+ (function (LevelUnits) {
362
+ LevelUnits["FT"] = "ft";
363
+ LevelUnits["M"] = "m";
364
+ LevelUnits["FL"] = "FL";
365
+ })(LevelUnits || (LevelUnits = {}));
366
+ var CloudLevelUnits;
367
+ (function (CloudLevelUnits) {
368
+ CloudLevelUnits["FT"] = "ft";
369
+ CloudLevelUnits["M"] = "m";
370
+ })(CloudLevelUnits || (CloudLevelUnits = {}));
371
+ /**
372
+ * The possible phenomena for the sigmet
373
+ */
374
+ var SigmetPhenomena;
375
+ (function (SigmetPhenomena) {
376
+ SigmetPhenomena["EMBD_TS"] = "Embedded thunderstorm(s)";
377
+ SigmetPhenomena["EMBD_TSGR"] = "Embedded thunderstorm(s) with hail";
378
+ SigmetPhenomena["FRQ_TS"] = "Frequent thunderstorm(s)";
379
+ SigmetPhenomena["FRQ_TSGR"] = "Frequent thunderstorm(s) with hail";
380
+ SigmetPhenomena["HVY_DS"] = "Heavy duststorm";
381
+ SigmetPhenomena["HVY_SS"] = "Heavy sandstorm";
382
+ SigmetPhenomena["OBSC_TS"] = "Obscured thunderstorm(s)";
383
+ SigmetPhenomena["OBSC_TSGR"] = "Obscured thunderstorm(s) with hail";
384
+ SigmetPhenomena["RDOACT_CLD"] = "Radioactive cloud";
385
+ SigmetPhenomena["SEV_ICE"] = "Severe icing";
386
+ SigmetPhenomena["SEV_ICE_FRZ_RN"] = "Severe icing due to freezing rain";
387
+ SigmetPhenomena["SEV_MTW"] = "Severe mountain wave";
388
+ SigmetPhenomena["SEV_TURB"] = "Severe turbulence";
389
+ SigmetPhenomena["SQL_TS"] = "Squall line thunderstorm(s)";
390
+ SigmetPhenomena["SQL_TSGR"] = "Squall line thunderstorm(s) with hail";
391
+ // 'TC' = 'Tropical cyclone', // Don't show this option in the list because it will be not used by KNMI.
392
+ SigmetPhenomena["VA_CLD"] = "Volcanic ash cloud";
393
+ })(SigmetPhenomena || (SigmetPhenomena = {}));
394
+ /**
395
+ * The possible phenomena for the airmet
396
+ */
397
+ var AirmetPhenomena;
398
+ (function (AirmetPhenomena) {
399
+ AirmetPhenomena["SFC_VIS"] = "Surface visibility";
400
+ AirmetPhenomena["SFC_WIND"] = "Surface wind";
401
+ AirmetPhenomena["OVC_CLD"] = "Overcast cloud";
402
+ AirmetPhenomena["BKN_CLD"] = "Broken cloud";
403
+ AirmetPhenomena["ISOL_CB"] = "Isolated cumulonimbus cloud";
404
+ AirmetPhenomena["OCNL_CB"] = "Occasional cumulonimbus cloud";
405
+ AirmetPhenomena["FRQ_CB"] = "Frequent cumulonimbus cloud";
406
+ AirmetPhenomena["ISOL_TS"] = "Isolated thunderstorm(s)";
407
+ AirmetPhenomena["OCNL_TS"] = "Occasional thunderstorm(s)";
408
+ AirmetPhenomena["ISOL_TSGR"] = "Isolated thunderstorm(s) with hail";
409
+ AirmetPhenomena["OCNL_TSGR"] = "Occasional thunderstorm(s) with hail";
410
+ AirmetPhenomena["ISOL_TCU"] = "Isolated towering cumulus cloud";
411
+ AirmetPhenomena["OCNL_TCU"] = "Occasional towering cumulus cloud";
412
+ AirmetPhenomena["FRQ_TCU"] = "Frequent towering cumulus cloud";
413
+ AirmetPhenomena["MOD_ICE"] = "Moderate icing";
414
+ AirmetPhenomena["MOD_MTW"] = "Moderate mountain wave";
415
+ AirmetPhenomena["MOD_TURB"] = "Moderate turbulence";
416
+ AirmetPhenomena["MT_OBSC"] = "Mountains obscured";
417
+ })(AirmetPhenomena || (AirmetPhenomena = {}));
418
+ /* Speed unit, e.g. 'KT', 'KMH' */
419
+ var MovementUnit;
420
+ (function (MovementUnit) {
421
+ MovementUnit["KT"] = "kt";
422
+ MovementUnit["KMH"] = "kmh";
423
+ })(MovementUnit || (MovementUnit = {}));
424
+ // can these be unified as SpeedUnit?
425
+ var WindUnit;
426
+ (function (WindUnit) {
427
+ WindUnit["KT"] = "kt";
428
+ WindUnit["MPS"] = "mps";
429
+ })(WindUnit || (WindUnit = {}));
430
+ var Direction;
431
+ (function (Direction) {
432
+ Direction["N"] = "N";
433
+ Direction["NNE"] = "NNE";
434
+ Direction["NE"] = "NE";
435
+ Direction["ENE"] = "ENE";
436
+ Direction["E"] = "E";
437
+ Direction["ESE"] = "ESE";
438
+ Direction["SE"] = "SE";
439
+ Direction["SSE"] = "SSE";
440
+ Direction["S"] = "S";
441
+ Direction["SSW"] = "SSW";
442
+ Direction["SW"] = "SW";
443
+ Direction["WSW"] = "WSW";
444
+ Direction["W"] = "W";
445
+ Direction["WNW"] = "WNW";
446
+ Direction["NW"] = "NW";
447
+ Direction["NNW"] = "NNW";
448
+ })(Direction || (Direction = {}));
449
+ var VisibilityCause;
450
+ (function (VisibilityCause) {
451
+ VisibilityCause["DZ"] = "Drizzle";
452
+ VisibilityCause["DU"] = "Dust";
453
+ VisibilityCause["PO"] = "Dust or sand devil";
454
+ VisibilityCause["DS"] = "Dust storm";
455
+ VisibilityCause["FG"] = "Fog";
456
+ VisibilityCause["FC"] = "Funnel clouds";
457
+ VisibilityCause["GR"] = "Hail";
458
+ VisibilityCause["HZ"] = "Haze";
459
+ VisibilityCause["PL"] = "Ice pellets";
460
+ VisibilityCause["BR"] = "Mist";
461
+ VisibilityCause["RA"] = "Rain";
462
+ VisibilityCause["SA"] = "Sand";
463
+ VisibilityCause["SS"] = "Sand storm";
464
+ VisibilityCause["FU"] = "Smoke";
465
+ VisibilityCause["SN"] = "Snow";
466
+ VisibilityCause["SG"] = "Snow grains";
467
+ VisibilityCause["GS"] = "Soft hail";
468
+ VisibilityCause["SQ"] = "Squalls";
469
+ VisibilityCause["VA"] = "Volcanic Ash";
470
+ })(VisibilityCause || (VisibilityCause = {}));
471
+
472
+ /* *
473
+ * Licensed under the Apache License, Version 2.0 (the "License");
474
+ * you may not use this file except in compliance with the License.
475
+ * You may obtain a copy of the License at
476
+ *
477
+ * http://www.apache.org/licenses/LICENSE-2.0
478
+ *
479
+ * Unless required by applicable law or agreed to in writing, software
480
+ * distributed under the License is distributed on an "AS IS" BASIS,
481
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
482
+ * See the License for the specific language governing permissions and
483
+ * limitations under the License.
484
+ *
485
+ * Copyright 2025 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
486
+ * Copyright 2025 - Finnish Meteorological Institute (FMI)
487
+ * Copyright 2025 - The Norwegian Meteorological Institute (MET Norway)
488
+ * */
489
+ var queryClientInstance = null;
490
+ var getQueryClient = function getQueryClient() {
491
+ queryClientInstance != null ? queryClientInstance : queryClientInstance = new QueryClient({
492
+ defaultOptions: {
493
+ queries: {
494
+ refetchOnWindowFocus: false,
495
+ refetchOnMount: false,
496
+ refetchOnReconnect: false,
497
+ refetchInterval: false,
498
+ placeholderData: keepPreviousData,
499
+ staleTime: 1000 * 60 * 5
500
+ }
501
+ }
502
+ });
503
+ return queryClientInstance;
504
+ };
505
+ var setQueryClient = function setQueryClient(client) {
506
+ queryClientInstance = client;
507
+ };
508
+ var configureLibraryDefaults = function configureLibraryDefaults(queryKeyPrefix, options) {
509
+ var client = getQueryClient();
510
+ client.setQueryDefaults(queryKeyPrefix, options);
511
+ };
512
+ var createTestQueryClient = function createTestQueryClient(overrides) {
513
+ var client = new QueryClient({
514
+ defaultOptions: {
515
+ queries: Object.assign({
516
+ retry: false,
517
+ staleTime: 0,
518
+ gcTime: 0,
519
+ refetchOnWindowFocus: false,
520
+ refetchOnMount: false,
521
+ refetchOnReconnect: false,
522
+ refetchInterval: false
523
+ }, overrides == null ? void 0 : overrides.queries),
524
+ mutations: Object.assign({
525
+ retry: false
526
+ }, overrides == null ? void 0 : overrides.mutations)
527
+ }
528
+ });
529
+ setQueryClient(client);
530
+ return client;
531
+ };
532
+ var resetQueryClient = function resetQueryClient() {
533
+ var _queryClientInstance, _queryClientInstance2;
534
+ void ((_queryClientInstance = queryClientInstance) == null ? void 0 : _queryClientInstance.cancelQueries());
535
+ (_queryClientInstance2 = queryClientInstance) == null || _queryClientInstance2.clear();
536
+ queryClientInstance = null;
537
+ };
538
+
539
+ var QueryClientProviderWrapper = function QueryClientProviderWrapper(_ref) {
540
+ var client = _ref.client,
541
+ children = _ref.children,
542
+ _ref$mode = _ref.mode,
543
+ mode = _ref$mode === void 0 ? 'production' : _ref$mode;
544
+ var queryClient = React.useMemo(function () {
545
+ if (client) {
546
+ setQueryClient(client);
547
+ return client;
548
+ }
549
+ return mode === 'test' ? createTestQueryClient() : getQueryClient();
550
+ }, [client, mode]);
551
+ return jsxs(QueryClientProvider, {
552
+ client: queryClient,
553
+ children: [children, jsx("div", {
554
+ style: {
555
+ position: 'fixed',
556
+ left: 8,
557
+ bottom: '5%',
558
+ zIndex: 99999
559
+ },
560
+ children: jsx(ReactQueryDevtools, {
561
+ buttonPosition: "relative",
562
+ initialIsOpen: false
563
+ })
564
+ })]
565
+ });
566
+ };
567
+
568
+ /* *
569
+ * Licensed under the Apache License, Version 2.0 (the "License");
570
+ * you may not use this file except in compliance with the License.
571
+ * You may obtain a copy of the License at
572
+ *
573
+ * http://www.apache.org/licenses/LICENSE-2.0
574
+ *
575
+ * Unless required by applicable law or agreed to in writing, software
576
+ * distributed under the License is distributed on an "AS IS" BASIS,
577
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
578
+ * See the License for the specific language governing permissions and
579
+ * limitations under the License.
580
+ *
581
+ * Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
582
+ * Copyright 2024 - Finnish Meteorological Institute (FMI)
583
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
584
+ * */
585
+ var API_NAMESPACE = 'api';
586
+ // Initialize and create provider if needed
587
+
588
+ export { API_NAMESPACE, AirmetPhenomena, CloudLevelUnits, Direction, LevelUnits, MovementUnit, ProductStatus, QueryClientProviderWrapper, SigmetPhenomena, VisibilityCause, WindUnit, configureLibraryDefaults, createTestQueryClient, getHeaders, getQueryClient, handleResponse, makeMockApiCall, optimisticUpdate, resetQueryClient, setQueryClient, useAuthQuery, withJsonFormat };
@@ -0,0 +1,3 @@
1
+ type JsonBodyType = unknown;
2
+ export declare const makeMockApiCall: (response: JsonBodyType, responseInit?: ResponseInit, delayDuration?: number) => jest.Mock;
3
+ export {};
@@ -0,0 +1 @@
1
+ export declare const API_NAMESPACE = "api";
@@ -0,0 +1,8 @@
1
+ export * from '@opengeoweb/authentication';
2
+ export * from './utils';
3
+ export * from './fakeApi';
4
+ export type * from './sigmet-airmet-api/types';
5
+ export * from './sigmet-airmet-api/definitions';
6
+ export type * from './sigmet-airmet-api/config-types';
7
+ export * from './query-client';
8
+ export { API_NAMESPACE } from './i18n';
@@ -0,0 +1,9 @@
1
+ import type { QueryClient } from '@tanstack/query-core';
2
+ import React from 'react';
3
+ interface QueryClientProviderWrapperProps {
4
+ client?: QueryClient;
5
+ children: React.ReactNode;
6
+ mode?: 'test' | 'production';
7
+ }
8
+ export declare const QueryClientProviderWrapper: ({ client, children, mode, }: QueryClientProviderWrapperProps) => React.ReactElement;
9
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './QueryClientProviderWrapper';
2
+ export * from './queryClient';
@@ -0,0 +1,10 @@
1
+ import type { DefaultOptions } from '@tanstack/query-core';
2
+ import { QueryClient } from '@tanstack/query-core';
3
+ export declare const getQueryClient: () => QueryClient;
4
+ export declare const setQueryClient: (client: QueryClient) => void;
5
+ export declare const configureLibraryDefaults: (queryKeyPrefix: string[], options: DefaultOptions["queries"]) => void;
6
+ export declare const createTestQueryClient: (overrides?: {
7
+ queries?: DefaultOptions["queries"];
8
+ mutations?: DefaultOptions["mutations"];
9
+ }) => QueryClient;
10
+ export declare const resetQueryClient: () => void;
@@ -0,0 +1,88 @@
1
+ import type { MapPreset } from '@opengeoweb/store';
2
+ export interface AllowedUnits {
3
+ unit_type: string;
4
+ allowed_units: string[];
5
+ }
6
+ export type FIRLocationGeoJson = GeoJSON.FeatureCollection<GeoJSON.Geometry, {
7
+ selectionType?: string;
8
+ }>;
9
+ export interface LevelMinMaxType {
10
+ FT?: number;
11
+ FL?: number;
12
+ M?: number;
13
+ }
14
+ export interface MovementMinMaxType {
15
+ KT?: number;
16
+ KMH?: number;
17
+ }
18
+ export interface CloudLevelMinMaxType {
19
+ FT?: number;
20
+ M?: number;
21
+ }
22
+ export interface SurfaceWindMinMaxType {
23
+ KT?: number;
24
+ MPS?: number;
25
+ }
26
+ export interface FIRArea {
27
+ fir_name: string;
28
+ fir_location: FIRLocationGeoJson;
29
+ location_indicator_atsr: string;
30
+ location_indicator_atsu: string;
31
+ max_hours_of_validity: number;
32
+ hours_before_validity: number;
33
+ level_min?: LevelMinMaxType;
34
+ level_max?: LevelMinMaxType;
35
+ level_rounding_FL?: number;
36
+ level_rounding_FT?: number;
37
+ level_rounding_M?: number;
38
+ movement_min?: MovementMinMaxType;
39
+ movement_max?: MovementMinMaxType;
40
+ movement_rounding_kt?: number;
41
+ movement_rounding_kmh?: number;
42
+ max_polygon_points?: number;
43
+ units: AllowedUnits[];
44
+ }
45
+ export interface FIRConfigSigmet extends FIRArea {
46
+ tc_max_hours_of_validity: number;
47
+ tc_hours_before_validity: number;
48
+ va_max_hours_of_validity: number;
49
+ va_hours_before_validity: number;
50
+ va_cld_degrees_minutes?: boolean;
51
+ adjacent_firs: string[];
52
+ }
53
+ export interface FIRConfigAirmet extends FIRArea {
54
+ cloud_level_min?: CloudLevelMinMaxType;
55
+ cloud_level_max?: CloudLevelMinMaxType;
56
+ cloud_lower_level_min?: CloudLevelMinMaxType;
57
+ cloud_lower_level_max?: CloudLevelMinMaxType;
58
+ cloud_level_rounding_ft?: number;
59
+ cloud_level_rounding_m_below?: number;
60
+ cloud_level_rounding_m_above?: number;
61
+ wind_direction_rounding?: number;
62
+ wind_speed_max?: SurfaceWindMinMaxType;
63
+ wind_speed_min?: SurfaceWindMinMaxType;
64
+ visibility_max?: number;
65
+ visibility_min?: number;
66
+ visibility_rounding_below?: number;
67
+ visibility_rounding_above?: number;
68
+ }
69
+ type SigmetFIRArea = Record<string, FIRConfigSigmet>;
70
+ type AirmetFIRArea = Record<string, FIRConfigAirmet>;
71
+ export type Firareas = SigmetFIRArea | AirmetFIRArea;
72
+ export interface ProductConfig {
73
+ location_indicator_mwo: string;
74
+ active_firs: string[];
75
+ valid_from_delay_minutes: number;
76
+ default_validity_minutes: number;
77
+ fir_areas: Firareas;
78
+ mapPreset?: MapPreset;
79
+ omit_change_va_and_rdoact_cloud?: boolean;
80
+ disable_amend_action?: boolean;
81
+ }
82
+ export interface SigmetConfig extends ProductConfig {
83
+ fir_areas: SigmetFIRArea;
84
+ }
85
+ export interface AirmetConfig extends ProductConfig {
86
+ fir_areas: AirmetFIRArea;
87
+ }
88
+ export {};
@@ -0,0 +1,142 @@
1
+ export type DateType = string;
2
+ export type ICAOLocation = string;
3
+ export type MWOLocation = string;
4
+ export type ATSULocation = string;
5
+ export type ATSRLocation = string;
6
+ /**
7
+ * ProductStatus is returned by the backend. The backend fills in this property.
8
+ * For the backend, it should only need to store 'DRAFT' | 'PUBLISHED' | 'CANCELLED' in its DB.
9
+ * The backend should derive and return the status 'EXPIRED' from the product properties.
10
+ *
11
+ * Note: ProductStatus from the backend should be refreshed regularly to display status updates. */
12
+ export declare enum ProductStatus {
13
+ DRAFT = "DRAFT",
14
+ PUBLISHED = "PUBLISHED",
15
+ RENEWED = "RENEWED",
16
+ CANCELLED = "CANCELLED",
17
+ EXPIRED = "EXPIRED",
18
+ DISCARDED = "DISCARDED"
19
+ }
20
+ /**
21
+ * ProductSequence is a sequence label with a counter of the SIGMETs/AIRMETs issued on a day (starting at with 1 01:00),
22
+ * max 3 characters long; first character should be a capital letter,
23
+ * others are numbers: A01-A99, 01-99 or 1-99 */
24
+ export type ProductSequenceId = string;
25
+ /**
26
+ * ProductCanbe lifecycle is determined by the backend. E.g. the backend fills in these properties:
27
+ * 'DRAFTED': product can be saved as draft
28
+ * 'DISCARDED': This product can be thrown away
29
+ * 'PUBLISHED': product can be PUBLISHED
30
+ * 'CANCELLED': product can be CANCELLED */
31
+ export type ProductCanbe = 'DRAFTED' | 'DISCARDED' | 'PUBLISHED' | 'RENEWED' | 'CANCELLED';
32
+ export type ObservationOrForcast = 'OBS' | 'FCST';
33
+ export declare enum LevelUnits {
34
+ 'FT' = "ft",
35
+ 'M' = "m",
36
+ 'FL' = "FL"
37
+ }
38
+ export declare enum CloudLevelUnits {
39
+ 'FT' = "ft",
40
+ 'M' = "m"
41
+ }
42
+ /** Change type of the Product, can be:
43
+ * INTSF:Intensifying
44
+ * WKN: Weakening
45
+ * NC: No change */
46
+ export type Change = 'INTSF' | 'WKN' | 'NC';
47
+ export type LevelInfoMode = 'AT' | 'BETW' | 'BETW_SFC' | 'TOPS' | 'TOPS_ABV' | 'TOPS_BLW' | 'ABV';
48
+ /**
49
+ * The possible phenomena for the sigmet
50
+ */
51
+ export declare enum SigmetPhenomena {
52
+ 'EMBD_TS' = "Embedded thunderstorm(s)",
53
+ 'EMBD_TSGR' = "Embedded thunderstorm(s) with hail",
54
+ 'FRQ_TS' = "Frequent thunderstorm(s)",
55
+ 'FRQ_TSGR' = "Frequent thunderstorm(s) with hail",
56
+ 'HVY_DS' = "Heavy duststorm",
57
+ 'HVY_SS' = "Heavy sandstorm",
58
+ 'OBSC_TS' = "Obscured thunderstorm(s)",
59
+ 'OBSC_TSGR' = "Obscured thunderstorm(s) with hail",
60
+ 'RDOACT_CLD' = "Radioactive cloud",
61
+ 'SEV_ICE' = "Severe icing",
62
+ 'SEV_ICE_FRZ_RN' = "Severe icing due to freezing rain",
63
+ 'SEV_MTW' = "Severe mountain wave",
64
+ 'SEV_TURB' = "Severe turbulence",
65
+ 'SQL_TS' = "Squall line thunderstorm(s)",
66
+ 'SQL_TSGR' = "Squall line thunderstorm(s) with hail",
67
+ 'VA_CLD' = "Volcanic ash cloud"
68
+ }
69
+ /**
70
+ * The possible phenomena for the airmet
71
+ */
72
+ export declare enum AirmetPhenomena {
73
+ 'SFC_VIS' = "Surface visibility",
74
+ 'SFC_WIND' = "Surface wind",
75
+ 'OVC_CLD' = "Overcast cloud",
76
+ 'BKN_CLD' = "Broken cloud",
77
+ 'ISOL_CB' = "Isolated cumulonimbus cloud",
78
+ 'OCNL_CB' = "Occasional cumulonimbus cloud",
79
+ 'FRQ_CB' = "Frequent cumulonimbus cloud",
80
+ 'ISOL_TS' = "Isolated thunderstorm(s)",
81
+ 'OCNL_TS' = "Occasional thunderstorm(s)",
82
+ 'ISOL_TSGR' = "Isolated thunderstorm(s) with hail",
83
+ 'OCNL_TSGR' = "Occasional thunderstorm(s) with hail",
84
+ 'ISOL_TCU' = "Isolated towering cumulus cloud",
85
+ 'OCNL_TCU' = "Occasional towering cumulus cloud",
86
+ 'FRQ_TCU' = "Frequent towering cumulus cloud",
87
+ 'MOD_ICE' = "Moderate icing",
88
+ 'MOD_MTW' = "Moderate mountain wave",
89
+ 'MOD_TURB' = "Moderate turbulence",
90
+ 'MT_OBSC' = "Mountains obscured"
91
+ }
92
+ export type SigmetMovementType = 'STATIONARY' | 'MOVEMENT' | 'FORECAST_POSITION' | 'NO_VA_EXP';
93
+ export type AirmetMovementType = 'STATIONARY' | 'MOVEMENT';
94
+ export declare enum MovementUnit {
95
+ 'KT' = "kt",
96
+ 'KMH' = "kmh"
97
+ }
98
+ export declare enum WindUnit {
99
+ 'KT' = "kt",
100
+ 'MPS' = "mps"
101
+ }
102
+ export declare enum Direction {
103
+ 'N' = "N",
104
+ 'NNE' = "NNE",
105
+ 'NE' = "NE",
106
+ 'ENE' = "ENE",
107
+ 'E' = "E",
108
+ 'ESE' = "ESE",
109
+ 'SE' = "SE",
110
+ 'SSE' = "SSE",
111
+ 'S' = "S",
112
+ 'SSW' = "SSW",
113
+ 'SW' = "SW",
114
+ 'WSW' = "WSW",
115
+ 'W' = "W",
116
+ 'WNW' = "WNW",
117
+ 'NW' = "NW",
118
+ 'NNW' = "NNW"
119
+ }
120
+ export type VisibilityUnit = 'm';
121
+ export declare enum VisibilityCause {
122
+ 'DZ' = "Drizzle",
123
+ 'DU' = "Dust",
124
+ 'PO' = "Dust or sand devil",
125
+ 'DS' = "Dust storm",
126
+ 'FG' = "Fog",
127
+ 'FC' = "Funnel clouds",
128
+ 'GR' = "Hail",
129
+ 'HZ' = "Haze",
130
+ 'PL' = "Ice pellets",
131
+ 'BR' = "Mist",
132
+ 'RA' = "Rain",
133
+ 'SA' = "Sand",
134
+ 'SS' = "Sand storm",
135
+ 'FU' = "Smoke",
136
+ 'SN' = "Snow",
137
+ 'SG' = "Snow grains",
138
+ 'GS' = "Soft hail",
139
+ 'SQ' = "Squalls",
140
+ 'VA' = "Volcanic Ash"
141
+ }
142
+ export type CloudLevelInfoMode = 'BETW' | 'BETW_SFC' | 'BETW_SFC_ABV' | 'BETW_ABV';
@@ -0,0 +1,101 @@
1
+ import type { AirmetMovementType, AirmetPhenomena, ATSRLocation, ATSULocation, Change, CloudLevelInfoMode, CloudLevelUnits, DateType, Direction, ICAOLocation, LevelInfoMode, LevelUnits, MovementUnit, MWOLocation, ObservationOrForcast, ProductCanbe, ProductSequenceId, ProductStatus, SigmetMovementType, SigmetPhenomena, VisibilityCause, VisibilityUnit, WindUnit } from './definitions';
2
+ export interface LevelType {
3
+ value: number;
4
+ unit: LevelUnits;
5
+ }
6
+ export interface CloudLevelType {
7
+ value: number;
8
+ unit: CloudLevelUnits;
9
+ }
10
+ export interface Coordinate {
11
+ latitude: number;
12
+ longitude: number;
13
+ }
14
+ export interface BaseProduct {
15
+ validDateStart: DateType;
16
+ validDateEnd: DateType;
17
+ firName: ICAOLocation;
18
+ locationIndicatorMWO: MWOLocation;
19
+ locationIndicatorATSU: ATSULocation;
20
+ locationIndicatorATSR: ATSRLocation;
21
+ uuid?: string;
22
+ sequence?: ProductSequenceId;
23
+ issueDate?: DateType;
24
+ author?: string;
25
+ }
26
+ interface Product extends BaseProduct {
27
+ status: ProductStatus;
28
+ isObservationOrForecast?: ObservationOrForcast;
29
+ observationOrForecastTime?: DateType;
30
+ change?: Change;
31
+ levelInfoMode?: LevelInfoMode;
32
+ level?: LevelType;
33
+ lowerLevel?: LevelType;
34
+ firGeometry?: GeoJSON.FeatureCollection;
35
+ startGeometry: GeoJSON.FeatureCollection;
36
+ startGeometryIntersect: GeoJSON.FeatureCollection;
37
+ movementSpeed?: number;
38
+ movementUnit?: MovementUnit;
39
+ movementDirection?: Direction;
40
+ }
41
+ export interface Sigmet extends Product {
42
+ phenomenon: SigmetPhenomena;
43
+ type: 'NORMAL' | 'TEST' | 'EXERCISE' | 'SHORT_TEST' | 'SHORT_VA_TEST';
44
+ endGeometry?: GeoJSON.FeatureCollection;
45
+ endGeometryIntersect?: GeoJSON.FeatureCollection;
46
+ movementType?: SigmetMovementType;
47
+ /** Extra properties in case of va SIGMET */
48
+ vaSigmetVolcanoName?: string;
49
+ vaSigmetVolcanoCoordinates?: Coordinate;
50
+ /** Extra properties in case of cancel va SIGMET, if set to unknown, property not set */
51
+ vaSigmetMoveToFIR?: ICAOLocation;
52
+ }
53
+ /**
54
+ * To cancel a published sigmet
55
+ * To cancel a published sigmet, we send a cancel sigmet with all the mandatory properties from the basesigmet. */
56
+ export interface CancelSigmet extends BaseProduct {
57
+ cancelsSigmetSequenceId: ProductSequenceId;
58
+ validDateStartOfSigmetToCancel: DateType;
59
+ validDateEndOfSigmetToCancel: DateType;
60
+ status: ProductStatus.PUBLISHED;
61
+ /** Extra properties in case of cancel va SIGMET, if set to unknown, property not set */
62
+ vaSigmetMoveToFIR?: ICAOLocation;
63
+ }
64
+ export interface Airmet extends Product {
65
+ phenomenon: AirmetPhenomena;
66
+ status: ProductStatus;
67
+ type: 'NORMAL' | 'TEST' | 'EXERCISE';
68
+ movementType: AirmetMovementType;
69
+ windSpeed?: number;
70
+ windUnit?: WindUnit;
71
+ windDirection?: number;
72
+ visibilityValue?: number;
73
+ visibilityCause?: VisibilityCause;
74
+ visibilityUnit?: VisibilityUnit;
75
+ cloudLevelInfoMode?: CloudLevelInfoMode;
76
+ cloudLevel?: CloudLevelType;
77
+ cloudLowerLevel?: CloudLevelType;
78
+ }
79
+ export interface CancelAirmet extends BaseProduct {
80
+ cancelsAirmetSequenceId: ProductSequenceId;
81
+ validDateStartOfAirmetToCancel: DateType;
82
+ validDateEndOfAirmetToCancel: DateType;
83
+ status: ProductStatus.PUBLISHED;
84
+ }
85
+ export interface SigmetFromBackend {
86
+ sigmet: Sigmet | CancelSigmet;
87
+ creationDate: DateType;
88
+ lastUpdateDate: DateType;
89
+ uuid: string;
90
+ canbe: ProductCanbe[];
91
+ author?: string;
92
+ }
93
+ export interface AirmetFromBackend {
94
+ airmet: Airmet | CancelAirmet;
95
+ creationDate: DateType;
96
+ lastUpdateDate: DateType;
97
+ uuid: string;
98
+ canbe: ProductCanbe[];
99
+ author?: string;
100
+ }
101
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { MutationOptions, QueryClient, UseQueryResult } from '@tanstack/react-query';
2
+ import type { Credentials } from '@opengeoweb/authentication';
3
+ export declare const getHeaders: (auth?: Credentials) => HeadersInit;
4
+ export declare const withJsonFormat: (url: string) => string;
5
+ export declare const handleResponse: (response: Response) => Promise<any>;
6
+ export declare const useAuthQuery: <T>(queryKey: string[], queryFn: (auth: Credentials) => Promise<T>, disabled?: boolean, refetchInterval?: number | false) => UseQueryResult<T>;
7
+ export declare const optimisticUpdate: <U extends {
8
+ id?: string;
9
+ }, T extends {
10
+ id?: string;
11
+ }>(updatedQueryKey: string[], queryClient: QueryClient, optimisticUpdate: (oldValue: U, variables: T) => U, errorCallback?: (err: Error) => void) => MutationOptions<Headers | null, Error, T, {
12
+ oldData: U[] | undefined;
13
+ }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/api",
3
- "version": "19.1.0",
3
+ "version": "19.1.1",
4
4
  "description": "GeoWeb API library for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -32,6 +32,7 @@
32
32
  },
33
33
  "files": [
34
34
  "dist",
35
+ "!dist/package.json",
35
36
  "README.md",
36
37
  "package.json"
37
38
  ]