Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/ci-module.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: ci

on:
push:
branches:
- master
- next
pull_request:
workflow_dispatch:
push:
branches:
- master
- next
pull_request:
workflow_dispatch:

jobs:
test:
uses: hapijs/.github/.github/workflows/ci-module.yml@min-node-18-hapi-21
test:
uses: hapijs/.github/.github/workflows/ci-module.yml@min-node-22-hapi-21
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
**/node_modules
**/package-lock.json

coverage.*
coverage/

**/.DS_Store
**/._*
Expand Down
29 changes: 13 additions & 16 deletions API.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
## Introduction

Accept helps to answer the question of how best to respond to a HTTP request, based on the requesting browser's capabilities. Accept will parse the headers of a HTTP request and tell you what the preferred encoding is, what language should be used, and what charsets and media types are accepted.
Accept helps to answer the question of how best to respond to a HTTP request, based on the requesting browser's capabilities. Accept will parse the headers of a HTTP request and tell you what the preferred encoding is, what language should be used, and what charsets and media types are accepted.

Additional details about Accept headers and content negotiation can be found in [IETF RFC 7231, Section 5.3](https://tools.ietf.org/html/rfc7231#section-5.3).

## Methods

### `charset(charsetHeader, [preferences])`

Given a string of acceptable charsets from a HTTP request Accept-Charset header, and an optional array of charset preferences, it will return a string indicating the best charset option that can be used in the HTTP response. This takes into account any weighting parameters given in the header for ordering and exclusion.
Given a string of acceptable charsets from a HTTP request Accept-Charset header, and an optional array of charset preferences, it will return a string indicating the best charset option that can be used in the HTTP response. This takes into account any weighting parameters given in the header for ordering and exclusion.

```
const charset = Accept.charsets("iso-8859-5, unicode-1-1;q=0.8"); // charset === "iso-8859-5"
Expand All @@ -26,7 +26,7 @@ const charsets = Accept.charsets("iso-8859-5;q=0.5, unicode-1-1;q=0.8"); // char

### `encoding(encodingHeader, [preferences])`

Given a string of acceptable encodings from a HTTP request Accept-Encoding header, and optionally an array of preferences, it will return a string with the best fit encoding that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered encoding is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on [Preferences](#preferences).
Given a string of acceptable encodings from a HTTP request Accept-Encoding header, and optionally an array of preferences, it will return a string with the best fit encoding that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered encoding is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on [Preferences](#preferences).

```
const encoding = Accept.encoding("gzip, deflate, sdch"); // encoding === "gzip"
Expand All @@ -43,9 +43,9 @@ const encodings = Accept.encodings("compress;q=0.5, gzip;q=1.0"); // encodings =

### `language(languageHeader, [preferences])`

Given a string of acceptable language ranges from a HTTP request Accept-Language header, and an optional array of language-tag preferences, it will return a string indicating the best language that can be used in the HTTP response. It respects the [q weightings](#weightings) of the languages in the header, returning the matched preference with the highest weighting. The case of the preference does not have to match the case of the option in the header.
Given a string of acceptable language ranges from a HTTP request Accept-Language header, and an optional array of language-tag preferences, it will return a string indicating the best language that can be used in the HTTP response. It respects the [q weightings](#weightings) of the languages in the header, returning the matched preference with the highest weighting. The case of the preference does not have to match the case of the option in the header.

If preferences is missing or an empty array, the highest weighted language is returned. If no preference matches, an empty string is returned.
If preferences is missing or an empty array, the highest weighted language is returned. If no preference matches, an empty string is returned.

```
const language = Accept.language("en;q=0.7, en-GB;q=0.8"); // language === "en-gb"
Expand All @@ -64,7 +64,7 @@ const languages = Accept.languages("da, en;q=0.7, en-GB;q=0.8"); // languages ==

### `mediaType(mediaTypeHeader, [preferences])`

Given a string of acceptable media types from a HTTP request Accept header, and optionally an array of preferences, it will return a string with the best fit media type that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered media type is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on [Preferences](#preferences).
Given a string of acceptable media types from a HTTP request Accept header, and optionally an array of preferences, it will return a string with the best fit media type that should be used in the HTTP response. If no preferences array parameter is given the highest weighted or first ordered media type is returned. If weightings are given in the header (using the q parameter) they are taken into account and the highest weighted match is returned. If a preferences array is given the best match from the array is returned. For more information about how the preferences array works see the section below on [Preferences](#preferences).

```
const mediaType = Accept.mediaType("text/plain, application/json;q=0.5, text/html, */*;q=0.1");
Expand All @@ -85,7 +85,7 @@ const mediaTypes = Accept.mediaTypes("text/plain, application/json;q=0.5, text/h

### `parseAll(headers)`

Given the headers from a Hapi request object, `parseAll()` will parse all of the Accepts-* headers it currently understands into an object.
Given the headers from a Hapi request object, `parseAll()` will parse all of the Accepts-\* headers it currently understands into an object.

```
const all = Accept.parseAll(request.headers);
Expand All @@ -97,31 +97,29 @@ const all = Accept.parseAll(request.headers);
// }
```


## Q Weightings

The Accept-* headers may optionally include preferential weighting to indicate which options are best for the requester. It does this with `q` parameters in the headers (which stands for quality). These q weightings must be in the range of 0 to 1, with a max of three decimal places. The weightings are used to order the data given in the header, with the highest number being most preferential. Anything with a q rating of 0 is not allowed at all.
The Accept-\* headers may optionally include preferential weighting to indicate which options are best for the requester. It does this with `q` parameters in the headers (which stands for quality). These q weightings must be in the range of 0 to 1, with a max of three decimal places. The weightings are used to order the data given in the header, with the highest number being most preferential. Anything with a q rating of 0 is not allowed at all.

If a particular Accept method allows a `preferences` array parameter, such as `encoding()`, the weightings in the header affect which preference will be returned. Your preferences are matched with the weighting in mind, and the highest weighted option will be returned, no matter what order you list your preferences. The header weighting is most important.
If a particular Accept method allows a `preferences` array parameter, such as `encoding()`, the weightings in the header affect which preference will be returned. Your preferences are matched with the weighting in mind, and the highest weighted option will be returned, no matter what order you list your preferences. The header weighting is most important.

```
const encoding = Accept.encoding("gzip;q=1.0, identity;q=0.5", ["identity", "gzip"]);
// encoding === "gzip"
// despite identity getting listed first in the preferences array, gzip has a higher q weighting, so it is returned.
```


## Encodings

### Preferences

If you are looking for a set of specific encodings you can pass that in as an array to the `preferences` parameter. Your preferences **must** be an array. In the preferences array you specify a list of possible encodings you want to look for, in order of preference. Accept will return back the most preferential option it can find, if any match. The preferences array does not support parameters, only base types.
If you are looking for a set of specific encodings you can pass that in as an array to the `preferences` parameter. Your preferences **must** be an array. In the preferences array you specify a list of possible encodings you want to look for, in order of preference. Accept will return back the most preferential option it can find, if any match. The preferences array does not support parameters, only base types.

```
const encoding = Accept.encoding("gzip, deflate, sdch", ["deflate", "identity"]); // encoding === "delate"
```

Your preferences are evaluated without any case sensitivity, to better match what the browser sends. This means that "gZip" will match a preference of ["gzip"].
Your preferences are evaluated without any case sensitivity, to better match what the browser sends. This means that "gZip" will match a preference of ["gzip"].

```
const encoding = Accept.encoding("gZip, deflate, sdch", ["gzip"]); // encoding === "gzip"
Expand All @@ -133,13 +131,12 @@ If you supply a preferences array, and no match is found, `encoding()` will retu
const encoding = Accept.encoding("gZip", ["deflate"]); // encoding === ""
```

If the encoding header is the special "*" that indicates the browser will accept any encoding. In that case the top preference from your supplied options will be returned.
If the encoding header is the special "\*" that indicates the browser will accept any encoding. In that case the top preference from your supplied options will be returned.

```
const encoding = Accept.encoding("*", ["gzip"]); // encoding === "gzip"
```


### Identity

When you ask Accept for a list of all the supported encodings from the request, using the `encodings()` function (plural, not singular), you will be returned an array of strings in order from most preferred to least as determined by the encoding weight.
Expand All @@ -148,4 +145,4 @@ When you ask Accept for a list of all the supported encodings from the request,
const encodings = Accept.encodings("compress;q=0.5, gzip;q=1.0"); // encodings === ["gzip", "compress", "identity"]
```

You'll notice that `identity` was returned in the array, even though it's not in the encoding header. Identity is always an option for encoding, unless specifically excluded in the header using a weighting of zero. Identity just means respond with no special encoding.
You'll notice that `identity` was returned in the array, even though it's not in the encoding header. Identity is always an option for encoding, unless specifically excluded in the header using a weighting of zero. Identity just means respond with no special encoding.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# @hapi/accept

#### HTTP Accept-* headers parsing.
#### HTTP Accept-\* headers parsing.

**accept** is part of the **hapi** ecosystem and was designed to work seamlessly with the [hapi web framework](https://hapi.dev) and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out [hapi](https://hapi.dev) – they work even better together.

Expand Down
48 changes: 0 additions & 48 deletions lib/index.js

This file was deleted.

8 changes: 8 additions & 0 deletions oxfmt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import DefaultOxfmtConfig from '@hapi/oxc-plugin/oxfmt';
import { defineConfig } from 'oxfmt';

import type { OxfmtConfig } from 'oxfmt';

export default defineConfig({
...DefaultOxfmtConfig,
}) as OxfmtConfig;
11 changes: 11 additions & 0 deletions oxlint.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import HapiRecommended from '@hapi/oxc-plugin/oxlint';
import { defineConfig } from 'oxlint';

import type { OxlintConfig } from 'oxlint';

export default defineConfig({
extends: [HapiRecommended],
env: {
...HapiRecommended.env,
},
}) as OxlintConfig;
85 changes: 49 additions & 36 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
{
"name": "@hapi/accept",
"description": "HTTP Accept-* headers parsing",
"version": "6.0.3",
"repository": "git://github.com/hapijs/accept",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib"
],
"keywords": [
"HTTP",
"header",
"accept",
"accept-encoding"
],
"eslintConfig": {
"extends": [
"plugin:@hapi/module"
]
},
"dependencies": {
"@hapi/boom": "^10.0.1",
"@hapi/hoek": "^11.0.2"
},
"devDependencies": {
"@hapi/code": "^9.0.3",
"@hapi/eslint-plugin": "^7.0.0",
"@hapi/lab": "^26.0.0",
"@types/node": "^17.0.31",
"typescript": "~4.6.4"
},
"scripts": {
"test": "lab -a @hapi/code -t 100 -L -Y",
"test-cov-html": "lab -a @hapi/code -r html -o coverage.html"
},
"license": "BSD-3-Clause"
"name": "@hapi/accept",
"version": "6.0.3",
"description": "HTTP Accept-* headers parsing",
"keywords": [
"HTTP",
"accept",
"accept-encoding",
"header"
],
"license": "BSD-3-Clause",
"repository": "git://github.com/hapijs/accept",
"files": [
"src",
"API.md",
"README.md"
],
"type": "module",
"types": "src/index.d.ts",
"exports": {
".": {
"types": "./src/index.d.ts",
"default": "./src/index.js"
}
},
"scripts": {
"test": "vitest run --coverage",
"typecheck": "tsc --noEmit",
"lint": "oxlint",
"lint:fix": "oxlint --fix",
"fmt": "oxfmt --check",
"fmt:fix": "oxfmt",
"check": "npm run lint && npm run fmt && npm run typecheck && npm test"
},
"dependencies": {
"@hapi/boom": "^10.0.1",
"@hapi/hoek": "^12.0.0-rc.0"
},
"devDependencies": {
"@hapi/oxc-plugin": "^1.0.4",
"@types/node": "^22",
"@vitest/coverage-v8": "^4.1.10",
"oxfmt": "^0.61.0",
"oxlint": "^1.76.0",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
},
"engines": {
"node": ">=22"
}
}
Loading