@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
@@ -1,434 +0,0 @@
1
- export type Period = {
2
- negative: boolean;
3
- years: number;
4
- months: number;
5
- weeks: number;
6
- days: number;
7
- };
8
-
9
- export type Duration = {
10
- negative: boolean;
11
- hours: number;
12
- minutes: number;
13
- seconds: number;
14
- milliseconds: number;
15
- };
16
-
17
- type AllowedIntervalTypes = "DATE" | "TIME";
18
- type AllowedIntervalTypesOrEither = AllowedIntervalTypes | "DATE_OR_TIME";
19
-
20
- type IntervalStringValidationResult =
21
- | {
22
- valid: true;
23
- type: AllowedIntervalTypes;
24
- negative: boolean;
25
- }
26
- | { valid: false };
27
-
28
- export type PeriodOrDuration =
29
- | {
30
- interval: Period;
31
- type: "DATE";
32
- }
33
- | {
34
- interval: Duration;
35
- type: "TIME";
36
- };
37
-
38
- const extractPeriodFromRegexMatch = (
39
- negative: boolean,
40
- match: RegExpExecArray,
41
- ): Period => {
42
- return {
43
- negative,
44
- years: parseInt(match[1] ?? "0", 10),
45
- months: parseInt(match[2] ?? "0", 10),
46
- weeks: parseInt(match[3] ?? "0", 10),
47
- days: parseInt(match[4] ?? "0", 10),
48
- };
49
- };
50
-
51
- const extractDurationFromRegexMatch = (
52
- negative: boolean,
53
- match: RegExpExecArray,
54
- ): Duration => {
55
- // eslint-disable-next-line no-magic-numbers
56
- const milliseconds = parseInt(match[4]?.padEnd(3, "0") ?? "0", 10);
57
-
58
- return {
59
- negative,
60
- hours: parseInt(match[1] ?? "0", 10),
61
- minutes: parseInt(match[2] ?? "0", 10),
62
- seconds: parseInt(match[3] ?? "0", 10),
63
- milliseconds,
64
- };
65
- };
66
-
67
- export const isZero = (interval: PeriodOrDuration): boolean => {
68
- if (interval.type === "DATE") {
69
- return (
70
- interval.interval.years === 0 &&
71
- interval.interval.months === 0 &&
72
- interval.interval.weeks === 0 &&
73
- interval.interval.days === 0
74
- );
75
- } else {
76
- return (
77
- interval.interval.hours === 0 &&
78
- interval.interval.minutes === 0 &&
79
- interval.interval.seconds === 0 &&
80
- interval.interval.milliseconds === 0
81
- );
82
- }
83
- };
84
-
85
- /**
86
- * Take an interval object and convert it to an ISO duration or period string. All parts of the
87
- * relevant part of the Interval object are included in the output, even if they are zero.
88
- *
89
- * Technically the ISO standard allows to mix period and duration parts, but we don't support that
90
- * here because it's incredibly hard to deal with all the edge cases. Maybe in a future ticket.
91
- *
92
- * The output here is allowed to be negative, in which case the minus sign is prepended to the
93
- * output.
94
- *
95
- * @param toFormat The PeriodOrDuration object to format
96
- */
97
- export const formatIntervalToISOIntervalString = (
98
- toFormat: PeriodOrDuration,
99
- ): string => {
100
- let output = "P";
101
-
102
- if (toFormat.type === "DATE") {
103
- output += `${toFormat.interval.years}Y${toFormat.interval.months}M${toFormat.interval.weeks}W${toFormat.interval.days}D`;
104
- } else {
105
- output += `T${toFormat.interval.hours}H${toFormat.interval.minutes}M${toFormat.interval.seconds}.${toFormat.interval.milliseconds
106
- .toString()
107
- // eslint-disable-next-line no-magic-numbers
108
- .padStart(3, "0")}S`;
109
- }
110
-
111
- if (toFormat.interval.negative) {
112
- output = `-${output}`;
113
- }
114
- return output;
115
- };
116
-
117
- /**
118
- * Take an interval object and convert it to a human readable string. Only non-zero parts are
119
- * included in the output (unless all parts are 0).
120
- *
121
- * The output here is allowed to be negative, in which case the minus sign is prepended to the
122
- * output and we wrap the whole thing in brackets e.g. -(1 year 2 days).
123
- *
124
- * @param toFormat The PeriodOrDuration object to format
125
- */
126
- export const formatIntervalToHumanReadableIntervalString = (
127
- toFormat: PeriodOrDuration,
128
- ): string => {
129
- const formatPart = (value: number, unit: string): string => {
130
- if (value === 0) {
131
- return "";
132
- } else if (value === 1) {
133
- return `${value} ${unit} `;
134
- } else {
135
- return `${value} ${unit}s `;
136
- }
137
- };
138
-
139
- let output = "";
140
-
141
- if (toFormat.type === "DATE") {
142
- if (isZero(toFormat)) {
143
- return "0 days";
144
- }
145
-
146
- output += formatPart(toFormat.interval.years, "year");
147
- output += formatPart(toFormat.interval.months, "month");
148
- output += formatPart(toFormat.interval.weeks, "week");
149
- output += formatPart(toFormat.interval.days, "day");
150
- } else {
151
- if (isZero(toFormat)) {
152
- return "0 seconds";
153
- }
154
-
155
- output += formatPart(toFormat.interval.hours, "hour");
156
- output += formatPart(toFormat.interval.minutes, "minute");
157
-
158
- const milliSecondsZero = toFormat.interval.milliseconds === 0;
159
- if (toFormat.interval.seconds !== 0 || !milliSecondsZero) {
160
- if (milliSecondsZero) {
161
- output += formatPart(toFormat.interval.seconds, "second");
162
- } else {
163
- output += `${toFormat.interval.seconds}.${toFormat.interval.milliseconds.toString().padStart(3, "0")} seconds `; // eslint-disable-line no-magic-numbers
164
- }
165
- }
166
- }
167
-
168
- if (toFormat.interval.negative) {
169
- output = `-(${output.trim()})`;
170
- }
171
-
172
- return output.trim();
173
- };
174
-
175
- const yearsPart = "(\\d+)\\s*y(?:ears?)?";
176
- const monthsPart = "(\\d+)\\s*m(?:o(?:nths?)?)?";
177
- const weeksPart = "(\\d+)\\s*w(?:eeks?)?";
178
- const daysPart = "(\\d+)\\s*d(?:ays?)?";
179
- const hoursPart = "(\\d+)\\s*h(?:ours?)?";
180
- const minutesPart = "(\\d+)\\s*m(?:in(?:s|utes?)?)?";
181
- const secondsPart = "(\\d+)(?:[,.](\\d{1,3}))?\\s*s(?:ec(?:s|onds?)?)?";
182
-
183
- /**
184
- * Matches a human readable period string, e.g. "1y 2mo 3weeks 4day" (each part is optional)
185
- */
186
- const humanReadablePeriodRegex = new RegExp(
187
- `^(?:${yearsPart})?\\s*(?:${monthsPart})?\\s*(?:${weeksPart})?\\s*(?:${daysPart})?\\s*$`,
188
- "i",
189
- );
190
-
191
- /**
192
- * Matches a human readable duration string, e.g. "1h 2m 3.456s" (each part is optional)
193
- */
194
- const humanReadableDurationRegex = new RegExp(
195
- `^(?:${hoursPart})?\\s*(?:${minutesPart})?\\s*(?:${secondsPart})?$`,
196
- "i",
197
- );
198
-
199
- /**
200
- * Matches a negative human readable period string, e.g. "-(1y 2mo 3weeks 4day)" (each part is optional)
201
- */
202
- const negativeHumanReadablePeriodRegex = new RegExp(
203
- `^\\s*-\\s*\\(\\s*${humanReadablePeriodRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`,
204
- "i",
205
- );
206
-
207
- /**
208
- * Matches a negative human readable period string with one field like "-1y" or "-1w"
209
- */
210
- const negativeHumanReadablePeriodRegexWithSingleField = new RegExp(
211
- `^\\s*-\\s*(?:\\s*${yearsPart}|${monthsPart}|${weeksPart}|${daysPart})\\s*$`,
212
- "i",
213
- );
214
-
215
- /**
216
- * Matches a negative human readable duration string, e.g. "-(1h 2m 3.456s)" (each part is optional)
217
- */
218
- const negativeHumanReadableDurationRegex = new RegExp(
219
- `^\\s*-\\s*\\(\\s*${humanReadableDurationRegex.source.replace(/[$^]/g, "")}\\s*\\)\\s*$`,
220
- "i",
221
- );
222
-
223
- /**
224
- * Matches a negative human readable duration string with one field like "-1h" or "-1.5s"
225
- */
226
- const negativeHumanReadableDurationRegexWithSingleField = new RegExp(
227
- `^\\s*-\\s*(?:\\s*${hoursPart}|${minutesPart}|${secondsPart})\\s*$`,
228
- "i",
229
- );
230
-
231
- /**
232
- * Try to parse a human readable interval string into an Interval object. Any parts not specified
233
- * are assumed to be zero. Note that the string must be either a period or a duration, not a mix of
234
- * both. So for example, "1y 2mo 3weeks 4day" is fine, as is "1h 2m 3.456s". However, "1y 2mo 1sec"
235
- * is not, since it's a mix of both.
236
- *
237
- * Negative intervals are allowed, although if multiple fields are provided the string must include
238
- * brackets, so "-(1y 2mo)" is also valid, as is "-5 seconds".
239
- *
240
- * The string is required to have at least some content, any string that is blank will throw an error.
241
- *
242
- * @param intervalString The human readable time string
243
- */
244
- export const parseHumanReadableIntervalString = (
245
- intervalString: string,
246
- ): PeriodOrDuration => {
247
- intervalString = intervalString?.trim();
248
-
249
- if (!intervalString) {
250
- throw new Error("Empty interval string");
251
- }
252
-
253
- const matchPositivePeriod = humanReadablePeriodRegex.exec(intervalString);
254
- const matchNegativePeriod =
255
- negativeHumanReadablePeriodRegex.exec(intervalString) ??
256
- negativeHumanReadablePeriodRegexWithSingleField.exec(intervalString);
257
- const matchPositiveDuration = humanReadableDurationRegex.exec(intervalString);
258
- const matchNegativeDuration =
259
- negativeHumanReadableDurationRegex.exec(intervalString) ??
260
- negativeHumanReadableDurationRegexWithSingleField.exec(intervalString);
261
-
262
- const matchPeriod = matchPositivePeriod ?? matchNegativePeriod;
263
- const matchDuration = matchPositiveDuration ?? matchNegativeDuration;
264
- const negative = (matchNegativePeriod ?? matchNegativeDuration) !== null;
265
-
266
- // I think this will happen only for the string "1M" or similar
267
- if (matchDuration && matchPeriod) {
268
- throw new Error("Ambiguous time format");
269
- }
270
-
271
- if (matchPeriod) {
272
- return {
273
- type: "DATE",
274
- interval: extractPeriodFromRegexMatch(negative, matchPeriod),
275
- };
276
- } else if (matchDuration) {
277
- return {
278
- type: "TIME",
279
- interval: extractDurationFromRegexMatch(negative, matchDuration),
280
- };
281
- } else {
282
- throw new Error(`Invalid human readable time: ${intervalString}`);
283
- }
284
- };
285
-
286
- /**
287
- * Check if the given string can be understood as a human readable duration or period string. The
288
- * type parameter specifies whether the string should be a date, time, or either.
289
- *
290
- * @param time the string to check
291
- * @param expectedType the type of the string - either "DATE", "TIME", or "ANY"
292
- */
293
- export const isValidHumanReadableIntervalString = (
294
- time: string,
295
- expectedType: AllowedIntervalTypesOrEither,
296
- ): IntervalStringValidationResult => {
297
- try {
298
- const validationResult = parseHumanReadableIntervalString(time);
299
- const actualType = validationResult.type;
300
- const negative = validationResult.interval.negative;
301
-
302
- if (actualType === expectedType || expectedType === "DATE_OR_TIME") {
303
- return {
304
- valid: true,
305
- type: actualType,
306
- negative,
307
- };
308
- } else {
309
- return { valid: false };
310
- }
311
- } catch (_e) {
312
- return { valid: false };
313
- }
314
- };
315
-
316
- /**
317
- * Convert an ISO duration OR period string to an Interval object. So for example,
318
- * "P1Y2M3W4D" is fine, as is "PT1H2M3.456S". However, "P1Y2M3W4D1H2M3.456S" is not, since
319
- * it's a mix of both. We're more forgiving than the ISO standard, so we allow for missing parts.
320
- * Also, the string is allowed to be negative, so "-P1Y2M3W4D" is also valid.
321
- *
322
- * The string is required to have at least some content, so the strings "", "P", and "PT" are
323
- * considered invalid (also if they start with a -).
324
- *
325
- * @param isoString The ISO duration or period string.
326
- */
327
- export const parseISOIntervalString = (isoString: string): PeriodOrDuration => {
328
- isoString = isoString?.trim();
329
-
330
- if (["", "P", "PT", "-", "-P", "-PT"].includes(isoString)) {
331
- throw new Error("Empty ISO duration");
332
- }
333
-
334
- const periodRegex = /^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?$/;
335
- const durationRegex =
336
- /^-?PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:[,.](\d{1,3}))?S)?$/;
337
-
338
- const matchPeriod = periodRegex.exec(isoString);
339
- const matchDuration = durationRegex.exec(isoString);
340
-
341
- if (matchPeriod) {
342
- return {
343
- type: "DATE",
344
- interval: extractPeriodFromRegexMatch(
345
- isoString.startsWith("-"),
346
- matchPeriod,
347
- ),
348
- };
349
- } else if (matchDuration) {
350
- return {
351
- type: "TIME",
352
- interval: extractDurationFromRegexMatch(
353
- isoString.startsWith("-"),
354
- matchDuration,
355
- ),
356
- };
357
- } else {
358
- throw new Error(`Invalid ISO duration: ${isoString}`);
359
- }
360
- };
361
-
362
- /**
363
- * Check if the given string is a valid duration or period ISO string. The type parameter
364
- * specifies whether the string should be a date, time, or either.
365
- *
366
- * @param isoString the string to check
367
- * @param type the type of the string - either "DATE", "TIME", or "ANY"
368
- */
369
- export const isValidISOIntervalString = (
370
- isoString: string,
371
- type: AllowedIntervalTypesOrEither,
372
- ): IntervalStringValidationResult => {
373
- try {
374
- const validationResult = parseISOIntervalString(isoString);
375
- const actualType = validationResult.type;
376
- const negative = validationResult.interval.negative;
377
-
378
- if (actualType === type || type === "DATE_OR_TIME") {
379
- return {
380
- valid: true,
381
- type: actualType,
382
- negative,
383
- };
384
- } else {
385
- return { valid: false };
386
- }
387
- } catch (_e) {
388
- return { valid: false };
389
- }
390
- };
391
-
392
- /**
393
- * Try to convert an interval string to an Interval object. The string can be either an ISO
394
- * duration/period string or a human readable string. If the string is not valid, an error is
395
- * thrown.
396
- *
397
- * @param time the time string, either ISO or human readable
398
- */
399
- export const parseGenericIntervalString = (time: string): PeriodOrDuration => {
400
- const validISO = isValidISOIntervalString(time, "DATE_OR_TIME");
401
- const validHumanReadable = isValidHumanReadableIntervalString(
402
- time,
403
- "DATE_OR_TIME",
404
- );
405
- if (validISO.valid) {
406
- return parseISOIntervalString(time);
407
- } else if (validHumanReadable.valid) {
408
- return parseHumanReadableIntervalString(time);
409
- } else {
410
- throw new Error(`Invalid interval string: ${time}`);
411
- }
412
- };
413
-
414
- /**
415
- * Check if the given string is a valid interval string, either human readable or ISO. The type parameter
416
- * specifies whether the string should be a period, duration, or either.
417
- *
418
- * @param time the time string to check
419
- * @param type the type of the string - either "DATE", "TIME", or "ANY"
420
- */
421
- export const isValidIntervalString = (
422
- time: string,
423
- type: AllowedIntervalTypesOrEither,
424
- ): IntervalStringValidationResult => {
425
- const validISO = isValidISOIntervalString(time, type);
426
- const validHumanReadable = isValidHumanReadableIntervalString(time, type);
427
- if (validISO.valid) {
428
- return validISO;
429
- } else if (validHumanReadable.valid) {
430
- return validHumanReadable;
431
- } else {
432
- return { valid: false };
433
- }
434
- };
package/src/navigator.ts DELETED
@@ -1,13 +0,0 @@
1
- /**
2
- *
3
- * @returns true if the platform of the user is Mac
4
- */
5
- export const isMac = (): boolean =>
6
- navigator?.userAgent?.toLowerCase()?.includes("mac");
7
-
8
- /**
9
- *
10
- * @returns true if the platform of the user is Windows
11
- */
12
- export const isWindows = (): boolean =>
13
- navigator?.userAgent?.toLowerCase()?.includes("windows");
@@ -1,56 +0,0 @@
1
- export class AbortError extends Error {}
2
-
3
- /**
4
- * Helper to create an abortable promise. Returns an AbortController and a Function
5
- * that you can pass your async handler to. Whenever the AbortController signal is
6
- * aborted then the async handler's promise will reject with an AbortError
7
- *
8
- * Example:
9
- * ```
10
- * import { abortUtils } from "@knime/utils"
11
- * const myFetchCall = async (params...) => {...};
12
- *
13
- * try {
14
- * const { runAbortablePromise, abortController } = createAbortablePromise(() =>
15
- * myFetchCall(params...),
16
- * );
17
- * } catch (e) {
18
- * if (e instanceof abortUtils.AbortError) {
19
- * console.info('ignore due to abort');
20
- * return;
21
- * }
22
- * }
23
- *
24
- * // somewhere else (while request is in-flight)
25
- * abortController.abort(new abortUtils.AbortError('reason here'))
26
- * ```
27
- */
28
- export const createAbortablePromise = () => {
29
- const abortController: AbortController = new AbortController();
30
-
31
- const runAbortablePromise = <T = unknown>(request: () => Promise<T>) => {
32
- return new Promise<T>((resolve, reject) => {
33
- // abort logic
34
- const abortListener = ({ target }: Event) => {
35
- abortController.signal.removeEventListener("abort", abortListener);
36
- const reason = (target as AbortSignal).reason;
37
- reject(reason instanceof AbortError ? reason : new AbortError(reason));
38
- };
39
-
40
- // the actual call
41
- request()
42
- .then(resolve)
43
- .catch((error) => {
44
- if (error instanceof AbortError) {
45
- return;
46
- }
47
-
48
- reject(error);
49
- });
50
-
51
- abortController.signal.addEventListener("abort", abortListener);
52
- });
53
- };
54
-
55
- return { abortController, runAbortablePromise };
56
- };
@@ -1,17 +0,0 @@
1
- export type UnwrappedPromise<T = unknown> = {
2
- resolve: (value: T | PromiseLike<T>) => void;
3
- reject: (reason?: unknown) => void;
4
- promise: Promise<T>;
5
- };
6
-
7
- export const createUnwrappedPromise = <T>(): UnwrappedPromise<T> => {
8
- let resolve: (value: T | PromiseLike<T>) => void = () => {};
9
- let reject: (reason?: unknown) => void = () => {};
10
-
11
- const promise = new Promise<T>((res, rej) => {
12
- resolve = res;
13
- reject = rej;
14
- });
15
-
16
- return { resolve, reject, promise };
17
- };
@@ -1,3 +0,0 @@
1
- export * from "./createAbortablePromise";
2
- export * from "./createUnwrappedPromise";
3
- export * from "./retryPromise";
@@ -1,45 +0,0 @@
1
- import sleep from "../sleep";
2
-
3
- export const DEFAULT_RETRY_DELAY_MS = 0;
4
- export const DEFAULT_RETRY_COUNT = 5;
5
-
6
- /**
7
- * Helper to add retry capability to an async function
8
- * @param fn async function
9
- * @param retryCount max number of retries. defaults to 5
10
- * @param retryDelayMS delay in-between retries in millisecs. defaults to 0
11
- * @param excludeError predicate fn to exclude specific errors from causing a retry
12
- */
13
- export async function retryPromise<T>({
14
- fn,
15
- retryCount = DEFAULT_RETRY_COUNT,
16
- retryDelayMS = DEFAULT_RETRY_DELAY_MS,
17
- excludeError,
18
- }: {
19
- fn: () => Promise<T>;
20
- retryCount?: number;
21
- retryDelayMS?: number;
22
- excludeError?: (error: Error) => boolean;
23
- }) {
24
- try {
25
- return await fn();
26
- } catch (error) {
27
- if (excludeError?.(error as Error)) {
28
- throw error;
29
- }
30
-
31
- if (retryCount > 0) {
32
- await sleep(retryDelayMS);
33
-
34
- // eslint-disable-next-line no-return-await
35
- return await retryPromise({
36
- fn,
37
- retryCount: retryCount - 1,
38
- retryDelayMS,
39
- excludeError,
40
- });
41
- }
42
-
43
- throw error;
44
- }
45
- }
@@ -1,72 +0,0 @@
1
- import DomPurify from "dompurify";
2
-
3
- const ALLOWED_TAGS = [
4
- "p",
5
- "div",
6
- "h1",
7
- "h2",
8
- "h3",
9
- "h4",
10
- "h5",
11
- "h6",
12
- "ul",
13
- "ol",
14
- "li",
15
- "blockquote",
16
- "b",
17
- "i",
18
- "s",
19
- "u",
20
- "sup",
21
- "sub",
22
- "ins",
23
- "del",
24
- "strong",
25
- "strike",
26
- "tt",
27
- "code",
28
- "big",
29
- "small",
30
- "br",
31
- "span",
32
- "em",
33
- ];
34
-
35
- /**
36
- * Sanitizes Raw HTML and only allow specific tags to be used, as per OWASP standards.
37
- * @param rawHTML
38
- * @param options.allowStyleAttribute - Allow the style attribute on elements
39
- * @param options.allowHyperlinks - Allow anchor tags with href attribute
40
- * @returns sanitized html
41
- */
42
- const sanitizeHTML = (
43
- rawHTML: string,
44
- options: { allowStyleAttribute?: boolean; allowHyperlinks?: boolean } = {
45
- allowStyleAttribute: false,
46
- allowHyperlinks: false,
47
- },
48
- ) => {
49
- const { allowStyleAttribute, allowHyperlinks } = options;
50
- const ALLOWED_ATTR = [
51
- ...(allowStyleAttribute ? ["style"] : []),
52
- ...(allowHyperlinks ? ["href"] : []),
53
- ];
54
- const allowedTags = allowHyperlinks ? [...ALLOWED_TAGS, "a"] : ALLOWED_TAGS;
55
-
56
- return DomPurify.sanitize(rawHTML, {
57
- ALLOWED_TAGS: allowedTags,
58
- ALLOWED_ATTR,
59
- });
60
- };
61
-
62
- /**
63
- * Removes any HTML tag from the input string. Keeps HTML entities
64
- * (e.g &nbsp; because these can be considered plain text)
65
- * @param rawHTML
66
- * @returns plain text
67
- */
68
- const stripHTML = (rawHTML: string) => {
69
- return DomPurify.sanitize(rawHTML, { ALLOWED_TAGS: [], ALLOWED_ATTR: [] });
70
- };
71
-
72
- export const sanitization = { sanitizeHTML, stripHTML };
package/src/sleep.ts DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * Returns promise that resolves after ms.
3
- */
4
- export default function sleep(ms: number) {
5
- return new Promise((resolve) => setTimeout(resolve, ms));
6
- }
@@ -1,7 +0,0 @@
1
- const defaultMaxLength = 160;
2
-
3
- // truncates a string to a given max length
4
- export default (string = "", maxLength = defaultMaxLength) => {
5
- const dots = string.length > maxLength ? "…" : "";
6
- return `${string.substring(0, maxLength - 1)}${dots}`;
7
- };
package/src/updateDate.ts DELETED
@@ -1,23 +0,0 @@
1
- import { getDate, getMonth, getYear, isValid, set } from "date-fns";
2
- /**
3
- * Updates the date part (year, day and month) of a date object (base)
4
- * time, offset (timezone) and so on will be left untouched.
5
- *
6
- * @param base - Date which will be used (copied) to set day, month and year.
7
- * @param date - Extract day, month and year from this date object.
8
- * @returns Copy of base with day, month and year of date.
9
- */
10
- export default (base: Date, date: Date | null) => {
11
- // ignore falsy dates
12
- if (date) {
13
- // allow invalid base and set time to 0
14
- base = isValid(base) ? base : new Date(Date.UTC(0, 0));
15
- return set(base, {
16
- year: getYear(date),
17
- month: getMonth(date),
18
- date: getDate(date),
19
- });
20
- }
21
-
22
- return base;
23
- };