or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Negotiator

1

2

Negotiator is an HTTP content negotiation library for Node.js applications that automatically selects the most appropriate response format based on client preferences expressed in HTTP Accept headers. It supports negotiation for media types, languages, character sets, and encodings, parsing quality values and priority rankings to determine optimal matches from available options.

3

4

## Package Information

5

6

- **Package Name**: negotiator

7

- **Package Type**: npm

8

- **Language**: JavaScript (Node.js)

9

- **Installation**: `npm install negotiator`

10

11

## Core Imports

12

13

```javascript

14

const Negotiator = require('negotiator');

15

```

16

17

## Basic Usage

18

19

```javascript

20

const Negotiator = require('negotiator');

21

22

// Create negotiator from request object

23

const negotiator = new Negotiator(request);

24

25

// Negotiate media types

26

const availableTypes = ['text/html', 'application/json', 'text/plain'];

27

const preferredType = negotiator.mediaType(availableTypes);

28

// Returns: 'text/html' (if client prefers HTML)

29

30

// Negotiate languages

31

const availableLanguages = ['en', 'es', 'fr'];

32

const preferredLanguage = negotiator.language(availableLanguages);

33

// Returns: 'en' (if client prefers English)

34

35

// Negotiate encodings

36

const availableEncodings = ['gzip', 'identity'];

37

const preferredEncoding = negotiator.encoding(availableEncodings);

38

// Returns: 'gzip' (if client accepts gzip)

39

```

40

41

## Architecture

42

43

Negotiator is built around a single constructor class that provides:

44

45

- **Constructor-based API**: Create instances from HTTP request objects containing Accept headers

46

- **Negotiation Methods**: Methods for each HTTP Accept header type (Accept, Accept-Language, Accept-Charset, Accept-Encoding)

47

- **Quality Value Parsing**: Automatic parsing of q-values and priority rankings according to RFC 2616

48

- **Backward Compatibility**: Legacy method aliases for older API versions

49

50

## Capabilities

51

52

### Media Type Negotiation

53

54

Negotiates the best media type from the Accept header based on client preferences and available options.

55

56

```javascript { .api }

57

/**

58

* Create a Negotiator instance from a request object

59

* @param {Object} request - HTTP request object with headers property

60

*/

61

function Negotiator(request);

62

63

/**

64

* Returns the most preferred media type from client

65

* @param {string[]} [available] - Array of available media types

66

* @returns {string|undefined} Most preferred media type, '*/*' if no Accept header, or undefined if none match

67

*/

68

Negotiator.prototype.mediaType(available);

69

70

/**

71

* Returns array of preferred media types ordered by client preference

72

* @param {string[]} [available] - Array of available media types

73

* @returns {string[]} Array of media types in preference order

74

*/

75

Negotiator.prototype.mediaTypes(available);

76

```

77

78

**Usage Examples:**

79

80

```javascript

81

const negotiator = new Negotiator(request);

82

83

// Get all client preferences in order

84

const allTypes = negotiator.mediaTypes();

85

// Returns: ['text/html', 'application/json', 'text/plain']

86

87

// Get best match from available types

88

const available = ['application/json', 'text/plain'];

89

const best = negotiator.mediaType(available);

90

// Returns: 'application/json' (if client prefers JSON over plain text)

91

```

92

93

### Language Negotiation

94

95

Negotiates the best language from the Accept-Language header based on client preferences and available options.

96

97

```javascript { .api }

98

/**

99

* Returns the most preferred language from client

100

* @param {string[]} [available] - Array of available languages

101

* @returns {string|undefined} Most preferred language, '*' if no Accept-Language header, or undefined if none match

102

*/

103

Negotiator.prototype.language(available);

104

105

/**

106

* Returns array of preferred languages ordered by client preference

107

* @param {string[]} [available] - Array of available languages

108

* @returns {string[]} Array of languages in preference order

109

*/

110

Negotiator.prototype.languages(available);

111

```

112

113

**Usage Examples:**

114

115

```javascript

116

const negotiator = new Negotiator(request);

117

118

// Get client language preferences

119

const languages = negotiator.languages();

120

// Returns: ['en-US', 'en', 'es'] (based on Accept-Language header)

121

122

// Find best match from available languages

123

const available = ['en', 'fr', 'de'];

124

const bestLanguage = negotiator.language(available);

125

// Returns: 'en' (if client prefers English)

126

```

127

128

### Charset Negotiation

129

130

Negotiates the best character set from the Accept-Charset header based on client preferences and available options.

131

132

```javascript { .api }

133

/**

134

* Returns the most preferred charset from client

135

* @param {string[]} [available] - Array of available charsets

136

* @returns {string|undefined} Most preferred charset, '*' if no Accept-Charset header, or undefined if none match

137

*/

138

Negotiator.prototype.charset(available);

139

140

/**

141

* Returns array of preferred charsets ordered by client preference

142

* @param {string[]} [available] - Array of available charsets

143

* @returns {string[]} Array of charsets in preference order

144

*/

145

Negotiator.prototype.charsets(available);

146

```

147

148

**Usage Examples:**

149

150

