@depup/type-is 2.1.0-depup.53 → 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 CHANGED
@@ -13,17 +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) @ 2.1.0 |
17
- | Processed | 2026-07-26 |
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 | 2 |
20
-
21
- ## Dependency Changes
22
-
23
- | Dependency | From | To |
24
- |------------|------|-----|
25
- | media-typer | ^1.1.0 | ^2.0.0 |
26
- | mime-types | ^3.0.0 | ^3.0.2 |
19
+ | Deps updated | 0 |
27
20
 
28
21
  ---
29
22
 
package/changes.json CHANGED
@@ -1,14 +1,5 @@
1
1
  {
2
- "bumped": {
3
- "media-typer": {
4
- "from": "^1.1.0",
5
- "to": "^2.0.0"
6
- },
7
- "mime-types": {
8
- "from": "^3.0.0",
9
- "to": "^3.0.2"
10
- }
11
- },
12
- "timestamp": "2026-07-26T00:59:41.969Z",
13
- "totalUpdated": 2
2
+ "bumped": {},
3
+ "timestamp": "2026-09-27T01:04:19.786Z",
4
+ "totalUpdated": 0
14
5
  }
@@ -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,76 +1,71 @@
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.1.0-depup.53",
5
- "contributors": [
6
- "Douglas Christopher Wilson <doug@somethingdoug.com>",
7
- "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
5
+ "keywords": [
6
+ "type-is",
7
+ "depup",
8
+ "updated-dependencies",
9
+ "security",
10
+ "latest",
11
+ "patched",
12
+ "content",
13
+ "type",
14
+ "checking"
8
15
  ],
9
- "license": "MIT",
10
16
  "repository": "jshttp/type-is",
11
17
  "funding": {
12
18
  "type": "opencollective",
13
19
  "url": "https://opencollective.com/express"
14
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
+ },
15
42
  "dependencies": {
16
- "content-type": "^2.0.0",
17
- "media-typer": "^2.0.0",
18
- "mime-types": "^3.0.2"
43
+ "content-type": "^3.1.1"
19
44
  },
20
45
  "devDependencies": {
21
- "eslint": "7.32.0",
22
- "eslint-config-standard": "14.1.1",
23
- "eslint-plugin-import": "2.31.0",
24
- "eslint-plugin-markdown": "2.2.1",
25
- "eslint-plugin-node": "11.1.0",
26
- "eslint-plugin-promise": "5.2.0",
27
- "eslint-plugin-standard": "4.1.0",
28
- "mocha": "9.2.2",
29
- "nyc": "15.1.0"
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"
30
51
  },
31
52
  "engines": {
32
- "node": ">= 18"
53
+ "node": ">= 22"
33
54
  },
34
- "files": [
35
- "LICENSE",
36
- "HISTORY.md",
37
- "index.js",
38
- "changes.json",
39
- "README.md"
40
- ],
41
- "scripts": {
42
- "lint": "eslint .",
43
- "test": "mocha --reporter spec --check-leaks --bail test/",
44
- "test:debug": "mocha --reporter spec --check-leaks --inspect --inspect-brk test/",
45
- "test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
46
- "test-cov": "nyc --reporter=html --reporter=text npm test"
55
+ "ts-scripts": {
56
+ "dist": [
57
+ "dist"
58
+ ],
59
+ "project": [
60
+ "tsconfig.build.json"
61
+ ]
47
62
  },
48
- "keywords": [
49
- "type-is",
50
- "depup",
51
- "updated-dependencies",
52
- "security",
53
- "latest",
54
- "patched",
55
- "content",
56
- "type",
57
- "checking"
58
- ],
59
63
  "depup": {
60
- "changes": {
61
- "media-typer": {
62
- "from": "^1.1.0",
63
- "to": "^2.0.0"
64
- },
65
- "mime-types": {
66
- "from": "^3.0.0",
67
- "to": "^3.0.2"
68
- }
69
- },
70
- "depsUpdated": 2,
64
+ "changes": {},
65
+ "depsUpdated": 0,
71
66
  "originalPackage": "type-is",
72
- "originalVersion": "2.1.0",
73
- "processedAt": "2026-07-26T00:59:44.235Z",
67
+ "originalVersion": "3.0.0",
68
+ "processedAt": "2026-09-27T01:04:22.945Z",
74
69
  "smokeTest": "passed"
75
70
  }
76
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,240 +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
- // Backward compatibility. TODO: Remove.
46
- if (value && typeof value === 'object') {
47
- value = value.headers['content-type']
48
- }
49
-
50
- var i
51
- var types = types_
52
-
53
- // remove parameters and normalize
54
- var val = normalizeType(value)
55
-
56
- // no type or invalid
57
- if (!val) {
58
- return false
59
- }
60
-
61
- // support flattened arguments
62
- if (types && !Array.isArray(types)) {
63
- types = new Array(arguments.length - 1)
64
- for (i = 0; i < types.length; i++) {
65
- types[i] = arguments[i + 1]
66
- }
67
- }
68
-
69
- // no types, return the content type
70
- if (!types || !types.length) {
71
- return val
72
- }
73
-
74
- var type
75
- for (i = 0; i < types.length; i++) {
76
- if (mimeMatch(normalize(type = types[i]), val)) {
77
- return type[0] === '+' || type.indexOf('*') !== -1
78
- ? val
79
- : type
80
- }
81
- }
82
-
83
- // no matches
84
- return false
85
- }
86
-
87
- /**
88
- * Check if a request has a request body.
89
- * A request with a body __must__ either have `transfer-encoding`
90
- * or `content-length` headers set.
91
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
92
- *
93
- * @param {Object} request
94
- * @return {Boolean}
95
- * @public
96
- */
97
-
98
- function hasbody (req) {
99
- return req.headers['transfer-encoding'] !== undefined ||
100
- !isNaN(req.headers['content-length'])
101
- }
102
-
103
- /**
104
- * Check if the incoming request contains the "Content-Type"
105
- * header field, and it contains any of the give mime `type`s.
106
- * If there is no request body, `null` is returned.
107
- * If there is no content type, `false` is returned.
108
- * Otherwise, it returns the first `type` that matches.
109
- *
110
- * Examples:
111
- *
112
- * // With Content-Type: text/html; charset=utf-8
113
- * this.is('html'); // => 'html'
114
- * this.is('text/html'); // => 'text/html'
115
- * this.is('text/*', 'application/json'); // => 'text/html'
116
- *
117
- * // When Content-Type is application/json
118
- * this.is('json', 'urlencoded'); // => 'json'
119
- * this.is('application/json'); // => 'application/json'
120
- * this.is('html', 'application/*'); // => 'application/json'
121
- *
122
- * this.is('html'); // => false
123
- *
124
- * @param {Object} req
125
- * @param {(String|Array)} types...
126
- * @return {(String|false|null)}
127
- * @public
128
- */
129
-
130
- function typeofrequest (req, types_) {
131
- // no body
132
- if (!hasbody(req)) return null
133
- // support flattened arguments
134
- var types = arguments.length > 2
135
- ? Array.prototype.slice.call(arguments, 1)
136
- : types_
137
- // request content type
138
- var value = req.headers['content-type']
139
-
140
- return typeis(value, types)
141
- }
142
-
143
- /**
144
- * Normalize a mime type.
145
- * If it's a shorthand, expand it to a valid mime type.
146
- *
147
- * In general, you probably want:
148
- *
149
- * var type = is(req, ['urlencoded', 'json', 'multipart']);
150
- *
151
- * Then use the appropriate body parsers.
152
- * These three are the most common request body types
153
- * and are thus ensured to work.
154
- *
155
- * @param {String} type
156
- * @return {String|false|null}
157
- * @public
158
- */
159
-
160
- function normalize (type) {
161
- if (typeof type !== 'string') {
162
- // invalid type
163
- return false
164
- }
165
-
166
- switch (type) {
167
- case 'urlencoded':
168
- return 'application/x-www-form-urlencoded'
169
- case 'multipart':
170
- return 'multipart/*'
171
- }
172
-
173
- if (type[0] === '+') {
174
- // "+json" -> "*/*+json" expando
175
- return '*/*' + type
176
- }
177
-
178
- return type.indexOf('/') === -1
179
- ? mime.lookup(type)
180
- : type
181
- }
182
-
183
- /**
184
- * Check if `expected` mime type
185
- * matches `actual` mime type with
186
- * wildcard and +suffix support.
187
- *
188
- * @param {String} expected
189
- * @param {String} actual
190
- * @return {Boolean}
191
- * @public
192
- */
193
-
194
- function mimeMatch (expected, actual) {
195
- // invalid type
196
- if (expected === false) {
197
- return false
198
- }
199
-
200
- // split types
201
- var actualParts = actual.split('/')
202
- var expectedParts = expected.split('/')
203
-
204
- // invalid format
205
- if (actualParts.length !== 2 || expectedParts.length !== 2) {
206
- return false
207
- }
208
-
209
- // validate type
210
- if (expectedParts[0] !== '*' && expectedParts[0] !== actualParts[0]) {
211
- return false
212
- }
213
-
214
- // validate suffix wildcard
215
- if (expectedParts[1].slice(0, 2) === '*+') {
216
- return expectedParts[1].length <= actualParts[1].length + 1 &&
217
- expectedParts[1].slice(1) === actualParts[1].slice(1 - expectedParts[1].length)
218
- }
219
-
220
- // validate subtype
221
- if (expectedParts[1] !== '*' && expectedParts[1] !== actualParts[1]) {
222
- return false
223
- }
224
-
225
- return true
226
- }
227
-
228
- /**
229
- * Normalize a type and remove parameters.
230
- *
231
- * @param {string} value
232
- * @return {(string|null)}
233
- * @private
234
- */
235
- function normalizeType (value) {
236
- if (!value) return null
237
- var type = contentType.parse(value, { parameters: false }).type
238
-
239
- return typer.test(type) ? type : null
240
- }