pax_global_header00006660000000000000000000000064134606067450014525gustar00rootroot0000000000000052 comment=bfebe3d4ac312debccb7dbbc79242e2581dea5f0 type-is-1.6.18/000077500000000000000000000000001346060674500132145ustar00rootroot00000000000000type-is-1.6.18/.eslintignore000066400000000000000000000000261346060674500157150ustar00rootroot00000000000000coverage node_modules type-is-1.6.18/.eslintrc.yml000066400000000000000000000000351346060674500156360ustar00rootroot00000000000000root: true extends: standard type-is-1.6.18/.gitignore000066400000000000000000000001051346060674500152000ustar00rootroot00000000000000.nyc_output/ coverage/ node_modules/ npm-debug.log package-lock.json type-is-1.6.18/.travis.yml000066400000000000000000000057701346060674500153360ustar00rootroot00000000000000language: node_js node_js: - "0.6" - "0.8" - "0.10" - "0.12" - "1.8" - "2.5" - "3.3" - "4.9" - "5.12" - "6.17" - "7.10" - "8.16" - "9.11" - "10.15" - "11.14" - "12.0" sudo: false dist: trusty env: global: # Suppress Node.js 0.6 compile warnings - "CXXCOM='$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-narrowing -Wno-strict-overflow $_CCCOMCOM $SOURCES'" cache: directories: - node_modules before_install: - | # Setup utility functions function node_version_lt () { [[ "$(v "$TRAVIS_NODE_VERSION")" -lt "$(v "${1}")" ]] } function npm_module_installed () { npm -lsp ls | grep -Fq "$(pwd)/node_modules/${1}:${1}@" } function npm_remove_module_re () { node -e ' fs = require("fs"); p = JSON.parse(fs.readFileSync("package.json", "utf8")); r = RegExp(process.argv[1]); for (k in p.devDependencies) { if (r.test(k)) delete p.devDependencies[k]; } fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); ' "$@" } function npm_use_module () { node -e ' fs = require("fs"); p = JSON.parse(fs.readFileSync("package.json", "utf8")); p.devDependencies[process.argv[1]] = process.argv[2]; fs.writeFileSync("package.json", JSON.stringify(p, null, 2) + "\n"); ' "$@" } function v () { tr '.' '\n' <<< "${1}" \ | awk '{ printf "%03d", $0 }' \ | sed 's/^0*//' } # Configure npm - | # Skip updating shrinkwrap / lock npm config set shrinkwrap false # Setup Node.js version-specific dependencies - | # Configure eslint for linting if node_version_lt '6.0'; then npm_remove_module_re '^eslint(-|$)' fi - | # Configure mocha for testing if node_version_lt '0.8' ; then npm_use_module 'mocha' '1.21.5' elif node_version_lt '0.10'; then npm_use_module 'mocha' '2.5.3' elif node_version_lt '4.0' ; then npm_use_module 'mocha' '3.5.3' elif node_version_lt '6.0' ; then npm_use_module 'mocha' '5.2.0' fi - | # Configure nyc for testing if node_version_lt '0.10'; then npm_remove_module_re '^nyc$' elif node_version_lt '4.0' ; then npm_use_module 'nyc' '10.3.2' elif node_version_lt '6.0' ; then npm_use_module 'nyc' '11.9.0' fi # Update Node.js modules - | # Prune & rebuild node_modules if [[ -d node_modules ]]; then npm prune npm rebuild fi before_scrpt: - | # Contents of node_modules npm -s ls ||: script: - | # Run test script, depending on nyc install if npm_module_installed 'nyc'; then npm run-script test-travis else npm test fi - | # Run linting, if eslint exists if npm_module_installed 'eslint'; then npm run-script lint fi after_script: - | # Upload coverage to coveralls if exists if [[ -d .nyc_output ]]; then npm install --save-dev coveralls@2 nyc report --reporter=text-lcov | coveralls fi type-is-1.6.18/HISTORY.md000066400000000000000000000125071346060674500147040ustar00rootroot000000000000001.6.18 / 2019-04-26 =================== * Fix regression passing request object to `typeis.is` 1.6.17 / 2019-04-25 =================== * deps: mime-types@~2.1.24 - Add Apple file extensions from IANA - Add extension `.csl` to `application/vnd.citationstyles.style+xml` - Add extension `.es` to `application/ecmascript` - Add extension `.nq` to `application/n-quads` - Add extension `.nt` to `application/n-triples` - Add extension `.owl` to `application/rdf+xml` - Add extensions `.siv` and `.sieve` to `application/sieve` - Add extensions from IANA for `image/*` types - Add extensions from IANA for `model/*` types - Add extensions to HEIC image types - Add new mime types - Add `text/mdx` with extension `.mdx` * perf: prevent internal `throw` on invalid type 1.6.16 / 2018-02-16 =================== * deps: mime-types@~2.1.18 - Add `application/raml+yaml` with extension `.raml` - Add `application/wasm` with extension `.wasm` - Add `text/shex` with extension `.shex` - Add extensions for JPEG-2000 images - Add extensions from IANA for `message/*` types - Add extension `.mjs` to `application/javascript` - Add extension `.wadl` to `application/vnd.sun.wadl+xml` - Add extension `.gz` to `application/gzip` - Add glTF types and extensions - Add new mime types - Update extensions `.md` and `.markdown` to be `text/markdown` - Update font MIME types - Update `text/hjson` to registered `application/hjson` 1.6.15 / 2017-03-31 =================== * deps: mime-types@~2.1.15 - Add new mime types 1.6.14 / 2016-11-18 =================== * deps: mime-types@~2.1.13 - Add new mime types 1.6.13 / 2016-05-18 =================== * deps: mime-types@~2.1.11 - Add new mime types 1.6.12 / 2016-02-28 =================== * deps: mime-types@~2.1.10 - Add new mime types - Fix extension of `application/dash+xml` - Update primary extension for `audio/mp4` 1.6.11 / 2016-01-29 =================== * deps: mime-types@~2.1.9 - Add new mime types 1.6.10 / 2015-12-01 =================== * deps: mime-types@~2.1.8 - Add new mime types 1.6.9 / 2015-09-27 ================== * deps: mime-types@~2.1.7 - Add new mime types 1.6.8 / 2015-09-04 ================== * deps: mime-types@~2.1.6 - Add new mime types 1.6.7 / 2015-08-20 ================== * Fix type error when given invalid type to match against * deps: mime-types@~2.1.5 - Add new mime types 1.6.6 / 2015-07-31 ================== * deps: mime-types@~2.1.4 - Add new mime types 1.6.5 / 2015-07-16 ================== * deps: mime-types@~2.1.3 - Add new mime types 1.6.4 / 2015-07-01 ================== * deps: mime-types@~2.1.2 - Add new mime types * perf: enable strict mode * perf: remove argument reassignment 1.6.3 / 2015-06-08 ================== * deps: mime-types@~2.1.1 - Add new mime types * perf: reduce try block size * perf: remove bitwise operations 1.6.2 / 2015-05-10 ================== * deps: mime-types@~2.0.11 - Add new mime types 1.6.1 / 2015-03-13 ================== * deps: mime-types@~2.0.10 - Add new mime types 1.6.0 / 2015-02-12 ================== * fix false-positives in `hasBody` `Transfer-Encoding` check * support wildcard for both type and subtype (`*/*`) 1.5.7 / 2015-02-09 ================== * fix argument reassignment * deps: mime-types@~2.0.9 - Add new mime types 1.5.6 / 2015-01-29 ================== * deps: mime-types@~2.0.8 - Add new mime types 1.5.5 / 2014-12-30 ================== * deps: mime-types@~2.0.7 - Add new mime types - Fix missing extensions - Fix various invalid MIME type entries - Remove example template MIME types - deps: mime-db@~1.5.0 1.5.4 / 2014-12-10 ================== * deps: mime-types@~2.0.4 - Add new mime types - deps: mime-db@~1.3.0 1.5.3 / 2014-11-09 ================== * deps: mime-types@~2.0.3 - Add new mime types - deps: mime-db@~1.2.0 1.5.2 / 2014-09-28 ================== * deps: mime-types@~2.0.2 - Add new mime types - deps: mime-db@~1.1.0 1.5.1 / 2014-09-07 ================== * Support Node.js 0.6 * deps: media-typer@0.3.0 * deps: mime-types@~2.0.1 - Support Node.js 0.6 1.5.0 / 2014-09-05 ================== * fix `hasbody` to be true for `content-length: 0` 1.4.0 / 2014-09-02 ================== * update mime-types 1.3.2 / 2014-06-24 ================== * use `~` range on mime-types 1.3.1 / 2014-06-19 ================== * fix global variable leak 1.3.0 / 2014-06-19 ================== * improve type parsing - invalid media type never matches - media type not case-sensitive - extra LWS does not affect results 1.2.2 / 2014-06-19 ================== * fix behavior on unknown type argument 1.2.1 / 2014-06-03 ================== * switch dependency from `mime` to `mime-types@1.0.0` 1.2.0 / 2014-05-11 ================== * support suffix matching: - `+json` matches `application/vnd+json` - `*/vnd+json` matches `application/vnd+json` - `application/*+json` matches `application/vnd+json` 1.1.0 / 2014-04-12 ================== * add non-array values support * expose internal utilities: - `.is()` - `.hasBody()` - `.normalize()` - `.match()` 1.0.1 / 2014-03-30 ================== * add `multipart` as a shorthand type-is-1.6.18/LICENSE000066400000000000000000000022241346060674500142210ustar00rootroot00000000000000(The MIT License) Copyright (c) 2014 Jonathan Ong Copyright (c) 2014-2015 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. type-is-1.6.18/README.md000066400000000000000000000120771346060674500145020ustar00rootroot00000000000000# type-is [![NPM Version][npm-version-image]][npm-url] [![NPM Downloads][npm-downloads-image]][npm-url] [![Node.js Version][node-version-image]][node-version-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] Infer the content-type of a request. ### Install This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/). Installation is done using the [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): ```sh $ npm install type-is ``` ## API ```js var http = require('http') var typeis = require('type-is') http.createServer(function (req, res) { var istext = typeis(req, ['text/*']) res.end('you ' + (istext ? 'sent' : 'did not send') + ' me text') }) ``` ### typeis(request, types) Checks if the `request` is one of the `types`. If the request has no body, even if there is a `Content-Type` header, then `null` is returned. If the `Content-Type` header is invalid or does not matches any of the `types`, then `false` is returned. Otherwise, a string of the type that matched is returned. The `request` argument is expected to be a Node.js HTTP request. The `types` argument is an array of type strings. Each type in the `types` array can be one of the following: - A file extension name such as `json`. This name will be returned if matched. - A mime type such as `application/json`. - A mime type with a wildcard such as `*/*` or `*/json` or `application/*`. The full mime type will be returned if matched. - A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched. Some examples to illustrate the inputs and returned value: ```js // req.headers.content-type = 'application/json' typeis(req, ['json']) // => 'json' typeis(req, ['html', 'json']) // => 'json' typeis(req, ['application/*']) // => 'application/json' typeis(req, ['application/json']) // => 'application/json' typeis(req, ['html']) // => false ``` ### typeis.hasBody(request) Returns a Boolean if the given `request` has a body, regardless of the `Content-Type` header. Having a body has no relation to how large the body is (it may be 0 bytes). This is similar to how file existence works. If a body does exist, then this indicates that there is data to read from the Node.js request stream. ```js if (typeis.hasBody(req)) { // read the body, since there is one req.on('data', function (chunk) { // ... }) } ``` ### typeis.is(mediaType, types) Checks if the `mediaType` is one of the `types`. If the `mediaType` is invalid or does not matches any of the `types`, then `false` is returned. Otherwise, a string of the type that matched is returned. The `mediaType` argument is expected to be a [media type](https://tools.ietf.org/html/rfc6838) string. The `types` argument is an array of type strings. Each type in the `types` array can be one of the following: - A file extension name such as `json`. This name will be returned if matched. - A mime type such as `application/json`. - A mime type with a wildcard such as `*/*` or `*/json` or `application/*`. The full mime type will be returned if matched. - A suffix such as `+json`. This can be combined with a wildcard such as `*/vnd+json` or `application/*+json`. The full mime type will be returned if matched. Some examples to illustrate the inputs and returned value: ```js var mediaType = 'application/json' typeis.is(mediaType, ['json']) // => 'json' typeis.is(mediaType, ['html', 'json']) // => 'json' typeis.is(mediaType, ['application/*']) // => 'application/json' typeis.is(mediaType, ['application/json']) // => 'application/json' typeis.is(mediaType, ['html']) // => false ``` ## Examples ### Example body parser ```js var express = require('express') var typeis = require('type-is') var app = express() app.use(function bodyParser (req, res, next) { if (!typeis.hasBody(req)) { return next() } switch (typeis(req, ['urlencoded', 'json', 'multipart'])) { case 'urlencoded': // parse urlencoded body throw new Error('implement urlencoded body parsing') case 'json': // parse json body throw new Error('implement json body parsing') case 'multipart': // parse multipart body throw new Error('implement multipart body parsing') default: // 415 error code res.statusCode = 415 res.end() break } }) ``` ## License [MIT](LICENSE) [coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/type-is/master [coveralls-url]: https://coveralls.io/r/jshttp/type-is?branch=master [node-version-image]: https://badgen.net/npm/node/type-is [node-version-url]: https://nodejs.org/en/download [npm-downloads-image]: https://badgen.net/npm/dm/type-is [npm-url]: https://npmjs.org/package/type-is [npm-version-image]: https://badgen.net/npm/v/type-is [travis-image]: https://badgen.net/travis/jshttp/type-is/master [travis-url]: https://travis-ci.org/jshttp/type-is type-is-1.6.18/index.js000066400000000000000000000126721346060674500146710ustar00rootroot00000000000000/*! * type-is * Copyright(c) 2014 Jonathan Ong * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module dependencies. * @private */ var typer = require('media-typer') var mime = require('mime-types') /** * Module exports. * @public */ module.exports = typeofrequest module.exports.is = typeis module.exports.hasBody = hasbody module.exports.normalize = normalize module.exports.match = mimeMatch /** * Compare a `value` content-type with `types`. * Each `type` can be an extension like `html`, * a special shortcut like `multipart` or `urlencoded`, * or a mime type. * * If no types match, `false` is returned. * Otherwise, the first `type` that matches is returned. * * @param {String} value * @param {Array} types * @public */ function typeis (value, types_) { var i var types = types_ // remove parameters and normalize var val = tryNormalizeType(value) // no type or invalid if (!val) { return false } // support flattened arguments if (types && !Array.isArray(types)) { types = new Array(arguments.length - 1) for (i = 0; i < types.length; i++) { types[i] = arguments[i + 1] } } // no types, return the content type if (!types || !types.length) { return val } var type for (i = 0; i < types.length; i++) { if (mimeMatch(normalize(type = types[i]), val)) { return type[0] === '+' || type.indexOf('*') !== -1 ? val : type } } // no matches return false } /** * Check if a request has a request body. * A request with a body __must__ either have `transfer-encoding` * or `content-length` headers set. * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3 * * @param {Object} request * @return {Boolean} * @public */ function hasbody (req) { return req.headers['transfer-encoding'] !== undefined || !isNaN(req.headers['content-length']) } /** * Check if the incoming request contains the "Content-Type" * header field, and it contains any of the give mime `type`s. * If there is no request body, `null` is returned. * If there is no content type, `false` is returned. * Otherwise, it returns the first `type` that matches. * * Examples: * * // With Content-Type: text/html; charset=utf-8 * this.is('html'); // => 'html' * this.is('text/html'); // => 'text/html' * this.is('text/*', 'application/json'); // => 'text/html' * * // When Content-Type is application/json * this.is('json', 'urlencoded'); // => 'json' * this.is('application/json'); // => 'application/json' * this.is('html', 'application/*'); // => 'application/json' * * this.is('html'); // => false * * @param {String|Array} types... * @return {String|false|null} * @public */ function typeofrequest (req, types_) { var types = types_ // no body if (!hasbody(req)) { return null } // support flattened arguments if (arguments.length > 2) { types = new Array(arguments.length - 1) for (var i = 0; i < types.length; i++) { types[i] = arguments[i + 1] } } // request content type var value = req.headers['content-type'] return typeis(value, types) } /** * Normalize a mime type. * If it's a shorthand, expand it to a valid mime type. * * In general, you probably want: * * var type = is(req, ['urlencoded', 'json', 'multipart']); * * Then use the appropriate body parsers. * These three are the most common request body types * and are thus ensured to work. * * @param {String} type * @private */ function normalize (type) { if (typeof type !== 'string') { // invalid type return false } switch (type) { case 'urlencoded': return 'application/x-www-form-urlencoded' case 'multipart': return 'multipart/*' } if (type[0] === '+') { // "+json" -> "*/*+json" expando return '*/*' + type } return type.indexOf('/') === -1 ? mime.lookup(type) : type } /** * Check if `expected` mime type * matches `actual` mime type with * wildcard and +suffix support. * * @param {String} expected * @param {String} actual * @return {Boolean} * @private */ function mimeMatch (expected, actual) { // invalid type if (expected === false) { return false } // split types var actualParts = actual.split('/') var expectedParts = expected.split('/') // invalid format if (actualParts.length !== 2 || expectedParts.length !== 2) { return false } // validate type if (expectedParts[0] !== '*' && expectedParts[0] !== actualParts[0]) { return false } // validate suffix wildcard if (expectedParts[1].substr(0, 2) === '*+') { return expectedParts[1].length <= actualParts[1].length + 1 && expectedParts[1].substr(1) === actualParts[1].substr(1 - expectedParts[1].length) } // validate subtype if (expectedParts[1] !== '*' && expectedParts[1] !== actualParts[1]) { return false } return true } /** * Normalize a type and remove parameters. * * @param {string} value * @return {string} * @private */ function normalizeType (value) { // parse the type var type = typer.parse(value) // remove the parameters type.parameters = undefined // reformat it return typer.format(type) } /** * Try to normalize a type and remove parameters. * * @param {string} value * @return {string} * @private */ function tryNormalizeType (value) { if (!value) { return null } try { return normalizeType(value) } catch (err) { return null } } type-is-1.6.18/package.json000066400000000000000000000021551346060674500155050ustar00rootroot00000000000000{ "name": "type-is", "description": "Infer the content-type of a request.", "version": "1.6.18", "contributors": [ "Douglas Christopher Wilson ", "Jonathan Ong (http://jongleberry.com)" ], "license": "MIT", "repository": "jshttp/type-is", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" }, "devDependencies": { "eslint": "5.16.0", "eslint-config-standard": "12.0.0", "eslint-plugin-import": "2.17.2", "eslint-plugin-markdown": "1.0.0", "eslint-plugin-node": "8.0.1", "eslint-plugin-promise": "4.1.1", "eslint-plugin-standard": "4.0.0", "mocha": "6.1.4", "nyc": "14.0.0" }, "engines": { "node": ">= 0.6" }, "files": [ "LICENSE", "HISTORY.md", "index.js" ], "scripts": { "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --reporter spec --check-leaks --bail test/", "test-cov": "nyc --reporter=html --reporter=text npm test", "test-travis": "nyc --reporter=text npm test" }, "keywords": [ "content", "type", "checking" ] } type-is-1.6.18/test/000077500000000000000000000000001346060674500141735ustar00rootroot00000000000000type-is-1.6.18/test/.eslintrc.yml000066400000000000000000000000231346060674500166120ustar00rootroot00000000000000env: mocha: true type-is-1.6.18/test/test.js000066400000000000000000000305661346060674500155220ustar00rootroot00000000000000 var assert = require('assert') var typeis = require('..') describe('typeis(req, types)', function () { it('should ignore params', function () { var req = createRequest('text/html; charset=utf-8') assert.strictEqual(typeis(req, ['text/*']), 'text/html') }) it('should ignore params LWS', function () { var req = createRequest('text/html ; charset=utf-8') assert.strictEqual(typeis(req, ['text/*']), 'text/html') }) it('should ignore casing', function () { var req = createRequest('text/HTML') assert.strictEqual(typeis(req, ['text/*']), 'text/html') }) it('should fail invalid type', function () { var req = createRequest('text/html**') assert.strictEqual(typeis(req, ['text/*']), false) }) it('should not match invalid type', function () { var req = createRequest('text/html') assert.strictEqual(typeis(req, ['text/html/']), false) assert.strictEqual(typeis(req, [undefined, null, true, function () {}]), false) }) describe('when no body is given', function () { it('should return null', function () { var req = { headers: {} } assert.strictEqual(typeis(req), null) assert.strictEqual(typeis(req, ['image/*']), null) assert.strictEqual(typeis(req, 'image/*', 'text/*'), null) }) }) describe('when no content type is given', function () { it('should return false', function () { var req = createRequest() assert.strictEqual(typeis(req), false) assert.strictEqual(typeis(req, ['image/*']), false) assert.strictEqual(typeis(req, ['text/*', 'image/*']), false) }) }) describe('give no types', function () { it('should return the mime type', function () { var req = createRequest('image/png') assert.strictEqual(typeis(req), 'image/png') }) }) describe('given one type', function () { it('should return the type or false', function () { var req = createRequest('image/png') assert.strictEqual(typeis(req, ['png']), 'png') assert.strictEqual(typeis(req, ['.png']), '.png') assert.strictEqual(typeis(req, ['image/png']), 'image/png') assert.strictEqual(typeis(req, ['image/*']), 'image/png') assert.strictEqual(typeis(req, ['*/png']), 'image/png') assert.strictEqual(typeis(req, ['jpeg']), false) assert.strictEqual(typeis(req, ['.jpeg']), false) assert.strictEqual(typeis(req, ['image/jpeg']), false) assert.strictEqual(typeis(req, ['text/*']), false) assert.strictEqual(typeis(req, ['*/jpeg']), false) assert.strictEqual(typeis(req, ['bogus']), false) assert.strictEqual(typeis(req, ['something/bogus*']), false) }) }) describe('given multiple types', function () { it('should return the first match or false', function () { var req = createRequest('image/png') assert.strictEqual(typeis(req, ['png']), 'png') assert.strictEqual(typeis(req, '.png'), '.png') assert.strictEqual(typeis(req, ['text/*', 'image/*']), 'image/png') assert.strictEqual(typeis(req, ['image/*', 'text/*']), 'image/png') assert.strictEqual(typeis(req, ['image/*', 'image/png']), 'image/png') assert.strictEqual(typeis(req, 'image/png', 'image/*'), 'image/png') assert.strictEqual(typeis(req, ['jpeg']), false) assert.strictEqual(typeis(req, ['.jpeg']), false) assert.strictEqual(typeis(req, ['text/*', 'application/*']), false) assert.strictEqual(typeis(req, ['text/html', 'text/plain', 'application/json']), false) }) }) describe('given +suffix', function () { it('should match suffix types', function () { var req = createRequest('application/vnd+json') assert.strictEqual(typeis(req, '+json'), 'application/vnd+json') assert.strictEqual(typeis(req, 'application/vnd+json'), 'application/vnd+json') assert.strictEqual(typeis(req, 'application/*+json'), 'application/vnd+json') assert.strictEqual(typeis(req, '*/vnd+json'), 'application/vnd+json') assert.strictEqual(typeis(req, 'application/json'), false) assert.strictEqual(typeis(req, 'text/*+json'), false) }) }) describe('given "*/*"', function () { it('should match any content-type', function () { assert.strictEqual(typeis(createRequest('text/html'), '*/*'), 'text/html') assert.strictEqual(typeis(createRequest('text/xml'), '*/*'), 'text/xml') assert.strictEqual(typeis(createRequest('application/json'), '*/*'), 'application/json') assert.strictEqual(typeis(createRequest('application/vnd+json'), '*/*'), 'application/vnd+json') }) it('should not match invalid content-type', function () { assert.strictEqual(typeis(createRequest('bogus'), '*/*'), false) }) it('should not match body-less request', function () { var req = { headers: { 'content-type': 'text/html' } } assert.strictEqual(typeis(req, '*/*'), null) }) }) describe('when Content-Type: application/x-www-form-urlencoded', function () { it('should match "urlencoded"', function () { var req = createRequest('application/x-www-form-urlencoded') assert.strictEqual(typeis(req, ['urlencoded']), 'urlencoded') assert.strictEqual(typeis(req, ['json', 'urlencoded']), 'urlencoded') assert.strictEqual(typeis(req, ['urlencoded', 'json']), 'urlencoded') }) }) describe('when Content-Type: multipart/form-data', function () { it('should match "multipart/*"', function () { var req = createRequest('multipart/form-data') assert.strictEqual(typeis(req, ['multipart/*']), 'multipart/form-data') }) it('should match "multipart"', function () { var req = createRequest('multipart/form-data') assert.strictEqual(typeis(req, ['multipart']), 'multipart') }) }) }) describe('typeis.hasBody(req)', function () { describe('content-length', function () { it('should indicate body', function () { var req = { headers: { 'content-length': '1' } } assert.strictEqual(typeis.hasBody(req), true) }) it('should be true when 0', function () { var req = { headers: { 'content-length': '0' } } assert.strictEqual(typeis.hasBody(req), true) }) it('should be false when bogus', function () { var req = { headers: { 'content-length': 'bogus' } } assert.strictEqual(typeis.hasBody(req), false) }) }) describe('transfer-encoding', function () { it('should indicate body', function () { var req = { headers: { 'transfer-encoding': 'chunked' } } assert.strictEqual(typeis.hasBody(req), true) }) }) }) describe('typeis.is(mediaType, types)', function () { it('should ignore params', function () { assert.strictEqual(typeis.is('text/html; charset=utf-8', ['text/*']), 'text/html') }) it('should ignore casing', function () { assert.strictEqual(typeis.is('text/HTML', ['text/*']), 'text/html') }) it('should fail invalid type', function () { assert.strictEqual(typeis.is('text/html**', ['text/*']), false) }) it('should not match invalid type', function () { var req = createRequest('text/html') assert.strictEqual(typeis(req, ['text/html/']), false) assert.strictEqual(typeis(req, [undefined, null, true, function () {}]), false) }) it('should not match invalid type', function () { assert.strictEqual(typeis.is('text/html', ['text/html/']), false) assert.strictEqual(typeis.is('text/html', [undefined, null, true, function () {}]), false) }) describe('when no media type is given', function () { it('should return false', function () { assert.strictEqual(typeis.is(), false) assert.strictEqual(typeis.is('', ['application/json']), false) assert.strictEqual(typeis.is(null, ['image/*']), false) assert.strictEqual(typeis.is(undefined, ['text/*', 'image/*']), false) }) }) describe('given no types', function () { it('should return the mime type', function () { assert.strictEqual(typeis.is('image/png'), 'image/png') }) }) describe('given one type', function () { it('should return the type or false', function () { assert.strictEqual(typeis.is('image/png', ['png']), 'png') assert.strictEqual(typeis.is('image/png', ['.png']), '.png') assert.strictEqual(typeis.is('image/png', ['image/png']), 'image/png') assert.strictEqual(typeis.is('image/png', ['image/*']), 'image/png') assert.strictEqual(typeis.is('image/png', ['*/png']), 'image/png') assert.strictEqual(typeis.is('image/png', ['jpeg']), false) assert.strictEqual(typeis.is('image/png', ['.jpeg']), false) assert.strictEqual(typeis.is('image/png', ['image/jpeg']), false) assert.strictEqual(typeis.is('image/png', ['text/*']), false) assert.strictEqual(typeis.is('image/png', ['*/jpeg']), false) assert.strictEqual(typeis.is('image/png', ['bogus']), false) assert.strictEqual(typeis.is('image/png', ['something/bogus*']), false) }) }) describe('given multiple types', function () { it('should return the first match or false', function () { assert.strictEqual(typeis.is('image/png', ['png']), 'png') assert.strictEqual(typeis.is('image/png', '.png'), '.png') assert.strictEqual(typeis.is('image/png', ['text/*', 'image/*']), 'image/png') assert.strictEqual(typeis.is('image/png', ['image/*', 'text/*']), 'image/png') assert.strictEqual(typeis.is('image/png', ['image/*', 'image/png']), 'image/png') assert.strictEqual(typeis.is('image/png', 'image/png', 'image/*'), 'image/png') assert.strictEqual(typeis.is('image/png', ['jpeg']), false) assert.strictEqual(typeis.is('image/png', ['.jpeg']), false) assert.strictEqual(typeis.is('image/png', ['text/*', 'application/*']), false) assert.strictEqual(typeis.is('image/png', ['text/html', 'text/plain', 'application/json']), false) }) }) describe('given +suffix', function () { it('should match suffix types', function () { assert.strictEqual(typeis.is('application/vnd+json', '+json'), 'application/vnd+json') assert.strictEqual(typeis.is('application/vnd+json', 'application/vnd+json'), 'application/vnd+json') assert.strictEqual(typeis.is('application/vnd+json', 'application/*+json'), 'application/vnd+json') assert.strictEqual(typeis.is('application/vnd+json', '*/vnd+json'), 'application/vnd+json') assert.strictEqual(typeis.is('application/vnd+json', 'application/json'), false) assert.strictEqual(typeis.is('application/vnd+json', 'text/*+json'), false) }) }) describe('given "*/*"', function () { it('should match any media type', function () { assert.strictEqual(typeis.is('text/html', '*/*'), 'text/html') assert.strictEqual(typeis.is('text/xml', '*/*'), 'text/xml') assert.strictEqual(typeis.is('application/json', '*/*'), 'application/json') assert.strictEqual(typeis.is('application/vnd+json', '*/*'), 'application/vnd+json') }) it('should not match invalid media type', function () { assert.strictEqual(typeis.is('bogus', '*/*'), false) }) }) describe('when media type is application/x-www-form-urlencoded', function () { it('should match "urlencoded"', function () { assert.strictEqual(typeis.is('application/x-www-form-urlencoded', ['urlencoded']), 'urlencoded') assert.strictEqual(typeis.is('application/x-www-form-urlencoded', ['json', 'urlencoded']), 'urlencoded') assert.strictEqual(typeis.is('application/x-www-form-urlencoded', ['urlencoded', 'json']), 'urlencoded') }) }) describe('when media type is multipart/form-data', function () { it('should match "multipart/*"', function () { assert.strictEqual(typeis.is('multipart/form-data', ['multipart/*']), 'multipart/form-data') }) it('should match "multipart"', function () { assert.strictEqual(typeis.is('multipart/form-data', ['multipart']), 'multipart') }) }) describe('when give request object', function () { it('should use the content-type header', function () { var req = createRequest('image/png') assert.strictEqual(typeis.is(req, ['png']), 'png') assert.strictEqual(typeis.is(req, ['jpeg']), false) }) it('should not check for body', function () { var req = { headers: { 'content-type': 'text/html' } } assert.strictEqual(typeis.is(req, ['html']), 'html') assert.strictEqual(typeis.is(req, ['jpeg']), false) }) }) }) function createRequest (type) { return { headers: { 'content-type': type || undefined, 'transfer-encoding': 'chunked' } } }