```javascript

151

const negotiator = new Negotiator(request);

152

153

// Get charset preferences

154

const charsets = negotiator.charsets();

155

// Returns: ['utf-8', 'iso-8859-1'] (if no Accept-Charset, defaults to '*')

156

157

// Find best charset match

158

const available = ['utf-8', 'iso-8859-1', 'ascii'];

159

const bestCharset = negotiator.charset(available);

160

// Returns: 'utf-8' (if client prefers UTF-8)

161

```

162

163

### Encoding Negotiation

164

165

Negotiates the best encoding from the Accept-Encoding header based on client preferences and available options. Supports preferred encoding arrays for tie-breaking.

166

167

```javascript { .api }

168

/**

169

* Returns the most preferred encoding from client

170

* @param {string[]} [available] - Array of available encodings

171

* @param {Object} [options] - Options object

172

* @param {string[]} [options.preferred] - Preferred encodings for tie-breaking

173

* @returns {string|undefined} Most preferred encoding, 'identity' if no Accept-Encoding header, or undefined if none match

174

*/

175

Negotiator.prototype.encoding(available, options);

176

177

/**

178

* Returns array of preferred encodings ordered by client preference

179

* @param {string[]} [available] - Array of available encodings

180

* @param {Object} [options] - Options object

181

* @param {string[]} [options.preferred] - Preferred encodings for tie-breaking

182

* @returns {string[]} Array of encodings in preference order

183

*/

184

Negotiator.prototype.encodings(available, options);

185

```

186

187

**Usage Examples:**

188

189

```javascript

190

const negotiator = new Negotiator(request);

191

192

// Get encoding preferences

193

const encodings = negotiator.encodings();

194

// Returns: ['gzip', 'deflate', 'identity'] (based on Accept-Encoding)

195

196

// Find best encoding with server preferences

197

const available = ['gzip', 'deflate', 'identity'];

198

const options = { preferred: ['gzip', 'deflate'] };

199

const bestEncoding = negotiator.encoding(available, options);

200

// Returns: 'gzip' (if client accepts and server prefers gzip)

201

202

// Identity encoding is automatically added with lowest quality if not specified

203

const identityIncluded = negotiator.encodings(['gzip']);

204

// Returns: ['gzip', 'identity'] (identity added automatically)

205

```

206

207

## Backward Compatibility Methods

208

209

Legacy method names are supported for backward compatibility:

210

211

```javascript { .api }

212

// These are aliases to the main methods

213

Negotiator.prototype.preferredCharset = Negotiator.prototype.charset;

214

Negotiator.prototype.preferredCharsets = Negotiator.prototype.charsets;

215

Negotiator.prototype.preferredEncoding = Negotiator.prototype.encoding;

216

Negotiator.prototype.preferredEncodings = Negotiator.prototype.encodings;

217

Negotiator.prototype.preferredLanguage = Negotiator.prototype.language;

218

Negotiator.prototype.preferredLanguages = Negotiator.prototype.languages;

219

Negotiator.prototype.preferredMediaType = Negotiator.prototype.mediaType;

220

Negotiator.prototype.preferredMediaTypes = Negotiator.prototype.mediaTypes;

221

```

222

223

## Error Handling

224

225

**Single methods** (`.mediaType()`, `.language()`, `.charset()`, `.encoding()`):

226

- Return default values when no Accept header is present (`*/*`, `*`, `*`, `identity` respectively)

227

- Return `undefined` when no acceptable match is found from available options

228

229

**Array methods** (`.mediaTypes()`, `.languages()`, `.charsets()`, `.encodings()`):

230

- Return arrays with default values when no Accept header is present

231

- Return arrays with acceptable matches in preference order

232

- Return empty arrays when no acceptable matches are found

233

234

```javascript

235

const negotiator = new Negotiator(request);

236

237

// No matching media type from available options

238

const result = negotiator.mediaType(['application/xml']);

239

// Returns: undefined (if client doesn't accept XML)

240

241

// No Accept header present - returns default

242

const defaultType = negotiator.mediaType();

243

// Returns: '*/*' (RFC 2616 default)

244

245

// Array method with no header - returns default array

246

const allTypes = negotiator.mediaTypes();

247

// Returns: ['*/*'] (default array when no Accept header)

248

```

249

250

## Quality Values and RFC 2616 Compliance

251

252

Negotiator follows RFC 2616 specifications for HTTP content negotiation:

253

254

- Quality values (q-values) are parsed and respected (e.g., `text/html;q=0.8`)

255

- Missing headers are treated according to RFC defaults (e.g., `*` for charset, `*/*` for media types)

256

- Specificity rules are applied (more specific matches take precedence)

257

- Wildcard matching is supported (`*/*`, `text/*`, `*`)

258

259

## Types

260

261

```javascript { .api }

262

/**

263

* HTTP request object expected by Negotiator constructor

264

*/

265

interface Request {

266

headers: {

267

accept?: string;

268

'accept-language'?: string;

269

'accept-charset'?: string;

270

'accept-encoding'?: string;

271

};

272

}

273

274

/**

275

* Options object for encoding negotiation

276

*/

277

interface EncodingOptions {

278

preferred?: string[];

279

}

280

```