@knime/utils 1.11.0 → 1.11.2

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 (86) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +67 -14
  3. package/dist/globals.d.ts +8 -0
  4. package/dist/index.js +714 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/capitalize.d.ts +20 -0
  7. package/dist/src/capitalize.d.ts.map +1 -0
  8. package/dist/src/dateMinMaxCheck.d.ts +19 -0
  9. package/dist/src/dateMinMaxCheck.d.ts.map +1 -0
  10. package/dist/src/debounce.d.ts +4 -0
  11. package/dist/src/debounce.d.ts.map +1 -0
  12. package/dist/src/fileExtensions.d.ts +33 -0
  13. package/dist/src/fileExtensions.d.ts.map +1 -0
  14. package/dist/src/filters.d.ts +13 -0
  15. package/dist/src/filters.d.ts.map +1 -0
  16. package/dist/src/format.d.ts +39 -0
  17. package/dist/src/format.d.ts.map +1 -0
  18. package/dist/src/formatHotkeys.d.ts +17 -0
  19. package/dist/src/formatHotkeys.d.ts.map +1 -0
  20. package/dist/src/getDeepActiveElement.d.ts +3 -0
  21. package/dist/src/getDeepActiveElement.d.ts.map +1 -0
  22. package/{src/getWrappedAroundIndex.ts → dist/src/getWrappedAroundIndex.d.ts} +3 -2
  23. package/dist/src/getWrappedAroundIndex.d.ts.map +1 -0
  24. package/{src/hotkeys.ts → dist/src/hotkeys.d.ts} +4 -17
  25. package/dist/src/hotkeys.d.ts.map +1 -0
  26. package/dist/src/index.d.ts +29 -0
  27. package/dist/src/index.d.ts.map +1 -0
  28. package/dist/src/intervalUtils.d.ts +114 -0
  29. package/dist/src/intervalUtils.d.ts.map +1 -0
  30. package/{src/localTimezone.ts → dist/src/localTimezone.d.ts} +3 -2
  31. package/dist/src/localTimezone.d.ts.map +1 -0
  32. package/dist/src/navigator.d.ts +11 -0
  33. package/dist/src/navigator.d.ts.map +1 -0
  34. package/{src/numIntegerDigits.ts → dist/src/numIntegerDigits.d.ts} +3 -2
  35. package/dist/src/numIntegerDigits.d.ts.map +1 -0
  36. package/dist/src/promise/createAbortablePromise.d.ts +32 -0
  37. package/dist/src/promise/createAbortablePromise.d.ts.map +1 -0
  38. package/dist/src/promise/createUnwrappedPromise.d.ts +7 -0
  39. package/dist/src/promise/createUnwrappedPromise.d.ts.map +1 -0
  40. package/dist/src/promise/index.d.ts +4 -0
  41. package/dist/src/promise/index.d.ts.map +1 -0
  42. package/dist/src/promise/retryPromise.d.ts +16 -0
  43. package/dist/src/promise/retryPromise.d.ts.map +1 -0
  44. package/dist/src/sanitization.d.ts +8 -0
  45. package/dist/src/sanitization.d.ts.map +1 -0
  46. package/dist/src/sleep.d.ts +5 -0
  47. package/dist/src/sleep.d.ts.map +1 -0
  48. package/dist/src/truncateString.d.ts +3 -0
  49. package/dist/src/truncateString.d.ts.map +1 -0
  50. package/dist/src/updateDate.d.ts +11 -0
  51. package/dist/src/updateDate.d.ts.map +1 -0
  52. package/{src/updateTime.ts → dist/src/updateTime.d.ts} +3 -11
  53. package/dist/src/updateTime.d.ts.map +1 -0
  54. package/dist/test-utils/index.d.ts +3 -0
  55. package/dist/test-utils/index.d.ts.map +1 -0
  56. package/dist/test-utils/index.js +40 -0
  57. package/dist/test-utils/index.js.map +1 -0
  58. package/dist/test-utils/muteConsole.d.ts +8 -0
  59. package/dist/test-utils/muteConsole.d.ts.map +1 -0
  60. package/package.json +51 -33
  61. package/src/capitalize.ts +0 -45
  62. package/src/dateMinMaxCheck.ts +0 -68
  63. package/src/debounce.ts +0 -28
  64. package/src/fileExtensions.ts +0 -87
  65. package/src/filters.ts +0 -114
  66. package/src/format.ts +0 -113
  67. package/src/formatHotkeys.ts +0 -98
  68. package/src/getDeepActiveElement.ts +0 -9
  69. package/src/index.ts +0 -76
  70. package/src/intervalUtils.ts +0 -434
  71. package/src/navigator.ts +0 -13
  72. package/src/promise/createAbortablePromise.ts +0 -56
  73. package/src/promise/createUnwrappedPromise.ts +0 -17
  74. package/src/promise/index.ts +0 -3
  75. package/src/promise/retryPromise.ts +0 -45
  76. package/src/sanitization.ts +0 -72
  77. package/src/sleep.ts +0 -6
  78. package/src/truncateString.ts +0 -7
  79. package/src/updateDate.ts +0 -23
  80. package/src/uploadManager/index.ts +0 -370
  81. package/test-utils/index.ts +0 -3
  82. package/test-utils/muteConsole.ts +0 -54
  83. /package/{src/audit → audit}/README.md +0 -0
  84. /package/{src/audit → audit}/bulkAudit.js +0 -0
  85. /package/{src/audit → audit}/cli.js +0 -0
  86. /package/{src/config/globals.d.ts → globals.d.ts} +0 -0
