@reykjavik/webtools 0.1.29 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -6
- package/README.md +38 -18
- package/esm/fixIcelandicLocale.js +9 -4
- package/esm/fixIcelandicLocale.privates.d.ts +6 -0
- package/esm/fixIcelandicLocale.privates.js +176 -43
- package/esm/http.d.ts +9 -2
- package/esm/http.js +9 -2
- package/fixIcelandicLocale.js +8 -3
- package/fixIcelandicLocale.privates.d.ts +6 -0
- package/fixIcelandicLocale.privates.js +177 -44
- package/http.d.ts +9 -2
- package/http.js +11 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,21 +4,28 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
-
## 0.1.
|
|
7
|
+
## 0.1.30
|
|
8
8
|
|
|
9
|
-
_2024-
|
|
9
|
+
_2024-09-15_
|
|
10
10
|
|
|
11
11
|
- `@reykjavik/webtools/http`:
|
|
12
|
-
- feat: Add `
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
- feat: Add `toMs` duration helper
|
|
13
|
+
- `@reykjavik/webtools/fixIcelandicLocale`:
|
|
14
|
+
- feat: Patch `Intl.RelativeTimeFormat`
|
|
15
|
+
- feat: Patch all `supportedLocalesOf` methods to report "is\*" as supported
|
|
16
|
+
- fix: Incorrect `PluralRules` results for negative values
|
|
17
|
+
- fix: Use each `Intl.*` class' `supportedLocalesOf` method to map locales
|
|
18
|
+
- fix: Remove unnecessary `Intl.\*` method instance-bindings
|
|
15
19
|
|
|
16
|
-
## 0.1.28
|
|
20
|
+
## 0.1.28 – 0.1.29
|
|
17
21
|
|
|
18
22
|
_2024-08-26_
|
|
19
23
|
|
|
20
24
|
- `@reykjavik/webtools/http`:
|
|
25
|
+
- feat: Add `cacheControlHeaders` helper that returns a `HeadersInit` object
|
|
21
26
|
- feat: `cacheControl` now also accepts `Map<string, string>` for headers
|
|
27
|
+
- fix: `cacheControl` with `maxAge: 'unset'` didn't delete `X-Cache-Control`
|
|
28
|
+
in dev mode
|
|
22
29
|
|
|
23
30
|
## 0.1.27
|
|
24
31
|
|
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ bun add @reykjavik/webtools
|
|
|
23
23
|
- [`cacheControlHeaders` helper](#cachecontrolheaders-helper)
|
|
24
24
|
- [Type `TTLConfig`](#type-ttlconfig)
|
|
25
25
|
- [`toSec` TTL helper](#tosec-ttl-helper)
|
|
26
|
+
- [`toMs` duration helper](#toms-duration-helper)
|
|
26
27
|
- [`@reykjavik/webtools/async`](#reykjavikwebtoolsasync)
|
|
27
28
|
- [`promiseAllObject`](#promiseallobject)
|
|
28
29
|
- [`maxWait`](#maxwait)
|
|
@@ -206,7 +207,7 @@ behavior.
|
|
|
206
207
|
**Syntax:**
|
|
207
208
|
`` toSec(ttl: number | `${number}${'s'|'m'|'h'|'d'|'w'}`): number ``
|
|
208
209
|
|
|
209
|
-
Converts a `TTL` (max-age) value into seconds
|
|
210
|
+
Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
|
|
210
211
|
negative input values.
|
|
211
212
|
|
|
212
213
|
```js
|
|
@@ -217,6 +218,22 @@ const ttl: TTL = '2h';
|
|
|
217
218
|
const ttlSec = toSec(ttl);
|
|
218
219
|
```
|
|
219
220
|
|
|
221
|
+
### `toMs` duration helper
|
|
222
|
+
|
|
223
|
+
**Syntax:**
|
|
224
|
+
`` toSec(duration: number | `${number}${'s'|'m'|'h'|'d'|'w'}`): number ``
|
|
225
|
+
|
|
226
|
+
Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
|
|
227
|
+
and/or negative input values.
|
|
228
|
+
|
|
229
|
+
```js
|
|
230
|
+
import type { toMs, TTL } from '@reykjavik/webtools/http';
|
|
231
|
+
|
|
232
|
+
const ttl: TTL = '2h';
|
|
233
|
+
|
|
234
|
+
const ttlSec = toMs(ttl);
|
|
235
|
+
```
|
|
236
|
+
|
|
220
237
|
---
|
|
221
238
|
|
|
222
239
|
## `@reykjavik/webtools/async`
|
|
@@ -288,15 +305,16 @@ This module patches the following methods/classes by substituting the `is`
|
|
|
288
305
|
locale with `da` (Danish) and apply a few post-hoc fixes to their return
|
|
289
306
|
values.
|
|
290
307
|
|
|
291
|
-
- `Intl.Collator` and `String.prototype.localeCompare`
|
|
292
|
-
- `Intl.NumberFormat` and `Number.prototype.toLocaleString`
|
|
308
|
+
- `Intl.Collator` and `String.prototype.localeCompare` (\*)
|
|
309
|
+
- `Intl.NumberFormat` and `Number.prototype.toLocaleString` (\*)
|
|
293
310
|
- `Intl.DateTimeFormat` and `Date.prototype.toLocaleString`,
|
|
294
|
-
`.toLocaleDateString`, and `.toLocaleTimeString`
|
|
311
|
+
`.toLocaleDateString`, and `.toLocaleTimeString` (\*)
|
|
312
|
+
- `Intl.RelativeDateFormat`
|
|
295
313
|
- `Intl.PluralRules`
|
|
296
314
|
- `Intl.ListFormat`
|
|
297
315
|
|
|
298
|
-
|
|
299
|
-
listed below.
|
|
316
|
+
(\*) The results are quite usable, but not entirely perfect. The
|
|
317
|
+
limitations/caveats are listed below.
|
|
300
318
|
|
|
301
319
|
To apply the patch, simply "side-effect import" this module at the top of your
|
|
302
320
|
app's entry point:
|
|
@@ -338,6 +356,8 @@ detection test.)
|
|
|
338
356
|
- The `dayPeriod` option has a couple of slight mismatches, at 5 am and 12
|
|
339
357
|
noon.
|
|
340
358
|
|
|
359
|
+
We eagerly accept bugfixes, additions, etc. to this module!
|
|
360
|
+
|
|
341
361
|
---
|
|
342
362
|
|
|
343
363
|
## `@reykjavik/webtools/SiteImprove`
|
|
@@ -573,19 +593,19 @@ export const myClass = vanillaClass(`
|
|
|
573
593
|
// more complex styles.
|
|
574
594
|
export const myOtherClass = vanillaClass(
|
|
575
595
|
(className) => `
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
580
|
-
.${className} > strong {
|
|
581
|
-
color: #c00;
|
|
582
|
-
}
|
|
583
|
-
@media (min-width: 800px) {
|
|
584
|
-
.${className} {
|
|
585
|
-
background-color: #eee;
|
|
596
|
+
.${className} {
|
|
597
|
+
background-color: #ccc;
|
|
598
|
+
padding: .5em 1em;
|
|
586
599
|
}
|
|
587
|
-
|
|
588
|
-
|
|
600
|
+
.${className} > strong {
|
|
601
|
+
color: #c00;
|
|
602
|
+
}
|
|
603
|
+
@media (min-width: 800px) {
|
|
604
|
+
.${className} {
|
|
605
|
+
background-color: #eee;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
`
|
|
589
609
|
);
|
|
590
610
|
|
|
591
611
|
export const humanReadableClass = vanillaClass(
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { _PatchedCollator, _PatchedDateTimeFormat, _patchedDateToLocaleDateString, _patchedDateToLocaleString, _patchedDateToLocaleTimeString, _PatchedListFormat, _PatchedNumberFormat, _patchedNumberToLocaleString, _PatchedPluralRules, _patchedStringLocaleCompare, } from './fixIcelandicLocale.privates.js';
|
|
1
|
+
import { _PatchedCollator, _PatchedDateTimeFormat, _patchedDateToLocaleDateString, _patchedDateToLocaleString, _patchedDateToLocaleTimeString, _PatchedListFormat, _PatchedNumberFormat, _patchedNumberToLocaleString, _PatchedPluralRules, _PatchedRelativeTimeFormat, _patchedStringLocaleCompare, } from './fixIcelandicLocale.privates.js';
|
|
2
2
|
/*
|
|
3
3
|
Mantra: Partial Icelandic suppoort is better than none. Partial Icelandic
|
|
4
4
|
suppoort is better than none. Partial Icelandic suppoort is better than
|
|
5
5
|
none. Partial Icelandic suppoort is better than none. Partial Icelandic...
|
|
6
6
|
*/
|
|
7
|
-
if (Intl.Collator.supportedLocalesOf(['is']).length
|
|
7
|
+
if (!Intl.Collator.supportedLocalesOf(['is']).length) {
|
|
8
8
|
Intl.Collator = _PatchedCollator;
|
|
9
9
|
String.prototype.localeCompare = _patchedStringLocaleCompare;
|
|
10
10
|
Intl.NumberFormat = _PatchedNumberFormat;
|
|
@@ -15,10 +15,15 @@ if (Intl.Collator.supportedLocalesOf(['is']).length < 1) {
|
|
|
15
15
|
Date.prototype.toLocaleTimeString = _patchedDateToLocaleTimeString;
|
|
16
16
|
}
|
|
17
17
|
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-unnecessary-condition */
|
|
18
|
-
if (Intl.ListFormat && Intl.ListFormat.supportedLocalesOf(['is']).length
|
|
18
|
+
if (Intl.ListFormat && !Intl.ListFormat.supportedLocalesOf(['is']).length) {
|
|
19
19
|
Intl.ListFormat = _PatchedListFormat;
|
|
20
20
|
}
|
|
21
|
-
if (Intl.PluralRules && Intl.PluralRules.supportedLocalesOf(['is']).length
|
|
21
|
+
if (Intl.PluralRules && !Intl.PluralRules.supportedLocalesOf(['is']).length) {
|
|
22
22
|
Intl.PluralRules = _PatchedPluralRules;
|
|
23
23
|
}
|
|
24
|
+
if (Intl.RelativeTimeFormat &&
|
|
25
|
+
!Intl.RelativeTimeFormat.supportedLocalesOf(['is']).length) {
|
|
26
|
+
Intl.RelativeTimeFormat =
|
|
27
|
+
_PatchedRelativeTimeFormat;
|
|
28
|
+
}
|
|
24
29
|
/* eslint-enable @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-unnecessary-condition */
|
|
@@ -75,3 +75,9 @@ export declare const _PatchedListFormat: {
|
|
|
75
75
|
} & {
|
|
76
76
|
$original: typeof Intl.ListFormat;
|
|
77
77
|
};
|
|
78
|
+
export declare const _PatchedRelativeTimeFormat: {
|
|
79
|
+
new (locales?: string | string[] | undefined, options?: Intl.RelativeTimeFormatOptions | undefined): Intl.RelativeTimeFormat;
|
|
80
|
+
supportedLocalesOf(locales?: string | string[] | undefined, options?: Intl.RelativeTimeFormatOptions | undefined): string[];
|
|
81
|
+
} & {
|
|
82
|
+
$original: typeof Intl.RelativeTimeFormat;
|
|
83
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var _a, _b;
|
|
2
|
-
const
|
|
3
|
-
const mapLocales = (locales) => {
|
|
1
|
+
var _a, _b, _c;
|
|
2
|
+
const islLocaleRe = /^isl?(?:-|$)/i;
|
|
3
|
+
const mapLocales = (constr, locales) => {
|
|
4
4
|
locales = typeof locales === 'string' ? [locales] : locales || [];
|
|
5
5
|
for (let i = 0, loc; (loc = locales[i]); i++) {
|
|
6
|
-
const
|
|
7
|
-
if (
|
|
6
|
+
const isIslLocale = islLocaleRe.test(loc);
|
|
7
|
+
if (isIslLocale) {
|
|
8
8
|
// Danish feels like a "good enough" substitution for Icelandic.
|
|
9
9
|
// For alphabetization, it seems to just the internal order of `Ø` and `Ö`
|
|
10
10
|
// that's different, and when the `sensitivity` option is set to "base"
|
|
@@ -15,22 +15,49 @@ const mapLocales = (locales) => {
|
|
|
15
15
|
// as fully equal to the base letter.
|
|
16
16
|
return ['da'];
|
|
17
17
|
}
|
|
18
|
-
if (
|
|
18
|
+
if (constr.supportedLocalesOf(loc).length) {
|
|
19
19
|
return; // no mapping needed. YOLO!
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
+
const patchSupportedLocalesOf = (constr) => {
|
|
24
|
+
const BASE_CHAR_CODE = 64; // 'A'.charCodeAt(0) - 1; // used for generating unique suffix for fake locales
|
|
25
|
+
const sLO = (locales, options) => {
|
|
26
|
+
let localesArr = typeof locales === 'string' ? [locales] : locales;
|
|
27
|
+
const memoIsl = [];
|
|
28
|
+
localesArr = localesArr.map((locale) => {
|
|
29
|
+
if (islLocaleRe.test(locale)) {
|
|
30
|
+
// Some engines throw a RangeError if the locale is weirdly shaped,
|
|
31
|
+
// so we must use a short, safe, unique fake locale instead,
|
|
32
|
+
// and store the actual locale in `memoIsl` for later reinsertion.
|
|
33
|
+
memoIsl.push(locale);
|
|
34
|
+
return `da-X${String.fromCharCode(BASE_CHAR_CODE + memoIsl.length)}`;
|
|
35
|
+
}
|
|
36
|
+
return locale;
|
|
37
|
+
});
|
|
38
|
+
const supportedLocales = constr.supportedLocalesOf(localesArr, options);
|
|
39
|
+
if (!memoIsl.length) {
|
|
40
|
+
return supportedLocales;
|
|
41
|
+
}
|
|
42
|
+
return supportedLocales.map((locale) => locale.startsWith('da-X') ? memoIsl.shift() : locale);
|
|
43
|
+
};
|
|
44
|
+
return sLO;
|
|
45
|
+
};
|
|
23
46
|
const combineParts = (parts) => parts.map(({ value }) => value).join('');
|
|
47
|
+
// ===========================================================================
|
|
48
|
+
// Collator
|
|
49
|
+
// ===========================================================================
|
|
50
|
+
const _Collator = Intl.Collator;
|
|
24
51
|
const PatchedCollator = function Collator(locales, options) {
|
|
25
52
|
if (!(this instanceof PatchedCollator)) {
|
|
26
53
|
// @ts-expect-error (YOLO! Can't be arsed)
|
|
27
54
|
return new PatchedCollator(locales, options);
|
|
28
55
|
}
|
|
29
|
-
const mappedLocales = mapLocales(locales);
|
|
30
|
-
const
|
|
56
|
+
const mappedLocales = mapLocales(_Collator, locales);
|
|
57
|
+
const super_ = _Collator(mappedLocales || locales, options);
|
|
31
58
|
const mapped = !!mappedLocales;
|
|
32
59
|
this.compare = (a, b) => {
|
|
33
|
-
const res1 =
|
|
60
|
+
const res1 = super_.compare(a, b);
|
|
34
61
|
if (!mapped) {
|
|
35
62
|
return res1;
|
|
36
63
|
}
|
|
@@ -39,14 +66,13 @@ const PatchedCollator = function Collator(locales, options) {
|
|
|
39
66
|
if (/\d/.test(a0 + b0)) {
|
|
40
67
|
return res1;
|
|
41
68
|
}
|
|
42
|
-
const res2 =
|
|
69
|
+
const res2 = super_.compare(a0, b0);
|
|
43
70
|
return res2 !== 0 ? res2 : res1;
|
|
44
71
|
};
|
|
45
|
-
this.resolvedOptions = () =>
|
|
72
|
+
this.resolvedOptions = () => super_.resolvedOptions();
|
|
46
73
|
};
|
|
47
74
|
PatchedCollator.prototype = { constructor: PatchedCollator };
|
|
48
|
-
|
|
49
|
-
PatchedCollator.supportedLocalesOf = _Collator.supportedLocalesOf;
|
|
75
|
+
PatchedCollator.supportedLocalesOf = /*#__PURE__*/ patchSupportedLocalesOf(_Collator);
|
|
50
76
|
PatchedCollator.$original = _Collator;
|
|
51
77
|
export const _PatchedCollator = PatchedCollator;
|
|
52
78
|
// ---------------------------------------------------------------------------
|
|
@@ -78,24 +104,26 @@ const PatchedNumberFormat = function NumberFormat(locales, options) {
|
|
|
78
104
|
// @ts-expect-error (YOLO! Can't be arsed)
|
|
79
105
|
return new PatchedNumberFormat(locales, options);
|
|
80
106
|
}
|
|
81
|
-
const mappedLocales = mapLocales(locales);
|
|
82
|
-
const
|
|
107
|
+
const mappedLocales = mapLocales(_NumberFormat, locales);
|
|
108
|
+
const super_ = _NumberFormat(mappedLocales || locales, options);
|
|
83
109
|
const mapped = !!mappedLocales;
|
|
84
|
-
this.format = (value) => combineParts(this.formatToParts(value));
|
|
85
|
-
this.formatRange = (value1, value2) =>
|
|
110
|
+
this.format = (value) => mapped ? combineParts(this.formatToParts(value)) : super_.format(value);
|
|
111
|
+
this.formatRange = (value1, value2) => mapped
|
|
112
|
+
? combineParts(this.formatRangeToParts(value1, value2))
|
|
113
|
+
: super_.formatRange(value1, value2);
|
|
86
114
|
this.formatToParts = (value) => {
|
|
87
|
-
const parts =
|
|
88
|
-
return mapped ? reformatNumberParts(
|
|
115
|
+
const parts = super_.formatToParts(value);
|
|
116
|
+
return mapped ? reformatNumberParts(super_, parts) : parts;
|
|
89
117
|
};
|
|
90
118
|
this.formatRangeToParts = (value1, value2) => {
|
|
91
|
-
const parts =
|
|
92
|
-
return mapped ? reformatNumberParts(
|
|
119
|
+
const parts = super_.formatRangeToParts(value1, value2);
|
|
120
|
+
return mapped ? reformatNumberParts(super_, parts) : parts;
|
|
93
121
|
};
|
|
94
|
-
this.resolvedOptions = () =>
|
|
122
|
+
this.resolvedOptions = () => super_.resolvedOptions();
|
|
95
123
|
};
|
|
96
124
|
PatchedNumberFormat.prototype = { constructor: PatchedNumberFormat };
|
|
97
|
-
|
|
98
|
-
|
|
125
|
+
PatchedNumberFormat.supportedLocalesOf =
|
|
126
|
+
/*#__PURE__*/ patchSupportedLocalesOf(_NumberFormat);
|
|
99
127
|
PatchedNumberFormat.$original = _NumberFormat;
|
|
100
128
|
export const _PatchedNumberFormat = PatchedNumberFormat;
|
|
101
129
|
// ---------------------------------------------------------------------------
|
|
@@ -197,7 +225,7 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
|
197
225
|
// @ts-expect-error (YOLO! Can't be arsed)
|
|
198
226
|
return new PatchedDateTimeFormat(locales, options);
|
|
199
227
|
}
|
|
200
|
-
const mappedLocales = mapLocales(locales);
|
|
228
|
+
const mappedLocales = mapLocales(_DateTimeFormat, locales);
|
|
201
229
|
if (options === null || options === void 0 ? void 0 : options.hour12) {
|
|
202
230
|
options = {
|
|
203
231
|
...options,
|
|
@@ -205,23 +233,25 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
|
205
233
|
hourCycle: 'h11',
|
|
206
234
|
};
|
|
207
235
|
}
|
|
208
|
-
const
|
|
236
|
+
const super_ = _DateTimeFormat(mappedLocales || locales, options);
|
|
209
237
|
const mapped = !!mappedLocales;
|
|
210
|
-
this.format = (value) => combineParts(this.formatToParts(value));
|
|
211
|
-
this.formatRange = (value1, value2) =>
|
|
238
|
+
this.format = (value) => mapped ? combineParts(this.formatToParts(value)) : super_.format(value);
|
|
239
|
+
this.formatRange = (value1, value2) => mapped
|
|
240
|
+
? combineParts(this.formatRangeToParts(value1, value2))
|
|
241
|
+
: super_.formatRange(value1, value2);
|
|
212
242
|
this.formatToParts = (value) => {
|
|
213
|
-
const parts =
|
|
214
|
-
return mapped ? reformatDateTimeParts(
|
|
243
|
+
const parts = super_.formatToParts(value);
|
|
244
|
+
return mapped ? reformatDateTimeParts(super_, parts) : parts;
|
|
215
245
|
};
|
|
216
246
|
this.formatRangeToParts = (value1, value2) => {
|
|
217
|
-
const parts =
|
|
218
|
-
return mapped ? reformatDateTimeParts(
|
|
247
|
+
const parts = super_.formatRangeToParts(value1, value2);
|
|
248
|
+
return mapped ? reformatDateTimeParts(super_, parts) : parts;
|
|
219
249
|
};
|
|
220
|
-
this.resolvedOptions = () =>
|
|
250
|
+
this.resolvedOptions = () => super_.resolvedOptions();
|
|
221
251
|
};
|
|
222
252
|
PatchedDateTimeFormat.prototype = { constructor: PatchedDateTimeFormat };
|
|
223
|
-
|
|
224
|
-
|
|
253
|
+
PatchedDateTimeFormat.supportedLocalesOf =
|
|
254
|
+
/*#__PURE__*/ patchSupportedLocalesOf(_DateTimeFormat);
|
|
225
255
|
PatchedDateTimeFormat.$original = _DateTimeFormat;
|
|
226
256
|
export const _PatchedDateTimeFormat = PatchedDateTimeFormat;
|
|
227
257
|
// ---------------------------------------------------------------------------
|
|
@@ -299,15 +329,14 @@ let PatchedPluralRules;
|
|
|
299
329
|
if (_PluralRules) {
|
|
300
330
|
PatchedPluralRules = (_a = class PluralRules extends _PluralRules {
|
|
301
331
|
pluralIsl(n) {
|
|
332
|
+
n = n < 0 ? -n : n;
|
|
302
333
|
return this.ord ? 'other' : n % 10 !== 1 || n % 100 === 11 ? 'other' : 'one';
|
|
303
334
|
}
|
|
304
335
|
constructor(locales, options) {
|
|
305
|
-
const mappedLocales = mapLocales(locales);
|
|
336
|
+
const mappedLocales = mapLocales(_PluralRules, locales);
|
|
306
337
|
super(mappedLocales || locales, options);
|
|
307
338
|
this.mapped = !!mappedLocales;
|
|
308
339
|
this.ord = (options === null || options === void 0 ? void 0 : options.type) === 'ordinal';
|
|
309
|
-
this.select = this.select.bind(this);
|
|
310
|
-
this.selectRange = this.selectRange.bind(this);
|
|
311
340
|
}
|
|
312
341
|
select(n) {
|
|
313
342
|
if (this.mapped) {
|
|
@@ -325,6 +354,7 @@ if (_PluralRules) {
|
|
|
325
354
|
return super.selectRange(n, n2);
|
|
326
355
|
}
|
|
327
356
|
},
|
|
357
|
+
_a.supportedLocalesOf = patchSupportedLocalesOf(_PluralRules),
|
|
328
358
|
_a.$original = _PluralRules,
|
|
329
359
|
_a);
|
|
330
360
|
}
|
|
@@ -338,11 +368,9 @@ let PatchedListFormat;
|
|
|
338
368
|
if (_ListFormat) {
|
|
339
369
|
PatchedListFormat = (_b = class ListFormat extends _ListFormat {
|
|
340
370
|
constructor(locales, options) {
|
|
341
|
-
const mappedLocales = mapLocales(locales);
|
|
371
|
+
const mappedLocales = mapLocales(_ListFormat, locales);
|
|
342
372
|
super(mappedLocales || locales, options);
|
|
343
373
|
this.mapped = !!mappedLocales;
|
|
344
|
-
this.format = this.format.bind(this);
|
|
345
|
-
this.formatToParts = this.formatToParts.bind(this);
|
|
346
374
|
}
|
|
347
375
|
format(list) {
|
|
348
376
|
return this.mapped ? combineParts(this.formatToParts(list)) : super.format(list);
|
|
@@ -351,8 +379,8 @@ if (_ListFormat) {
|
|
|
351
379
|
const parts = super.formatToParts(list);
|
|
352
380
|
if (this.mapped) {
|
|
353
381
|
for (const item of parts) {
|
|
354
|
-
const { value } = item;
|
|
355
|
-
if (
|
|
382
|
+
const { type, value } = item;
|
|
383
|
+
if (type === 'literal' && (value === ' el. ' || value === ' eller ')) {
|
|
356
384
|
item.value = ' eða ';
|
|
357
385
|
}
|
|
358
386
|
}
|
|
@@ -360,7 +388,112 @@ if (_ListFormat) {
|
|
|
360
388
|
return parts;
|
|
361
389
|
}
|
|
362
390
|
},
|
|
391
|
+
_b.supportedLocalesOf = patchSupportedLocalesOf(_ListFormat),
|
|
363
392
|
_b.$original = _ListFormat,
|
|
364
393
|
_b);
|
|
365
394
|
}
|
|
366
395
|
export const _PatchedListFormat = PatchedListFormat;
|
|
396
|
+
// ===========================================================================
|
|
397
|
+
// RelativeTimeFormat
|
|
398
|
+
// ===========================================================================
|
|
399
|
+
const _RelativeTimeFormat = Intl.RelativeTimeFormat;
|
|
400
|
+
let PatchedRelativeTimeFormat;
|
|
401
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
402
|
+
if (_RelativeTimeFormat) {
|
|
403
|
+
let pluralIsl;
|
|
404
|
+
let numFormatIsl;
|
|
405
|
+
const islUnits = {
|
|
406
|
+
year: [['ári', 'árum', 'ár', 'ár'], ''],
|
|
407
|
+
quarter: [['ársfjórðungi', 'ársfjórðungum', 'ársfjórðung', 'ársfjórðunga'], 'ársfj.'],
|
|
408
|
+
month: [['mánuði', 'mánuðum', 'mánuð', 'mánuði'], 'mán.'],
|
|
409
|
+
week: [['viku', 'vikum', 'viku', 'vikur'], ''],
|
|
410
|
+
day: [['degi', 'dögum', 'dag', 'daga'], ''],
|
|
411
|
+
hour: [['klukkustund', 'klukkustundum', 'klukkustund', 'klukkustundir'], 'klst.'],
|
|
412
|
+
minute: [['mínútu', 'mínútum', 'mínútu', 'mínútur'], 'mín.'],
|
|
413
|
+
second: [['sekúndu', 'sekúndum', 'sekúndu', 'sekúndur'], 'sek.'],
|
|
414
|
+
};
|
|
415
|
+
const phrases = {
|
|
416
|
+
nu: 'núna',
|
|
417
|
+
'næste år': 'á næsta ári',
|
|
418
|
+
'sidste år': 'á síðasta ári',
|
|
419
|
+
'i år': 'á þessu ári',
|
|
420
|
+
'sidste kvartal': 'síðasti ársfjórðungur',
|
|
421
|
+
'dette kvartal': 'þessi ársfjórðungur',
|
|
422
|
+
'næste kvartal': 'næsti ársfjórðungur',
|
|
423
|
+
'sidste kvt.': 'síðasti ársfj.',
|
|
424
|
+
'dette kvt.': 'þessi ársfj.',
|
|
425
|
+
'næste kvt.': 'næsti ársfj.',
|
|
426
|
+
'sidste måned': 'í síðasta mánuði',
|
|
427
|
+
'denne måned': 'í þessum mánuði',
|
|
428
|
+
'næste måned': 'í næsta mánuði',
|
|
429
|
+
'sidste md.': 'í síðasta mán.',
|
|
430
|
+
'denne md.': 'í þessum mán.',
|
|
431
|
+
'næste md.': 'í næsta mán.',
|
|
432
|
+
'sidste uge': 'í síðustu viku',
|
|
433
|
+
'denne uge': 'í þessari viku',
|
|
434
|
+
'næste uge': 'í næstu viku',
|
|
435
|
+
'i forgårs': 'í fyrradag',
|
|
436
|
+
'i går': 'í gær',
|
|
437
|
+
'i dag': 'í dag',
|
|
438
|
+
'i morgen': 'á morgun',
|
|
439
|
+
'i overmorgen': 'eftir tvo daga',
|
|
440
|
+
'denne time': 'þessa stundina',
|
|
441
|
+
'dette minut': 'á þessari mínútu',
|
|
442
|
+
};
|
|
443
|
+
PatchedRelativeTimeFormat = (_c = class RelativeTimeFormat extends _RelativeTimeFormat {
|
|
444
|
+
constructor(locales, options) {
|
|
445
|
+
const mappedLocales = mapLocales(_RelativeTimeFormat, locales);
|
|
446
|
+
super(mappedLocales || locales, options);
|
|
447
|
+
this.mapped = !!mappedLocales;
|
|
448
|
+
}
|
|
449
|
+
format(value, unit) {
|
|
450
|
+
return this.mapped
|
|
451
|
+
? combineParts(this.formatToParts(value, unit))
|
|
452
|
+
: super.format(value, unit);
|
|
453
|
+
}
|
|
454
|
+
// eslint-disable-next-line complexity
|
|
455
|
+
formatToParts(value, unit) {
|
|
456
|
+
const parts = super.formatToParts(value, unit);
|
|
457
|
+
if (!this.mapped) {
|
|
458
|
+
return parts;
|
|
459
|
+
}
|
|
460
|
+
if (!pluralIsl) {
|
|
461
|
+
pluralIsl = new _PatchedPluralRules('is');
|
|
462
|
+
}
|
|
463
|
+
if (!numFormatIsl) {
|
|
464
|
+
numFormatIsl = new _PatchedNumberFormat('is');
|
|
465
|
+
}
|
|
466
|
+
const options = this.resolvedOptions();
|
|
467
|
+
const unitSngl = unit.replace(/s$/, '');
|
|
468
|
+
if (parts.length === 1) {
|
|
469
|
+
const firstPart = parts[0];
|
|
470
|
+
firstPart.value = phrases[firstPart.value] || firstPart.value;
|
|
471
|
+
return parts;
|
|
472
|
+
}
|
|
473
|
+
const [long, short] = islUnits[unitSngl];
|
|
474
|
+
const idx = (value < 0 ? 0 : 2) + (pluralIsl.select(value) === 'one' ? 0 : 1);
|
|
475
|
+
const prefixStr = options.style === 'narrow' &&
|
|
476
|
+
(unitSngl === 'second' || unitSngl === 'minute' || unitSngl === 'hour')
|
|
477
|
+
? value < 0
|
|
478
|
+
? '-'
|
|
479
|
+
: '+'
|
|
480
|
+
: value < 0
|
|
481
|
+
? 'fyrir '
|
|
482
|
+
: 'eftir ';
|
|
483
|
+
const valueStr = (options.style !== 'long' && short) || long[idx];
|
|
484
|
+
const islParts = [
|
|
485
|
+
{ type: 'literal', value: prefixStr },
|
|
486
|
+
...numFormatIsl.formatToParts(Math.abs(value)).map((part) => {
|
|
487
|
+
part.unit =
|
|
488
|
+
unitSngl;
|
|
489
|
+
return part;
|
|
490
|
+
}),
|
|
491
|
+
{ type: 'literal', value: ` ${valueStr}` },
|
|
492
|
+
];
|
|
493
|
+
return islParts;
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
_c.$original = _RelativeTimeFormat,
|
|
497
|
+
_c);
|
|
498
|
+
}
|
|
499
|
+
export const _PatchedRelativeTimeFormat = PatchedRelativeTimeFormat;
|
package/esm/http.d.ts
CHANGED
|
@@ -158,12 +158,19 @@ type TTLObj = {
|
|
|
158
158
|
*/
|
|
159
159
|
export type TTLConfig = TTL | TTLKeywords | TTLObj;
|
|
160
160
|
/**
|
|
161
|
-
* Converts a `TTL` (max-age) value into seconds
|
|
162
|
-
*
|
|
161
|
+
* Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
|
|
162
|
+
* negative input values.
|
|
163
163
|
*
|
|
164
164
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
165
165
|
*/
|
|
166
166
|
export declare const toSec: (ttl: TTL) => number;
|
|
167
|
+
/**
|
|
168
|
+
* Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
|
|
169
|
+
* and/or negative input values.
|
|
170
|
+
*
|
|
171
|
+
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#toms-duration-helper
|
|
172
|
+
*/
|
|
173
|
+
export declare const toMs: (ttl: TTL) => number;
|
|
167
174
|
type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
|
|
168
175
|
headers?: Record<string, string | Array<string>>;
|
|
169
176
|
};
|
package/esm/http.js
CHANGED
|
@@ -133,8 +133,8 @@ const unitToSeconds = {
|
|
|
133
133
|
w: 7 * 24 * 3600,
|
|
134
134
|
};
|
|
135
135
|
/**
|
|
136
|
-
* Converts a `TTL` (max-age) value into seconds
|
|
137
|
-
*
|
|
136
|
+
* Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
|
|
137
|
+
* negative input values.
|
|
138
138
|
*
|
|
139
139
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
140
140
|
*/
|
|
@@ -146,6 +146,13 @@ export const toSec = (ttl) => {
|
|
|
146
146
|
}
|
|
147
147
|
return Math.max(0, Math.round(ttl)) || 0;
|
|
148
148
|
};
|
|
149
|
+
/**
|
|
150
|
+
* Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
|
|
151
|
+
* and/or negative input values.
|
|
152
|
+
*
|
|
153
|
+
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#toms-duration-helper
|
|
154
|
+
*/
|
|
155
|
+
export const toMs = (ttl) => toSec(ttl) * 1000;
|
|
149
156
|
const toRespnseStubHeaders = (response) => {
|
|
150
157
|
if (response instanceof Map) {
|
|
151
158
|
return response;
|
package/fixIcelandicLocale.js
CHANGED
|
@@ -6,7 +6,7 @@ const fixIcelandicLocale_privates_js_1 = require("./fixIcelandicLocale.privates.
|
|
|
6
6
|
suppoort is better than none. Partial Icelandic suppoort is better than
|
|
7
7
|
none. Partial Icelandic suppoort is better than none. Partial Icelandic...
|
|
8
8
|
*/
|
|
9
|
-
if (Intl.Collator.supportedLocalesOf(['is']).length
|
|
9
|
+
if (!Intl.Collator.supportedLocalesOf(['is']).length) {
|
|
10
10
|
Intl.Collator = fixIcelandicLocale_privates_js_1._PatchedCollator;
|
|
11
11
|
String.prototype.localeCompare = fixIcelandicLocale_privates_js_1._patchedStringLocaleCompare;
|
|
12
12
|
Intl.NumberFormat = fixIcelandicLocale_privates_js_1._PatchedNumberFormat;
|
|
@@ -17,10 +17,15 @@ if (Intl.Collator.supportedLocalesOf(['is']).length < 1) {
|
|
|
17
17
|
Date.prototype.toLocaleTimeString = fixIcelandicLocale_privates_js_1._patchedDateToLocaleTimeString;
|
|
18
18
|
}
|
|
19
19
|
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-unnecessary-condition */
|
|
20
|
-
if (Intl.ListFormat && Intl.ListFormat.supportedLocalesOf(['is']).length
|
|
20
|
+
if (Intl.ListFormat && !Intl.ListFormat.supportedLocalesOf(['is']).length) {
|
|
21
21
|
Intl.ListFormat = fixIcelandicLocale_privates_js_1._PatchedListFormat;
|
|
22
22
|
}
|
|
23
|
-
if (Intl.PluralRules && Intl.PluralRules.supportedLocalesOf(['is']).length
|
|
23
|
+
if (Intl.PluralRules && !Intl.PluralRules.supportedLocalesOf(['is']).length) {
|
|
24
24
|
Intl.PluralRules = fixIcelandicLocale_privates_js_1._PatchedPluralRules;
|
|
25
25
|
}
|
|
26
|
+
if (Intl.RelativeTimeFormat &&
|
|
27
|
+
!Intl.RelativeTimeFormat.supportedLocalesOf(['is']).length) {
|
|
28
|
+
Intl.RelativeTimeFormat =
|
|
29
|
+
fixIcelandicLocale_privates_js_1._PatchedRelativeTimeFormat;
|
|
30
|
+
}
|
|
26
31
|
/* eslint-enable @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-unnecessary-condition */
|
|
@@ -75,3 +75,9 @@ export declare const _PatchedListFormat: {
|
|
|
75
75
|
} & {
|
|
76
76
|
$original: typeof Intl.ListFormat;
|
|
77
77
|
};
|
|
78
|
+
export declare const _PatchedRelativeTimeFormat: {
|
|
79
|
+
new (locales?: string | string[] | undefined, options?: Intl.RelativeTimeFormatOptions | undefined): Intl.RelativeTimeFormat;
|
|
80
|
+
supportedLocalesOf(locales?: string | string[] | undefined, options?: Intl.RelativeTimeFormatOptions | undefined): string[];
|
|
81
|
+
} & {
|
|
82
|
+
$original: typeof Intl.RelativeTimeFormat;
|
|
83
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _a, _b;
|
|
2
|
+
var _a, _b, _c;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports._PatchedListFormat = exports._PatchedPluralRules = exports._patchedDateToLocaleTimeString = exports._patchedDateToLocaleDateString = exports._patchedDateToLocaleString = exports._PatchedDateTimeFormat = exports._patchedNumberToLocaleString = exports._PatchedNumberFormat = exports._patchedStringLocaleCompare = exports._PatchedCollator = void 0;
|
|
5
|
-
const
|
|
6
|
-
const mapLocales = (locales) => {
|
|
4
|
+
exports._PatchedRelativeTimeFormat = exports._PatchedListFormat = exports._PatchedPluralRules = exports._patchedDateToLocaleTimeString = exports._patchedDateToLocaleDateString = exports._patchedDateToLocaleString = exports._PatchedDateTimeFormat = exports._patchedNumberToLocaleString = exports._PatchedNumberFormat = exports._patchedStringLocaleCompare = exports._PatchedCollator = void 0;
|
|
5
|
+
const islLocaleRe = /^isl?(?:-|$)/i;
|
|
6
|
+
const mapLocales = (constr, locales) => {
|
|
7
7
|
locales = typeof locales === 'string' ? [locales] : locales || [];
|
|
8
8
|
for (let i = 0, loc; (loc = locales[i]); i++) {
|
|
9
|
-
const
|
|
10
|
-
if (
|
|
9
|
+
const isIslLocale = islLocaleRe.test(loc);
|
|
10
|
+
if (isIslLocale) {
|
|
11
11
|
// Danish feels like a "good enough" substitution for Icelandic.
|
|
12
12
|
// For alphabetization, it seems to just the internal order of `Ø` and `Ö`
|
|
13
13
|
// that's different, and when the `sensitivity` option is set to "base"
|
|
@@ -18,22 +18,49 @@ const mapLocales = (locales) => {
|
|
|
18
18
|
// as fully equal to the base letter.
|
|
19
19
|
return ['da'];
|
|
20
20
|
}
|
|
21
|
-
if (
|
|
21
|
+
if (constr.supportedLocalesOf(loc).length) {
|
|
22
22
|
return; // no mapping needed. YOLO!
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
|
+
const patchSupportedLocalesOf = (constr) => {
|
|
27
|
+
const BASE_CHAR_CODE = 64; // 'A'.charCodeAt(0) - 1; // used for generating unique suffix for fake locales
|
|
28
|
+
const sLO = (locales, options) => {
|
|
29
|
+
let localesArr = typeof locales === 'string' ? [locales] : locales;
|
|
30
|
+
const memoIsl = [];
|
|
31
|
+
localesArr = localesArr.map((locale) => {
|
|
32
|
+
if (islLocaleRe.test(locale)) {
|
|
33
|
+
// Some engines throw a RangeError if the locale is weirdly shaped,
|
|
34
|
+
// so we must use a short, safe, unique fake locale instead,
|
|
35
|
+
// and store the actual locale in `memoIsl` for later reinsertion.
|
|
36
|
+
memoIsl.push(locale);
|
|
37
|
+
return `da-X${String.fromCharCode(BASE_CHAR_CODE + memoIsl.length)}`;
|
|
38
|
+
}
|
|
39
|
+
return locale;
|
|
40
|
+
});
|
|
41
|
+
const supportedLocales = constr.supportedLocalesOf(localesArr, options);
|
|
42
|
+
if (!memoIsl.length) {
|
|
43
|
+
return supportedLocales;
|
|
44
|
+
}
|
|
45
|
+
return supportedLocales.map((locale) => locale.startsWith('da-X') ? memoIsl.shift() : locale);
|
|
46
|
+
};
|
|
47
|
+
return sLO;
|
|
48
|
+
};
|
|
26
49
|
const combineParts = (parts) => parts.map(({ value }) => value).join('');
|
|
50
|
+
// ===========================================================================
|
|
51
|
+
// Collator
|
|
52
|
+
// ===========================================================================
|
|
53
|
+
const _Collator = Intl.Collator;
|
|
27
54
|
const PatchedCollator = function Collator(locales, options) {
|
|
28
55
|
if (!(this instanceof PatchedCollator)) {
|
|
29
56
|
// @ts-expect-error (YOLO! Can't be arsed)
|
|
30
57
|
return new PatchedCollator(locales, options);
|
|
31
58
|
}
|
|
32
|
-
const mappedLocales = mapLocales(locales);
|
|
33
|
-
const
|
|
59
|
+
const mappedLocales = mapLocales(_Collator, locales);
|
|
60
|
+
const super_ = _Collator(mappedLocales || locales, options);
|
|
34
61
|
const mapped = !!mappedLocales;
|
|
35
62
|
this.compare = (a, b) => {
|
|
36
|
-
const res1 =
|
|
63
|
+
const res1 = super_.compare(a, b);
|
|
37
64
|
if (!mapped) {
|
|
38
65
|
return res1;
|
|
39
66
|
}
|
|
@@ -42,14 +69,13 @@ const PatchedCollator = function Collator(locales, options) {
|
|
|
42
69
|
if (/\d/.test(a0 + b0)) {
|
|
43
70
|
return res1;
|
|
44
71
|
}
|
|
45
|
-
const res2 =
|
|
72
|
+
const res2 = super_.compare(a0, b0);
|
|
46
73
|
return res2 !== 0 ? res2 : res1;
|
|
47
74
|
};
|
|
48
|
-
this.resolvedOptions = () =>
|
|
75
|
+
this.resolvedOptions = () => super_.resolvedOptions();
|
|
49
76
|
};
|
|
50
77
|
PatchedCollator.prototype = { constructor: PatchedCollator };
|
|
51
|
-
|
|
52
|
-
PatchedCollator.supportedLocalesOf = _Collator.supportedLocalesOf;
|
|
78
|
+
PatchedCollator.supportedLocalesOf = /*#__PURE__*/ patchSupportedLocalesOf(_Collator);
|
|
53
79
|
PatchedCollator.$original = _Collator;
|
|
54
80
|
exports._PatchedCollator = PatchedCollator;
|
|
55
81
|
// ---------------------------------------------------------------------------
|
|
@@ -82,24 +108,26 @@ const PatchedNumberFormat = function NumberFormat(locales, options) {
|
|
|
82
108
|
// @ts-expect-error (YOLO! Can't be arsed)
|
|
83
109
|
return new PatchedNumberFormat(locales, options);
|
|
84
110
|
}
|
|
85
|
-
const mappedLocales = mapLocales(locales);
|
|
86
|
-
const
|
|
111
|
+
const mappedLocales = mapLocales(_NumberFormat, locales);
|
|
112
|
+
const super_ = _NumberFormat(mappedLocales || locales, options);
|
|
87
113
|
const mapped = !!mappedLocales;
|
|
88
|
-
this.format = (value) => combineParts(this.formatToParts(value));
|
|
89
|
-
this.formatRange = (value1, value2) =>
|
|
114
|
+
this.format = (value) => mapped ? combineParts(this.formatToParts(value)) : super_.format(value);
|
|
115
|
+
this.formatRange = (value1, value2) => mapped
|
|
116
|
+
? combineParts(this.formatRangeToParts(value1, value2))
|
|
117
|
+
: super_.formatRange(value1, value2);
|
|
90
118
|
this.formatToParts = (value) => {
|
|
91
|
-
const parts =
|
|
92
|
-
return mapped ? reformatNumberParts(
|
|
119
|
+
const parts = super_.formatToParts(value);
|
|
120
|
+
return mapped ? reformatNumberParts(super_, parts) : parts;
|
|
93
121
|
};
|
|
94
122
|
this.formatRangeToParts = (value1, value2) => {
|
|
95
|
-
const parts =
|
|
96
|
-
return mapped ? reformatNumberParts(
|
|
123
|
+
const parts = super_.formatRangeToParts(value1, value2);
|
|
124
|
+
return mapped ? reformatNumberParts(super_, parts) : parts;
|
|
97
125
|
};
|
|
98
|
-
this.resolvedOptions = () =>
|
|
126
|
+
this.resolvedOptions = () => super_.resolvedOptions();
|
|
99
127
|
};
|
|
100
128
|
PatchedNumberFormat.prototype = { constructor: PatchedNumberFormat };
|
|
101
|
-
|
|
102
|
-
|
|
129
|
+
PatchedNumberFormat.supportedLocalesOf =
|
|
130
|
+
/*#__PURE__*/ patchSupportedLocalesOf(_NumberFormat);
|
|
103
131
|
PatchedNumberFormat.$original = _NumberFormat;
|
|
104
132
|
exports._PatchedNumberFormat = PatchedNumberFormat;
|
|
105
133
|
// ---------------------------------------------------------------------------
|
|
@@ -202,7 +230,7 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
|
202
230
|
// @ts-expect-error (YOLO! Can't be arsed)
|
|
203
231
|
return new PatchedDateTimeFormat(locales, options);
|
|
204
232
|
}
|
|
205
|
-
const mappedLocales = mapLocales(locales);
|
|
233
|
+
const mappedLocales = mapLocales(_DateTimeFormat, locales);
|
|
206
234
|
if (options === null || options === void 0 ? void 0 : options.hour12) {
|
|
207
235
|
options = {
|
|
208
236
|
...options,
|
|
@@ -210,23 +238,25 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
|
210
238
|
hourCycle: 'h11',
|
|
211
239
|
};
|
|
212
240
|
}
|
|
213
|
-
const
|
|
241
|
+
const super_ = _DateTimeFormat(mappedLocales || locales, options);
|
|
214
242
|
const mapped = !!mappedLocales;
|
|
215
|
-
this.format = (value) => combineParts(this.formatToParts(value));
|
|
216
|
-
this.formatRange = (value1, value2) =>
|
|
243
|
+
this.format = (value) => mapped ? combineParts(this.formatToParts(value)) : super_.format(value);
|
|
244
|
+
this.formatRange = (value1, value2) => mapped
|
|
245
|
+
? combineParts(this.formatRangeToParts(value1, value2))
|
|
246
|
+
: super_.formatRange(value1, value2);
|
|
217
247
|
this.formatToParts = (value) => {
|
|
218
|
-
const parts =
|
|
219
|
-
return mapped ? reformatDateTimeParts(
|
|
248
|
+
const parts = super_.formatToParts(value);
|
|
249
|
+
return mapped ? reformatDateTimeParts(super_, parts) : parts;
|
|
220
250
|
};
|
|
221
251
|
this.formatRangeToParts = (value1, value2) => {
|
|
222
|
-
const parts =
|
|
223
|
-
return mapped ? reformatDateTimeParts(
|
|
252
|
+
const parts = super_.formatRangeToParts(value1, value2);
|
|
253
|
+
return mapped ? reformatDateTimeParts(super_, parts) : parts;
|
|
224
254
|
};
|
|
225
|
-
this.resolvedOptions = () =>
|
|
255
|
+
this.resolvedOptions = () => super_.resolvedOptions();
|
|
226
256
|
};
|
|
227
257
|
PatchedDateTimeFormat.prototype = { constructor: PatchedDateTimeFormat };
|
|
228
|
-
|
|
229
|
-
|
|
258
|
+
PatchedDateTimeFormat.supportedLocalesOf =
|
|
259
|
+
/*#__PURE__*/ patchSupportedLocalesOf(_DateTimeFormat);
|
|
230
260
|
PatchedDateTimeFormat.$original = _DateTimeFormat;
|
|
231
261
|
exports._PatchedDateTimeFormat = PatchedDateTimeFormat;
|
|
232
262
|
// ---------------------------------------------------------------------------
|
|
@@ -307,15 +337,14 @@ let PatchedPluralRules;
|
|
|
307
337
|
if (_PluralRules) {
|
|
308
338
|
PatchedPluralRules = (_a = class PluralRules extends _PluralRules {
|
|
309
339
|
pluralIsl(n) {
|
|
340
|
+
n = n < 0 ? -n : n;
|
|
310
341
|
return this.ord ? 'other' : n % 10 !== 1 || n % 100 === 11 ? 'other' : 'one';
|
|
311
342
|
}
|
|
312
343
|
constructor(locales, options) {
|
|
313
|
-
const mappedLocales = mapLocales(locales);
|
|
344
|
+
const mappedLocales = mapLocales(_PluralRules, locales);
|
|
314
345
|
super(mappedLocales || locales, options);
|
|
315
346
|
this.mapped = !!mappedLocales;
|
|
316
347
|
this.ord = (options === null || options === void 0 ? void 0 : options.type) === 'ordinal';
|
|
317
|
-
this.select = this.select.bind(this);
|
|
318
|
-
this.selectRange = this.selectRange.bind(this);
|
|
319
348
|
}
|
|
320
349
|
select(n) {
|
|
321
350
|
if (this.mapped) {
|
|
@@ -333,6 +362,7 @@ if (_PluralRules) {
|
|
|
333
362
|
return super.selectRange(n, n2);
|
|
334
363
|
}
|
|
335
364
|
},
|
|
365
|
+
_a.supportedLocalesOf = patchSupportedLocalesOf(_PluralRules),
|
|
336
366
|
_a.$original = _PluralRules,
|
|
337
367
|
_a);
|
|
338
368
|
}
|
|
@@ -346,11 +376,9 @@ let PatchedListFormat;
|
|
|
346
376
|
if (_ListFormat) {
|
|
347
377
|
PatchedListFormat = (_b = class ListFormat extends _ListFormat {
|
|
348
378
|
constructor(locales, options) {
|
|
349
|
-
const mappedLocales = mapLocales(locales);
|
|
379
|
+
const mappedLocales = mapLocales(_ListFormat, locales);
|
|
350
380
|
super(mappedLocales || locales, options);
|
|
351
381
|
this.mapped = !!mappedLocales;
|
|
352
|
-
this.format = this.format.bind(this);
|
|
353
|
-
this.formatToParts = this.formatToParts.bind(this);
|
|
354
382
|
}
|
|
355
383
|
format(list) {
|
|
356
384
|
return this.mapped ? combineParts(this.formatToParts(list)) : super.format(list);
|
|
@@ -359,8 +387,8 @@ if (_ListFormat) {
|
|
|
359
387
|
const parts = super.formatToParts(list);
|
|
360
388
|
if (this.mapped) {
|
|
361
389
|
for (const item of parts) {
|
|
362
|
-
const { value } = item;
|
|
363
|
-
if (
|
|
390
|
+
const { type, value } = item;
|
|
391
|
+
if (type === 'literal' && (value === ' el. ' || value === ' eller ')) {
|
|
364
392
|
item.value = ' eða ';
|
|
365
393
|
}
|
|
366
394
|
}
|
|
@@ -368,7 +396,112 @@ if (_ListFormat) {
|
|
|
368
396
|
return parts;
|
|
369
397
|
}
|
|
370
398
|
},
|
|
399
|
+
_b.supportedLocalesOf = patchSupportedLocalesOf(_ListFormat),
|
|
371
400
|
_b.$original = _ListFormat,
|
|
372
401
|
_b);
|
|
373
402
|
}
|
|
374
403
|
exports._PatchedListFormat = PatchedListFormat;
|
|
404
|
+
// ===========================================================================
|
|
405
|
+
// RelativeTimeFormat
|
|
406
|
+
// ===========================================================================
|
|
407
|
+
const _RelativeTimeFormat = Intl.RelativeTimeFormat;
|
|
408
|
+
let PatchedRelativeTimeFormat;
|
|
409
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
410
|
+
if (_RelativeTimeFormat) {
|
|
411
|
+
let pluralIsl;
|
|
412
|
+
let numFormatIsl;
|
|
413
|
+
const islUnits = {
|
|
414
|
+
year: [['ári', 'árum', 'ár', 'ár'], ''],
|
|
415
|
+
quarter: [['ársfjórðungi', 'ársfjórðungum', 'ársfjórðung', 'ársfjórðunga'], 'ársfj.'],
|
|
416
|
+
month: [['mánuði', 'mánuðum', 'mánuð', 'mánuði'], 'mán.'],
|
|
417
|
+
week: [['viku', 'vikum', 'viku', 'vikur'], ''],
|
|
418
|
+
day: [['degi', 'dögum', 'dag', 'daga'], ''],
|
|
419
|
+
hour: [['klukkustund', 'klukkustundum', 'klukkustund', 'klukkustundir'], 'klst.'],
|
|
420
|
+
minute: [['mínútu', 'mínútum', 'mínútu', 'mínútur'], 'mín.'],
|
|
421
|
+
second: [['sekúndu', 'sekúndum', 'sekúndu', 'sekúndur'], 'sek.'],
|
|
422
|
+
};
|
|
423
|
+
const phrases = {
|
|
424
|
+
nu: 'núna',
|
|
425
|
+
'næste år': 'á næsta ári',
|
|
426
|
+
'sidste år': 'á síðasta ári',
|
|
427
|
+
'i år': 'á þessu ári',
|
|
428
|
+
'sidste kvartal': 'síðasti ársfjórðungur',
|
|
429
|
+
'dette kvartal': 'þessi ársfjórðungur',
|
|
430
|
+
'næste kvartal': 'næsti ársfjórðungur',
|
|
431
|
+
'sidste kvt.': 'síðasti ársfj.',
|
|
432
|
+
'dette kvt.': 'þessi ársfj.',
|
|
433
|
+
'næste kvt.': 'næsti ársfj.',
|
|
434
|
+
'sidste måned': 'í síðasta mánuði',
|
|
435
|
+
'denne måned': 'í þessum mánuði',
|
|
436
|
+
'næste måned': 'í næsta mánuði',
|
|
437
|
+
'sidste md.': 'í síðasta mán.',
|
|
438
|
+
'denne md.': 'í þessum mán.',
|
|
439
|
+
'næste md.': 'í næsta mán.',
|
|
440
|
+
'sidste uge': 'í síðustu viku',
|
|
441
|
+
'denne uge': 'í þessari viku',
|
|
442
|
+
'næste uge': 'í næstu viku',
|
|
443
|
+
'i forgårs': 'í fyrradag',
|
|
444
|
+
'i går': 'í gær',
|
|
445
|
+
'i dag': 'í dag',
|
|
446
|
+
'i morgen': 'á morgun',
|
|
447
|
+
'i overmorgen': 'eftir tvo daga',
|
|
448
|
+
'denne time': 'þessa stundina',
|
|
449
|
+
'dette minut': 'á þessari mínútu',
|
|
450
|
+
};
|
|
451
|
+
PatchedRelativeTimeFormat = (_c = class RelativeTimeFormat extends _RelativeTimeFormat {
|
|
452
|
+
constructor(locales, options) {
|
|
453
|
+
const mappedLocales = mapLocales(_RelativeTimeFormat, locales);
|
|
454
|
+
super(mappedLocales || locales, options);
|
|
455
|
+
this.mapped = !!mappedLocales;
|
|
456
|
+
}
|
|
457
|
+
format(value, unit) {
|
|
458
|
+
return this.mapped
|
|
459
|
+
? combineParts(this.formatToParts(value, unit))
|
|
460
|
+
: super.format(value, unit);
|
|
461
|
+
}
|
|
462
|
+
// eslint-disable-next-line complexity
|
|
463
|
+
formatToParts(value, unit) {
|
|
464
|
+
const parts = super.formatToParts(value, unit);
|
|
465
|
+
if (!this.mapped) {
|
|
466
|
+
return parts;
|
|
467
|
+
}
|
|
468
|
+
if (!pluralIsl) {
|
|
469
|
+
pluralIsl = new exports._PatchedPluralRules('is');
|
|
470
|
+
}
|
|
471
|
+
if (!numFormatIsl) {
|
|
472
|
+
numFormatIsl = new exports._PatchedNumberFormat('is');
|
|
473
|
+
}
|
|
474
|
+
const options = this.resolvedOptions();
|
|
475
|
+
const unitSngl = unit.replace(/s$/, '');
|
|
476
|
+
if (parts.length === 1) {
|
|
477
|
+
const firstPart = parts[0];
|
|
478
|
+
firstPart.value = phrases[firstPart.value] || firstPart.value;
|
|
479
|
+
return parts;
|
|
480
|
+
}
|
|
481
|
+
const [long, short] = islUnits[unitSngl];
|
|
482
|
+
const idx = (value < 0 ? 0 : 2) + (pluralIsl.select(value) === 'one' ? 0 : 1);
|
|
483
|
+
const prefixStr = options.style === 'narrow' &&
|
|
484
|
+
(unitSngl === 'second' || unitSngl === 'minute' || unitSngl === 'hour')
|
|
485
|
+
? value < 0
|
|
486
|
+
? '-'
|
|
487
|
+
: '+'
|
|
488
|
+
: value < 0
|
|
489
|
+
? 'fyrir '
|
|
490
|
+
: 'eftir ';
|
|
491
|
+
const valueStr = (options.style !== 'long' && short) || long[idx];
|
|
492
|
+
const islParts = [
|
|
493
|
+
{ type: 'literal', value: prefixStr },
|
|
494
|
+
...numFormatIsl.formatToParts(Math.abs(value)).map((part) => {
|
|
495
|
+
part.unit =
|
|
496
|
+
unitSngl;
|
|
497
|
+
return part;
|
|
498
|
+
}),
|
|
499
|
+
{ type: 'literal', value: ` ${valueStr}` },
|
|
500
|
+
];
|
|
501
|
+
return islParts;
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
_c.$original = _RelativeTimeFormat,
|
|
505
|
+
_c);
|
|
506
|
+
}
|
|
507
|
+
exports._PatchedRelativeTimeFormat = PatchedRelativeTimeFormat;
|
package/http.d.ts
CHANGED
|
@@ -158,12 +158,19 @@ type TTLObj = {
|
|
|
158
158
|
*/
|
|
159
159
|
export type TTLConfig = TTL | TTLKeywords | TTLObj;
|
|
160
160
|
/**
|
|
161
|
-
* Converts a `TTL` (max-age) value into seconds
|
|
162
|
-
*
|
|
161
|
+
* Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
|
|
162
|
+
* negative input values.
|
|
163
163
|
*
|
|
164
164
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
165
165
|
*/
|
|
166
166
|
export declare const toSec: (ttl: TTL) => number;
|
|
167
|
+
/**
|
|
168
|
+
* Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
|
|
169
|
+
* and/or negative input values.
|
|
170
|
+
*
|
|
171
|
+
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#toms-duration-helper
|
|
172
|
+
*/
|
|
173
|
+
export declare const toMs: (ttl: TTL) => number;
|
|
167
174
|
type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
|
|
168
175
|
headers?: Record<string, string | Array<string>>;
|
|
169
176
|
};
|
package/http.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HTTP_502_BadGateway = exports.HTTP_501_NotImplemented = exports.HTTP_500_InternalServerError = exports.HTTP_451_UnavailableForLegalReasons = exports.HTTP_431_RequestHeaderFieldsTooLarge = exports.HTTP_429_TooManyRequests = exports.HTTP_428_PreconditionRequired = exports.HTTP_426_UpgradeRequired = exports.HTTP_424_FailedDependency = exports.HTTP_423_Locked = exports.HTTP_422_UnprocessableContent = exports.HTTP_421_MisdirectedRequest = exports.HTTP_418_ImATeapot = exports.HTTP_417_ExpectationFailed = exports.HTTP_416_RangeNotSatisfiable = exports.HTTP_415_UnsupportedMediaType = exports.HTTP_414_URITooLong = exports.HTTP_413_PayloadTooLarge = exports.HTTP_412_PreconditionFailed = exports.HTTP_411_LengthRequired = exports.HTTP_410_Gone = exports.HTTP_409_Conflict = exports.HTTP_408_RequestTimeout = exports.HTTP_407_ProxyAuthenticationRequired = exports.HTTP_406_NotAcceptable = exports.HTTP_405_MethodNotAllowed = exports.HTTP_404_NotFound = exports.HTTP_403_Forbidden = exports.HTTP_401_Unauthorized = exports.HTTP_400_BadRequest = exports.HTTP_308_PermanentRedirect = exports.HTTP_307_TemporaryRedirect = exports.HTTP_304_NotModified = exports.HTTP_303_SeeOther = exports.HTTP_302_Found = exports.HTTP_301_MovedPermanently = exports.HTTP_226_IMUsed = exports.HTTP_208_AlreadyReported = exports.HTTP_207_MultiStatus = exports.HTTP_206_PartialContent = exports.HTTP_205_ResetContent = exports.HTTP_204_NoContent = exports.HTTP_203_NonAuthoritativeInformation = exports.HTTP_202_Accepted = exports.HTTP_201_Created = exports.HTTP_200_OK = exports.HTTP_103_EarlyHints = exports.HTTP_102_Processing = exports.HTTP_101_SwitchingProtocols = exports.HTTP_100_Continue = void 0;
|
|
4
|
-
exports.cacheControlHeaders = exports.cacheControl = exports.toSec = exports.HTTP_511_NetworkAuthenticationRequired = exports.HTTP_510_NotExtended = exports.HTTP_508_LoopDetected = exports.HTTP_507_InsufficientStorage = exports.HTTP_506_VariantAlsoNegotiates = exports.HTTP_505_HTTPVersionNotSupported = exports.HTTP_504_GatewayTimeout = exports.HTTP_503_ServiceUnavailable = void 0;
|
|
4
|
+
exports.cacheControlHeaders = exports.cacheControl = exports.toMs = exports.toSec = exports.HTTP_511_NetworkAuthenticationRequired = exports.HTTP_510_NotExtended = exports.HTTP_508_LoopDetected = exports.HTTP_507_InsufficientStorage = exports.HTTP_506_VariantAlsoNegotiates = exports.HTTP_505_HTTPVersionNotSupported = exports.HTTP_504_GatewayTimeout = exports.HTTP_503_ServiceUnavailable = void 0;
|
|
5
5
|
// INFORMATION
|
|
6
6
|
/** The client should continue the request or ignore the response if the request is already finished. */
|
|
7
7
|
exports.HTTP_100_Continue = 100;
|
|
@@ -137,8 +137,8 @@ const unitToSeconds = {
|
|
|
137
137
|
w: 7 * 24 * 3600,
|
|
138
138
|
};
|
|
139
139
|
/**
|
|
140
|
-
* Converts a `TTL` (max-age) value into seconds
|
|
141
|
-
*
|
|
140
|
+
* Converts a `TTL` (max-age) value into seconds. Returns `0` for bad and/or
|
|
141
|
+
* negative input values.
|
|
142
142
|
*
|
|
143
143
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
144
144
|
*/
|
|
@@ -151,6 +151,14 @@ const toSec = (ttl) => {
|
|
|
151
151
|
return Math.max(0, Math.round(ttl)) || 0;
|
|
152
152
|
};
|
|
153
153
|
exports.toSec = toSec;
|
|
154
|
+
/**
|
|
155
|
+
* Converts a `TTL` (duration) value into milliseconds. Returns `0` for bad
|
|
156
|
+
* and/or negative input values.
|
|
157
|
+
*
|
|
158
|
+
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#toms-duration-helper
|
|
159
|
+
*/
|
|
160
|
+
const toMs = (ttl) => (0, exports.toSec)(ttl) * 1000;
|
|
161
|
+
exports.toMs = toMs;
|
|
154
162
|
const toRespnseStubHeaders = (response) => {
|
|
155
163
|
if (response instanceof Map) {
|
|
156
164
|
return response;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reykjavik/webtools",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"description": "Misc. JS/TS helpers used by Reykjavík City's web dev teams.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": "ssh://git@github.com:reykjavikcity/webtools.git",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@reykjavik/hanna-utils": "^0.2.
|
|
14
|
+
"@reykjavik/hanna-utils": "^0.2.16"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"@remix-run/react": "^2.6.0",
|