ednl-liftstatus-web-components 1.61.2 → 1.62.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 (154) hide show
  1. package/dist/cjs/api-BDbCaWHW.js +796 -0
  2. package/dist/cjs/debounce-DUdTuYyk.js +306 -0
  3. package/dist/cjs/ednl-liftstatus-web-components.cjs.js +1 -1
  4. package/dist/cjs/em-dash-BaIXt_2W.js +6 -0
  5. package/dist/cjs/error-message-DHsnNSTO.js +67 -0
  6. package/dist/cjs/icons-AUFyHyZx.js +81 -0
  7. package/dist/cjs/init-B8WotsHH.js +12 -0
  8. package/dist/cjs/is-empty-object-Cr9p07dP.js +7 -0
  9. package/dist/cjs/isEmpty-C46AwMJT.js +686 -0
  10. package/dist/cjs/isNil-B-fGcnNC.js +27 -0
  11. package/dist/cjs/isObjectLike-Bhr7FCs9.js +138 -0
  12. package/dist/cjs/isSymbol-1eHA2e9E.js +30 -0
  13. package/dist/cjs/loader.cjs.js +1 -1
  14. package/dist/cjs/locale-state-D434QK1o.js +60 -0
  15. package/dist/cjs/{ls-3d-scene_14.cjs.entry.js → ls-3d-scene.cjs.entry.js} +2059 -24361
  16. package/dist/cjs/ls-counters.cjs.entry.js +505 -0
  17. package/dist/cjs/ls-data.cjs.entry.js +4474 -0
  18. package/dist/cjs/ls-date-picker.cjs.entry.js +3298 -0
  19. package/dist/cjs/ls-energy-usage.cjs.entry.js +220 -206
  20. package/dist/cjs/ls-history-swimlane.cjs.entry.js +1786 -0
  21. package/dist/cjs/ls-indicator.cjs.entry.js +84 -0
  22. package/dist/cjs/ls-recent-stops.cjs.entry.js +2179 -0
  23. package/dist/cjs/ls-reset-steering.cjs.entry.js +208 -0
  24. package/dist/cjs/ls-status-count.cjs.entry.js +211 -0
  25. package/dist/cjs/ls-status-history.cjs.entry.js +488 -0
  26. package/dist/cjs/ls-status-item.cjs.entry.js +241 -0
  27. package/dist/cjs/ls-status-messages.cjs.entry.js +245 -0
  28. package/dist/cjs/ls-status.cjs.entry.js +156 -0
  29. package/dist/cjs/ls-swimlane.cjs.entry.js +820 -0
  30. package/dist/cjs/nl-CxoXyGvE.js +20 -0
  31. package/dist/cjs/nodrag-DdOgffWc.js +489 -0
  32. package/dist/cjs/period-Bqvedndf.js +63 -0
  33. package/dist/cjs/range-RkYbFtor.js +17 -0
  34. package/dist/cjs/safe-relative-time-DJTmYfc4.js +47 -0
  35. package/dist/cjs/sensorInfo-DN3WW3kt.js +51 -0
  36. package/dist/cjs/sensors-DqBjrPzl.js +321 -0
  37. package/dist/cjs/sortBy-BxklLsbW.js +2370 -0
  38. package/dist/cjs/status-codes.store-CxSiaNxt.js +158 -0
  39. package/dist/cjs/{init-DTU-5DzQ.js → store-ByFQQL9z.js} +89 -2599
  40. package/dist/cjs/store-error-CjlXhka5.js +23 -0
  41. package/dist/cjs/swimlane-constants-DRNSr6Ai.js +238 -0
  42. package/dist/cjs/timestamps-BIjmQUZ_.js +29 -0
  43. package/dist/cjs/transform-CXJtL0ob.js +4273 -0
  44. package/dist/cjs/values-Cm898VVc.js +190 -0
  45. package/dist/collection/collection-manifest.json +7 -1
  46. package/dist/collection/components/ls-counters/ls-counters.js +4 -3
  47. package/dist/collection/components/ls-counters/ls-counters.utils.js +0 -1
  48. package/dist/collection/components/ls-status-history/ls-status-history.css +9 -4
  49. package/dist/collection/components/ls-status-history/ls-status-history.js +14 -6
  50. package/dist/collection/components/ls-status-history/ls-status-history.utils.js +3 -1
  51. package/dist/collection/utils/em-dash.js +2 -0
  52. package/dist/collection/utils/translations.js +4 -0
  53. package/dist/components/em-dash.js +1 -0
  54. package/dist/components/ls-counters.js +1 -1
  55. package/dist/components/ls-status-history.js +1 -1
  56. package/dist/components/store.js +1 -1
  57. package/dist/ednl-liftstatus-web-components/ednl-liftstatus-web-components.esm.js +1 -1
  58. package/dist/ednl-liftstatus-web-components/p-1833ab57.entry.js +1 -0
  59. package/dist/ednl-liftstatus-web-components/p-1ede7002.entry.js +1 -0
  60. package/dist/ednl-liftstatus-web-components/p-25d4fbe9.entry.js +1 -0
  61. package/dist/ednl-liftstatus-web-components/p-45d22b78.entry.js +1 -0
  62. package/dist/ednl-liftstatus-web-components/p-49dec6f7.entry.js +1 -0
  63. package/dist/ednl-liftstatus-web-components/p-565b648d.entry.js +12 -0
  64. package/dist/ednl-liftstatus-web-components/p-566b122a.entry.js +1 -0
  65. package/dist/ednl-liftstatus-web-components/p-59ed0f4c.entry.js +1 -0
  66. package/dist/ednl-liftstatus-web-components/p-71a443d6.entry.js +1 -0
  67. package/dist/ednl-liftstatus-web-components/p-833ca3b7.entry.js +1 -0
  68. package/dist/ednl-liftstatus-web-components/p-B9avPOKf.js +1 -0
  69. package/dist/ednl-liftstatus-web-components/p-BGkoB2Fp.js +1 -0
  70. package/dist/ednl-liftstatus-web-components/p-BNLlCAGL.js +1 -0
  71. package/dist/ednl-liftstatus-web-components/p-BRcAanmR.js +1 -0
  72. package/dist/ednl-liftstatus-web-components/p-BXzXRhF2.js +1 -0
  73. package/dist/ednl-liftstatus-web-components/p-BuFJl4bx.js +1 -0
  74. package/dist/ednl-liftstatus-web-components/p-Bw7PDNGZ.js +1 -0
  75. package/dist/ednl-liftstatus-web-components/p-BwePdsnC.js +1 -0
  76. package/dist/ednl-liftstatus-web-components/p-C2wsufGp.js +1 -0
  77. package/dist/ednl-liftstatus-web-components/p-CPEl--Uc.js +1 -0
  78. package/dist/ednl-liftstatus-web-components/{p-BsQE35C8.js → p-CqIIZZwb.js} +1 -1
  79. package/dist/ednl-liftstatus-web-components/p-CqapRXVk.js +1 -0
  80. package/dist/ednl-liftstatus-web-components/p-D6stZ-hq.js +1 -0
  81. package/dist/ednl-liftstatus-web-components/p-DFTN3X9p.js +1 -0
  82. package/dist/ednl-liftstatus-web-components/p-DLuZqxqb.js +2 -0
  83. package/dist/ednl-liftstatus-web-components/p-DZFB7QnF.js +1 -0
  84. package/dist/ednl-liftstatus-web-components/p-Di-aPGj-.js +1 -0
  85. package/dist/ednl-liftstatus-web-components/p-DjSNdVAB.js +1 -0
  86. package/dist/ednl-liftstatus-web-components/p-GHMPnNk2.js +1 -0
  87. package/dist/ednl-liftstatus-web-components/p-MFjd05op.js +1 -0
  88. package/dist/ednl-liftstatus-web-components/p-UIJuKZgx.js +1 -0
  89. package/dist/ednl-liftstatus-web-components/p-Zo7BqT5S.js +1 -0
  90. package/dist/ednl-liftstatus-web-components/p-bXk7HZ2Z.js +1 -0
  91. package/dist/ednl-liftstatus-web-components/p-bcfac6cf.entry.js +1 -0
  92. package/dist/ednl-liftstatus-web-components/p-c9888cfa.entry.js +1 -0
  93. package/dist/ednl-liftstatus-web-components/p-dbxvlVVS.js +1 -0
  94. package/dist/ednl-liftstatus-web-components/p-f272fab3.entry.js +1 -0
  95. package/dist/ednl-liftstatus-web-components/p-f4b51684.entry.js +1 -0
  96. package/dist/ednl-liftstatus-web-components/p-f9ef29c8.entry.js +1 -0
  97. package/dist/ednl-liftstatus-web-components/p-gYSXSXh4.js +1 -0
  98. package/dist/ednl-liftstatus-web-components/p-nKqbk1fp.js +1 -0
  99. package/dist/ednl-liftstatus-web-components/p-udS2Cuut.js +1 -0
  100. package/dist/ednl-liftstatus-web-components/p-zpY4DTin.js +1 -0
  101. package/dist/esm/api-UfFwgR8t.js +787 -0
  102. package/dist/esm/debounce-Bab2sXAi.js +304 -0
  103. package/dist/esm/ednl-liftstatus-web-components.js +3 -3
  104. package/dist/esm/em-dash-CqapRXVk.js +4 -0
  105. package/dist/esm/error-message-CeSJc06I.js +62 -0
  106. package/dist/esm/icons-D5SXjqxY.js +76 -0
  107. package/dist/esm/{index-BsQE35C8.js → index-CqIIZZwb.js} +1 -1
  108. package/dist/esm/init-zpY4DTin.js +10 -0
  109. package/dist/esm/is-empty-object-BNLlCAGL.js +5 -0
  110. package/dist/esm/isEmpty-CyFPxYUf.js +670 -0
  111. package/dist/esm/isNil-DjSNdVAB.js +25 -0
  112. package/dist/esm/isObjectLike-CPEl--Uc.js +132 -0
  113. package/dist/esm/isSymbol-BqXpHTHW.js +28 -0
  114. package/dist/esm/loader.js +3 -3
  115. package/dist/esm/locale-state-CWnIr7Tx.js +58 -0
  116. package/dist/esm/{ls-3d-scene_14.entry.js → ls-3d-scene.entry.js} +2066 -24355
  117. package/dist/esm/ls-counters.entry.js +503 -0
  118. package/dist/esm/ls-data.entry.js +4472 -0
  119. package/dist/esm/ls-date-picker.entry.js +3296 -0
  120. package/dist/esm/ls-energy-usage.entry.js +185 -171
  121. package/dist/esm/ls-history-swimlane.entry.js +1784 -0
  122. package/dist/esm/ls-indicator.entry.js +82 -0
  123. package/dist/esm/ls-recent-stops.entry.js +2177 -0
  124. package/dist/esm/ls-reset-steering.entry.js +206 -0
  125. package/dist/esm/ls-status-count.entry.js +209 -0
  126. package/dist/esm/ls-status-history.entry.js +486 -0
  127. package/dist/esm/ls-status-item.entry.js +239 -0
  128. package/dist/esm/ls-status-messages.entry.js +243 -0
  129. package/dist/esm/ls-status.entry.js +154 -0
  130. package/dist/esm/ls-swimlane.entry.js +818 -0
  131. package/dist/esm/nl-DnseJVT7.js +18 -0
  132. package/dist/esm/nodrag-SvS3YAgi.js +484 -0
  133. package/dist/esm/period-ETScFoSl.js +60 -0
  134. package/dist/esm/range-BRcAanmR.js +15 -0
  135. package/dist/esm/safe-relative-time-B4Au03u7.js +44 -0
  136. package/dist/esm/sensorInfo-C6-8bOVj.js +49 -0
  137. package/dist/esm/sensors-DFTN3X9p.js +298 -0
  138. package/dist/esm/sortBy-CkXKwZ1N.js +2357 -0
  139. package/dist/esm/status-codes.store-DAFOLojD.js +154 -0
  140. package/dist/esm/{init-LFKAglbp.js → store-DaB-RvVn.js} +90 -2538
  141. package/dist/esm/store-error-BIwzy5fm.js +20 -0
  142. package/dist/esm/swimlane-constants-Bw6I6ZqC.js +222 -0
  143. package/dist/esm/timestamps-zpfoEaEE.js +25 -0
  144. package/dist/esm/transform-B-QWH-7l.js +4254 -0
  145. package/dist/esm/values-CmHpsdW5.js +185 -0
  146. package/dist/types/components/ls-counters/ls-counters.utils.d.ts +0 -1
  147. package/dist/types/components/ls-status-history/ls-status-history.d.ts +5 -0
  148. package/dist/types/utils/em-dash.d.ts +2 -0
  149. package/dist/types/utils/translations.d.ts +4 -0
  150. package/dist/types/utils/types.d.ts +6 -0
  151. package/package.json +1 -1
  152. package/dist/ednl-liftstatus-web-components/p-85e27496.entry.js +0 -1
  153. package/dist/ednl-liftstatus-web-components/p-BIAdTj7v.js +0 -2
  154. package/dist/ednl-liftstatus-web-components/p-c1ca83a1.entry.js +0 -12