package/dist/index.js ADDED
@@ -0,0 +1,714 @@
1
+ import { isValid, set, getDate, getMonth, getYear, isAfter, isBefore } from 'date-fns';
2
+ import { filesize } from 'filesize';
3
+ import DomPurify from 'dompurify';
4
+
5
+ const capitalize = (input) => input.charAt(0).toUpperCase() + input.substring(1);
6
+ const formats = {
7
+ customFormat: (input, delimiter) => capitalize(input.replace(delimiter, " ").toLowerCase()),
8
+ kebabFormat: (input) => formats.customFormat(input, "-"),
9
+ snakeFormat: (input) => formats.customFormat(input, "_"),
10
+ camelPascalCase: (input) => capitalize(
11
+ (input.match(/([A-Z]?[^A-Z]*)/g) ?? []).slice(0, -1).join(" ").toLowerCase()
12
+ )
13
+ };
14
+ const caseFormatter = ({
15
+ string,
16
+ delimiter,
17
+ format
18
+ }) => {
19
+ if (delimiter) {
20
+ return formats.customFormat(string, delimiter);
21
+ }
22
+ if (format) {
23
+ return formats[format](string, delimiter ?? "");
24
+ }
25
+ return capitalize(string);
26
+ };
27
+
28
+ const updateDate = (base, date) => {
29
+ if (date) {
30
+ base = isValid(base) ? base : new Date(Date.UTC(0, 0));
31
+ return set(base, {
32
+ year: getYear(date),
33
+ month: getMonth(date),
34
+ date: getDate(date)
35
+ });
36
+ }
37
+ return base;
38
+ };
39
+
40
+ const updateTime = (base, date) => {
41
+ const d = new Date(base);
42
+ if (date) {
43
+ d.setHours(date.getHours());
44
+ d.setMinutes(date.getMinutes());
45
+ d.setSeconds(date.getSeconds());
46
+ d.setMilliseconds(date.getMilliseconds());
47
+ }
48
+ return d;
49
+ };
50
+
51
+ const isBeforeMinDate = (date, min, checkDate, checkTime) => {
52
+ if (min) {
53
+ if (checkTime && checkDate) {
54
+ return isBefore(date, min);
55
+ }
56
+ if (checkTime) {
57
+ const base = /* @__PURE__ */ new Date(0);
58
+ return isBefore(updateTime(base, date), updateTime(base, min));
59
+ }
60
+ if (checkDate) {
61
+ const base = /* @__PURE__ */ new Date(0);
62
+ return isBefore(updateDate(base, date), updateDate(base, min));
63
+ }
64
+ }
65
+ return false;
66
+ };
67
+ const isAfterMaxDate = (date, max, checkDate, checkTime) => {
68
+ if (max) {
69
+ if (checkTime && checkDate) {
70
+ return isAfter(date, max);
71
+ }
72
+ if (checkTime) {
73
+ const base = /* @__PURE__ */ new Date(0);
74
+ return isAfter(updateTime(base, date), updateTime(base, max));
75
+ }
76
+ if (checkDate) {
77
+ const base = /* @__PURE__ */ new Date(0);
78
+ return isAfter(updateDate(base, date), updateDate(base, max));
79
+ }
80
+ }
81
+ return false;
82
+ };
83
+
84
+ const debounce = (callback, wait) => {
85
+ let timer;
86
+ let lastCall = 0;
87
+ return (...args) => {
88
+ const [value, index] = args;
89
+ clearTimeout(timer);
90
+ const now = Date.now();
91
+ const timeFromLastCall = now - lastCall;
92
+ if (timeFromLastCall > wait) {
93
+ lastCall = now;
94
+ callback(value, index);
95
+ } else {
96
+ timer = setTimeout(() => {
97
+ lastCall = now;
98
+ callback(value, index);
99
+ }, wait);
100
+ }
101
+ };
102
+ };
103
+
104
+ const modeDefinitions = [
105
+ {
106
+ id: "search",
107
+ normalize(searchTerm, caseSensitiveSearch) {
108
+ return caseSensitiveSearch ? searchTerm : searchTerm.toLowerCase();
109
+ },
110
+ test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
111
+ const testText = caseSensitiveSearch ? text : text.toLowerCase();
112
+ const matches = testText.includes(normalizedSearchTerm);
113
+ return inverseSearch ? !matches : matches;
114
+ }
115
+ },
116
+ {
117
+ id: "wildcard",
118
+ normalize(searchTerm, caseSensitiveSearch) {
119
+ if (searchTerm.length > 0) {
120
+ const escapedSearchTerm = searchTerm.replace(
121
+ /[-[\]{}()+.,\\^$|#\s]/g,
122
+ "\\$&"
123
+ );
124
+ const wildcardSearchTerm = escapedSearchTerm.replace(/\*/g, ".*").replace(/\?/g, ".?");
125
+ searchTerm = `^${wildcardSearchTerm}$`;
126
+ } else {
127
+ return { test: () => false };
128
+ }
129
+ try {
130
+ const flags = caseSensitiveSearch ? "" : "i";
131
+ return new RegExp(searchTerm, flags);
132
+ } catch (_error) {
133
+ return /$^/;
134
+ }
135
+ },
136
+ test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
137
+ const matches = normalizedSearchTerm.test(text);
138
+ return inverseSearch ? !matches : matches;
139
+ }
140
+ },
141
+ {
142
+ id: "regex",
143
+ normalize(searchTerm, caseSensitiveSearch) {
144
+ try {
145
+ const flags = caseSensitiveSearch ? "" : "i";
146
+ return new RegExp(`^(${searchTerm})$`, flags);
147
+ } catch (_error) {
148
+ return /$^/;
149
+ }
150
+ },
151
+ test(text, normalizedSearchTerm, caseSensitiveSearch, inverseSearch) {
152
+ const matches = normalizedSearchTerm.test(text);
153
+ return inverseSearch ? !matches : matches;
154
+ }
155
+ },
156
+ {
157
+ id: "type",
158
+ normalize(selectedTypes) {
159
+ return { test: (type) => selectedTypes.includes(type) };
160
+ },
161
+ test(type, normalizedSearchTerm) {
162
+ if (typeof type === "undefined") {
163
+ return false;
164
+ }
165
+ return normalizedSearchTerm.test(type);
166
+ }
167
+ }
168
+ ];
169
+ const filters = Object.assign({}, ...modeDefinitions.map((obj) => ({ [obj.id]: obj })));
170
+
171
+ const getLocalTimeZone = () => Intl.DateTimeFormat().resolvedOptions().timeZone;
172
+
173
+ const formatDateString = (dateString, useTimeZone = false) => {
174
+ const date = new Date(dateString);
175
+ if (isNaN(date)) {
176
+ throw Error("Invalid Date format");
177
+ }
178
+ const baseDateOptions = {
179
+ day: "numeric",
180
+ month: "short",
181
+ year: "numeric"
182
+ };
183
+ const dateOptions = useTimeZone ? { ...baseDateOptions, timeZone: getLocalTimeZone() } : baseDateOptions;
184
+ return date.toLocaleDateString("en-US", dateOptions);
185
+ };
186
+ const formatTimeString = (timeString, useTimeZone = false) => {
187
+ const time = new Date(timeString);
188
+ if (isNaN(time)) {
189
+ throw Error("Invalid Date format");
190
+ }
191
+ const baseTimeOptions = {
192
+ hour: "numeric",
193
+ minute: "2-digit"
194
+ };
195
+ const timeOptions = useTimeZone ? { ...baseTimeOptions, timeZone: getLocalTimeZone() } : baseTimeOptions;
196
+ return time.toLocaleTimeString("en-US", timeOptions);
197
+ };
198
+ const formatDateTimeString = (dateTimeString, useTimeZone = false) => {
199
+ return `${formatDateString(dateTimeString, useTimeZone)} ${formatTimeString(
200
+ dateTimeString,
201
+ useTimeZone
202
+ )}`;
203
+ };
204
+ const formatLocalDateTimeString = (date, showTime) => showTime ? formatDateTimeString(date, true) : formatDateString(date, true);
205
+ const formatFileSize = (bytes, decimals = 1) => {
206
+ const safeBytes = Number.isFinite(bytes) && bytes >= 0 ? bytes : 0;
207
+ const safeDecimals = Number.isFinite(decimals) && decimals >= 0 ? Math.floor(decimals) : 0;
208
+ return filesize(safeBytes, {
209
+ output: "string",
210
+ base: 2,
211
+ standard: "iec",
212
+ round: safeDecimals,
213
+ pad: true
214
+ });
215
+ };
216
+
217
+ const isMac = () => navigator?.userAgent?.toLowerCase()?.includes("mac");
218
+ const isWindows = () => navigator?.userAgent?.toLowerCase()?.includes("windows");
219
+
220
+ const navigator$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
221
+ __proto__: null,
222
+ isMac,
223
+ isWindows
224
+ }, Symbol.toStringTag, { value: 'Module' }));
225
+
226
+ const globalKeyMap = {
227
+ ArrowUp: "↑",
228
+ ArrowDown: "↓",
229
+ ArrowLeft: "←",
230
+ ArrowRight: "→",
231
+ Enter: "↵",
232
+ " ": "Space",
233
+ // we use event.key and there space is an actual space not the code "Space"
234
+ CtrlOrCmd: "Ctrl"
235
+ };
236
+ const MacOSkeyMap = {
237
+ Shift: "⇧",
238
+ Delete: "⌫",
239
+ CtrlOrCmd: "⌘",
240
+ Ctrl: "⌃",
241
+ Alt: "⌥",
242
+ Enter: "↩"
243
+ };
244
+ const formatHotkey = (hotkey) => {
245
+ const mapSymbols = (formatMap) => (key) => formatMap[key] ?? key;
246
+ const pipe = (...fns) => fns.reduce(
247
+ (f, g) => (arg) => g(f(arg)),
248
+ (arg) => arg
249
+ );
250
+ const macKeyFormatter = pipe(
251
+ mapSymbols(MacOSkeyMap),
252
+ mapSymbols(globalKeyMap)
253
+ );
254
+ const generalKeyFormatter = mapSymbols(globalKeyMap);
255
+ return isMac() ? macKeyFormatter(hotkey) : generalKeyFormatter(hotkey);
256
+ };
257
+ const getDefaultSeparator = () => " ";
258
+ const formatHotkeys = (hotkeys, getSeparator = getDefaultSeparator) => hotkeys.map(formatHotkey).join(getSeparator());
259
+
260
+ const getDeepActiveElement = () => {
261
+ let element = document?.activeElement;
262
+ while (element?.shadowRoot) {
263
+ element = element?.shadowRoot?.activeElement;
264
+ }
265
+ return element;
266
+ };
267
+
268
+ const getWrappedAroundIndex = (index, length) => (index % length + length) % length;
269
+
270
+ const extractPeriodFromRegexMatch = (negative, match) => {
271
+ return {
272
+ negative,
273
+ years: parseInt(match[1] ?? "0", 10),
274
+ months: parseInt(match[2] ?? "0", 10),
275
+ weeks: parseInt(match[3] ?? "0", 10),
276
+ days: parseInt(match[4] ?? "0", 10)
277
+ };
278
+ };
279
+ const extractDurationFromRegexMatch = (negative, match) => {
280
+ const milliseconds = parseInt(match[4]?.padEnd(3, "0") ?? "0", 10);
281
+ return {
282
+ negative,
283
+ hours: parseInt(match[1] ?? "0", 10),
284
+ minutes: parseInt(match[2] ?? "0", 10),
285
+ seconds: parseInt(match[3] ?? "0", 10),
286
+ milliseconds
287
+ };
288
+ };
289
+ const isZero = (interval) => {
290
+ if (interval.type === "DATE") {
291
+ return interval.interval.years === 0 && interval.interval.months === 0 && interval.interval.weeks === 0 && interval.interval.days === 0;
292
+ } else {
293
+ return interval.interval.hours === 0 && interval.interval.minutes === 0 && interval.interval.seconds === 0 && interval.interval.milliseconds === 0;
294
+ }
295
+ };
296
+ const formatIntervalToISOIntervalString = (toFormat) => {
297
+ let output = "P";
298
+ if (toFormat.type === "DATE") {
299
+ output += `${toFormat.interval.years}Y${toFormat.interval.months}M${toFormat.interval.weeks}W${toFormat.interval.days}D`;
300
+ } else {
301
+ output += `T${toFormat.interval.hours}H${toFormat.interval.minutes}M${toFormat.interval.seconds}.${toFormat.interval.milliseconds.toString().padStart(3, "0")}S`;
302
+ }
303
+ if (toFormat.interval.negative) {
304
+ output = `-${output}`;
305
+ }
306
+ return output;
307
+ };
308
+ const formatIntervalToHumanReadableIntervalString = (toFormat) => {
309
+ const formatPart = (value, unit) => {
310
+ if (value === 0) {
311
+ return "";
312
+ } else if (value === 1) {
313
+ return `${value} ${unit} `;
314
+ } else {
315
+ return `${value} ${unit}s `;
316
+ }
317
+ };
318
+ let output = "";
319
+ if (toFormat.type === "DATE") {
320
+ if (isZero(toFormat)) {
321
+ return "0 days";
322
+ }
323
+ output += formatPart(toFormat.interval.years, "year");
324
+ output += formatPart(toFormat.interval.months, "month");
325
+ output += formatPart(toFormat.interval.weeks, "week");
326
+ output += formatPart(toFormat.interval.days, "day");
327
+ } else {
328
+ if (isZero(toFormat)) {
329
+ return "0 seconds";
330
+ }
331
+ output += formatPart(toFormat.interval.hours, "hour");
332
+ output += formatPart(toFormat.interval.minutes, "minute");
333
+ const milliSecondsZero = toFormat.interval.milliseconds === 0;
334
+ if (toFormat.interval.seconds !== 0 || !milliSecondsZero) {
335
+ if (milliSecondsZero) {
336
+ output += formatPart(toFormat.interval.seconds, "second");
337
+ } else {
338
+ output += `${toFormat.interval.seconds}.${toFormat.interval.milliseconds.toString().padStart(3, "0")} seconds `;
339
+ }
340
+ }
341
+ }
342
+ if (toFormat.interval.negative) {
343
+ output = `-(${output.trim()})`;
344
+ }
345
+ return output.trim();
346
+ };
347
+ const yearsPart = "(\\d+)\\s*y(?:ears?)?";
348
+ const monthsPart = "(\\d+)\\s*m(?:o(?:nths?)?)?";
349
+ const weeksPart = "(\\d+)\\s*w(?:eeks?)?";
350
+ const daysPart = "(\\d+)\\s*d(?:ays?)?";
351
+ const hoursPart = "(\\d+)\\s*h(?:ours?)?";
352
+ const minutesPart = "(\\d+)\\s*m(?:in(?:s|utes?)?)?";
353
+ const secondsPart = "(\\d+)(?:[,.](\\d{1,3}))?\\s*s(?:ec(?:s|onds?)?)?";
354
+ const humanReadablePeriodRegex = new RegExp(
355
+ `^(?:${yearsPart})?\\s*(?:${monthsPart})?\\s*(?:${weeksPart})?\\s*(?:${daysPart})?\\s*$`,
356
+ "i"
357
+ );
358
+ const humanReadableDurationRegex = new RegExp(
359
+ `^(?:${hoursPart})?\\s*(?:${minutesPart})?\\s*(?:${secondsPart})?$`,
360
+ "i"
361
+ );
362
+ const negativeHumanReadablePeriodRegex = new RegExp(
363
+ `^\\s*-\\s*\\(\\s*${humanReadablePeriodRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`,
364
+ "i"
365
+ );
366
+ const negativeHumanReadablePeriodRegexWithSingleField = new RegExp(
367
+ `^\\s*-\\s*(?:\\s*${yearsPart}|${monthsPart}|${weeksPart}|${daysPart})\\s*$`,
368
+ "i"
369
+ );
370
+ const negativeHumanReadableDurationRegex = new RegExp(
371
+ `^\\s*-\\s*\\(\\s*${humanReadableDurationRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`,
372
+ "i"
373
+ );
374
+ const negativeHumanReadableDurationRegexWithSingleField = new RegExp(
375
+ `^\\s*-\\s*(?:\\s*${hoursPart}|${minutesPart}|${secondsPart})\\s*$`,
376
+ "i"
377
+ );
378
+ const parseHumanReadableIntervalString = (intervalString) => {
379
+ intervalString = intervalString?.trim();
380
+ if (!intervalString) {
381
+ throw new Error("Empty interval string");
382
+ }
383
+ const matchPositivePeriod = humanReadablePeriodRegex.exec(intervalString);
384
+ const matchNegativePeriod = negativeHumanReadablePeriodRegex.exec(intervalString) ?? negativeHumanReadablePeriodRegexWithSingleField.exec(intervalString);
385
+ const matchPositiveDuration = humanReadableDurationRegex.exec(intervalString);
386
+ const matchNegativeDuration = negativeHumanReadableDurationRegex.exec(intervalString) ?? negativeHumanReadableDurationRegexWithSingleField.exec(intervalString);
387
+ const matchPeriod = matchPositivePeriod ?? matchNegativePeriod;
388
+ const matchDuration = matchPositiveDuration ?? matchNegativeDuration;
389
+ const negative = (matchNegativePeriod ?? matchNegativeDuration) !== null;
390
+ if (matchDuration && matchPeriod) {
391
+ throw new Error("Ambiguous time format");
392
+ }
393
+ if (matchPeriod) {
394
+ return {
395
+ type: "DATE",
396
+ interval: extractPeriodFromRegexMatch(negative, matchPeriod)
397
+ };
398
+ } else if (matchDuration) {
399
+ return {
400
+ type: "TIME",
401
+ interval: extractDurationFromRegexMatch(negative, matchDuration)
402
+ };
403
+ } else {
404
+ throw new Error(`Invalid human readable time: ${intervalString}`);
405
+ }
406
+ };
407
+ const isValidHumanReadableIntervalString = (time, expectedType) => {
408
+ try {
409
+ const validationResult = parseHumanReadableIntervalString(time);
410
+ const actualType = validationResult.type;
411
+ const negative = validationResult.interval.negative;
412
+ if (actualType === expectedType || expectedType === "DATE_OR_TIME") {
413
+ return {
414
+ valid: true,
415
+ type: actualType,
416
+ negative
417
+ };
418
+ } else {
419
+ return { valid: false };
420
+ }
421
+ } catch (_e) {
422
+ return { valid: false };
423
+ }
424
+ };
425
+ const parseISOIntervalString = (isoString) => {
426
+ isoString = isoString?.trim();
427
+ if (["", "P", "PT", "-", "-P", "-PT"].includes(isoString)) {
428
+ throw new Error("Empty ISO duration");
429
+ }
430
+ const periodRegex = /^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?$/;
431
+ const durationRegex = /^-?PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:[,.](\d{1,3}))?S)?$/;
432
+ const matchPeriod = periodRegex.exec(isoString);
433
+ const matchDuration = durationRegex.exec(isoString);
434
+ if (matchPeriod) {
435
+ return {
436
+ type: "DATE",
437
+ interval: extractPeriodFromRegexMatch(
438
+ isoString.startsWith("-"),
439
+ matchPeriod
440
+ )
441
+ };
442
+ } else if (matchDuration) {
443
+ return {
444
+ type: "TIME",
445
+ interval: extractDurationFromRegexMatch(
446
+ isoString.startsWith("-"),
447
+ matchDuration
448
+ )
449
+ };
450
+ } else {
451
+ throw new Error(`Invalid ISO duration: ${isoString}`);
452
+ }
453
+ };
454
+ const isValidISOIntervalString = (isoString, type) => {
455
+ try {
456
+ const validationResult = parseISOIntervalString(isoString);
457
+ const actualType = validationResult.type;
458
+ const negative = validationResult.interval.negative;
459
+ if (actualType === type || type === "DATE_OR_TIME") {
460
+ return {
461
+ valid: true,
462
+ type: actualType,
463
+ negative
464
+ };
465
+ } else {
466
+ return { valid: false };
467
+ }
468
+ } catch (_e) {
469
+ return { valid: false };
470
+ }
471
+ };
472
+ const parseGenericIntervalString = (time) => {
473
+ const validISO = isValidISOIntervalString(time, "DATE_OR_TIME");
474
+ const validHumanReadable = isValidHumanReadableIntervalString(
475
+ time,
476
+ "DATE_OR_TIME"
477
+ );
478
+ if (validISO.valid) {
479
+ return parseISOIntervalString(time);
480
+ } else if (validHumanReadable.valid) {
481
+ return parseHumanReadableIntervalString(time);
482
+ } else {
483
+ throw new Error(`Invalid interval string: ${time}`);
484
+ }
485
+ };
486
+ const isValidIntervalString = (time, type) => {
487
+ const validISO = isValidISOIntervalString(time, type);
488
+ const validHumanReadable = isValidHumanReadableIntervalString(time, type);
489
+ if (validISO.valid) {
490
+ return validISO;
491
+ } else if (validHumanReadable.valid) {
492
+ return validHumanReadable;
493
+ } else {
494
+ return { valid: false };
495
+ }
496
+ };
497
+
498
+ const intervalUtils = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
499
+ __proto__: null,
500
+ formatIntervalToHumanReadableIntervalString,
501
+ formatIntervalToISOIntervalString,
502
+ isValidHumanReadableIntervalString,
503
+ isValidISOIntervalString,
504
+ isValidIntervalString,
505
+ isZero,
506
+ parseGenericIntervalString,
507
+ parseHumanReadableIntervalString,
508
+ parseISOIntervalString
509
+ }, Symbol.toStringTag, { value: 'Module' }));
510
+
511
+ const numIntegerDigits = (input) => Math.max(Math.floor(Math.log10(Math.abs(input))), 0) + 1;
512
+
513
+ class AbortError extends Error {
514
+ }
515
+ const createAbortablePromise = () => {
516
+ const abortController = new AbortController();
517
+ const runAbortablePromise = (request) => {
518
+ return new Promise((resolve, reject) => {
519
+ const abortListener = ({ target }) => {
520
+ abortController.signal.removeEventListener("abort", abortListener);
521
+ const reason = target.reason;
522
+ reject(reason instanceof AbortError ? reason : new AbortError(reason));
523
+ };
524
+ request().then(resolve).catch((error) => {
525
+ if (error instanceof AbortError) {
526
+ return;
527
+ }
528
+ reject(error);
529
+ });
530
+ abortController.signal.addEventListener("abort", abortListener);
531
+ });
532
+ };
533
+ return { abortController, runAbortablePromise };
534
+ };
535
+
536
+ const createUnwrappedPromise = () => {
537
+ let resolve = () => {
538
+ };
539
+ let reject = () => {
540
+ };
541
+ const promise = new Promise((res, rej) => {
542
+ resolve = res;
543
+ reject = rej;
544
+ });
545
+ return { resolve, reject, promise };
546
+ };
547
+
548
+ function sleep(ms) {
549
+ return new Promise((resolve) => setTimeout(resolve, ms));
550
+ }
551
+
552
+ const DEFAULT_RETRY_DELAY_MS = 0;
553
+ const DEFAULT_RETRY_COUNT = 5;
554
+ async function retryPromise({
555
+ fn,
556
+ retryCount = DEFAULT_RETRY_COUNT,
557
+ retryDelayMS = DEFAULT_RETRY_DELAY_MS,
558
+ excludeError
559
+ }) {
560
+ try {
561
+ return await fn();
562
+ } catch (error) {
563
+ if (excludeError?.(error)) {
564
+ throw error;
565
+ }
566
+ if (retryCount > 0) {
567
+ await sleep(retryDelayMS);
568
+ return await retryPromise({
569
+ fn,
570
+ retryCount: retryCount - 1,
571
+ retryDelayMS,
572
+ excludeError
573
+ });
574
+ }
575
+ throw error;
576
+ }
577
+ }
578
+
579
+ const index = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
580
+ __proto__: null,
581
+ AbortError,
582
+ DEFAULT_RETRY_COUNT,
583
+ DEFAULT_RETRY_DELAY_MS,
584
+ createAbortablePromise,
585
+ createUnwrappedPromise,
586
+ retryPromise
587
+ }, Symbol.toStringTag, { value: 'Module' }));
588
+
589
+ const ALLOWED_TAGS = [
590
+ "p",
591
+ "div",
592
+ "h1",
593
+ "h2",
594
+ "h3",
595
+ "h4",
596
+ "h5",
597
+ "h6",
598
+ "ul",
599
+ "ol",
600
+ "li",
601
+ "blockquote",
602
+ "b",
603
+ "i",
604
+ "s",
605
+ "u",
606
+ "sup",
607
+ "sub",
608
+ "ins",
609
+ "del",
610
+ "strong",
611
+ "strike",
612
+ "tt",
613
+ "code",
614
+ "big",
615
+ "small",
616
+ "br",
617
+ "span",
618
+ "em"
619
+ ];
620
+ const sanitizeHTML = (rawHTML, options = {
621
+ allowStyleAttribute: false,
622
+ allowHyperlinks: false
623
+ }) => {
624
+ const { allowStyleAttribute, allowHyperlinks } = options;
625
+ const ALLOWED_ATTR = [
626
+ ...allowStyleAttribute ? ["style"] : [],
627
+ ...allowHyperlinks ? ["href"] : []
628
+ ];
629
+ const allowedTags = allowHyperlinks ? [...ALLOWED_TAGS, "a"] : ALLOWED_TAGS;
630
+ return DomPurify.sanitize(rawHTML, {
631
+ ALLOWED_TAGS: allowedTags,
632
+ ALLOWED_ATTR
633
+ });
634
+ };
635
+ const stripHTML = (rawHTML) => {
636
+ return DomPurify.sanitize(rawHTML, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] });
637
+ };
638
+ const sanitization = { sanitizeHTML, stripHTML };
639
+
640
+ const defaultMaxLength = 160;
641
+ const truncateString = (string = "", maxLength = defaultMaxLength) => {
642
+ const dots = string.length > maxLength ? "…" : "";
643
+ return `${string.substring(0, maxLength - 1)}${dots}`;
644
+ };
645
+
646
+ const getFileExtension = (nameOrPath) => {
647
+ const basename = nameOrPath.split(/[\\/]/).pop() ?? "";
648
+ const parts = basename.split(".");
649
+ if (basename === "" || parts.length === 1) {
650
+ return "";
651
+ }
652
+ return parts.at(-1) ?? "";
653
+ };
654
+ const KNAR = Object.freeze({
655
+ extension: "knar",
656
+ mimeType: "application/vnd.knime.workflow-group+zip",
657
+ matches(file) {
658
+ const extension = getFileExtension(file.name);
659
+ return extension === this.extension;
660
+ }
661
+ });
662
+ const KNWF = Object.freeze({
663
+ extension: "knwf",
664
+ mimeType: "application/vnd.knime.workflow+zip",
665
+ matches(file) {
666
+ const extension = getFileExtension(file.name);
667
+ return extension === this.extension;
668
+ },
669
+ /**
670
+ * Gets the name of a .knwf file without the extension. If the file is not
671
+ * matched as a .knwf file then this function will return the default value,
672
+ * which is empty string ("") if param is not provided
673
+ */
674
+ getNameOrDefault(file, defaultValue = "") {
675
+ if (!this.matches(file)) {
676
+ return defaultValue;
677
+ }
678
+ return file.name.replace(`.${this.extension}`, "");
679
+ }
680
+ });
681
+ const knimeFileFormats = { KNAR, KNWF };
682
+ const getFileMimeType = (file) => {
683
+ const DEFAULT_MIMETYPE = "application/octet-stream";
684
+ const extension = getFileExtension(file.name);
685
+ if (!extension) {
686
+ return DEFAULT_MIMETYPE;
687
+ }
688
+ if (KNWF.matches(file)) {
689
+ return KNWF.mimeType;
690
+ }
691
+ if (KNAR.matches(file)) {
692
+ return KNAR.mimeType;
693
+ }
694
+ if (!file.type) {
695
+ return DEFAULT_MIMETYPE;
696
+ }
697
+ return file.type;
698
+ };
699
+
700
+ const isModifierKeyPressed = (event) => {
701
+ return event.ctrlKey || event.metaKey || event.altKey || event.shiftKey;
702
+ };
703
+ const isKeyWithoutModifiers = (event, keys) => {
704
+ const keyList = Array.isArray(keys) ? keys : [keys];
705
+ return keyList.includes(event.key) && !isModifierKeyPressed(event);
706
+ };
707
+ const getMetaOrCtrlKey = () => {
708
+ return isMac() ? "metaKey" : "ctrlKey";
709
+ };
710
+
711
+ const hotkeys = { formatHotkeys, formatHotkey, getDefaultSeparator };
712
+
713
+ export { capitalize, caseFormatter, debounce, filters, formatDateString, formatDateTimeString, formatFileSize, formatLocalDateTimeString, formatTimeString, getDeepActiveElement, getFileExtension, getFileMimeType, getLocalTimeZone, getMetaOrCtrlKey, getWrappedAroundIndex, hotkeys, intervalUtils, isAfterMaxDate, isBeforeMinDate, isKeyWithoutModifiers, isModifierKeyPressed, knimeFileFormats, navigator$1 as navigatorUtils, numIntegerDigits, index as promise, sanitization, sleep, truncateString, updateDate, updateTime };
714
+ //# sourceMappingURL=index.js.map