@reykjavik/webtools 0.1.23 → 0.1.25
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 +16 -0
- package/README.md +35 -33
- package/esm/fixIcelandicLocale.js +6 -4
- package/esm/fixIcelandicLocale.privates.d.ts +19 -3
- package/esm/fixIcelandicLocale.privates.js +69 -9
- package/esm/http.d.ts +10 -3
- package/esm/http.js +33 -7
- package/esm/remix/Wait.d.ts +1 -1
- package/esm/remix/Wait.js +1 -1
- package/fixIcelandicLocale.js +5 -3
- package/fixIcelandicLocale.privates.d.ts +19 -3
- package/fixIcelandicLocale.privates.js +75 -13
- package/http.d.ts +10 -3
- package/http.js +33 -7
- package/package.json +1 -1
- package/remix/Wait.d.ts +1 -1
- package/remix/Wait.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
+
## 0.1.25
|
|
8
|
+
|
|
9
|
+
_2024-05-17_
|
|
10
|
+
|
|
11
|
+
- `@reykjavik/webtools/http`:
|
|
12
|
+
- feat: `cacheControl` now also accepts standard `Response` objects
|
|
13
|
+
|
|
14
|
+
## 0.1.24
|
|
15
|
+
|
|
16
|
+
_2024-03-22_
|
|
17
|
+
|
|
18
|
+
- `@reykjavik/webtools/fixIcelandicLocale`:
|
|
19
|
+
- fix: Add missing patches for `Date.prototype.toLocaleString` and
|
|
20
|
+
`Date.prototype.toLocaleTimeString`
|
|
21
|
+
- fix: Correct `Date.prototype.toLocaleDateString` options defaults/handling
|
|
22
|
+
|
|
7
23
|
## 0.1.23
|
|
8
24
|
|
|
9
25
|
_2024-03-21_
|
package/README.md
CHANGED
|
@@ -56,7 +56,8 @@ Various framework agnostic helpers for leveraging HTTP magic.
|
|
|
56
56
|
|
|
57
57
|
### HTTP Status Codes
|
|
58
58
|
|
|
59
|
-
All the web-related HTTP status codes are exported with human-readable names
|
|
59
|
+
All the web-related HTTP status codes are exported with human-readable names
|
|
60
|
+
and a short JSDoc comment:
|
|
60
61
|
|
|
61
62
|
- `HTTP_200_OK`
|
|
62
63
|
- `HTTP_303_SeeOther`
|
|
@@ -71,34 +72,42 @@ All the web-related HTTP status codes are exported with human-readable names:
|
|
|
71
72
|
- `HTTP_500_InternalServerError`
|
|
72
73
|
- ...ad nauseum.
|
|
73
74
|
|
|
75
|
+
These make your code more readable and less prone to accidental mistakes:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { HTTP_200_OK, HTTP_404_NotFound } from '@reykjavik/webtools/http';
|
|
79
|
+
|
|
80
|
+
console.log(HTTP_200_OK); // 200
|
|
81
|
+
console.log(HTTP_404_NotFound); // 404
|
|
82
|
+
```
|
|
83
|
+
|
|
74
84
|
### Types for HTTP Status code groups
|
|
75
85
|
|
|
76
86
|
These type unions are useful when writing HTTP helper functions and error
|
|
77
|
-
|
|
87
|
+
handlers, etc.
|
|
78
88
|
|
|
79
89
|
Union Types for the more commonly occurrring HTTP Status codes:
|
|
80
90
|
|
|
81
|
-
- `
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
- `
|
|
85
|
-
|
|
86
|
-
- `
|
|
87
|
-
- `
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
- `HTTP_STATUS` (all the status-codes!)
|
|
91
|
+
- `HTTP_INFO` (100, 101)
|
|
92
|
+
- `HTTP_SUCCESS` (200, 201, 202)
|
|
93
|
+
- `HTTP_REDIRECTION` (301, 302, 303, 304, 307, 308)
|
|
94
|
+
- `HTTP_NOTMODIFIED` (304)
|
|
95
|
+
- `HTTP_ERROR` (400, 404, 410, 401, 403, 500)
|
|
96
|
+
- `HTTP_CLIENT_ERROR` (400, 404, 410, 401, 403)
|
|
97
|
+
- `HTTP_NOT_FOUND` (400, 404, 410)
|
|
98
|
+
- `HTTP_BANNED` (401, 403)
|
|
99
|
+
- `HTTP_SERVER_ERROR` (500)
|
|
100
|
+
|
|
101
|
+
It also offers more complete union types, including all the esoteric status
|
|
102
|
+
codes, are also available:
|
|
103
|
+
|
|
104
|
+
- `HTTP_STATUS` (**all** the status-codes!)
|
|
96
105
|
- `HTTP_INFO_ALL` (1\*\*)
|
|
97
106
|
- `HTTP_SUCCESS_ALL` (2\*\*)
|
|
98
107
|
- `HTTP_REDIRECTION_ALL` (3\*\*)
|
|
99
|
-
- `HTTP_ERROR_ALL`
|
|
108
|
+
- `HTTP_ERROR_ALL` (4\*\* and 5\*\*)
|
|
100
109
|
- `HTTP_CLIENT_ERROR_ALL` (4\*\*)
|
|
101
|
-
- `HTTP_SERVER_ERROR_ALL` (
|
|
110
|
+
- `HTTP_SERVER_ERROR_ALL` (5\*\*)
|
|
102
111
|
|
|
103
112
|
### `cacheControl` helper
|
|
104
113
|
|
|
@@ -259,7 +268,8 @@ values.
|
|
|
259
268
|
|
|
260
269
|
- `Intl.Collator` and `String.prototype.localeCompare`
|
|
261
270
|
- `Intl.NumberFormat` and `Number.prototype.toLocaleString`
|
|
262
|
-
- `Intl.DateTimeFormat` and `Date.prototype.
|
|
271
|
+
- `Intl.DateTimeFormat` and `Date.prototype.toLocaleString`,
|
|
272
|
+
`.toLocaleDateString`, and `.toLocaleTimeString`
|
|
263
273
|
- `Intl.PluralRules`
|
|
264
274
|
- `Intl.ListFormat`
|
|
265
275
|
|
|
@@ -332,28 +342,20 @@ editor), but there's a brief summary:
|
|
|
332
342
|
- `scriptUrl?: string` — The full SiteImprove analytics script URL.
|
|
333
343
|
(alternative to `accountId` prop).
|
|
334
344
|
- `hasConsented?: boolean` — Manual GDPR 'analytics' consent flag. Allows hard
|
|
335
|
-
opt-out, but defers to
|
|
336
|
-
|
|
337
|
-
available.
|
|
345
|
+
opt-out, but defers to [`CookieHubProvider` values](#usecookiehubconsent) if
|
|
346
|
+
they are available.
|
|
338
347
|
- `onLoad?: (e: unknown) => void` — Fires when the script has loaded.
|
|
339
348
|
- `onError?: (e: unknown) => void` — Fires if loading the script failed.
|
|
340
349
|
|
|
341
350
|
Example usage somewhere in your application:
|
|
342
351
|
|
|
343
|
-
```
|
|
352
|
+
```jsz
|
|
344
353
|
import { SiteImprove } from '@reykjavik/webtools/SiteImprove';
|
|
345
354
|
|
|
346
|
-
// ideally emit this from your loader function
|
|
347
355
|
const siteImproveAccountId = '[ACCOUNT_ID]'; // e.g. "7654321"
|
|
348
356
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
<SiteImprove
|
|
352
|
-
accountId={siteImproveAccountId}
|
|
353
|
-
onError={(error) =>
|
|
354
|
-
Logger('error', 'An error occured initializing siteimprove', error)
|
|
355
|
-
}
|
|
356
|
-
/>;
|
|
357
|
+
// ...then inside your main App component
|
|
358
|
+
<SiteImprove accountId={siteImproveAccountId} />;
|
|
357
359
|
```
|
|
358
360
|
|
|
359
361
|
In dev mode it does NOT load the SiteImprove script and merely logs page-view
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _PatchedCollator, _PatchedDateTimeFormat,
|
|
1
|
+
import { _PatchedCollator, _PatchedDateTimeFormat, _patchedDateToLocaleDateString, _patchedDateToLocaleString, _patchedDateToLocaleTimeString, _PatchedListFormat, _PatchedNumberFormat, _patchedNumberToLocaleString, _PatchedPluralRules, _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
|
|
@@ -6,11 +6,13 @@ import { _PatchedCollator, _PatchedDateTimeFormat, _PatchedListFormat, _patchedL
|
|
|
6
6
|
*/
|
|
7
7
|
if (Intl.Collator.supportedLocalesOf(['is']).length < 1) {
|
|
8
8
|
Intl.Collator = _PatchedCollator;
|
|
9
|
-
String.prototype.localeCompare =
|
|
9
|
+
String.prototype.localeCompare = _patchedStringLocaleCompare;
|
|
10
10
|
Intl.NumberFormat = _PatchedNumberFormat;
|
|
11
|
-
Number.prototype.toLocaleString =
|
|
11
|
+
Number.prototype.toLocaleString = _patchedNumberToLocaleString;
|
|
12
12
|
Intl.DateTimeFormat = _PatchedDateTimeFormat;
|
|
13
|
-
Date.prototype.
|
|
13
|
+
Date.prototype.toLocaleString = _patchedDateToLocaleString;
|
|
14
|
+
Date.prototype.toLocaleDateString = _patchedDateToLocaleDateString;
|
|
15
|
+
Date.prototype.toLocaleTimeString = _patchedDateToLocaleTimeString;
|
|
14
16
|
}
|
|
15
17
|
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-unnecessary-condition */
|
|
16
18
|
if (Intl.ListFormat && Intl.ListFormat.supportedLocalesOf(['is']).length < 1) {
|
|
@@ -5,7 +5,7 @@ export declare const _PatchedCollator: {
|
|
|
5
5
|
} & {
|
|
6
6
|
$original: typeof Intl.Collator;
|
|
7
7
|
};
|
|
8
|
-
export declare const
|
|
8
|
+
export declare const _patchedStringLocaleCompare: {
|
|
9
9
|
(this: string, that: string, locales?: string | Array<string>, options?: Intl.CollatorOptions): number;
|
|
10
10
|
$original: {
|
|
11
11
|
(that: string): number;
|
|
@@ -20,7 +20,7 @@ export declare const _PatchedNumberFormat: {
|
|
|
20
20
|
} & {
|
|
21
21
|
$original: typeof Intl.NumberFormat;
|
|
22
22
|
};
|
|
23
|
-
export declare const
|
|
23
|
+
export declare const _patchedNumberToLocaleString: {
|
|
24
24
|
(this: number, locales?: string | Array<string>, options?: Intl.NumberFormatOptions): string;
|
|
25
25
|
$original: {
|
|
26
26
|
(locales?: string | string[] | undefined, options?: Intl.NumberFormatOptions | undefined): string;
|
|
@@ -35,7 +35,23 @@ export declare const _PatchedDateTimeFormat: {
|
|
|
35
35
|
} & {
|
|
36
36
|
$original: typeof Intl.DateTimeFormat;
|
|
37
37
|
};
|
|
38
|
-
export declare const
|
|
38
|
+
export declare const _patchedDateToLocaleString: {
|
|
39
|
+
(this: Date, locales?: string | Array<string>, options?: Intl.DateTimeFormatOptions): string;
|
|
40
|
+
$original: {
|
|
41
|
+
(): string;
|
|
42
|
+
(locales?: string | string[] | undefined, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
43
|
+
(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export declare const _patchedDateToLocaleDateString: {
|
|
47
|
+
(this: Date, locales?: string | Array<string>, options?: Intl.DateTimeFormatOptions): string;
|
|
48
|
+
$original: {
|
|
49
|
+
(): string;
|
|
50
|
+
(locales?: string | string[] | undefined, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
51
|
+
(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export declare const _patchedDateToLocaleTimeString: {
|
|
39
55
|
(this: Date, locales?: string | Array<string>, options?: Intl.DateTimeFormatOptions): string;
|
|
40
56
|
$original: {
|
|
41
57
|
(): string;
|
|
@@ -50,11 +50,11 @@ PatchedCollator.supportedLocalesOf = _Collator.supportedLocalesOf;
|
|
|
50
50
|
PatchedCollator.$original = _Collator;
|
|
51
51
|
export const _PatchedCollator = PatchedCollator;
|
|
52
52
|
// ---------------------------------------------------------------------------
|
|
53
|
-
const
|
|
54
|
-
export const
|
|
53
|
+
const _stringLocaleCompare = String.prototype.localeCompare;
|
|
54
|
+
export const _patchedStringLocaleCompare = function localeCompare(that, locales, options) {
|
|
55
55
|
return _PatchedCollator(locales, options).compare(this, that);
|
|
56
56
|
};
|
|
57
|
-
|
|
57
|
+
_patchedStringLocaleCompare.$original = _stringLocaleCompare;
|
|
58
58
|
// ===========================================================================
|
|
59
59
|
// NumberFormat
|
|
60
60
|
// ===========================================================================
|
|
@@ -99,11 +99,11 @@ PatchedNumberFormat.supportedLocalesOf = _NumberFormat.supportedLocalesOf;
|
|
|
99
99
|
PatchedNumberFormat.$original = _NumberFormat;
|
|
100
100
|
export const _PatchedNumberFormat = PatchedNumberFormat;
|
|
101
101
|
// ---------------------------------------------------------------------------
|
|
102
|
-
const
|
|
103
|
-
export const
|
|
102
|
+
const _numberToLocaleString = Number.prototype.toLocaleString;
|
|
103
|
+
export const _patchedNumberToLocaleString = function toLocaleString(locales, options) {
|
|
104
104
|
return _PatchedNumberFormat(locales, options).format(this);
|
|
105
105
|
};
|
|
106
|
-
|
|
106
|
+
_patchedNumberToLocaleString.$original = _numberToLocaleString;
|
|
107
107
|
// ===========================================================================
|
|
108
108
|
// DateTimeFormat
|
|
109
109
|
// ===========================================================================
|
|
@@ -225,11 +225,71 @@ PatchedDateTimeFormat.supportedLocalesOf = _DateTimeFormat.supportedLocalesOf;
|
|
|
225
225
|
PatchedDateTimeFormat.$original = _DateTimeFormat;
|
|
226
226
|
export const _PatchedDateTimeFormat = PatchedDateTimeFormat;
|
|
227
227
|
// ---------------------------------------------------------------------------
|
|
228
|
-
const
|
|
229
|
-
export const
|
|
228
|
+
const _dateToLocaleString = Date.prototype.toLocaleString;
|
|
229
|
+
export const _patchedDateToLocaleString = function toLocaleString(locales, options) {
|
|
230
|
+
options = options || {};
|
|
231
|
+
if (!options.weekday &&
|
|
232
|
+
!options.year &&
|
|
233
|
+
!options.month &&
|
|
234
|
+
!options.day &&
|
|
235
|
+
!options.dayPeriod &&
|
|
236
|
+
!options.hour &&
|
|
237
|
+
!options.minute &&
|
|
238
|
+
!options.second &&
|
|
239
|
+
!options.fractionalSecondDigits) {
|
|
240
|
+
options = {
|
|
241
|
+
...options,
|
|
242
|
+
year: 'numeric',
|
|
243
|
+
month: 'numeric',
|
|
244
|
+
day: 'numeric',
|
|
245
|
+
hour: 'numeric',
|
|
246
|
+
minute: 'numeric',
|
|
247
|
+
second: 'numeric',
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return _PatchedDateTimeFormat(locales, options).format(this);
|
|
251
|
+
};
|
|
252
|
+
_patchedDateToLocaleString.$original = _dateToLocaleString;
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
const _dateToLocaleDateString = Date.prototype.toLocaleDateString;
|
|
255
|
+
export const _patchedDateToLocaleDateString = function toLocaleDateString(locales, options) {
|
|
256
|
+
options = options || {};
|
|
257
|
+
if (options.timeStyle) {
|
|
258
|
+
throw new TypeError("can't set option timeStyle in Date.toLocaleDateString()");
|
|
259
|
+
}
|
|
260
|
+
if (!options.weekday && !options.year && !options.month && !options.day) {
|
|
261
|
+
options = {
|
|
262
|
+
...options,
|
|
263
|
+
year: 'numeric',
|
|
264
|
+
month: 'numeric',
|
|
265
|
+
day: 'numeric',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
return _PatchedDateTimeFormat(locales, options).format(this);
|
|
269
|
+
};
|
|
270
|
+
_patchedDateToLocaleDateString.$original = _dateToLocaleDateString;
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
const _dateToLocaleTimeString = Date.prototype.toLocaleTimeString;
|
|
273
|
+
export const _patchedDateToLocaleTimeString = function toLocaleTimeString(locales, options) {
|
|
274
|
+
options = options || {};
|
|
275
|
+
if (options.dateStyle) {
|
|
276
|
+
throw new TypeError("can't set option dateStyle in Date.toLocaleTimeString()");
|
|
277
|
+
}
|
|
278
|
+
if (!options.dayPeriod &&
|
|
279
|
+
!options.hour &&
|
|
280
|
+
!options.minute &&
|
|
281
|
+
!options.second &&
|
|
282
|
+
!options.fractionalSecondDigits) {
|
|
283
|
+
options = {
|
|
284
|
+
...options,
|
|
285
|
+
hour: 'numeric',
|
|
286
|
+
minute: 'numeric',
|
|
287
|
+
second: 'numeric',
|
|
288
|
+
};
|
|
289
|
+
}
|
|
230
290
|
return _PatchedDateTimeFormat(locales, options).format(this);
|
|
231
291
|
};
|
|
232
|
-
|
|
292
|
+
_patchedDateToLocaleTimeString.$original = _dateToLocaleTimeString;
|
|
233
293
|
// ===========================================================================
|
|
234
294
|
// PluralRules
|
|
235
295
|
// ===========================================================================
|
package/esm/http.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import { ServerResponse } from 'node:http';
|
|
2
3
|
/** The client should continue the request or ignore the response if the request is already finished. */
|
|
3
4
|
export declare const HTTP_100_Continue = 100;
|
|
4
5
|
/** Response to an Upgrade request header from the client and indicates the protocol the server is switching to. */
|
|
@@ -163,13 +164,19 @@ export type TTLConfig = TTL | TTLKeywords | TTLObj;
|
|
|
163
164
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
164
165
|
*/
|
|
165
166
|
export declare const toSec: (ttl: TTL) => number;
|
|
167
|
+
type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
|
|
168
|
+
headers?: Record<string, string | Array<string>>;
|
|
169
|
+
};
|
|
170
|
+
type ResponseStub = {
|
|
171
|
+
headers: Pick<Headers, 'set' | 'get' | 'delete' | 'append'>;
|
|
172
|
+
};
|
|
166
173
|
/**
|
|
167
174
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
168
175
|
* on a HTTP response
|
|
169
176
|
*
|
|
170
177
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#getcssbundleurl
|
|
171
178
|
*/
|
|
172
|
-
export declare const cacheControl: (response:
|
|
173
|
-
res:
|
|
179
|
+
export declare const cacheControl: (response: ServerResponseStub | ResponseStub | {
|
|
180
|
+
res: ServerResponseStub | ResponseStub;
|
|
174
181
|
}, ttlCfg: TTLConfig, eTag?: string | number) => void;
|
|
175
182
|
export {};
|
package/esm/http.js
CHANGED
|
@@ -146,6 +146,31 @@ export const toSec = (ttl) => {
|
|
|
146
146
|
}
|
|
147
147
|
return Math.max(0, Math.round(ttl)) || 0;
|
|
148
148
|
};
|
|
149
|
+
const toRespnseStubHeaders = (response) => {
|
|
150
|
+
if ('headers' in response && !('setHeader' in response)) {
|
|
151
|
+
return response.headers;
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
get: (name) => {
|
|
155
|
+
const val = response.getHeader(name);
|
|
156
|
+
if (Array.isArray(val)) {
|
|
157
|
+
return val.join(', ');
|
|
158
|
+
}
|
|
159
|
+
return val != null ? `${val}` : null;
|
|
160
|
+
},
|
|
161
|
+
set: (name, value) => response.setHeader(name, value),
|
|
162
|
+
append: (name, value) => {
|
|
163
|
+
const existing = response.getHeader(name);
|
|
164
|
+
if (existing) {
|
|
165
|
+
response.setHeader(name, `${existing}, ${value}`);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
response.setHeader(name, value);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
delete: (name) => response.removeHeader(name),
|
|
172
|
+
};
|
|
173
|
+
};
|
|
149
174
|
const stabilities = {
|
|
150
175
|
revalidate: ', must-revalidate',
|
|
151
176
|
immutable: ', immutable',
|
|
@@ -153,16 +178,17 @@ const stabilities = {
|
|
|
153
178
|
};
|
|
154
179
|
const setCC = (response, cc) => {
|
|
155
180
|
const devModeHeader = 'X-Cache-Control';
|
|
181
|
+
const headers = toRespnseStubHeaders(response);
|
|
156
182
|
// Also set `X-Cache-Control` in dev mode, because some frameworks
|
|
157
|
-
// **cough** **
|
|
183
|
+
// **cough** **Nextjs** **cough** forcefully override the `Cache-Control`
|
|
158
184
|
// header when the server is in dev mode.
|
|
159
185
|
if (!cc) {
|
|
160
|
-
|
|
161
|
-
process.env.NODE_ENV !== 'production' &&
|
|
186
|
+
headers.delete('Cache-Control');
|
|
187
|
+
process.env.NODE_ENV !== 'production' && headers.delete(devModeHeader);
|
|
162
188
|
return;
|
|
163
189
|
}
|
|
164
|
-
|
|
165
|
-
process.env.NODE_ENV !== 'production' &&
|
|
190
|
+
headers.set('Cache-Control', cc);
|
|
191
|
+
process.env.NODE_ENV !== 'production' && headers.set(devModeHeader, cc);
|
|
166
192
|
};
|
|
167
193
|
/**
|
|
168
194
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
@@ -189,7 +215,7 @@ export const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
189
215
|
}
|
|
190
216
|
}
|
|
191
217
|
if (maxAge == null) {
|
|
192
|
-
response.
|
|
218
|
+
toRespnseStubHeaders(response).delete('Cache-Control');
|
|
193
219
|
return;
|
|
194
220
|
}
|
|
195
221
|
maxAge = toSec(maxAge);
|
|
@@ -204,5 +230,5 @@ export const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
204
230
|
const scope = opts.publ ? 'public' : 'private';
|
|
205
231
|
const stability = (opts.stability && stabilities[opts.stability]) || stabilities.immutable;
|
|
206
232
|
setCC(response, `${scope}, max-age=${maxAge + sWR + sIE + stability}`);
|
|
207
|
-
eTag != null && response.
|
|
233
|
+
eTag != null && toRespnseStubHeaders(response).set('ETag', String(eTag));
|
|
208
234
|
};
|
package/esm/remix/Wait.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type WaitComponent<CustomProps extends Record<string, unknown> = Record<n
|
|
|
37
37
|
displayName?: string;
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
41
41
|
* component, to provide a more ergonomic API.
|
|
42
42
|
*
|
|
43
43
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|
package/esm/remix/Wait.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { Suspense } from 'react';
|
|
2
2
|
import { Await } from '@remix-run/react';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
5
5
|
* component, to provide a more ergonomic API.
|
|
6
6
|
*
|
|
7
7
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|
package/fixIcelandicLocale.js
CHANGED
|
@@ -8,11 +8,13 @@ const fixIcelandicLocale_privates_js_1 = require("./fixIcelandicLocale.privates.
|
|
|
8
8
|
*/
|
|
9
9
|
if (Intl.Collator.supportedLocalesOf(['is']).length < 1) {
|
|
10
10
|
Intl.Collator = fixIcelandicLocale_privates_js_1._PatchedCollator;
|
|
11
|
-
String.prototype.localeCompare = fixIcelandicLocale_privates_js_1.
|
|
11
|
+
String.prototype.localeCompare = fixIcelandicLocale_privates_js_1._patchedStringLocaleCompare;
|
|
12
12
|
Intl.NumberFormat = fixIcelandicLocale_privates_js_1._PatchedNumberFormat;
|
|
13
|
-
Number.prototype.toLocaleString = fixIcelandicLocale_privates_js_1.
|
|
13
|
+
Number.prototype.toLocaleString = fixIcelandicLocale_privates_js_1._patchedNumberToLocaleString;
|
|
14
14
|
Intl.DateTimeFormat = fixIcelandicLocale_privates_js_1._PatchedDateTimeFormat;
|
|
15
|
-
Date.prototype.
|
|
15
|
+
Date.prototype.toLocaleString = fixIcelandicLocale_privates_js_1._patchedDateToLocaleString;
|
|
16
|
+
Date.prototype.toLocaleDateString = fixIcelandicLocale_privates_js_1._patchedDateToLocaleDateString;
|
|
17
|
+
Date.prototype.toLocaleTimeString = fixIcelandicLocale_privates_js_1._patchedDateToLocaleTimeString;
|
|
16
18
|
}
|
|
17
19
|
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-unnecessary-condition */
|
|
18
20
|
if (Intl.ListFormat && Intl.ListFormat.supportedLocalesOf(['is']).length < 1) {
|
|
@@ -5,7 +5,7 @@ export declare const _PatchedCollator: {
|
|
|
5
5
|
} & {
|
|
6
6
|
$original: typeof Intl.Collator;
|
|
7
7
|
};
|
|
8
|
-
export declare const
|
|
8
|
+
export declare const _patchedStringLocaleCompare: {
|
|
9
9
|
(this: string, that: string, locales?: string | Array<string>, options?: Intl.CollatorOptions): number;
|
|
10
10
|
$original: {
|
|
11
11
|
(that: string): number;
|
|
@@ -20,7 +20,7 @@ export declare const _PatchedNumberFormat: {
|
|
|
20
20
|
} & {
|
|
21
21
|
$original: typeof Intl.NumberFormat;
|
|
22
22
|
};
|
|
23
|
-
export declare const
|
|
23
|
+
export declare const _patchedNumberToLocaleString: {
|
|
24
24
|
(this: number, locales?: string | Array<string>, options?: Intl.NumberFormatOptions): string;
|
|
25
25
|
$original: {
|
|
26
26
|
(locales?: string | string[] | undefined, options?: Intl.NumberFormatOptions | undefined): string;
|
|
@@ -35,7 +35,23 @@ export declare const _PatchedDateTimeFormat: {
|
|
|
35
35
|
} & {
|
|
36
36
|
$original: typeof Intl.DateTimeFormat;
|
|
37
37
|
};
|
|
38
|
-
export declare const
|
|
38
|
+
export declare const _patchedDateToLocaleString: {
|
|
39
|
+
(this: Date, locales?: string | Array<string>, options?: Intl.DateTimeFormatOptions): string;
|
|
40
|
+
$original: {
|
|
41
|
+
(): string;
|
|
42
|
+
(locales?: string | string[] | undefined, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
43
|
+
(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export declare const _patchedDateToLocaleDateString: {
|
|
47
|
+
(this: Date, locales?: string | Array<string>, options?: Intl.DateTimeFormatOptions): string;
|
|
48
|
+
$original: {
|
|
49
|
+
(): string;
|
|
50
|
+
(locales?: string | string[] | undefined, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
51
|
+
(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions | undefined): string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export declare const _patchedDateToLocaleTimeString: {
|
|
39
55
|
(this: Date, locales?: string | Array<string>, options?: Intl.DateTimeFormatOptions): string;
|
|
40
56
|
$original: {
|
|
41
57
|
(): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a, _b;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports._PatchedListFormat = exports._PatchedPluralRules = exports.
|
|
4
|
+
exports._PatchedListFormat = exports._PatchedPluralRules = exports._patchedDateToLocaleTimeString = exports._patchedDateToLocaleDateString = exports._patchedDateToLocaleString = exports._PatchedDateTimeFormat = exports._patchedNumberToLocaleString = exports._PatchedNumberFormat = exports._patchedStringLocaleCompare = exports._PatchedCollator = void 0;
|
|
5
5
|
const _Collator = Intl.Collator;
|
|
6
6
|
const mapLocales = (locales) => {
|
|
7
7
|
locales = typeof locales === 'string' ? [locales] : locales || [];
|
|
@@ -53,12 +53,12 @@ PatchedCollator.supportedLocalesOf = _Collator.supportedLocalesOf;
|
|
|
53
53
|
PatchedCollator.$original = _Collator;
|
|
54
54
|
exports._PatchedCollator = PatchedCollator;
|
|
55
55
|
// ---------------------------------------------------------------------------
|
|
56
|
-
const
|
|
57
|
-
const
|
|
56
|
+
const _stringLocaleCompare = String.prototype.localeCompare;
|
|
57
|
+
const _patchedStringLocaleCompare = function localeCompare(that, locales, options) {
|
|
58
58
|
return (0, exports._PatchedCollator)(locales, options).compare(this, that);
|
|
59
59
|
};
|
|
60
|
-
exports.
|
|
61
|
-
exports.
|
|
60
|
+
exports._patchedStringLocaleCompare = _patchedStringLocaleCompare;
|
|
61
|
+
exports._patchedStringLocaleCompare.$original = _stringLocaleCompare;
|
|
62
62
|
// ===========================================================================
|
|
63
63
|
// NumberFormat
|
|
64
64
|
// ===========================================================================
|
|
@@ -103,12 +103,12 @@ PatchedNumberFormat.supportedLocalesOf = _NumberFormat.supportedLocalesOf;
|
|
|
103
103
|
PatchedNumberFormat.$original = _NumberFormat;
|
|
104
104
|
exports._PatchedNumberFormat = PatchedNumberFormat;
|
|
105
105
|
// ---------------------------------------------------------------------------
|
|
106
|
-
const
|
|
107
|
-
const
|
|
106
|
+
const _numberToLocaleString = Number.prototype.toLocaleString;
|
|
107
|
+
const _patchedNumberToLocaleString = function toLocaleString(locales, options) {
|
|
108
108
|
return (0, exports._PatchedNumberFormat)(locales, options).format(this);
|
|
109
109
|
};
|
|
110
|
-
exports.
|
|
111
|
-
exports.
|
|
110
|
+
exports._patchedNumberToLocaleString = _patchedNumberToLocaleString;
|
|
111
|
+
exports._patchedNumberToLocaleString.$original = _numberToLocaleString;
|
|
112
112
|
// ===========================================================================
|
|
113
113
|
// DateTimeFormat
|
|
114
114
|
// ===========================================================================
|
|
@@ -230,12 +230,74 @@ PatchedDateTimeFormat.supportedLocalesOf = _DateTimeFormat.supportedLocalesOf;
|
|
|
230
230
|
PatchedDateTimeFormat.$original = _DateTimeFormat;
|
|
231
231
|
exports._PatchedDateTimeFormat = PatchedDateTimeFormat;
|
|
232
232
|
// ---------------------------------------------------------------------------
|
|
233
|
-
const
|
|
234
|
-
const
|
|
233
|
+
const _dateToLocaleString = Date.prototype.toLocaleString;
|
|
234
|
+
const _patchedDateToLocaleString = function toLocaleString(locales, options) {
|
|
235
|
+
options = options || {};
|
|
236
|
+
if (!options.weekday &&
|
|
237
|
+
!options.year &&
|
|
238
|
+
!options.month &&
|
|
239
|
+
!options.day &&
|
|
240
|
+
!options.dayPeriod &&
|
|
241
|
+
!options.hour &&
|
|
242
|
+
!options.minute &&
|
|
243
|
+
!options.second &&
|
|
244
|
+
!options.fractionalSecondDigits) {
|
|
245
|
+
options = {
|
|
246
|
+
...options,
|
|
247
|
+
year: 'numeric',
|
|
248
|
+
month: 'numeric',
|
|
249
|
+
day: 'numeric',
|
|
250
|
+
hour: 'numeric',
|
|
251
|
+
minute: 'numeric',
|
|
252
|
+
second: 'numeric',
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
return (0, exports._PatchedDateTimeFormat)(locales, options).format(this);
|
|
256
|
+
};
|
|
257
|
+
exports._patchedDateToLocaleString = _patchedDateToLocaleString;
|
|
258
|
+
exports._patchedDateToLocaleString.$original = _dateToLocaleString;
|
|
259
|
+
// ---------------------------------------------------------------------------
|
|
260
|
+
const _dateToLocaleDateString = Date.prototype.toLocaleDateString;
|
|
261
|
+
const _patchedDateToLocaleDateString = function toLocaleDateString(locales, options) {
|
|
262
|
+
options = options || {};
|
|
263
|
+
if (options.timeStyle) {
|
|
264
|
+
throw new TypeError("can't set option timeStyle in Date.toLocaleDateString()");
|
|
265
|
+
}
|
|
266
|
+
if (!options.weekday && !options.year && !options.month && !options.day) {
|
|
267
|
+
options = {
|
|
268
|
+
...options,
|
|
269
|
+
year: 'numeric',
|
|
270
|
+
month: 'numeric',
|
|
271
|
+
day: 'numeric',
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return (0, exports._PatchedDateTimeFormat)(locales, options).format(this);
|
|
275
|
+
};
|
|
276
|
+
exports._patchedDateToLocaleDateString = _patchedDateToLocaleDateString;
|
|
277
|
+
exports._patchedDateToLocaleDateString.$original = _dateToLocaleDateString;
|
|
278
|
+
// ---------------------------------------------------------------------------
|
|
279
|
+
const _dateToLocaleTimeString = Date.prototype.toLocaleTimeString;
|
|
280
|
+
const _patchedDateToLocaleTimeString = function toLocaleTimeString(locales, options) {
|
|
281
|
+
options = options || {};
|
|
282
|
+
if (options.dateStyle) {
|
|
283
|
+
throw new TypeError("can't set option dateStyle in Date.toLocaleTimeString()");
|
|
284
|
+
}
|
|
285
|
+
if (!options.dayPeriod &&
|
|
286
|
+
!options.hour &&
|
|
287
|
+
!options.minute &&
|
|
288
|
+
!options.second &&
|
|
289
|
+
!options.fractionalSecondDigits) {
|
|
290
|
+
options = {
|
|
291
|
+
...options,
|
|
292
|
+
hour: 'numeric',
|
|
293
|
+
minute: 'numeric',
|
|
294
|
+
second: 'numeric',
|
|
295
|
+
};
|
|
296
|
+
}
|
|
235
297
|
return (0, exports._PatchedDateTimeFormat)(locales, options).format(this);
|
|
236
298
|
};
|
|
237
|
-
exports.
|
|
238
|
-
exports.
|
|
299
|
+
exports._patchedDateToLocaleTimeString = _patchedDateToLocaleTimeString;
|
|
300
|
+
exports._patchedDateToLocaleTimeString.$original = _dateToLocaleTimeString;
|
|
239
301
|
// ===========================================================================
|
|
240
302
|
// PluralRules
|
|
241
303
|
// ===========================================================================
|
package/http.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ServerResponse } from 'node:http';
|
|
2
3
|
/** The client should continue the request or ignore the response if the request is already finished. */
|
|
3
4
|
export declare const HTTP_100_Continue = 100;
|
|
4
5
|
/** Response to an Upgrade request header from the client and indicates the protocol the server is switching to. */
|
|
@@ -163,13 +164,19 @@ export type TTLConfig = TTL | TTLKeywords | TTLObj;
|
|
|
163
164
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#tosec-ttl-helper
|
|
164
165
|
*/
|
|
165
166
|
export declare const toSec: (ttl: TTL) => number;
|
|
167
|
+
type ServerResponseStub = Pick<ServerResponse, 'setHeader' | 'getHeader' | 'removeHeader'> & {
|
|
168
|
+
headers?: Record<string, string | Array<string>>;
|
|
169
|
+
};
|
|
170
|
+
type ResponseStub = {
|
|
171
|
+
headers: Pick<Headers, 'set' | 'get' | 'delete' | 'append'>;
|
|
172
|
+
};
|
|
166
173
|
/**
|
|
167
174
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
168
175
|
* on a HTTP response
|
|
169
176
|
*
|
|
170
177
|
* @see https://github.com/reykjavikcity/webtools/blob/v0.1/README.md#getcssbundleurl
|
|
171
178
|
*/
|
|
172
|
-
export declare const cacheControl: (response:
|
|
173
|
-
res:
|
|
179
|
+
export declare const cacheControl: (response: ServerResponseStub | ResponseStub | {
|
|
180
|
+
res: ServerResponseStub | ResponseStub;
|
|
174
181
|
}, ttlCfg: TTLConfig, eTag?: string | number) => void;
|
|
175
182
|
export {};
|
package/http.js
CHANGED
|
@@ -151,6 +151,31 @@ const toSec = (ttl) => {
|
|
|
151
151
|
return Math.max(0, Math.round(ttl)) || 0;
|
|
152
152
|
};
|
|
153
153
|
exports.toSec = toSec;
|
|
154
|
+
const toRespnseStubHeaders = (response) => {
|
|
155
|
+
if ('headers' in response && !('setHeader' in response)) {
|
|
156
|
+
return response.headers;
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
get: (name) => {
|
|
160
|
+
const val = response.getHeader(name);
|
|
161
|
+
if (Array.isArray(val)) {
|
|
162
|
+
return val.join(', ');
|
|
163
|
+
}
|
|
164
|
+
return val != null ? `${val}` : null;
|
|
165
|
+
},
|
|
166
|
+
set: (name, value) => response.setHeader(name, value),
|
|
167
|
+
append: (name, value) => {
|
|
168
|
+
const existing = response.getHeader(name);
|
|
169
|
+
if (existing) {
|
|
170
|
+
response.setHeader(name, `${existing}, ${value}`);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
response.setHeader(name, value);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
delete: (name) => response.removeHeader(name),
|
|
177
|
+
};
|
|
178
|
+
};
|
|
154
179
|
const stabilities = {
|
|
155
180
|
revalidate: ', must-revalidate',
|
|
156
181
|
immutable: ', immutable',
|
|
@@ -158,16 +183,17 @@ const stabilities = {
|
|
|
158
183
|
};
|
|
159
184
|
const setCC = (response, cc) => {
|
|
160
185
|
const devModeHeader = 'X-Cache-Control';
|
|
186
|
+
const headers = toRespnseStubHeaders(response);
|
|
161
187
|
// Also set `X-Cache-Control` in dev mode, because some frameworks
|
|
162
|
-
// **cough** **
|
|
188
|
+
// **cough** **Nextjs** **cough** forcefully override the `Cache-Control`
|
|
163
189
|
// header when the server is in dev mode.
|
|
164
190
|
if (!cc) {
|
|
165
|
-
|
|
166
|
-
process.env.NODE_ENV !== 'production' &&
|
|
191
|
+
headers.delete('Cache-Control');
|
|
192
|
+
process.env.NODE_ENV !== 'production' && headers.delete(devModeHeader);
|
|
167
193
|
return;
|
|
168
194
|
}
|
|
169
|
-
|
|
170
|
-
process.env.NODE_ENV !== 'production' &&
|
|
195
|
+
headers.set('Cache-Control', cc);
|
|
196
|
+
process.env.NODE_ENV !== 'production' && headers.set(devModeHeader, cc);
|
|
171
197
|
};
|
|
172
198
|
/**
|
|
173
199
|
* Use this function to quickly set the `Cache-Control` header with a `max-age=`
|
|
@@ -194,7 +220,7 @@ const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
194
220
|
}
|
|
195
221
|
}
|
|
196
222
|
if (maxAge == null) {
|
|
197
|
-
response.
|
|
223
|
+
toRespnseStubHeaders(response).delete('Cache-Control');
|
|
198
224
|
return;
|
|
199
225
|
}
|
|
200
226
|
maxAge = (0, exports.toSec)(maxAge);
|
|
@@ -209,6 +235,6 @@ const cacheControl = (response, ttlCfg, eTag) => {
|
|
|
209
235
|
const scope = opts.publ ? 'public' : 'private';
|
|
210
236
|
const stability = (opts.stability && stabilities[opts.stability]) || stabilities.immutable;
|
|
211
237
|
setCC(response, `${scope}, max-age=${maxAge + sWR + sIE + stability}`);
|
|
212
|
-
eTag != null && response.
|
|
238
|
+
eTag != null && toRespnseStubHeaders(response).set('ETag', String(eTag));
|
|
213
239
|
};
|
|
214
240
|
exports.cacheControl = cacheControl;
|
package/package.json
CHANGED
package/remix/Wait.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type WaitComponent<CustomProps extends Record<string, unknown> = Record<n
|
|
|
37
37
|
displayName?: string;
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
40
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
41
41
|
* component, to provide a more ergonomic API.
|
|
42
42
|
*
|
|
43
43
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|
package/remix/Wait.js
CHANGED
|
@@ -27,7 +27,7 @@ exports.Wait = void 0;
|
|
|
27
27
|
const react_1 = __importStar(require("react"));
|
|
28
28
|
const react_2 = require("@remix-run/react");
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* A thin wrapper around [Remix's `Await`](https://remix.run/docs/en/2/components/await)
|
|
31
31
|
* component, to provide a more ergonomic API.
|
|
32
32
|
*
|
|
33
33
|
* If the awaited promise (`props.for`) resolves to an object with a truthy
|