@depup/type-is 2.0.1-depup.0 → 3.0.0-depup.0
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 +3 -9
- package/changes.json +3 -8
- package/dist/index.d.ts +63 -0
- package/dist/index.js +170 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -49
- package/HISTORY.md +0 -292
- package/index.js +0 -250
package/README.md
CHANGED
|
@@ -13,16 +13,10 @@ npm install @depup/type-is
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [type-is](https://www.npmjs.com/package/type-is) @
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [type-is](https://www.npmjs.com/package/type-is) @ 3.0.0 |
|
|
17
|
+
| Processed | 2026-09-27 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
|
-
| Deps updated |
|
|
20
|
-
|
|
21
|
-
## Dependency Changes
|
|
22
|
-
|
|
23
|
-
| Dependency | From | To |
|
|
24
|
-
|------------|------|-----|
|
|
25
|
-
| mime-types | ^3.0.0 | ^3.0.2 |
|
|
19
|
+
| Deps updated | 0 |
|
|
26
20
|
|
|
27
21
|
---
|
|
28
22
|
|
package/changes.json
CHANGED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* type-is
|
|
3
|
+
* Copyright(c) 2014 Jonathan Ong
|
|
4
|
+
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
|
5
|
+
* MIT Licensed
|
|
6
|
+
*/
|
|
7
|
+
import { ContentType } from "content-type";
|
|
8
|
+
/**
|
|
9
|
+
* Node.js HTTP request shape.
|
|
10
|
+
*/
|
|
11
|
+
export interface RequestLike {
|
|
12
|
+
headers: Record<string, string | string[] | undefined>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check if a request has a request body. A request with a body must either have
|
|
16
|
+
* `transfer-encoding` or `content-length` headers set.
|
|
17
|
+
*/
|
|
18
|
+
export declare function hasBody(req: RequestLike): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* The default behavior of `lookup` handles only a few common shorthands.
|
|
21
|
+
*/
|
|
22
|
+
export declare function DEFAULT_LOOKUP(value: string): string | string[] | undefined;
|
|
23
|
+
export interface NormalizeOptions {
|
|
24
|
+
lookup?: (value: string) => string | string[] | undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Normalize MIME type by:
|
|
28
|
+
*
|
|
29
|
+
* - If the string contains a `/`, then it is returned as the type.
|
|
30
|
+
* - If the string starts with `+` (so it is a `+suffix` shorthand like `+json`), then it is expanded to contain the complete wildcard notation of `*\/*+suffix`.
|
|
31
|
+
* - Else the string is assumed to be a file extension and the mapped media type is returned, or the original input if there is no mapping.
|
|
32
|
+
*/
|
|
33
|
+
export declare function normalize(value: string, options?: NormalizeOptions): string | string[];
|
|
34
|
+
/**
|
|
35
|
+
* Compile an expected mime type into a reusable matcher.
|
|
36
|
+
*/
|
|
37
|
+
export declare function match(expected: string): (actual: string) => boolean;
|
|
38
|
+
export type ParameterValue = (key: string, value: string) => string;
|
|
39
|
+
/**
|
|
40
|
+
* Normalize a parameter value for comparison.
|
|
41
|
+
*/
|
|
42
|
+
export declare function DEFAULT_PARAMETER_VALUE(key: string, value: string): string;
|
|
43
|
+
export interface TypeIsOptions extends NormalizeOptions {
|
|
44
|
+
parameterValue?: ParameterValue;
|
|
45
|
+
}
|
|
46
|
+
export declare class TypeIs {
|
|
47
|
+
private readonly hasParameters;
|
|
48
|
+
private readonly patterns;
|
|
49
|
+
private readonly parameterValue;
|
|
50
|
+
/**
|
|
51
|
+
* Compile a list of expected mime types into a reusable matcher.
|
|
52
|
+
*/
|
|
53
|
+
constructor(types: readonly string[], options?: TypeIsOptions);
|
|
54
|
+
/**
|
|
55
|
+
* Check whether a content type matches one of the configured types.
|
|
56
|
+
*/
|
|
57
|
+
is(value: string): string | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Check whether a request body matches one of the configured types.
|
|
60
|
+
*/
|
|
61
|
+
request(req: RequestLike): string | undefined;
|
|
62
|
+
contentType(contentType: Pick<ContentType, "type" | "parameters">): string | undefined;
|
|
63
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* type-is
|
|
3
|
+
* Copyright(c) 2014 Jonathan Ong
|
|
4
|
+
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
|
5
|
+
* MIT Licensed
|
|
6
|
+
*/
|
|
7
|
+
import { parse, isTypeValid, isTokenValid } from "content-type";
|
|
8
|
+
/**
|
|
9
|
+
* Check if a request has a request body. A request with a body must either have
|
|
10
|
+
* `transfer-encoding` or `content-length` headers set.
|
|
11
|
+
*/
|
|
12
|
+
export function hasBody(req) {
|
|
13
|
+
return (req.headers["transfer-encoding"] !== undefined ||
|
|
14
|
+
!Number.isNaN(Number(req.headers["content-length"])));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The default behavior of `lookup` handles only a few common shorthands.
|
|
18
|
+
*/
|
|
19
|
+
export function DEFAULT_LOOKUP(value) {
|
|
20
|
+
switch (value) {
|
|
21
|
+
case "urlencoded":
|
|
22
|
+
return "application/x-www-form-urlencoded";
|
|
23
|
+
case "multipart":
|
|
24
|
+
return "multipart/*";
|
|
25
|
+
case "json":
|
|
26
|
+
return "application/json";
|
|
27
|
+
default:
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Normalize MIME type by:
|
|
33
|
+
*
|
|
34
|
+
* - If the string contains a `/`, then it is returned as the type.
|
|
35
|
+
* - If the string starts with `+` (so it is a `+suffix` shorthand like `+json`), then it is expanded to contain the complete wildcard notation of `*\/*+suffix`.
|
|
36
|
+
* - Else the string is assumed to be a file extension and the mapped media type is returned, or the original input if there is no mapping.
|
|
37
|
+
*/
|
|
38
|
+
export function normalize(value, options) {
|
|
39
|
+
if (value.includes("/"))
|
|
40
|
+
return value;
|
|
41
|
+
if (value.startsWith("+"))
|
|
42
|
+
return `*/*${value}`;
|
|
43
|
+
const lookup = options?.lookup ?? DEFAULT_LOOKUP;
|
|
44
|
+
return lookup(value) ?? value;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Compile an expected mime type into a reusable matcher.
|
|
48
|
+
*/
|
|
49
|
+
export function match(expected) {
|
|
50
|
+
const expectedSlash = expected.indexOf("/");
|
|
51
|
+
if (expectedSlash === -1 || !isTypeValid(expected)) {
|
|
52
|
+
throw new TypeError(`Invalid mime type: ${expected}`);
|
|
53
|
+
}
|
|
54
|
+
const type = expected.slice(0, expectedSlash);
|
|
55
|
+
let subtype = expected.slice(expectedSlash + 1);
|
|
56
|
+
let suffix = "";
|
|
57
|
+
if (subtype.startsWith("*+")) {
|
|
58
|
+
suffix = subtype.slice(1);
|
|
59
|
+
subtype = "*";
|
|
60
|
+
}
|
|
61
|
+
if (type === "*" && subtype === "*") {
|
|
62
|
+
if (!suffix)
|
|
63
|
+
return (actual) => isTypeValid(actual);
|
|
64
|
+
return (actual) => {
|
|
65
|
+
return (actual.charAt(actual.length - suffix.length - 1) !== "/" &&
|
|
66
|
+
actual.endsWith(suffix) &&
|
|
67
|
+
isTypeValid(actual));
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (type === "*") {
|
|
71
|
+
return (actual) => {
|
|
72
|
+
return (actual.charAt(actual.length - subtype.length - 1) === "/" &&
|
|
73
|
+
actual.endsWith(subtype) &&
|
|
74
|
+
isTokenValid(actual, 0, actual.length - subtype.length - 1));
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (subtype === "*") {
|
|
78
|
+
return (actual) => {
|
|
79
|
+
return (actual.charAt(type.length) === "/" &&
|
|
80
|
+
actual.startsWith(type) &&
|
|
81
|
+
actual.endsWith(suffix) &&
|
|
82
|
+
isTokenValid(actual, type.length + 1, actual.length - suffix.length));
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return (actual) => actual === expected;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Normalize a parameter value for comparison.
|
|
89
|
+
*/
|
|
90
|
+
export function DEFAULT_PARAMETER_VALUE(key, value) {
|
|
91
|
+
if (key === "charset")
|
|
92
|
+
return value.toLowerCase();
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
export class TypeIs {
|
|
96
|
+
hasParameters = false;
|
|
97
|
+
patterns = [];
|
|
98
|
+
parameterValue;
|
|
99
|
+
/**
|
|
100
|
+
* Compile a list of expected mime types into a reusable matcher.
|
|
101
|
+
*/
|
|
102
|
+
constructor(types, options) {
|
|
103
|
+
this.parameterValue = options?.parameterValue ?? DEFAULT_PARAMETER_VALUE;
|
|
104
|
+
for (const key of types) {
|
|
105
|
+
const contentType = parse(key);
|
|
106
|
+
const hasParameters = Object.keys(contentType.parameters).length > 0;
|
|
107
|
+
const type = normalize(contentType.type, options);
|
|
108
|
+
const parameters = contentType.parameters;
|
|
109
|
+
// Normalize parameter values before comparison.
|
|
110
|
+
for (const key of Object.keys(parameters)) {
|
|
111
|
+
parameters[key] = this.parameterValue(key, parameters[key]);
|
|
112
|
+
}
|
|
113
|
+
this.hasParameters ||= hasParameters;
|
|
114
|
+
if (Array.isArray(type)) {
|
|
115
|
+
for (const t of type) {
|
|
116
|
+
this.patterns.push({
|
|
117
|
+
key,
|
|
118
|
+
match: match(t),
|
|
119
|
+
parameters,
|
|
120
|
+
hasParameters,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this.patterns.push({
|
|
126
|
+
key,
|
|
127
|
+
match: match(type),
|
|
128
|
+
parameters,
|
|
129
|
+
hasParameters,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check whether a content type matches one of the configured types.
|
|
136
|
+
*/
|
|
137
|
+
is(value) {
|
|
138
|
+
const contentType = parse(value, { parameters: this.hasParameters });
|
|
139
|
+
return this.contentType(contentType);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Check whether a request body matches one of the configured types.
|
|
143
|
+
*/
|
|
144
|
+
request(req) {
|
|
145
|
+
if (!hasBody(req))
|
|
146
|
+
return;
|
|
147
|
+
const header = req.headers["content-type"];
|
|
148
|
+
if (!header)
|
|
149
|
+
return;
|
|
150
|
+
const value = Array.isArray(header) ? header[0] : header;
|
|
151
|
+
return this.is(value);
|
|
152
|
+
}
|
|
153
|
+
contentType(contentType) {
|
|
154
|
+
for (const pattern of this.patterns) {
|
|
155
|
+
if (pattern.match(contentType.type)) {
|
|
156
|
+
const parametersMatch = !pattern.hasParameters ||
|
|
157
|
+
Object.keys(pattern.parameters).every((key) => {
|
|
158
|
+
const actual = contentType.parameters[key];
|
|
159
|
+
if (actual === undefined)
|
|
160
|
+
return false;
|
|
161
|
+
const expected = pattern.parameters[key];
|
|
162
|
+
return expected === this.parameterValue(key, actual);
|
|
163
|
+
});
|
|
164
|
+
if (parametersMatch)
|
|
165
|
+
return pattern.key;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * type-is\n * Copyright(c) 2014 Jonathan Ong\n * Copyright(c) 2014-2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\nimport { parse, isTypeValid, isTokenValid, ContentType } from \"content-type\";\n\n/**\n * Node.js HTTP request shape.\n */\nexport interface RequestLike {\n headers: Record<string, string | string[] | undefined>;\n}\n\n/**\n * Check if a request has a request body. A request with a body must either have\n * `transfer-encoding` or `content-length` headers set.\n */\nexport function hasBody(req: RequestLike): boolean {\n return (\n req.headers[\"transfer-encoding\"] !== undefined ||\n !Number.isNaN(Number(req.headers[\"content-length\"]))\n );\n}\n\n/**\n * The default behavior of `lookup` handles only a few common shorthands.\n */\nexport function DEFAULT_LOOKUP(value: string): string | string[] | undefined {\n switch (value) {\n case \"urlencoded\":\n return \"application/x-www-form-urlencoded\";\n case \"multipart\":\n return \"multipart/*\";\n case \"json\":\n return \"application/json\";\n default:\n return undefined;\n }\n}\n\nexport interface NormalizeOptions {\n lookup?: (value: string) => string | string[] | undefined;\n}\n\n/**\n * Normalize MIME type by:\n *\n * - If the string contains a `/`, then it is returned as the type.\n * - If the string starts with `+` (so it is a `+suffix` shorthand like `+json`), then it is expanded to contain the complete wildcard notation of `*\\/*+suffix`.\n * - Else the string is assumed to be a file extension and the mapped media type is returned, or the original input if there is no mapping.\n */\nexport function normalize(\n value: string,\n options?: NormalizeOptions,\n): string | string[] {\n if (value.includes(\"/\")) return value;\n if (value.startsWith(\"+\")) return `*/*${value}`;\n const lookup = options?.lookup ?? DEFAULT_LOOKUP;\n return lookup(value) ?? value;\n}\n\n/**\n * Compile an expected mime type into a reusable matcher.\n */\nexport function match(expected: string): (actual: string) => boolean {\n const expectedSlash = expected.indexOf(\"/\");\n\n if (expectedSlash === -1 || !isTypeValid(expected)) {\n throw new TypeError(`Invalid mime type: ${expected}`);\n }\n\n const type = expected.slice(0, expectedSlash);\n let subtype = expected.slice(expectedSlash + 1);\n let suffix = \"\";\n\n if (subtype.startsWith(\"*+\")) {\n suffix = subtype.slice(1);\n subtype = \"*\";\n }\n\n if (type === \"*\" && subtype === \"*\") {\n if (!suffix) return (actual: string) => isTypeValid(actual);\n\n return (actual: string) => {\n return (\n actual.charAt(actual.length - suffix.length - 1) !== \"/\" &&\n actual.endsWith(suffix) &&\n isTypeValid(actual)\n );\n };\n }\n\n if (type === \"*\") {\n return (actual: string) => {\n return (\n actual.charAt(actual.length - subtype.length - 1) === \"/\" &&\n actual.endsWith(subtype) &&\n isTokenValid(actual, 0, actual.length - subtype.length - 1)\n );\n };\n }\n\n if (subtype === \"*\") {\n return (actual: string) => {\n return (\n actual.charAt(type.length) === \"/\" &&\n actual.startsWith(type) &&\n actual.endsWith(suffix) &&\n isTokenValid(actual, type.length + 1, actual.length - suffix.length)\n );\n };\n }\n\n return (actual: string): boolean => actual === expected;\n}\n\ninterface Pattern {\n key: string;\n match: (value: string) => boolean;\n parameters: Record<string, string>;\n hasParameters: boolean;\n}\n\nexport type ParameterValue = (key: string, value: string) => string;\n\n/**\n * Normalize a parameter value for comparison.\n */\nexport function DEFAULT_PARAMETER_VALUE(key: string, value: string): string {\n if (key === \"charset\") return value.toLowerCase();\n return value;\n}\n\nexport interface TypeIsOptions extends NormalizeOptions {\n parameterValue?: ParameterValue;\n}\n\nexport class TypeIs {\n private readonly hasParameters: boolean = false;\n private readonly patterns: Pattern[] = [];\n private readonly parameterValue: ParameterValue;\n\n /**\n * Compile a list of expected mime types into a reusable matcher.\n */\n constructor(types: readonly string[], options?: TypeIsOptions) {\n this.parameterValue = options?.parameterValue ?? DEFAULT_PARAMETER_VALUE;\n\n for (const key of types) {\n const contentType = parse(key);\n const hasParameters = Object.keys(contentType.parameters).length > 0;\n const type = normalize(contentType.type, options);\n const parameters = contentType.parameters;\n\n // Normalize parameter values before comparison.\n for (const key of Object.keys(parameters)) {\n parameters[key] = this.parameterValue(key, parameters[key]);\n }\n\n this.hasParameters ||= hasParameters;\n\n if (Array.isArray(type)) {\n for (const t of type) {\n this.patterns.push({\n key,\n match: match(t),\n parameters,\n hasParameters,\n });\n }\n } else {\n this.patterns.push({\n key,\n match: match(type),\n parameters,\n hasParameters,\n });\n }\n }\n }\n\n /**\n * Check whether a content type matches one of the configured types.\n */\n is(value: string): string | undefined {\n const contentType = parse(value, { parameters: this.hasParameters });\n return this.contentType(contentType);\n }\n\n /**\n * Check whether a request body matches one of the configured types.\n */\n request(req: RequestLike): string | undefined {\n if (!hasBody(req)) return;\n const header = req.headers[\"content-type\"];\n if (!header) return;\n const value = Array.isArray(header) ? header[0] : header;\n return this.is(value);\n }\n\n contentType(\n contentType: Pick<ContentType, \"type\" | \"parameters\">,\n ): string | undefined {\n for (const pattern of this.patterns) {\n if (pattern.match(contentType.type)) {\n const parametersMatch =\n !pattern.hasParameters ||\n Object.keys(pattern.parameters).every((key) => {\n const actual = contentType.parameters[key];\n if (actual === undefined) return false;\n const expected = pattern.parameters[key];\n return expected === this.parameterValue(key, actual);\n });\n\n if (parametersMatch) return pattern.key;\n }\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,46 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/type-is",
|
|
3
|
+
"version": "3.0.0-depup.0",
|
|
3
4
|
"description": "Infer the content-type of a request. (with updated dependencies)",
|
|
4
|
-
"version": "2.0.1-depup.0",
|
|
5
|
-
"contributors": [
|
|
6
|
-
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
|
7
|
-
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
|
8
|
-
],
|
|
9
|
-
"license": "MIT",
|
|
10
|
-
"repository": "jshttp/type-is",
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"content-type": "^1.0.5",
|
|
13
|
-
"media-typer": "^1.1.0",
|
|
14
|
-
"mime-types": "^3.0.2"
|
|
15
|
-
},
|
|
16
|
-
"devDependencies": {
|
|
17
|
-
"eslint": "7.32.0",
|
|
18
|
-
"eslint-config-standard": "14.1.1",
|
|
19
|
-
"eslint-plugin-import": "2.25.4",
|
|
20
|
-
"eslint-plugin-markdown": "2.2.1",
|
|
21
|
-
"eslint-plugin-node": "11.1.0",
|
|
22
|
-
"eslint-plugin-promise": "5.2.0",
|
|
23
|
-
"eslint-plugin-standard": "4.1.0",
|
|
24
|
-
"mocha": "9.2.1",
|
|
25
|
-
"nyc": "15.1.0"
|
|
26
|
-
},
|
|
27
|
-
"engines": {
|
|
28
|
-
"node": ">= 0.6"
|
|
29
|
-
},
|
|
30
|
-
"files": [
|
|
31
|
-
"LICENSE",
|
|
32
|
-
"HISTORY.md",
|
|
33
|
-
"index.js",
|
|
34
|
-
"changes.json",
|
|
35
|
-
"README.md"
|
|
36
|
-
],
|
|
37
|
-
"scripts": {
|
|
38
|
-
"lint": "eslint .",
|
|
39
|
-
"test": "mocha --reporter spec --check-leaks --bail test/",
|
|
40
|
-
"test:debug": "mocha --reporter spec --check-leaks --inspect --inspect-brk test/",
|
|
41
|
-
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
|
|
42
|
-
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
|
43
|
-
},
|
|
44
5
|
"keywords": [
|
|
45
6
|
"type-is",
|
|
46
7
|
"depup",
|
|
@@ -52,17 +13,59 @@
|
|
|
52
13
|
"type",
|
|
53
14
|
"checking"
|
|
54
15
|
],
|
|
16
|
+
"repository": "jshttp/type-is",
|
|
17
|
+
"funding": {
|
|
18
|
+
"type": "opencollective",
|
|
19
|
+
"url": "https://opencollective.com/express"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"contributors": [
|
|
23
|
+
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
|
24
|
+
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
|
25
|
+
],
|
|
26
|
+
"type": "module",
|
|
27
|
+
"exports": "./dist/index.js",
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"typings": "./dist/index.d.ts",
|
|
30
|
+
"files": [
|
|
31
|
+
"dist/",
|
|
32
|
+
"changes.json",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"bench": "vitest bench",
|
|
37
|
+
"build": "ts-scripts build",
|
|
38
|
+
"format": "ts-scripts format",
|
|
39
|
+
"specs": "ts-scripts specs",
|
|
40
|
+
"test": "ts-scripts test"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"content-type": "^3.1.1"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@borderless/ts-scripts": "^0.15.0",
|
|
47
|
+
"@types/node": "^22.13.10",
|
|
48
|
+
"@vitest/coverage-v8": "^5.0.1",
|
|
49
|
+
"typescript": "^7.0.2",
|
|
50
|
+
"vitest": "^5.0.1"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">= 22"
|
|
54
|
+
},
|
|
55
|
+
"ts-scripts": {
|
|
56
|
+
"dist": [
|
|
57
|
+
"dist"
|
|
58
|
+
],
|
|
59
|
+
"project": [
|
|
60
|
+
"tsconfig.build.json"
|
|
61
|
+
]
|
|
62
|
+
},
|
|
55
63
|
"depup": {
|
|
56
|
-
"changes": {
|
|
57
|
-
|
|
58
|
-
"from": "^3.0.0",
|
|
59
|
-
"to": "^3.0.2"
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"depsUpdated": 1,
|
|
64
|
+
"changes": {},
|
|
65
|
+
"depsUpdated": 0,
|
|
63
66
|
"originalPackage": "type-is",
|
|
64
|
-
"originalVersion": "
|
|
65
|
-
"processedAt": "2026-
|
|
67
|
+
"originalVersion": "3.0.0",
|
|
68
|
+
"processedAt": "2026-09-27T01:04:22.945Z",
|
|
66
69
|
"smokeTest": "passed"
|
|
67
70
|
}
|
|
68
71
|
}
|
package/HISTORY.md
DELETED
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
2.0.1 / 2025-03-27
|
|
2
|
-
==========
|
|
3
|
-
|
|
4
|
-
2.0.0 / 2024-08-31
|
|
5
|
-
==========
|
|
6
|
-
|
|
7
|
-
* Drop node <18
|
|
8
|
-
* Use `content-type@^1.0.5` and `media-typer@^1.0.0` for type validation
|
|
9
|
-
- No behavior changes, upgrades `media-typer`
|
|
10
|
-
* deps: mime-types@^3.0.0
|
|
11
|
-
- Add `application/toml` with extension `.toml`
|
|
12
|
-
- Add `application/ubjson` with extension `.ubj`
|
|
13
|
-
- Add `application/x-keepass2` with extension `.kdbx`
|
|
14
|
-
- Add deprecated iWorks mime types and extensions
|
|
15
|
-
- Add extension `.amr` to `audio/amr`
|
|
16
|
-
- Add extension `.cjs` to `application/node`
|
|
17
|
-
- Add extension `.dbf` to `application/vnd.dbf`
|
|
18
|
-
- Add extension `.m4s` to `video/iso.segment`
|
|
19
|
-
- Add extension `.mvt` to `application/vnd.mapbox-vector-tile`
|
|
20
|
-
- Add extension `.mxmf` to `audio/mobile-xmf`
|
|
21
|
-
- Add extension `.opus` to `audio/ogg`
|
|
22
|
-
- Add extension `.rar` to `application/vnd.rar`
|
|
23
|
-
- Add extension `.td` to `application/urc-targetdesc+xml`
|
|
24
|
-
- Add extension `.trig` to `application/trig`
|
|
25
|
-
- Add extensions from IANA for `application/*+xml` types
|
|
26
|
-
- Add `image/avif` with extension `.avif`
|
|
27
|
-
- Add `image/ktx2` with extension `.ktx2`
|
|
28
|
-
- Add `image/vnd.ms-dds` with extension `.dds`
|
|
29
|
-
- Add new upstream MIME types
|
|
30
|
-
- Fix extension of `application/vnd.apple.keynote` to be `.key`
|
|
31
|
-
- Remove ambigious extensions from IANA for `application/*+xml` types
|
|
32
|
-
- Update primary extension to `.es` for `application/ecmascript`
|
|
33
|
-
|
|
34
|
-
1.6.18 / 2019-04-26
|
|
35
|
-
===================
|
|
36
|
-
|
|
37
|
-
* Fix regression passing request object to `typeis.is`
|
|
38
|
-
|
|
39
|
-
1.6.17 / 2019-04-25
|
|
40
|
-
===================
|
|
41
|
-
|
|
42
|
-
* deps: mime-types@~2.1.24
|
|
43
|
-
- Add Apple file extensions from IANA
|
|
44
|
-
- Add extension `.csl` to `application/vnd.citationstyles.style+xml`
|
|
45
|
-
- Add extension `.es` to `application/ecmascript`
|
|
46
|
-
- Add extension `.nq` to `application/n-quads`
|
|
47
|
-
- Add extension `.nt` to `application/n-triples`
|
|
48
|
-
- Add extension `.owl` to `application/rdf+xml`
|
|
49
|
-
- Add extensions `.siv` and `.sieve` to `application/sieve`
|
|
50
|
-
- Add extensions from IANA for `image/*` types
|
|
51
|
-
- Add extensions from IANA for `model/*` types
|
|
52
|
-
- Add extensions to HEIC image types
|
|
53
|
-
- Add new mime types
|
|
54
|
-
- Add `text/mdx` with extension `.mdx`
|
|
55
|
-
* perf: prevent internal `throw` on invalid type
|
|
56
|
-
|
|
57
|
-
1.6.16 / 2018-02-16
|
|
58
|
-
===================
|
|
59
|
-
|
|
60
|
-
* deps: mime-types@~2.1.18
|
|
61
|
-
- Add `application/raml+yaml` with extension `.raml`
|
|
62
|
-
- Add `application/wasm` with extension `.wasm`
|
|
63
|
-
- Add `text/shex` with extension `.shex`
|
|
64
|
-
- Add extensions for JPEG-2000 images
|
|
65
|
-
- Add extensions from IANA for `message/*` types
|
|
66
|
-
- Add extension `.mjs` to `application/javascript`
|
|
67
|
-
- Add extension `.wadl` to `application/vnd.sun.wadl+xml`
|
|
68
|
-
- Add extension `.gz` to `application/gzip`
|
|
69
|
-
- Add glTF types and extensions
|
|
70
|
-
- Add new mime types
|
|
71
|
-
- Update extensions `.md` and `.markdown` to be `text/markdown`
|
|
72
|
-
- Update font MIME types
|
|
73
|
-
- Update `text/hjson` to registered `application/hjson`
|
|
74
|
-
|
|
75
|
-
1.6.15 / 2017-03-31
|
|
76
|
-
===================
|
|
77
|
-
|
|
78
|
-
* deps: mime-types@~2.1.15
|
|
79
|
-
- Add new mime types
|
|
80
|
-
|
|
81
|
-
1.6.14 / 2016-11-18
|
|
82
|
-
===================
|
|
83
|
-
|
|
84
|
-
* deps: mime-types@~2.1.13
|
|
85
|
-
- Add new mime types
|
|
86
|
-
|
|
87
|
-
1.6.13 / 2016-05-18
|
|
88
|
-
===================
|
|
89
|
-
|
|
90
|
-
* deps: mime-types@~2.1.11
|
|
91
|
-
- Add new mime types
|
|
92
|
-
|
|
93
|
-
1.6.12 / 2016-02-28
|
|
94
|
-
===================
|
|
95
|
-
|
|
96
|
-
* deps: mime-types@~2.1.10
|
|
97
|
-
- Add new mime types
|
|
98
|
-
- Fix extension of `application/dash+xml`
|
|
99
|
-
- Update primary extension for `audio/mp4`
|
|
100
|
-
|
|
101
|
-
1.6.11 / 2016-01-29
|
|
102
|
-
===================
|
|
103
|
-
|
|
104
|
-
* deps: mime-types@~2.1.9
|
|
105
|
-
- Add new mime types
|
|
106
|
-
|
|
107
|
-
1.6.10 / 2015-12-01
|
|
108
|
-
===================
|
|
109
|
-
|
|
110
|
-
* deps: mime-types@~2.1.8
|
|
111
|
-
- Add new mime types
|
|
112
|
-
|
|
113
|
-
1.6.9 / 2015-09-27
|
|
114
|
-
==================
|
|
115
|
-
|
|
116
|
-
* deps: mime-types@~2.1.7
|
|
117
|
-
- Add new mime types
|
|
118
|
-
|
|
119
|
-
1.6.8 / 2015-09-04
|
|
120
|
-
==================
|
|
121
|
-
|
|
122
|
-
* deps: mime-types@~2.1.6
|
|
123
|
-
- Add new mime types
|
|
124
|
-
|
|
125
|
-
1.6.7 / 2015-08-20
|
|
126
|
-
==================
|
|
127
|
-
|
|
128
|
-
* Fix type error when given invalid type to match against
|
|
129
|
-
* deps: mime-types@~2.1.5
|
|
130
|
-
- Add new mime types
|
|
131
|
-
|
|
132
|
-
1.6.6 / 2015-07-31
|
|
133
|
-
==================
|
|
134
|
-
|
|
135
|
-
* deps: mime-types@~2.1.4
|
|
136
|
-
- Add new mime types
|
|
137
|
-
|
|
138
|
-
1.6.5 / 2015-07-16
|
|
139
|
-
==================
|
|
140
|
-
|
|
141
|
-
* deps: mime-types@~2.1.3
|
|
142
|
-
- Add new mime types
|
|
143
|
-
|
|
144
|
-
1.6.4 / 2015-07-01
|
|
145
|
-
==================
|
|
146
|
-
|
|
147
|
-
* deps: mime-types@~2.1.2
|
|
148
|
-
- Add new mime types
|
|
149
|
-
* perf: enable strict mode
|
|
150
|
-
* perf: remove argument reassignment
|
|
151
|
-
|
|
152
|
-
1.6.3 / 2015-06-08
|
|
153
|
-
==================
|
|
154
|
-
|
|
155
|
-
* deps: mime-types@~2.1.1
|
|
156
|
-
- Add new mime types
|
|
157
|
-
* perf: reduce try block size
|
|
158
|
-
* perf: remove bitwise operations
|
|
159
|
-
|
|
160
|
-
1.6.2 / 2015-05-10
|
|
161
|
-
==================
|
|
162
|
-
|
|
163
|
-
* deps: mime-types@~2.0.11
|
|
164
|
-
- Add new mime types
|
|
165
|
-
|
|
166
|
-
1.6.1 / 2015-03-13
|
|
167
|
-
==================
|
|
168
|
-
|
|
169
|
-
* deps: mime-types@~2.0.10
|
|
170
|
-
- Add new mime types
|
|
171
|
-
|
|
172
|
-
1.6.0 / 2015-02-12
|
|
173
|
-
==================
|
|
174
|
-
|
|
175
|
-
* fix false-positives in `hasBody` `Transfer-Encoding` check
|
|
176
|
-
* support wildcard for both type and subtype (`*/*`)
|
|
177
|
-
|
|
178
|
-
1.5.7 / 2015-02-09
|
|
179
|
-
==================
|
|
180
|
-
|
|
181
|
-
* fix argument reassignment
|
|
182
|
-
* deps: mime-types@~2.0.9
|
|
183
|
-
- Add new mime types
|
|
184
|
-
|
|
185
|
-
1.5.6 / 2015-01-29
|
|
186
|
-
==================
|
|
187
|
-
|
|
188
|
-
* deps: mime-types@~2.0.8
|
|
189
|
-
- Add new mime types
|
|
190
|
-
|
|
191
|
-
1.5.5 / 2014-12-30
|
|
192
|
-
==================
|
|
193
|
-
|
|
194
|
-
* deps: mime-types@~2.0.7
|
|
195
|
-
- Add new mime types
|
|
196
|
-
- Fix missing extensions
|
|
197
|
-
- Fix various invalid MIME type entries
|
|
198
|
-
- Remove example template MIME types
|
|
199
|
-
- deps: mime-db@~1.5.0
|
|
200
|
-
|
|
201
|
-
1.5.4 / 2014-12-10
|
|
202
|
-
==================
|
|
203
|
-
|
|
204
|
-
* deps: mime-types@~2.0.4
|
|
205
|
-
- Add new mime types
|
|
206
|
-
- deps: mime-db@~1.3.0
|
|
207
|
-
|
|
208
|
-
1.5.3 / 2014-11-09
|
|
209
|
-
==================
|
|
210
|
-
|
|
211
|
-
* deps: mime-types@~2.0.3
|
|
212
|
-
- Add new mime types
|
|
213
|
-
- deps: mime-db@~1.2.0
|
|
214
|
-
|
|
215
|
-
1.5.2 / 2014-09-28
|
|
216
|
-
==================
|
|
217
|
-
|
|
218
|
-
* deps: mime-types@~2.0.2
|
|
219
|
-
- Add new mime types
|
|
220
|
-
- deps: mime-db@~1.1.0
|
|
221
|
-
|
|
222
|
-
1.5.1 / 2014-09-07
|
|
223
|
-
==================
|
|
224
|
-
|
|
225
|
-
* Support Node.js 0.6
|
|
226
|
-
* deps: media-typer@0.3.0
|
|
227
|
-
* deps: mime-types@~2.0.1
|
|
228
|
-
- Support Node.js 0.6
|
|
229
|
-
|
|
230
|
-
1.5.0 / 2014-09-05
|
|
231
|
-
==================
|
|
232
|
-
|
|
233
|
-
* fix `hasbody` to be true for `content-length: 0`
|
|
234
|
-
|
|
235
|
-
1.4.0 / 2014-09-02
|
|
236
|
-
==================
|
|
237
|
-
|
|
238
|
-
* update mime-types
|
|
239
|
-
|
|
240
|
-
1.3.2 / 2014-06-24
|
|
241
|
-
==================
|
|
242
|
-
|
|
243
|
-
* use `~` range on mime-types
|
|
244
|
-
|
|
245
|
-
1.3.1 / 2014-06-19
|
|
246
|
-
==================
|
|
247
|
-
|
|
248
|
-
* fix global variable leak
|
|
249
|
-
|
|
250
|
-
1.3.0 / 2014-06-19
|
|
251
|
-
==================
|
|
252
|
-
|
|
253
|
-
* improve type parsing
|
|
254
|
-
|
|
255
|
-
- invalid media type never matches
|
|
256
|
-
- media type not case-sensitive
|
|
257
|
-
- extra LWS does not affect results
|
|
258
|
-
|
|
259
|
-
1.2.2 / 2014-06-19
|
|
260
|
-
==================
|
|
261
|
-
|
|
262
|
-
* fix behavior on unknown type argument
|
|
263
|
-
|
|
264
|
-
1.2.1 / 2014-06-03
|
|
265
|
-
==================
|
|
266
|
-
|
|
267
|
-
* switch dependency from `mime` to `mime-types@1.0.0`
|
|
268
|
-
|
|
269
|
-
1.2.0 / 2014-05-11
|
|
270
|
-
==================
|
|
271
|
-
|
|
272
|
-
* support suffix matching:
|
|
273
|
-
|
|
274
|
-
- `+json` matches `application/vnd+json`
|
|
275
|
-
- `*/vnd+json` matches `application/vnd+json`
|
|
276
|
-
- `application/*+json` matches `application/vnd+json`
|
|
277
|
-
|
|
278
|
-
1.1.0 / 2014-04-12
|
|
279
|
-
==================
|
|
280
|
-
|
|
281
|
-
* add non-array values support
|
|
282
|
-
* expose internal utilities:
|
|
283
|
-
|
|
284
|
-
- `.is()`
|
|
285
|
-
- `.hasBody()`
|
|
286
|
-
- `.normalize()`
|
|
287
|
-
- `.match()`
|
|
288
|
-
|
|
289
|
-
1.0.1 / 2014-03-30
|
|
290
|
-
==================
|
|
291
|
-
|
|
292
|
-
* add `multipart` as a shorthand
|
package/index.js
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* type-is
|
|
3
|
-
* Copyright(c) 2014 Jonathan Ong
|
|
4
|
-
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
|
5
|
-
* MIT Licensed
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'use strict'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Module dependencies.
|
|
12
|
-
* @private
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
var contentType = require('content-type')
|
|
16
|
-
var mime = require('mime-types')
|
|
17
|
-
var typer = require('media-typer')
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Module exports.
|
|
21
|
-
* @public
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
module.exports = typeofrequest
|
|
25
|
-
module.exports.is = typeis
|
|
26
|
-
module.exports.hasBody = hasbody
|
|
27
|
-
module.exports.normalize = normalize
|
|
28
|
-
module.exports.match = mimeMatch
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Compare a `value` content-type with `types`.
|
|
32
|
-
* Each `type` can be an extension like `html`,
|
|
33
|
-
* a special shortcut like `multipart` or `urlencoded`,
|
|
34
|
-
* or a mime type.
|
|
35
|
-
*
|
|
36
|
-
* If no types match, `false` is returned.
|
|
37
|
-
* Otherwise, the first `type` that matches is returned.
|
|
38
|
-
*
|
|
39
|
-
* @param {String} value
|
|
40
|
-
* @param {Array} types
|
|
41
|
-
* @public
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
function typeis (value, types_) {
|
|
45
|
-
var i
|
|
46
|
-
var types = types_
|
|
47
|
-
|
|
48
|
-
// remove parameters and normalize
|
|
49
|
-
var val = tryNormalizeType(value)
|
|
50
|
-
|
|
51
|
-
// no type or invalid
|
|
52
|
-
if (!val) {
|
|
53
|
-
return false
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// support flattened arguments
|
|
57
|
-
if (types && !Array.isArray(types)) {
|
|
58
|
-
types = new Array(arguments.length - 1)
|
|
59
|
-
for (i = 0; i < types.length; i++) {
|
|
60
|
-
types[i] = arguments[i + 1]
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// no types, return the content type
|
|
65
|
-
if (!types || !types.length) {
|
|
66
|
-
return val
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
var type
|
|
70
|
-
for (i = 0; i < types.length; i++) {
|
|
71
|
-
if (mimeMatch(normalize(type = types[i]), val)) {
|
|
72
|
-
return type[0] === '+' || type.indexOf('*') !== -1
|
|
73
|
-
? val
|
|
74
|
-
: type
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// no matches
|
|
79
|
-
return false
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Check if a request has a request body.
|
|
84
|
-
* A request with a body __must__ either have `transfer-encoding`
|
|
85
|
-
* or `content-length` headers set.
|
|
86
|
-
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
|
|
87
|
-
*
|
|
88
|
-
* @param {Object} request
|
|
89
|
-
* @return {Boolean}
|
|
90
|
-
* @public
|
|
91
|
-
*/
|
|
92
|
-
|
|
93
|
-
function hasbody (req) {
|
|
94
|
-
return req.headers['transfer-encoding'] !== undefined ||
|
|
95
|
-
!isNaN(req.headers['content-length'])
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Check if the incoming request contains the "Content-Type"
|
|
100
|
-
* header field, and it contains any of the give mime `type`s.
|
|
101
|
-
* If there is no request body, `null` is returned.
|
|
102
|
-
* If there is no content type, `false` is returned.
|
|
103
|
-
* Otherwise, it returns the first `type` that matches.
|
|
104
|
-
*
|
|
105
|
-
* Examples:
|
|
106
|
-
*
|
|
107
|
-
* // With Content-Type: text/html; charset=utf-8
|
|
108
|
-
* this.is('html'); // => 'html'
|
|
109
|
-
* this.is('text/html'); // => 'text/html'
|
|
110
|
-
* this.is('text/*', 'application/json'); // => 'text/html'
|
|
111
|
-
*
|
|
112
|
-
* // When Content-Type is application/json
|
|
113
|
-
* this.is('json', 'urlencoded'); // => 'json'
|
|
114
|
-
* this.is('application/json'); // => 'application/json'
|
|
115
|
-
* this.is('html', 'application/*'); // => 'application/json'
|
|
116
|
-
*
|
|
117
|
-
* this.is('html'); // => false
|
|
118
|
-
*
|
|
119
|
-
* @param {Object} req
|
|
120
|
-
* @param {(String|Array)} types...
|
|
121
|
-
* @return {(String|false|null)}
|
|
122
|
-
* @public
|
|
123
|
-
*/
|
|
124
|
-
|
|
125
|
-
function typeofrequest (req, types_) {
|
|
126
|
-
// no body
|
|
127
|
-
if (!hasbody(req)) return null
|
|
128
|
-
// support flattened arguments
|
|
129
|
-
var types = arguments.length > 2
|
|
130
|
-
? Array.prototype.slice.call(arguments, 1)
|
|
131
|
-
: types_
|
|
132
|
-
// request content type
|
|
133
|
-
var value = req.headers['content-type']
|
|
134
|
-
|
|
135
|
-
return typeis(value, types)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Normalize a mime type.
|
|
140
|
-
* If it's a shorthand, expand it to a valid mime type.
|
|
141
|
-
*
|
|
142
|
-
* In general, you probably want:
|
|
143
|
-
*
|
|
144
|
-
* var type = is(req, ['urlencoded', 'json', 'multipart']);
|
|
145
|
-
*
|
|
146
|
-
* Then use the appropriate body parsers.
|
|
147
|
-
* These three are the most common request body types
|
|
148
|
-
* and are thus ensured to work.
|
|
149
|
-
*
|
|
150
|
-
* @param {String} type
|
|
151
|
-
* @return {String|false|null}
|
|
152
|
-
* @public
|
|
153
|
-
*/
|
|
154
|
-
|
|
155
|
-
function normalize (type) {
|
|
156
|
-
if (typeof type !== 'string') {
|
|
157
|
-
// invalid type
|
|
158
|
-
return false
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
switch (type) {
|
|
162
|
-
case 'urlencoded':
|
|
163
|
-
return 'application/x-www-form-urlencoded'
|
|
164
|
-
case 'multipart':
|
|
165
|
-
return 'multipart/*'
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (type[0] === '+') {
|
|
169
|
-
// "+json" -> "*/*+json" expando
|
|
170
|
-
return '*/*' + type
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return type.indexOf('/') === -1
|
|
174
|
-
? mime.lookup(type)
|
|
175
|
-
: type
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Check if `expected` mime type
|
|
180
|
-
* matches `actual` mime type with
|
|
181
|
-
* wildcard and +suffix support.
|
|
182
|
-
*
|
|
183
|
-
* @param {String} expected
|
|
184
|
-
* @param {String} actual
|
|
185
|
-
* @return {Boolean}
|
|
186
|
-
* @public
|
|
187
|
-
*/
|
|
188
|
-
|
|
189
|
-
function mimeMatch (expected, actual) {
|
|
190
|
-
// invalid type
|
|
191
|
-
if (expected === false) {
|
|
192
|
-
return false
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// split types
|
|
196
|
-
var actualParts = actual.split('/')
|
|
197
|
-
var expectedParts = expected.split('/')
|
|
198
|
-
|
|
199
|
-
// invalid format
|
|
200
|
-
if (actualParts.length !== 2 || expectedParts.length !== 2) {
|
|
201
|
-
return false
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// validate type
|
|
205
|
-
if (expectedParts[0] !== '*' && expectedParts[0] !== actualParts[0]) {
|
|
206
|
-
return false
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// validate suffix wildcard
|
|
210
|
-
if (expectedParts[1].slice(0, 2) === '*+') {
|
|
211
|
-
return expectedParts[1].length <= actualParts[1].length + 1 &&
|
|
212
|
-
expectedParts[1].slice(1) === actualParts[1].slice(1 - expectedParts[1].length)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// validate subtype
|
|
216
|
-
if (expectedParts[1] !== '*' && expectedParts[1] !== actualParts[1]) {
|
|
217
|
-
return false
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return true
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Normalize a type and remove parameters.
|
|
225
|
-
*
|
|
226
|
-
* @param {string} value
|
|
227
|
-
* @return {(string|null)}
|
|
228
|
-
* @private
|
|
229
|
-
*/
|
|
230
|
-
function normalizeType (value) {
|
|
231
|
-
// Parse the type
|
|
232
|
-
var type = contentType.parse(value).type
|
|
233
|
-
|
|
234
|
-
return typer.test(type) ? type : null
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Try to normalize a type and remove parameters.
|
|
239
|
-
*
|
|
240
|
-
* @param {string} value
|
|
241
|
-
* @return {(string|null)}
|
|
242
|
-
* @private
|
|
243
|
-
*/
|
|
244
|
-
function tryNormalizeType (value) {
|
|
245
|
-
try {
|
|
246
|
-
return value ? normalizeType(value) : null
|
|
247
|
-
} catch (err) {
|
|
248
|
-
return null
|
|
249
|
-
}
|
|
250
|
-
}
|