dx-server 0.13.0 → 0.14.0-alpha.1
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/README.md +397 -265
- package/lib/body.js +1 -1
- package/lib/body.js.map +1 -0
- package/lib/bodyHelpers.js +22 -9
- package/lib/bodyHelpers.js.map +1 -0
- package/lib/dx.d.ts +1 -1
- package/lib/dx.js +12 -6
- package/lib/dx.js.map +1 -0
- package/lib/dxHelpers.d.ts +2 -1
- package/lib/dxHelpers.js +105 -87
- package/lib/dxHelpers.js.map +1 -0
- package/lib/helpers.js.map +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -0
- package/lib/logger.d.ts +3 -2
- package/lib/logger.js +54 -46
- package/lib/logger.js.map +1 -0
- package/lib/router.js +5 -5
- package/lib/router.js.map +1 -0
- package/lib/static.js +4 -3
- package/lib/static.js.map +1 -0
- package/lib/staticHelpers.d.ts +5 -1
- package/lib/staticHelpers.js +150 -134
- package/lib/staticHelpers.js.map +1 -0
- package/lib/stream.d.ts +1 -1
- package/lib/stream.js +11 -5
- package/lib/stream.js.map +1 -0
- package/lib/vendors/contentType.js +7 -30
- package/lib/vendors/contentType.js.map +1 -0
- package/lib/vendors/etag.d.ts +2 -2
- package/lib/vendors/etag.js +15 -25
- package/lib/vendors/etag.js.map +1 -0
- package/lib/vendors/fresh.js +10 -17
- package/lib/vendors/fresh.js.map +1 -0
- package/lib/vendors/mime.js +4 -4
- package/lib/vendors/mime.js.map +1 -0
- package/lib/vendors/mimeDb.d.ts +2544 -2544
- package/lib/vendors/mimeDb.js +7100 -7079
- package/lib/vendors/mimeDb.js.map +1 -0
- package/lib/vendors/mimeScore.js +10 -11
- package/lib/vendors/mimeScore.js.map +1 -0
- package/lib/vendors/rangeParser.d.ts +2 -10
- package/lib/vendors/rangeParser.js +16 -29
- package/lib/vendors/rangeParser.js.map +1 -0
- package/package.json +32 -27
package/lib/vendors/etag.js
CHANGED
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
// etag: https://github.com/jshttp/etag/blob/b9f0642256e63654287299d205bc6ced71b1a228/index.js#L39
|
|
2
|
-
import
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
3
|
import { createReadStream } from 'node:fs';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { pipeline } from 'node:stream/promises';
|
|
5
|
+
export function entityTag(buf) {
|
|
6
|
+
// content hash is a strong validator: same bytes -> same tag. never weak (W/).
|
|
6
7
|
return buf.length
|
|
7
|
-
?
|
|
8
|
-
|
|
9
|
-
.update(buf)
|
|
10
|
-
.digest('base64')
|
|
11
|
-
.substring(0, 27)}"`
|
|
12
|
-
: `${weak ? 'W/' : ''}"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"`;
|
|
8
|
+
? `"${buf.length.toString(16)}-${createHash('sha1').update(buf).digest('base64').substring(0, 27)}"`
|
|
9
|
+
: '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"';
|
|
13
10
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#directives
|
|
14
11
|
// weak W/ vs strong eTag
|
|
15
12
|
// same weak eTag: 2 resources might be semantically equivalent, but not byte-for-byte identical
|
|
16
13
|
}
|
|
17
|
-
export async function entityTagPath(fileStat, filePath
|
|
14
|
+
export async function entityTagPath(fileStat, filePath) {
|
|
18
15
|
const hash = createHash('sha1');
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.on('finish', defer.resolve)
|
|
22
|
-
.on('error', defer.reject);
|
|
23
|
-
await defer.promise;
|
|
24
|
-
return `${fileStat.size.toString(16)}-${hash
|
|
25
|
-
.digest('base64')
|
|
26
|
-
.substring(0, 27)}`;
|
|
16
|
+
await pipeline(createReadStream(filePath), hash);
|
|
17
|
+
return `"${fileStat.size.toString(16)}-${hash.digest('base64').substring(0, 27)}"`;
|
|
27
18
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#directives
|
|
28
19
|
// weak W/ vs strong eTag
|
|
29
20
|
// same weak eTag: 2 resources might be semantically equivalent, but not byte-for-byte identical
|
|
30
21
|
}
|
|
31
|
-
const
|
|
22
|
+
const cacheControlNoCacheRegexp = /(?:^|,)\s*?no-cache\s*?(?:,|$)/;
|
|
32
23
|
export function statTag(stat) {
|
|
33
24
|
const mtime = stat.mtime.getTime().toString(16);
|
|
34
25
|
const size = stat.size.toString(16);
|
|
@@ -43,7 +34,7 @@ export function isFreshETag(req, etag) {
|
|
|
43
34
|
// to support end-to-end reload requests
|
|
44
35
|
// https://tools.ietf.org/html/rfc2616#section-14.9.4
|
|
45
36
|
const cacheControl = req.headers['cache-control'];
|
|
46
|
-
if (cacheControl &&
|
|
37
|
+
if (cacheControl && cacheControlNoCacheRegexp.test(cacheControl))
|
|
47
38
|
return;
|
|
48
39
|
if (noneMatch && noneMatch !== '*') {
|
|
49
40
|
if (!etag)
|
|
@@ -68,7 +59,7 @@ export function isFreshModifiedSince(req, lastModified) {
|
|
|
68
59
|
// to support end-to-end reload requests
|
|
69
60
|
// https://tools.ietf.org/html/rfc2616#section-14.9.4
|
|
70
61
|
const cacheControl = req.headers['cache-control'];
|
|
71
|
-
if (cacheControl &&
|
|
62
|
+
if (cacheControl && cacheControlNoCacheRegexp.test(cacheControl))
|
|
72
63
|
return;
|
|
73
64
|
if (modifiedSince && lastModified) {
|
|
74
65
|
const lastModifiedDate = Date.parse(lastModified);
|
|
@@ -84,12 +75,11 @@ function parseTokenList(str) {
|
|
|
84
75
|
// gather tokens
|
|
85
76
|
for (let i = 0, len = str.length; i < len; i++) {
|
|
86
77
|
switch (str.charCodeAt(i)) {
|
|
87
|
-
case 0x20
|
|
88
|
-
if (start === end)
|
|
78
|
+
case 0x20 /* */:
|
|
79
|
+
if (start === end)
|
|
89
80
|
start = end = i + 1;
|
|
90
|
-
}
|
|
91
81
|
break;
|
|
92
|
-
case 0x2c
|
|
82
|
+
case 0x2c /* , */:
|
|
93
83
|
list.push(str.substring(start, end));
|
|
94
84
|
start = end = i + 1;
|
|
95
85
|
break;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"etag.js","sourceRoot":"","sources":["../../src/vendors/etag.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAA;AAEtC,OAAO,EAAC,gBAAgB,EAAa,MAAM,SAAS,CAAA;AACpD,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAE7C,MAAM,UAAU,SAAS,CAAC,GAAW;IACpC,+EAA+E;IAC/E,OAAO,GAAG,CAAC,MAAM;QAChB,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG;QACpG,CAAC,CAAC,iCAAiC,CAAA;IACpC,4EAA4E;IAC5E,yBAAyB;IACzB,gGAAgG;AACjG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAe,EAAE,QAAgB;IACpE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IAC/B,MAAM,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAA;IAChD,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAA;IAClF,4EAA4E;IAC5E,yBAAyB;IACzB,gGAAgG;AACjG,CAAC;AAED,MAAM,yBAAyB,GAAG,gCAAgC,CAAA;AAClE,MAAM,UAAU,OAAO,CAAC,IAAW;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAEnC,OAAO,IAAI,IAAI,IAAI,KAAK,GAAG,CAAA;AAC5B,CAAC;AACD,6FAA6F;AAC7F,MAAM,UAAU,WAAW,CAAC,GAAoB,EAAE,IAAY;IAC7D,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IAC9C,IAAI,CAAC,SAAS;QAAE,OAAM;IAEtB,mDAAmD;IACnD,wCAAwC;IACxC,qDAAqD;IACrD,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IACjD,IAAI,YAAY,IAAI,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC;QAAE,OAAM;IAExE,IAAI,SAAS,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAM;QAEjB,IAAI,SAAS,GAAG,IAAI,CAAA;QACpB,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,EAAE,IAAI,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;gBACtE,SAAS,GAAG,KAAK,CAAA;gBACjB,MAAK;YACN,CAAC;QACF,CAAC;QACD,IAAI,SAAS;YAAE,OAAM;IACtB,CAAC;IAED,OAAO,IAAI,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAoB,EAAE,YAAoB;IAC9E,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACtD,IAAI,CAAC,aAAa;QAAE,OAAM;IAE1B,mDAAmD;IACnD,wCAAwC;IACxC,qDAAqD;IACrD,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IACjD,IAAI,YAAY,IAAI,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC;QAAE,OAAM;IAExE,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;QACnC,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QACjD,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;QACnD,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,gBAAgB,IAAI,iBAAiB,CAAA;IACtG,CAAC;IACD,OAAO,IAAI,CAAA;AACZ,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IAClC,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,MAAM,IAAI,GAAG,EAAE,CAAA;IACf,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,gBAAgB;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,QAAQ,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,OAAO;gBAChB,IAAI,KAAK,KAAK,GAAG;oBAAE,KAAK,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;gBACtC,MAAK;YACN,KAAK,IAAI,CAAC,OAAO;gBAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;gBACpC,KAAK,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;gBACnB,MAAK;YACN;gBACC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;gBACX,MAAK;QACP,CAAC;IACF,CAAC;IACD,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;IACpC,OAAO,IAAI,CAAA;AACZ,CAAC","sourcesContent":["// etag: https://github.com/jshttp/etag/blob/b9f0642256e63654287299d205bc6ced71b1a228/index.js#L39\nimport {createHash} from 'node:crypto'\nimport type {IncomingMessage} from 'node:http'\nimport {createReadStream, type Stats} from 'node:fs'\nimport {pipeline} from 'node:stream/promises'\n\nexport function entityTag(buf: Buffer) {\n\t// content hash is a strong validator: same bytes -> same tag. never weak (W/).\n\treturn buf.length\n\t\t? `\"${buf.length.toString(16)}-${createHash('sha1').update(buf).digest('base64').substring(0, 27)}\"`\n\t\t: '\"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk\"'\n\t// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#directives\n\t// weak W/ vs strong eTag\n\t// same weak eTag: 2 resources might be semantically equivalent, but not byte-for-byte identical\n}\n\nexport async function entityTagPath(fileStat: Stats, filePath: string) {\n\tconst hash = createHash('sha1')\n\tawait pipeline(createReadStream(filePath), hash)\n\treturn `\"${fileStat.size.toString(16)}-${hash.digest('base64').substring(0, 27)}\"`\n\t// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag#directives\n\t// weak W/ vs strong eTag\n\t// same weak eTag: 2 resources might be semantically equivalent, but not byte-for-byte identical\n}\n\nconst cacheControlNoCacheRegexp = /(?:^|,)\\s*?no-cache\\s*?(?:,|$)/\nexport function statTag(stat: Stats) {\n\tconst mtime = stat.mtime.getTime().toString(16)\n\tconst size = stat.size.toString(16)\n\n\treturn `\"${size}-${mtime}\"`\n}\n// https://github.com/jshttp/fresh/blob/05254186fd7428915224db46144fc94293a7df7d/index.js#L33\nexport function isFreshETag(req: IncomingMessage, etag: string) {\n\tconst noneMatch = req.headers['if-none-match']\n\tif (!noneMatch) return\n\n\t// Always return stale when Cache-Control: no-cache\n\t// to support end-to-end reload requests\n\t// https://tools.ietf.org/html/rfc2616#section-14.9.4\n\tconst cacheControl = req.headers['cache-control']\n\tif (cacheControl && cacheControlNoCacheRegexp.test(cacheControl)) return\n\n\tif (noneMatch && noneMatch !== '*') {\n\t\tif (!etag) return\n\n\t\tlet etagStale = true\n\t\tfor (const match of parseTokenList(noneMatch)) {\n\t\t\tif (match === etag || match === `W/${etag}` || `W/${match}` === etag) {\n\t\t\t\tetagStale = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (etagStale) return\n\t}\n\n\treturn true\n}\n\nexport function isFreshModifiedSince(req: IncomingMessage, lastModified: string) {\n\tconst modifiedSince = req.headers['if-modified-since']\n\tif (!modifiedSince) return\n\n\t// Always return stale when Cache-Control: no-cache\n\t// to support end-to-end reload requests\n\t// https://tools.ietf.org/html/rfc2616#section-14.9.4\n\tconst cacheControl = req.headers['cache-control']\n\tif (cacheControl && cacheControlNoCacheRegexp.test(cacheControl)) return\n\n\tif (modifiedSince && lastModified) {\n\t\tconst lastModifiedDate = Date.parse(lastModified)\n\t\tconst modifiedSinceDate = Date.parse(modifiedSince)\n\t\treturn !isNaN(lastModifiedDate) && !isNaN(modifiedSinceDate) && lastModifiedDate <= modifiedSinceDate\n\t}\n\treturn true\n}\n\nfunction parseTokenList(str: string) {\n\tlet end = 0\n\tconst list = []\n\tlet start = 0\n\n\t// gather tokens\n\tfor (let i = 0, len = str.length; i < len; i++) {\n\t\tswitch (str.charCodeAt(i)) {\n\t\t\tcase 0x20 /* */:\n\t\t\t\tif (start === end) start = end = i + 1\n\t\t\t\tbreak\n\t\t\tcase 0x2c /* , */:\n\t\t\t\tlist.push(str.substring(start, end))\n\t\t\t\tstart = end = i + 1\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tend = i + 1\n\t\t\t\tbreak\n\t\t}\n\t}\n\t// final token\n\tlist.push(str.substring(start, end))\n\treturn list\n}\n"]}
|
package/lib/vendors/fresh.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const cacheControlNoCacheRegexp = /(?:^|,)\s*?no-cache\s*?(?:,|$)/;
|
|
2
2
|
/**
|
|
3
3
|
* Check freshness of the response using request and response headers.
|
|
4
4
|
*
|
|
@@ -12,31 +12,26 @@ export function fresh(reqHeaders, resHeaders) {
|
|
|
12
12
|
const modifiedSince = reqHeaders['if-modified-since'];
|
|
13
13
|
const noneMatch = reqHeaders['if-none-match'];
|
|
14
14
|
// unconditional request
|
|
15
|
-
if (!modifiedSince && !noneMatch)
|
|
15
|
+
if (!modifiedSince && !noneMatch)
|
|
16
16
|
return false;
|
|
17
|
-
}
|
|
18
17
|
// Always return stale when Cache-Control: no-cache
|
|
19
18
|
// to support end-to-end reload requests
|
|
20
19
|
// https://tools.ietf.org/html/rfc2616#section-14.9.4
|
|
21
20
|
const cacheControl = reqHeaders['cache-control'];
|
|
22
|
-
if (cacheControl &&
|
|
21
|
+
if (cacheControl && cacheControlNoCacheRegexp.test(cacheControl))
|
|
23
22
|
return false;
|
|
24
|
-
}
|
|
25
23
|
// if-none-match takes precedent over if-modified-since
|
|
26
24
|
if (noneMatch) {
|
|
27
|
-
if (noneMatch === '*')
|
|
25
|
+
if (noneMatch === '*')
|
|
28
26
|
return true;
|
|
29
|
-
}
|
|
30
27
|
const etag = resHeaders.etag;
|
|
31
|
-
if (!etag)
|
|
28
|
+
if (!etag)
|
|
32
29
|
return false;
|
|
33
|
-
}
|
|
34
30
|
const matches = parseTokenList(noneMatch);
|
|
35
31
|
for (let i = 0; i < matches.length; i++) {
|
|
36
32
|
const match = matches[i];
|
|
37
|
-
if (match === etag || match === 'W/' + etag || 'W/' + match === etag)
|
|
33
|
+
if (match === etag || match === 'W/' + etag || 'W/' + match === etag)
|
|
38
34
|
return true;
|
|
39
|
-
}
|
|
40
35
|
}
|
|
41
36
|
return false;
|
|
42
37
|
}
|
|
@@ -44,9 +39,8 @@ export function fresh(reqHeaders, resHeaders) {
|
|
|
44
39
|
if (modifiedSince) {
|
|
45
40
|
const lastModified = resHeaders['last-modified'];
|
|
46
41
|
const modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince));
|
|
47
|
-
if (modifiedStale)
|
|
42
|
+
if (modifiedStale)
|
|
48
43
|
return false;
|
|
49
|
-
}
|
|
50
44
|
}
|
|
51
45
|
return true;
|
|
52
46
|
}
|
|
@@ -75,12 +69,11 @@ export function parseTokenList(str) {
|
|
|
75
69
|
let i = 0, len = str.length;
|
|
76
70
|
for (; i < len; i++) {
|
|
77
71
|
switch (str.charCodeAt(i)) {
|
|
78
|
-
case 0x20
|
|
79
|
-
if (start === end)
|
|
72
|
+
case 0x20 /* */:
|
|
73
|
+
if (start === end)
|
|
80
74
|
start = end = i + 1;
|
|
81
|
-
}
|
|
82
75
|
break;
|
|
83
|
-
case 0x2c
|
|
76
|
+
case 0x2c /* , */:
|
|
84
77
|
list.push(str.substring(start, end));
|
|
85
78
|
start = end = i + 1;
|
|
86
79
|
break;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fresh.js","sourceRoot":"","sources":["../../src/vendors/fresh.ts"],"names":[],"mappings":"AAAA,MAAM,yBAAyB,GAAG,gCAAgC,CAAA;AAElE;;;;;;;GAOG;AAEH,MAAM,UAAU,KAAK,CAAC,UAA+B,EAAE,UAA+B;IACrF,SAAS;IACT,MAAM,aAAa,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAA;IACrD,MAAM,SAAS,GAAG,UAAU,CAAC,eAAe,CAAC,CAAA;IAE7C,wBAAwB;IACxB,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAA;IAE9C,mDAAmD;IACnD,wCAAwC;IACxC,qDAAqD;IACrD,MAAM,YAAY,GAAG,UAAU,CAAC,eAAe,CAAC,CAAA;IAChD,IAAI,YAAY,IAAI,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAA;IAE9E,uDAAuD;IACvD,IAAI,SAAS,EAAE,CAAC;QACf,IAAI,SAAS,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA;QAClC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAA;QAE5B,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAA;QAEvB,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,CAAA;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;YACxB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,KAAK,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAA;QAClF,CAAC;QAED,OAAO,KAAK,CAAA;IACb,CAAC;IAED,oBAAoB;IACpB,IAAI,aAAa,EAAE,CAAC;QACnB,MAAM,YAAY,GAAG,UAAU,CAAC,eAAe,CAAC,CAAA;QAChD,MAAM,aAAa,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC,CAAC,CAAA;QAErG,IAAI,aAAa;YAAE,OAAO,KAAK,CAAA;IAChC,CAAC;IAED,OAAO,IAAI,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AAEH,MAAM,UAAU,aAAa,CAAC,IAAS;IACtC,MAAM,SAAS,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAE1C,kEAAkE;IAClE,OAAO,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAA;AACvD,CAAC;AAED;;;;;GAKG;AAEH,MAAM,UAAU,cAAc,CAAC,GAAW;IACzC,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,gBAAgB;IAChB,IAAI,CAAC,GAAG,CAAC,EACR,GAAG,GAAG,GAAG,CAAC,MAAM,CAAA;IACjB,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACrB,QAAQ,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,OAAO;gBAChB,IAAI,KAAK,KAAK,GAAG;oBAAE,KAAK,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;gBACtC,MAAK;YACN,KAAK,IAAI,CAAC,OAAO;gBAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;gBACpC,KAAK,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;gBACnB,MAAK;YACN;gBACC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;gBACX,MAAK;QACP,CAAC;IACF,CAAC;IAED,cAAc;IACd,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;IAEpC,OAAO,IAAI,CAAA;AACZ,CAAC","sourcesContent":["const cacheControlNoCacheRegexp = /(?:^|,)\\s*?no-cache\\s*?(?:,|$)/\n\n/**\n * Check freshness of the response using request and response headers.\n *\n * @param {Object} reqHeaders\n * @param {Object} resHeaders\n * @return {Boolean}\n * @public\n */\n\nexport function fresh(reqHeaders: Record<string, any>, resHeaders: Record<string, any>) {\n\t// fields\n\tconst modifiedSince = reqHeaders['if-modified-since']\n\tconst noneMatch = reqHeaders['if-none-match']\n\n\t// unconditional request\n\tif (!modifiedSince && !noneMatch) return false\n\n\t// Always return stale when Cache-Control: no-cache\n\t// to support end-to-end reload requests\n\t// https://tools.ietf.org/html/rfc2616#section-14.9.4\n\tconst cacheControl = reqHeaders['cache-control']\n\tif (cacheControl && cacheControlNoCacheRegexp.test(cacheControl)) return false\n\n\t// if-none-match takes precedent over if-modified-since\n\tif (noneMatch) {\n\t\tif (noneMatch === '*') return true\n\t\tconst etag = resHeaders.etag\n\n\t\tif (!etag) return false\n\n\t\tconst matches = parseTokenList(noneMatch)\n\t\tfor (let i = 0; i < matches.length; i++) {\n\t\t\tconst match = matches[i]\n\t\t\tif (match === etag || match === 'W/' + etag || 'W/' + match === etag) return true\n\t\t}\n\n\t\treturn false\n\t}\n\n\t// if-modified-since\n\tif (modifiedSince) {\n\t\tconst lastModified = resHeaders['last-modified']\n\t\tconst modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince))\n\n\t\tif (modifiedStale) return false\n\t}\n\n\treturn true\n}\n\n/**\n * Parse an HTTP Date into a number.\n *\n * @param {string} date\n * @private\n */\n\nexport function parseHttpDate(date: any) {\n\tconst timestamp = date && Date.parse(date)\n\n\t// istanbul ignore next: guard against date.js Date.parse patching\n\treturn typeof timestamp === 'number' ? timestamp : NaN\n}\n\n/**\n * Parse a HTTP token list.\n *\n * @param {string} str\n * @private\n */\n\nexport function parseTokenList(str: string) {\n\tlet end = 0\n\tconst list: string[] = []\n\tlet start = 0\n\n\t// gather tokens\n\tlet i = 0,\n\t\tlen = str.length\n\tfor (; i < len; i++) {\n\t\tswitch (str.charCodeAt(i)) {\n\t\t\tcase 0x20 /* */:\n\t\t\t\tif (start === end) start = end = i + 1\n\t\t\t\tbreak\n\t\t\tcase 0x2c /* , */:\n\t\t\t\tlist.push(str.substring(start, end))\n\t\t\t\tstart = end = i + 1\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tend = i + 1\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\t// final token\n\tlist.push(str.substring(start, end))\n\n\treturn list\n}\n"]}
|
package/lib/vendors/mime.js
CHANGED
|
@@ -21,15 +21,15 @@ export function contentTypeForExtension(extension) {
|
|
|
21
21
|
}
|
|
22
22
|
return mimeType;
|
|
23
23
|
}
|
|
24
|
-
const
|
|
25
|
-
const
|
|
24
|
+
const extractTypeRegexp = /^\s*([^;\s]*)(?:;|\s|$)/;
|
|
25
|
+
const textTypeRegexp = /^text\//i;
|
|
26
26
|
function determineCharset(type) {
|
|
27
27
|
// _TODO: use media-typer
|
|
28
|
-
const match =
|
|
28
|
+
const match = extractTypeRegexp.exec(type);
|
|
29
29
|
const mime = match && mimeDb[match[1].toLowerCase()];
|
|
30
30
|
if (mime?.charset)
|
|
31
31
|
return mime.charset;
|
|
32
32
|
// default text/* to utf-8
|
|
33
|
-
if (match &&
|
|
33
|
+
if (match && textTypeRegexp.test(match[1]))
|
|
34
34
|
return 'UTF-8';
|
|
35
35
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.js","sourceRoot":"","sources":["../../src/vendors/mime.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AAExC,MAAM,MAAM,GAQR,SAAS,CAAA;AAEb,MAAM,eAAe,GAAuC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AAE/E,KAAK,MAAM,CAAC,IAAI,EAAE,EAAC,UAAU,GAAG,EAAE,EAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7D,KAAK,MAAM,SAAS,IAAI,UAAU;QACjC,eAAe,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,CAAA;AAEzF,SAAS,aAAa,CAAC,GAAW,EAAE,KAAc,EAAE,KAAc;IACjE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACjE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEjE,OAAO,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAA;AACvC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACxD,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAA;IACzD,IAAI,CAAC,QAAQ;QAAE,OAAM;IACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAA;QAC1C,IAAI,OAAO;YAAE,OAAO,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;IACpE,CAAC;IACD,OAAO,QAAQ,CAAA;AAChB,CAAC;AAED,MAAM,iBAAiB,GAAG,yBAAyB,CAAA;AACnD,MAAM,cAAc,GAAG,UAAU,CAAA;AAEjC,SAAS,gBAAgB,CAAC,IAAY;IACrC,yBAAyB;IACzB,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;IAEpD,IAAI,IAAI,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC,OAAO,CAAA;IAEtC,0BAA0B;IAC1B,IAAI,KAAK,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAA;AAC3D,CAAC","sourcesContent":["import mimeDbRaw from './mimeDb.js'\nimport {mimeScore} from './mimeScore.js'\n\nconst mimeDb: Record<\n\tstring,\n\t{\n\t\tsource?: string\n\t\tcharset?: string\n\t\tcompressible?: boolean\n\t\textensions?: string[]\n\t}\n> = mimeDbRaw\n\nconst extensionToMime: Record<string, string | undefined> = Object.create(null)\n\nfor (const [type, {extensions = []}] of Object.entries(mimeDb))\n\tfor (const extension of extensions)\n\t\textensionToMime[extension] = preferredType(extension, type, extensionToMime[extension])\n\nfunction preferredType(ext: string, type0?: string, type1?: string) {\n\tconst score0 = type0 ? mimeScore(type0, mimeDb[type0].source) : 0\n\tconst score1 = type1 ? mimeScore(type1, mimeDb[type1].source) : 0\n\n\treturn score0 > score1 ? type0 : type1\n}\n\nexport function contentTypeForExtension(extension: string) {\n\tconst mimeType = extensionToMime[extension.toLowerCase()]\n\tif (!mimeType) return\n\tif (!mimeType.includes('charset')) {\n\t\tconst charset = determineCharset(mimeType)\n\t\tif (charset) return mimeType + '; charset=' + charset.toLowerCase()\n\t}\n\treturn mimeType\n}\n\nconst extractTypeRegexp = /^\\s*([^;\\s]*)(?:;|\\s|$)/\nconst textTypeRegexp = /^text\\//i\n\nfunction determineCharset(type: string) {\n\t// _TODO: use media-typer\n\tconst match = extractTypeRegexp.exec(type)\n\tconst mime = match && mimeDb[match[1].toLowerCase()]\n\n\tif (mime?.charset) return mime.charset\n\n\t// default text/* to utf-8\n\tif (match && textTypeRegexp.test(match[1])) return 'UTF-8'\n}\n"]}
|