@@ -0,0 +1,796 @@
1
+ 'use strict';
2
+
3
+ var store = require('./store-ByFQQL9z.js');
4
+ var isEmpty = require('./isEmpty-C46AwMJT.js');
5
+
6
+ class HTTPError extends Error {
7
+ response;
8
+ request;
9
+ options;
10
+ constructor(response, request, options) {
11
+ const code = (response.status || response.status === 0) ? response.status : '';
12
+ const title = response.statusText || '';
13
+ const status = `${code} ${title}`.trim();
14
+ const reason = status ? `status code ${status}` : 'an unknown error';
15
+ super(`Request failed with ${reason}: ${request.method} ${request.url}`);
16
+ this.name = 'HTTPError';
17
+ this.response = response;
18
+ this.request = request;
19
+ this.options = options;
20
+ }
21
+ }
22
+
23
+ class TimeoutError extends Error {
24
+ request;
25
+ constructor(request) {
26
+ super(`Request timed out: ${request.method} ${request.url}`);
27
+ this.name = 'TimeoutError';
28
+ this.request = request;
29
+ }
30
+ }
31
+
32
+ const supportsRequestStreams = (() => {
33
+ let duplexAccessed = false;
34
+ let hasContentType = false;
35
+ const supportsReadableStream = typeof globalThis.ReadableStream === 'function';
36
+ const supportsRequest = typeof globalThis.Request === 'function';
37
+ if (supportsReadableStream && supportsRequest) {
38
+ try {
39
+ hasContentType = new globalThis.Request('https://empty.invalid', {
40
+ body: new globalThis.ReadableStream(),
41
+ method: 'POST',
42
+ // @ts-expect-error - Types are outdated.
43
+ get duplex() {
44
+ duplexAccessed = true;
45
+ return 'half';
46
+ },
47
+ }).headers.has('Content-Type');
48
+ }
49
+ catch (error) {
50
+ // QQBrowser on iOS throws "unsupported BodyInit type" error (see issue #581)
51
+ if (error instanceof Error && error.message === 'unsupported BodyInit type') {
52
+ return false;
53
+ }
54
+ throw error;
55
+ }
56
+ }
57
+ return duplexAccessed && !hasContentType;
58
+ })();
59
+ const supportsAbortController = typeof globalThis.AbortController === 'function';
60
+ const supportsAbortSignal = typeof globalThis.AbortSignal === 'function' && typeof globalThis.AbortSignal.any === 'function';
61
+ const supportsResponseStreams = typeof globalThis.ReadableStream === 'function';
62
+ const supportsFormData = typeof globalThis.FormData === 'function';
63
+ const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete'];
64
+ const responseTypes = {
65
+ json: 'application/json',
66
+ text: 'text/*',
67
+ formData: 'multipart/form-data',
68
+ arrayBuffer: '*/*',
69
+ blob: '*/*',
70
+ // Supported in modern Fetch implementations (for example, browsers and recent Node.js/undici).
71
+ // We still feature-check at runtime before exposing the shortcut.
72
+ bytes: '*/*',
73
+ };
74
+ // The maximum value of a 32bit int (see issue #117)
75
+ const maxSafeTimeout = 2_147_483_647;
76
+ // Size in bytes of a typical form boundary, used to help estimate upload size
77
+ const usualFormBoundarySize = new TextEncoder().encode('------WebKitFormBoundaryaxpyiPgbbPti10Rw').length;
78
+ const stop = Symbol('stop');
79
+ const kyOptionKeys = {
80
+ json: true,
81
+ parseJson: true,
82
+ stringifyJson: true,
83
+ searchParams: true,
84
+ prefixUrl: true,
85
+ retry: true,
86
+ timeout: true,
87
+ hooks: true,
88
+ throwHttpErrors: true,
89
+ onDownloadProgress: true,
90
+ onUploadProgress: true,
91
+ fetch: true,
92
+ };
93
+ const requestOptionsRegistry = {
94
+ method: true,
95
+ headers: true,
96
+ body: true,
97
+ mode: true,
98
+ credentials: true,
99
+ cache: true,
100
+ redirect: true,
101
+ referrer: true,
102
+ referrerPolicy: true,
103
+ integrity: true,
104
+ keepalive: true,
105
+ signal: true,
106
+ window: true,
107
+ dispatcher: true,
108
+ duplex: true,
109
+ priority: true,
110
+ };
111
+
112
+ // eslint-disable-next-line @typescript-eslint/ban-types
113
+ const getBodySize = (body) => {
114
+ if (!body) {
115
+ return 0;
116
+ }
117
+ if (body instanceof FormData) {
118
+ // This is an approximation, as FormData size calculation is not straightforward
119
+ let size = 0;
120
+ for (const [key, value] of body) {
121
+ size += usualFormBoundarySize;
122
+ size += new TextEncoder().encode(`Content-Disposition: form-data; name="${key}"`).length;
123
+ size += typeof value === 'string'
124
+ ? new TextEncoder().encode(value).length
125
+ : value.size;
126
+ }
127
+ return size;
128
+ }
129
+ if (body instanceof Blob) {
130
+ return body.size;
131
+ }
132
+ if (body instanceof ArrayBuffer) {
133
+ return body.byteLength;
134
+ }
135
+ if (typeof body === 'string') {
136
+ return new TextEncoder().encode(body).length;
137
+ }
138
+ if (body instanceof URLSearchParams) {
139
+ return new TextEncoder().encode(body.toString()).length;
140
+ }
141
+ if ('byteLength' in body) {
142
+ return (body).byteLength;
143
+ }
144
+ if (typeof body === 'object' && body !== null) {
145
+ try {
146
+ const jsonString = JSON.stringify(body);
147
+ return new TextEncoder().encode(jsonString).length;
148
+ }
149
+ catch {
150
+ return 0;
151
+ }
152
+ }
153
+ return 0; // Default case, unable to determine size
154
+ };
155
+ const streamResponse = (response, onDownloadProgress) => {
156
+ const totalBytes = Number(response.headers.get('content-length')) || 0;
157
+ let transferredBytes = 0;
158
+ if (response.status === 204) {
159
+ if (onDownloadProgress) {
160
+ onDownloadProgress({ percent: 1, totalBytes, transferredBytes }, new Uint8Array());
161
+ }
162
+ return new Response(null, {
163
+ status: response.status,
164
+ statusText: response.statusText,
165
+ headers: response.headers,
166
+ });
167
+ }
168
+ return new Response(new ReadableStream({
169
+ async start(controller) {
170
+ const reader = response.body.getReader();
171
+ if (onDownloadProgress) {
172
+ onDownloadProgress({ percent: 0, transferredBytes: 0, totalBytes }, new Uint8Array());
173
+ }
174
+ async function read() {
175
+ const { done, value } = await reader.read();
176
+ if (done) {
177
+ controller.close();
178
+ return;
179
+ }
180
+ if (onDownloadProgress) {
181
+ transferredBytes += value.byteLength;
182
+ const percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
183
+ onDownloadProgress({ percent, transferredBytes, totalBytes }, value);
184
+ }
185
+ controller.enqueue(value);
186
+ await read();
187
+ }
188
+ await read();
189
+ },
190
+ }), {
191
+ status: response.status,
192
+ statusText: response.statusText,
193
+ headers: response.headers,
194
+ });
195
+ };
196
+ // eslint-disable-next-line @typescript-eslint/ban-types
197
+ const streamRequest = (request, onUploadProgress, originalBody) => {
198
+ // Use original body for size calculation since request.body is already a stream
199
+ const totalBytes = getBodySize(originalBody ?? request.body);
200
+ let transferredBytes = 0;
201
+ return new Request(request, {
202
+ // @ts-expect-error - Types are outdated.
203
+ duplex: 'half',
204
+ body: new ReadableStream({
205
+ async start(controller) {
206
+ const reader = request.body instanceof ReadableStream ? request.body.getReader() : new Response('').body.getReader();
207
+ async function read() {
208
+ const { done, value } = await reader.read();
209
+ if (done) {
210
+ // Ensure 100% progress is reported when the upload is complete
211
+ if (onUploadProgress) {
212
+ onUploadProgress({ percent: 1, transferredBytes, totalBytes: Math.max(totalBytes, transferredBytes) }, new Uint8Array());
213
+ }
214
+ controller.close();
215
+ return;
216
+ }
217
+ transferredBytes += value.byteLength;
218
+ let percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
219
+ if (totalBytes < transferredBytes || percent === 1) {
220
+ percent = 0.99;
221
+ }
222
+ if (onUploadProgress) {
223
+ onUploadProgress({ percent: Number(percent.toFixed(2)), transferredBytes, totalBytes }, value);
224
+ }
225
+ controller.enqueue(value);
226
+ await read();
227
+ }
228
+ await read();
229
+ },
230
+ }),
231
+ });
232
+ };
233
+
234
+ // eslint-disable-next-line @typescript-eslint/ban-types
235
+ const isObject = (value) => value !== null && typeof value === 'object';
236
+
237
+ const validateAndMerge = (...sources) => {
238
+ for (const source of sources) {
239
+ if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {
240
+ throw new TypeError('The `options` argument must be an object');
241
+ }
242
+ }
243
+ return deepMerge({}, ...sources);
244
+ };
245
+ const mergeHeaders = (source1 = {}, source2 = {}) => {
246
+ const result = new globalThis.Headers(source1);
247
+ const isHeadersInstance = source2 instanceof globalThis.Headers;
248
+ const source = new globalThis.Headers(source2);
249
+ for (const [key, value] of source.entries()) {
250
+ if ((isHeadersInstance && value === 'undefined') || value === undefined) {
251
+ result.delete(key);
252
+ }
253
+ else {
254
+ result.set(key, value);
255
+ }
256
+ }
257
+ return result;
258
+ };
259
+ function newHookValue(original, incoming, property) {
260
+ return (Object.hasOwn(incoming, property) && incoming[property] === undefined)
261
+ ? []
262
+ : deepMerge(original[property] ?? [], incoming[property] ?? []);
263
+ }
264
+ const mergeHooks = (original = {}, incoming = {}) => ({
265
+ beforeRequest: newHookValue(original, incoming, 'beforeRequest'),
266
+ beforeRetry: newHookValue(original, incoming, 'beforeRetry'),
267
+ afterResponse: newHookValue(original, incoming, 'afterResponse'),
268
+ beforeError: newHookValue(original, incoming, 'beforeError'),
269
+ });
270
+ // TODO: Make this strongly-typed (no `any`).
271
+ const deepMerge = (...sources) => {
272
+ let returnValue = {};
273
+ let headers = {};
274
+ let hooks = {};
275
+ for (const source of sources) {
276
+ if (Array.isArray(source)) {
277
+ if (!Array.isArray(returnValue)) {
278
+ returnValue = [];
279
+ }
280
+ returnValue = [...returnValue, ...source];
281
+ }
282
+ else if (isObject(source)) {
283
+ for (let [key, value] of Object.entries(source)) {
284
+ if (isObject(value) && key in returnValue) {
285
+ value = deepMerge(returnValue[key], value);
286
+ }
287
+ returnValue = { ...returnValue, [key]: value };
288
+ }
289
+ if (isObject(source.hooks)) {
290
+ hooks = mergeHooks(hooks, source.hooks);
291
+ returnValue.hooks = hooks;
292
+ }
293
+ if (isObject(source.headers)) {
294
+ headers = mergeHeaders(headers, source.headers);
295
+ returnValue.headers = headers;
296
+ }
297
+ }
298
+ }
299
+ return returnValue;
300
+ };
301
+
302
+ const normalizeRequestMethod = (input) => requestMethods.includes(input) ? input.toUpperCase() : input;
303
+ const retryMethods = ['get', 'put', 'head', 'delete', 'options', 'trace'];
304
+ const retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];
305
+ const retryAfterStatusCodes = [413, 429, 503];
306
+ const defaultRetryOptions = {
307
+ limit: 2,
308
+ methods: retryMethods,
309
+ statusCodes: retryStatusCodes,
310
+ afterStatusCodes: retryAfterStatusCodes,
311
+ maxRetryAfter: Number.POSITIVE_INFINITY,
312
+ backoffLimit: Number.POSITIVE_INFINITY,
313
+ delay: attemptCount => 0.3 * (2 ** (attemptCount - 1)) * 1000,
314
+ };
315
+ const normalizeRetryOptions = (retry = {}) => {
316
+ if (typeof retry === 'number') {
317
+ return {
318
+ ...defaultRetryOptions,
319
+ limit: retry,
320
+ };
321
+ }
322
+ if (retry.methods && !Array.isArray(retry.methods)) {
323
+ throw new Error('retry.methods must be an array');
324
+ }
325
+ if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {
326
+ throw new Error('retry.statusCodes must be an array');
327
+ }
328
+ return {
329
+ ...defaultRetryOptions,
330
+ ...retry,
331
+ };
332
+ };
333
+
334
+ // `Promise.race()` workaround (#91)
335
+ async function timeout(request, init, abortController, options) {
336
+ return new Promise((resolve, reject) => {
337
+ const timeoutId = setTimeout(() => {
338
+ if (abortController) {
339
+ abortController.abort();
340
+ }
341
+ reject(new TimeoutError(request));
342
+ }, options.timeout);
343
+ void options
344
+ .fetch(request, init)
345
+ .then(resolve)
346
+ .catch(reject)
347
+ .then(() => {
348
+ clearTimeout(timeoutId);
349
+ });
350
+ });
351
+ }
352
+
353
+ // https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111
354
+ async function delay(ms, { signal }) {
355
+ return new Promise((resolve, reject) => {
356
+ if (signal) {
357
+ signal.throwIfAborted();
358
+ signal.addEventListener('abort', abortHandler, { once: true });
359
+ }
360
+ function abortHandler() {
361
+ clearTimeout(timeoutId);
362
+ reject(signal.reason);
363
+ }
364
+ const timeoutId = setTimeout(() => {
365
+ signal?.removeEventListener('abort', abortHandler);
366
+ resolve();
367
+ }, ms);
368
+ });
369
+ }
370
+
371
+ const findUnknownOptions = (request, options) => {
372
+ const unknownOptions = {};
373
+ for (const key in options) {
374
+ if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && !(key in request)) {
375
+ unknownOptions[key] = options[key];
376
+ }
377
+ }
378
+ return unknownOptions;
379
+ };
380
+ const hasSearchParameters = (search) => {
381
+ if (search === undefined) {
382
+ return false;
383
+ }
384
+ // The `typeof array` still gives "object", so we need different checking for array.
385
+ if (Array.isArray(search)) {
386
+ return search.length > 0;
387
+ }
388
+ if (search instanceof URLSearchParams) {
389
+ return search.size > 0;
390
+ }
391
+ // Record
392
+ if (typeof search === 'object') {
393
+ return Object.keys(search).length > 0;
394
+ }
395
+ if (typeof search === 'string') {
396
+ return search.trim().length > 0;
397
+ }
398
+ return Boolean(search);
399
+ };
400
+
401
+ class Ky {
402
+ static create(input, options) {
403
+ const ky = new Ky(input, options);
404
+ const function_ = async () => {
405
+ if (typeof ky._options.timeout === 'number' && ky._options.timeout > maxSafeTimeout) {
406
+ throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
407
+ }
408
+ // Delay the fetch so that body method shortcuts can set the Accept header
409
+ await Promise.resolve();
410
+ // Before using ky.request, _fetch clones it and saves the clone for future retries to use.
411
+ // If retry is not needed, close the cloned request's ReadableStream for memory safety.
412
+ let response = await ky._fetch();
413
+ for (const hook of ky._options.hooks.afterResponse) {
414
+ // eslint-disable-next-line no-await-in-loop
415
+ const modifiedResponse = await hook(ky.request, ky._options, ky._decorateResponse(response.clone()));
416
+ if (modifiedResponse instanceof globalThis.Response) {
417
+ response = modifiedResponse;
418
+ }
419
+ }
420
+ ky._decorateResponse(response);
421
+ if (!response.ok && ky._options.throwHttpErrors) {
422
+ let error = new HTTPError(response, ky.request, ky._options);
423
+ for (const hook of ky._options.hooks.beforeError) {
424
+ // eslint-disable-next-line no-await-in-loop
425
+ error = await hook(error);
426
+ }
427
+ throw error;
428
+ }
429
+ // If `onDownloadProgress` is passed, it uses the stream API internally
430
+ if (ky._options.onDownloadProgress) {
431
+ if (typeof ky._options.onDownloadProgress !== 'function') {
432
+ throw new TypeError('The `onDownloadProgress` option must be a function');
433
+ }
434
+ if (!supportsResponseStreams) {
435
+ throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');
436
+ }
437
+ return streamResponse(response.clone(), ky._options.onDownloadProgress);
438
+ }
439
+ return response;
440
+ };
441
+ const isRetriableMethod = ky._options.retry.methods.includes(ky.request.method.toLowerCase());
442
+ const result = (isRetriableMethod ? ky._retry(function_) : function_())
443
+ .finally(async () => {
444
+ // Now that we know a retry is not needed, close the ReadableStream of the cloned request.
445
+ if (!ky.request.bodyUsed) {
446
+ await ky.request.body?.cancel();
447
+ }
448
+ });
449
+ for (const [type, mimeType] of Object.entries(responseTypes)) {
450
+ // Only expose `.bytes()` when the environment implements it.
451
+ if (type === 'bytes'
452
+ && typeof globalThis.Response?.prototype?.bytes !== 'function') {
453
+ continue;
454
+ }
455
+ result[type] = async () => {
456
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
457
+ ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);
458
+ const response = await result;
459
+ if (type === 'json') {
460
+ if (response.status === 204) {
461
+ return '';
462
+ }
463
+ const text = await response.text();
464
+ if (text === '') {
465
+ return '';
466
+ }
467
+ if (options.parseJson) {
468
+ return options.parseJson(text);
469
+ }
470
+ return JSON.parse(text);
471
+ }
472
+ return response[type]();
473
+ };
474
+ }
475
+ return result;
476
+ }
477
+ // eslint-disable-next-line unicorn/prevent-abbreviations
478
+ static #normalizeSearchParams(searchParams) {
479
+ // Filter out undefined values from plain objects
480
+ if (searchParams && typeof searchParams === 'object' && !Array.isArray(searchParams) && !(searchParams instanceof URLSearchParams)) {
481
+ return Object.fromEntries(Object.entries(searchParams).filter(([, value]) => value !== undefined));
482
+ }
483
+ return searchParams;
484
+ }
485
+ request;
486
+ abortController;
487
+ _retryCount = 0;
488
+ _input;
489
+ _options;
490
+ // eslint-disable-next-line complexity
491
+ constructor(input, options = {}) {
492
+ this._input = input;
493
+ this._options = {
494
+ ...options,
495
+ headers: mergeHeaders(this._input.headers, options.headers),
496
+ hooks: mergeHooks({
497
+ beforeRequest: [],
498
+ beforeRetry: [],
499
+ beforeError: [],
500
+ afterResponse: [],
501
+ }, options.hooks),
502
+ method: normalizeRequestMethod(options.method ?? this._input.method ?? 'GET'),
503
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
504
+ prefixUrl: String(options.prefixUrl || ''),
505
+ retry: normalizeRetryOptions(options.retry),
506
+ throwHttpErrors: options.throwHttpErrors !== false,
507
+ timeout: options.timeout ?? 10_000,
508
+ fetch: options.fetch ?? globalThis.fetch.bind(globalThis),
509
+ };
510
+ if (typeof this._input !== 'string' && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
511
+ throw new TypeError('`input` must be a string, URL, or Request');
512
+ }
513
+ if (this._options.prefixUrl && typeof this._input === 'string') {
514
+ if (this._input.startsWith('/')) {
515
+ throw new Error('`input` must not begin with a slash when using `prefixUrl`');
516
+ }
517
+ if (!this._options.prefixUrl.endsWith('/')) {
518
+ this._options.prefixUrl += '/';
519
+ }
520
+ this._input = this._options.prefixUrl + this._input;
521
+ }
522
+ if (supportsAbortController && supportsAbortSignal) {
523
+ const originalSignal = this._options.signal ?? this._input.signal;
524
+ this.abortController = new globalThis.AbortController();
525
+ this._options.signal = originalSignal ? AbortSignal.any([originalSignal, this.abortController.signal]) : this.abortController.signal;
526
+ }
527
+ if (supportsRequestStreams) {
528
+ // @ts-expect-error - Types are outdated.
529
+ this._options.duplex = 'half';
530
+ }
531
+ if (this._options.json !== undefined) {
532
+ this._options.body = this._options.stringifyJson?.(this._options.json) ?? JSON.stringify(this._options.json);
533
+ this._options.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json');
534
+ }
535
+ this.request = new globalThis.Request(this._input, this._options);
536
+ if (hasSearchParameters(this._options.searchParams)) {
537
+ // eslint-disable-next-line unicorn/prevent-abbreviations
538
+ const textSearchParams = typeof this._options.searchParams === 'string'
539
+ ? this._options.searchParams.replace(/^\?/, '')
540
+ : new URLSearchParams(Ky.#normalizeSearchParams(this._options.searchParams)).toString();
541
+ // eslint-disable-next-line unicorn/prevent-abbreviations
542
+ const searchParams = '?' + textSearchParams;
543
+ const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams);
544
+ // To provide correct form boundary, Content-Type header should be deleted each time when new Request instantiated from another one
545
+ if (((supportsFormData && this._options.body instanceof globalThis.FormData)
546
+ || this._options.body instanceof URLSearchParams) && !(this._options.headers && this._options.headers['content-type'])) {
547
+ this.request.headers.delete('content-type');
548
+ }
549
+ // The spread of `this.request` is required as otherwise it misses the `duplex` option for some reason and throws.
550
+ this.request = new globalThis.Request(new globalThis.Request(url, { ...this.request }), this._options);
551
+ }
552
+ // If `onUploadProgress` is passed, it uses the stream API internally
553
+ if (this._options.onUploadProgress) {
554
+ if (typeof this._options.onUploadProgress !== 'function') {
555
+ throw new TypeError('The `onUploadProgress` option must be a function');
556
+ }
557
+ if (!supportsRequestStreams) {
558
+ throw new Error('Request streams are not supported in your environment. The `duplex` option for `Request` is not available.');
559
+ }
560
+ const originalBody = this.request.body;
561
+ if (originalBody) {
562
+ // Pass original body to calculate size correctly (before it becomes a stream)
563
+ this.request = streamRequest(this.request, this._options.onUploadProgress, this._options.body);
564
+ }
565
+ }
566
+ }
567
+ _calculateRetryDelay(error) {
568
+ this._retryCount++;
569
+ if (this._retryCount > this._options.retry.limit || error instanceof TimeoutError) {
570
+ throw error;
571
+ }
572
+ if (error instanceof HTTPError) {
573
+ if (!this._options.retry.statusCodes.includes(error.response.status)) {
574
+ throw error;
575
+ }
576
+ const retryAfter = error.response.headers.get('Retry-After')
577
+ ?? error.response.headers.get('RateLimit-Reset')
578
+ ?? error.response.headers.get('X-RateLimit-Reset') // GitHub
579
+ ?? error.response.headers.get('X-Rate-Limit-Reset'); // Twitter
580
+ if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) {
581
+ let after = Number(retryAfter) * 1000;
582
+ if (Number.isNaN(after)) {
583
+ after = Date.parse(retryAfter) - Date.now();
584
+ }
585
+ else if (after >= Date.parse('2024-01-01')) {
586
+ // A large number is treated as a timestamp (fixed threshold protects against clock skew)
587
+ after -= Date.now();
588
+ }
589
+ const max = this._options.retry.maxRetryAfter ?? after;
590
+ return after < max ? after : max;
591
+ }
592
+ if (error.response.status === 413) {
593
+ throw error;
594
+ }
595
+ }
596
+ const retryDelay = this._options.retry.delay(this._retryCount);
597
+ return Math.min(this._options.retry.backoffLimit, retryDelay);
598
+ }
599
+ _decorateResponse(response) {
600
+ if (this._options.parseJson) {
601
+ response.json = async () => this._options.parseJson(await response.text());
602
+ }
603
+ return response;
604
+ }
605
+ async _retry(function_) {
606
+ try {
607
+ return await function_();
608
+ }
609
+ catch (error) {
610
+ const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout);
611
+ if (this._retryCount < 1) {
612
+ throw error;
613
+ }
614
+ await delay(ms, { signal: this._options.signal });
615
+ for (const hook of this._options.hooks.beforeRetry) {
616
+ // eslint-disable-next-line no-await-in-loop
617
+ const hookResult = await hook({
618
+ request: this.request,
619
+ options: this._options,
620
+ error: error,
621
+ retryCount: this._retryCount,
622
+ });
623
+ // If `stop` is returned from the hook, the retry process is stopped
624
+ if (hookResult === stop) {
625
+ return;
626
+ }
627
+ }
628
+ return this._retry(function_);
629
+ }
630
+ }
631
+ async _fetch() {
632
+ for (const hook of this._options.hooks.beforeRequest) {
633
+ // eslint-disable-next-line no-await-in-loop
634
+ const result = await hook(this.request, this._options);
635
+ if (result instanceof Request) {
636
+ this.request = result;
637
+ break;
638
+ }
639
+ if (result instanceof Response) {
640
+ return result;
641
+ }
642
+ }
643
+ const nonRequestOptions = findUnknownOptions(this.request, this._options);
644
+ // Cloning is done here to prepare in advance for retries
645
+ const mainRequest = this.request;
646
+ this.request = mainRequest.clone();
647
+ if (this._options.timeout === false) {
648
+ return this._options.fetch(mainRequest, nonRequestOptions);
649
+ }
650
+ return timeout(mainRequest, nonRequestOptions, this.abortController, this._options);
651
+ }
652
+ }
653
+
654
+ /*! MIT License © Sindre Sorhus */
655
+ const createInstance = (defaults) => {
656
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
657
+ const ky = (input, options) => Ky.create(input, validateAndMerge(defaults, options));
658
+ for (const method of requestMethods) {
659
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
660
+ ky[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, { method }));
661
+ }
662
+ ky.create = (newDefaults) => createInstance(validateAndMerge(newDefaults));
663
+ ky.extend = (newDefaults) => {
664
+ if (typeof newDefaults === 'function') {
665
+ newDefaults = newDefaults(defaults ?? {});
666
+ }
667
+ return createInstance(validateAndMerge(defaults, newDefaults));
668
+ };
669
+ ky.stop = stop;
670
+ return ky;
671
+ };
672
+ const ky = createInstance();
673
+
674
+ const REQUEST_TIMEOUT_MS = 60000;
675
+ const authHeader = (accessToken) => ({
676
+ Authorization: `Bearer ${accessToken}`,
677
+ });
678
+ class MissingApiConfigError extends Error {
679
+ constructor(message) {
680
+ super(message);
681
+ this.name = 'MissingApiConfigError';
682
+ }
683
+ }
684
+ async function authenticate({ apiUrl, accessToken }) {
685
+ return ky
686
+ .post(`${apiUrl}/liftstatus/auth`, {
687
+ headers: authHeader(accessToken),
688
+ json: { accessToken },
689
+ throwHttpErrors: true,
690
+ })
691
+ .json();
692
+ }
693
+ async function fetchSensorSummary({ apiUrl, accessToken, objectType, objectId, sensorId, from, }) {
694
+ return ky
695
+ .get(`${apiUrl}/liftstatus/${objectType}/${objectId}/sensor/${sensorId}/summary`, {
696
+ headers: authHeader(accessToken),
697
+ searchParams: { from },
698
+ throwHttpErrors: true,
699
+ timeout: REQUEST_TIMEOUT_MS,
700
+ })
701
+ .json();
702
+ }
703
+ async function fetchSensorData({ apiUrl, accessToken, objectType, objectId, from, to, sensors, }) {
704
+ return ky
705
+ .post(`${apiUrl}/liftstatus/${objectType}/${objectId}/sensor`, {
706
+ headers: authHeader(accessToken),
707
+ searchParams: {
708
+ from,
709
+ to,
710
+ sensors: sensors.map(String).join(),
711
+ },
712
+ throwHttpErrors: true,
713
+ timeout: REQUEST_TIMEOUT_MS,
714
+ })
715
+ .json();
716
+ }
717
+ /**
718
+ * Fetches the status codes of the given impact levels that were active in the
719
+ * given period. Only concrete levels can be asked for: the API has a level for
720
+ * every code it returns, so it has no "unknown" to filter on. An empty `levels`
721
+ * reads as "no filter" server side, so pass at least one level.
722
+ */
723
+ async function fetchStatusCodeHistory({ apiUrl, accessToken, objectType, objectId, from, to, levels, }) {
724
+ return ky
725
+ .get(`${apiUrl}/liftstatus/${objectType}/${objectId}/status-code`, {
726
+ headers: authHeader(accessToken),
727
+ searchParams: { from, to, levels: levels.join() },
728
+ throwHttpErrors: true,
729
+ timeout: REQUEST_TIMEOUT_MS,
730
+ })
731
+ .json();
732
+ }
733
+ /**
734
+ * Fetches the reference (description and impact level) of every status code
735
+ * whose code starts with `controller`. The API needs at least 4 characters.
736
+ */
737
+ async function fetchStatusCodeReference({ apiUrl, accessToken, controller, }) {
738
+ return ky
739
+ .get(`${apiUrl}/liftstatus/status-codes/reference`, {
740
+ headers: authHeader(accessToken),
741
+ searchParams: { controller },
742
+ throwHttpErrors: true,
743
+ timeout: REQUEST_TIMEOUT_MS,
744
+ })
745
+ .json();
746
+ }
747
+ async function fetchSensorSummaries({ apiUrl, accessToken, objectType, objectId, from, to, sensors, }) {
748
+ return ky
749
+ .post(`${apiUrl}/liftstatus/${objectType}/${objectId}/sensor/summary`, {
750
+ headers: authHeader(accessToken),
751
+ searchParams: {
752
+ from,
753
+ to,
754
+ sensors: sensors.map(String).join(),
755
+ },
756
+ throwHttpErrors: true,
757
+ timeout: REQUEST_TIMEOUT_MS,
758
+ })
759
+ .json();
760
+ }
761
+ /** A sensor series over the given period, bucketed by `resolution`. */
762
+ async function fetchSensorSeries({ apiUrl, accessToken, objectType, objectId, from, to, sensors, resolution, }) {
763
+ return ky
764
+ .post(`${apiUrl}/liftstatus/${objectType}/${objectId}/sensor/series`, {
765
+ headers: authHeader(accessToken),
766
+ searchParams: {
767
+ from,
768
+ to,
769
+ sensors: sensors.map(String).join(),
770
+ resolution,
771
+ },
772
+ throwHttpErrors: true,
773
+ timeout: REQUEST_TIMEOUT_MS,
774
+ })
775
+ .json();
776
+ }
777
+ async function sendResetCommand({ idKey, command }) {
778
+ const store$1 = await store.getStore(idKey);
779
+ const { accessToken, apiUrl, externalIdentifier, objectType } = store$1.state;
780
+ if (apiUrl === undefined || accessToken === undefined || objectType === undefined || isEmpty.isEmpty(apiUrl) || isEmpty.isEmpty(accessToken) || isEmpty.isEmpty(objectType)) {
781
+ throw new MissingApiConfigError('Cannot send reset command: missing API URL, access token, or object type.');
782
+ }
783
+ await ky.post(`${apiUrl}/liftstatus/command/${objectType}/${externalIdentifier}/${command}`, {
784
+ headers: authHeader(accessToken),
785
+ throwHttpErrors: true,
786
+ });
787
+ }
788
+
789
+ exports.authenticate = authenticate;
790
+ exports.fetchSensorData = fetchSensorData;
791
+ exports.fetchSensorSeries = fetchSensorSeries;
792
+ exports.fetchSensorSummaries = fetchSensorSummaries;
793
+ exports.fetchSensorSummary = fetchSensorSummary;
794
+ exports.fetchStatusCodeHistory = fetchStatusCodeHistory;
795
+ exports.fetchStatusCodeReference = fetchStatusCodeReference;
796
+ exports.sendResetCommand = sendResetCommand;