From 238eedd8c1096ad2e3b44ddcbdea703e5eeb4e40 Mon Sep 17 00:00:00 2001 From: herrmannplatz Date: Fri, 20 Jan 2023 21:30:45 +0100 Subject: [PATCH 1/2] build: add type definitions --- index.js | 6 +-- package.json | 11 +++-- types/index.d.ts | 94 +++++++++++++++++++++++++++++++++++++++++++ types/index.test-d.ts | 29 +++++++++++++ 4 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 types/index.d.ts create mode 100644 types/index.test-d.ts diff --git a/index.js b/index.js index e9b2f63..7c4f94c 100644 --- a/index.js +++ b/index.js @@ -119,7 +119,7 @@ Accepts.prototype.types = function (types_) { * ['gzip', 'deflate'] * * @param {String|Array} encodings... - * @return {String|Array} + * @return {String|Array|Boolean} * @public */ @@ -152,7 +152,7 @@ Accepts.prototype.encodings = function (encodings_) { * ['utf-8', 'utf-7', 'iso-8859-1'] * * @param {String|Array} charsets... - * @return {String|Array} + * @return {String|Array|Boolean} * @public */ @@ -185,7 +185,7 @@ Accepts.prototype.charsets = function (charsets_) { * ['es', 'pt', 'en'] * * @param {String|Array} langs... - * @return {Array|String} + * @return {String|Array|Boolean} * @public */ diff --git a/package.json b/package.json index 0f2d15d..31fd111 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "accepts", "description": "Higher-level content negotiation", "version": "1.3.8", + "types": "types/index.d.ts", "contributors": [ "Douglas Christopher Wilson ", "Jonathan Ong (http://jongleberry.com)" @@ -13,6 +14,7 @@ "negotiator": "0.6.3" }, "devDependencies": { + "@types/node": "18.11.18", "deep-equal": "1.0.1", "eslint": "7.32.0", "eslint-config-standard": "14.1.1", @@ -22,12 +24,14 @@ "eslint-plugin-promise": "4.3.1", "eslint-plugin-standard": "4.1.0", "mocha": "9.2.0", - "nyc": "15.1.0" + "nyc": "15.1.0", + "tsd": "^0.25.0" }, "files": [ "LICENSE", "HISTORY.md", - "index.js" + "index.js", + "types/index.d.ts" ], "engines": { "node": ">= 0.6" @@ -36,7 +40,8 @@ "lint": "eslint .", "test": "mocha --reporter spec --check-leaks --bail test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", - "test-cov": "nyc --reporter=html --reporter=text npm test" + "test-cov": "nyc --reporter=html --reporter=text npm test", + "test-typescript": "tsd" }, "keywords": [ "content", diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..767f9e7 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,94 @@ +/// + +import { IncomingMessage } from "http"; + +declare namespace accepts { + interface Accepts { + /** + * Return the first accepted charset. If nothing in `charsets` is accepted, then `false` is returned. + * If no charsets are supplied, all accepted charsets are returned, in the order of the client's preference + * (most preferred first). + */ + charset(): string[]; + charset(charsets: string[]): string | string[] | false; + charset(...charsets: string[]): string | string[] | false; + + /** + * Return the first accepted charset. If nothing in `charsets` is accepted, then `false` is returned. + * If no charsets are supplied, all accepted charsets are returned, in the order of the client's preference + * (most preferred first). + */ + charsets(): string[]; + charsets(charsets: string[]): string | string[] | false; + charsets(...charsets: string[]): string | string[] | false; + + /** + * Return the first accepted encoding. If nothing in `encodings` is accepted, then `false` is returned. + * If no encodings are supplied, all accepted encodings are returned, in the order of the client's preference + * (most preferred first). + */ + encoding(): string[]; + encoding(encodings: string[]): string | string[] | false; + encoding(...encodings: string[]): string | string[] | false; + + /** + * Return the first accepted encoding. If nothing in `encodings` is accepted, then `false` is returned. + * If no encodings are supplied, all accepted encodings are returned, in the order of the client's preference + * (most preferred first). + */ + encodings(): string[]; + encodings(encodings: string[]): string | string[] | false; + encodings(...encodings: string[]): string | string[] | false; + + /** + * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. + * If no languaes are supplied, all accepted languages are returned, in the order of the client's preference + * (most preferred first). + */ + language(): string[]; + language(languages: string[]): string | string[] | false; + language(...languages: string[]): string | string[] | false; + + /** + * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. + * If no languaes are supplied, all accepted languages are returned, in the order of the client's preference + * (most preferred first). + */ + languages(): string[]; + languages(languages: string[]): string | string[] | false; + languages(...languages: string[]): string | string[] | false; + + /** + * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. + * If no languaes are supplied, all accepted languages are returned, in the order of the client's preference + * (most preferred first). + */ + lang(): string[]; + lang(languages: string[]): string | string[] | false; + lang(...languages: string[]): string | string[] | false; + + /** + * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. + * If no languaes are supplied, all accepted languages are returned, in the order of the client's preference + * (most preferred first). + */ + langs(): string[]; + langs(languages: string[]): string | string[] | false; + langs(...languages: string[]): string | string[] | false; + + /** + * Return the first accepted type (and it is returned as the same text as what appears in the `types` array). If nothing in `types` is accepted, then `false` is returned. + * If no types are supplied, return the entire set of acceptable types. + * + * The `types` array can contain full MIME types or file extensions. Any value that is not a full MIME types is passed to `require('mime-types').lookup`. + */ + type(types: string[]): string | string[] | false; + type(...types: string[]): string | string[] | false; + types(types: string[]): string | string[] | false; + types(...types: string[]): string | string[] | false; + } +} + +declare function accepts(req: IncomingMessage): accepts.Accepts; + +export = accepts; diff --git a/types/index.test-d.ts b/types/index.test-d.ts new file mode 100644 index 0000000..46f64eb --- /dev/null +++ b/types/index.test-d.ts @@ -0,0 +1,29 @@ +import accepts from ".."; + +const req: any = {}; + +const accept = accepts(req); + +const charsets = accept.charsets(); +const charsetFromEmpty = accept.charset(); +const charsetFromEmptyArray = accept.charset([]); +const charsetFromParams = accept.charset("json", "text"); +const charsetFromArray = accept.charset(["json", "txt"]); + +const encodings = accept.encodings(); +const encodingFromEmpty = accept.encoding(); +const encodingFromEmptyArray = accept.encoding([]); +const encodingFromParams = accept.encoding("json", "text"); +const encodingFromArray = accept.encoding(["json", "text"]); + +const languages = accept.languages(); +const languageFromEmpty = accept.language(); +const languageFromEmptyArray = accept.language([]); +const languageFromParams = accept.language("json", "text"); +const languageFromArray = accept.language(["json", "text"]); + +const types = accept.types(); +const typeFromEmpty = accept.type(); +const typeFromEmptyArray = accept.type([]); +const typeFromParams = accept.type("json", "text"); +const typeFromArray = accept.type(["json", "text"]); From f70419330cf213dc4d5993ee6ed8f5aee2173fa3 Mon Sep 17 00:00:00 2001 From: herrmannplatz Date: Sat, 21 Jan 2023 11:14:57 +0100 Subject: [PATCH 2/2] tests: add cases with empty array --- test/charset.js | 8 ++++++++ test/encoding.js | 9 +++++++++ test/language.js | 8 ++++++++ test/type.js | 8 ++++++++ types/index.d.ts | 20 ++++++++++---------- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/test/charset.js b/test/charset.js index 0bec5c9..ac49843 100644 --- a/test/charset.js +++ b/test/charset.js @@ -65,6 +65,14 @@ describe('accepts.charsets()', function () { assert.strictEqual(accept.charsets(['utf-7', 'utf-8']), 'utf-8') }) }) + + describe('with an empty array', function () { + it('should return accepted types', function () { + var req = createRequest('utf-8, iso-8859-1;q=0.2, utf-7;q=0.5') + var accept = accepts(req) + assert.ok(deepEqual(accept.charsets(), ['utf-8', 'utf-7', 'iso-8859-1'])) + }) + }) }) function createRequest (charset) { diff --git a/test/encoding.js b/test/encoding.js index 0e8585a..94a5063 100644 --- a/test/encoding.js +++ b/test/encoding.js @@ -65,6 +65,15 @@ describe('accepts.encodings()', function () { assert.strictEqual(accept.encodings(['compress', 'gzip']), 'gzip') }) }) + + describe('with an empty array', function () { + it('should return accepted types', function () { + var req = createRequest('gzip, compress;q=0.2') + var accept = accepts(req) + assert.ok(deepEqual(accept.encodings([]), ['gzip', 'compress', 'identity'])) + assert.strictEqual(accept.encodings('gzip', 'compress'), 'gzip') + }) + }) }) function createRequest (encoding) { diff --git a/test/language.js b/test/language.js index 58a0ea1..72254f8 100644 --- a/test/language.js +++ b/test/language.js @@ -65,6 +65,14 @@ describe('accepts.languages()', function () { assert.strictEqual(accept.languages(['es', 'en']), 'es') }) }) + + describe('with an empty array', function () { + it('should return accepted types', function () { + var req = createRequest('en;q=0.8, es, pt') + var accept = accepts(req) + assert.deepEqual(accept.languages([]), ['es', 'pt', 'en']) + }) + }) }) function createRequest (language) { diff --git a/test/type.js b/test/type.js index bbe91f3..9c88489 100644 --- a/test/type.js +++ b/test/type.js @@ -109,6 +109,14 @@ describe('accepts.types()', function () { assert.strictEqual(accept.types('image/png'), false) }) }) + + describe('with an empty array', function () { + it('should return all accepted types', function () { + var req = createRequest('application/*;q=0.2, image/jpeg;q=0.8, text/html, text/plain') + var accept = accepts(req) + assert.ok(deepEqual(accept.types([]), ['text/html', 'text/plain', 'image/jpeg', 'application/*'])) + }) + }) }) function createRequest (type) { diff --git a/types/index.d.ts b/types/index.d.ts index 767f9e7..fd52603 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -11,7 +11,7 @@ declare namespace accepts { */ charset(): string[]; charset(charsets: string[]): string | string[] | false; - charset(...charsets: string[]): string | string[] | false; + charset(...charsets: string[]): string | false; /** * Return the first accepted charset. If nothing in `charsets` is accepted, then `false` is returned. @@ -20,7 +20,7 @@ declare namespace accepts { */ charsets(): string[]; charsets(charsets: string[]): string | string[] | false; - charsets(...charsets: string[]): string | string[] | false; + charsets(...charsets: string[]): string | false; /** * Return the first accepted encoding. If nothing in `encodings` is accepted, then `false` is returned. @@ -29,7 +29,7 @@ declare namespace accepts { */ encoding(): string[]; encoding(encodings: string[]): string | string[] | false; - encoding(...encodings: string[]): string | string[] | false; + encoding(...encodings: string[]): string | false; /** * Return the first accepted encoding. If nothing in `encodings` is accepted, then `false` is returned. @@ -38,7 +38,7 @@ declare namespace accepts { */ encodings(): string[]; encodings(encodings: string[]): string | string[] | false; - encodings(...encodings: string[]): string | string[] | false; + encodings(...encodings: string[]): string | false; /** * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. @@ -47,7 +47,7 @@ declare namespace accepts { */ language(): string[]; language(languages: string[]): string | string[] | false; - language(...languages: string[]): string | string[] | false; + language(...languages: string[]): string | false; /** * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. @@ -56,7 +56,7 @@ declare namespace accepts { */ languages(): string[]; languages(languages: string[]): string | string[] | false; - languages(...languages: string[]): string | string[] | false; + languages(...languages: string[]): string | false; /** * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. @@ -65,7 +65,7 @@ declare namespace accepts { */ lang(): string[]; lang(languages: string[]): string | string[] | false; - lang(...languages: string[]): string | string[] | false; + lang(...languages: string[]): string | false; /** * Return the first accepted language. If nothing in `languages` is accepted, then `false` is returned. @@ -74,7 +74,7 @@ declare namespace accepts { */ langs(): string[]; langs(languages: string[]): string | string[] | false; - langs(...languages: string[]): string | string[] | false; + langs(...languages: string[]): string | false; /** * Return the first accepted type (and it is returned as the same text as what appears in the `types` array). If nothing in `types` is accepted, then `false` is returned. @@ -83,9 +83,9 @@ declare namespace accepts { * The `types` array can contain full MIME types or file extensions. Any value that is not a full MIME types is passed to `require('mime-types').lookup`. */ type(types: string[]): string | string[] | false; - type(...types: string[]): string | string[] | false; + type(...types: string[]): string | false; types(types: string[]): string | string[] | false; - types(...types: string[]): string | string[] | false; + types(...types: string[]): string | false; } }