Skip to content

Commit a4efa37

Browse files
committed
Refactor
No longer accepts a string as the first argument. Signed-off-by: Richie Bendall <[email protected]>
1 parent bacc534 commit a4efa37

File tree

11 files changed

+106
-4534
lines changed

11 files changed

+106
-4534
lines changed

.gitignore

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
dist/*
2-
docs/*
1+
# Build directories
2+
dist/
3+
docs/
4+
5+
# Lock files
6+
package-lock.json
7+
yarn.lock
38

49
# Created by https://www.gitignore.io/api/node,linux,macos,windows
510
# Edit at https://www.gitignore.io/?templates=node,linux,macos,windows

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

package.json

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
"version": "0.0.0",
1212
"main": "dist/index.js",
1313
"files": [
14-
"src/**/*",
15-
"dist/**/*"
14+
"dist"
1615
],
1716
"engines": {
1817
"node": ">=10"
@@ -22,46 +21,33 @@
2221
"license": "MIT",
2322
"scripts": {
2423
"docs": "typedoc",
25-
"build": "tsc && yarn docs",
26-
"dev": "yarn build --watch",
24+
"build": "tsc && typedoc",
25+
"dev": "tsc --watch",
2726
"lint": "xo",
28-
"test": "yarn lint && ava"
27+
"test": "xo && ava"
2928
},
3029
"dependencies": {
31-
"@sindresorhus/is": "^2.0.0",
3230
"cheerio": "^1.0.0-rc.3",
3331
"content-type": "^1.0.4",
34-
"iconv-lite": "^0.5.0",
35-
"nice-try": "^2.0.0"
32+
"iconv-lite": "^0.6.2",
33+
"nice-try": "^2.0.1"
3634
},
3735
"devDependencies": {
38-
"@types/cheerio": "^0.22.13",
36+
"@richienb/tsconfig": "^0.1.1",
37+
"@richienb/typedoc": "^0.1.1",
38+
"@types/cheerio": "^0.22.21",
3939
"@types/content-type": "^1.1.3",
4040
"@types/nice-try": "^2.0.0",
41-
"ava": "^3.3.0",
42-
"eslint-config-richienb": "^0.3.0",
41+
"ava": "^3.12.1",
42+
"eslint-config-richienb": "^0.4.2",
4343
"node-fetch": "^2.6.0",
44-
"ts-node": "^8.5.4",
45-
"typedoc": "^0.16.4",
46-
"typescript": "^3.7.4",
47-
"xo": "^0.26.0"
48-
},
49-
"resolutions": {
50-
"eslint": "^6.8.0"
44+
"ts-node": "^9.0.0",
45+
"typedoc": "^0.19.0",
46+
"typescript": "^4.0.2",
47+
"xo": "^0.33.0"
5148
},
5249
"xo": {
53-
"extends": "richienb/ts",
54-
"overrides": [
55-
{
56-
"files": "test.js",
57-
"rules": {
58-
"import/default": 0,
59-
"node/no-missing-import": 0,
60-
"import/no-unresolved": 0,
61-
"node/no-unsupported-features/node-builtins": 0
62-
}
63-
}
64-
]
50+
"extends": "richienb"
6551
},
6652
"ava": {
6753
"extensions": [

source/index.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import getCharset from "./utils/get-charset"
2+
import {decode} from "iconv-lite"
3+
4+
/**
5+
* Detect buffer encoding and convert to target encoding
6+
* ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding
7+
*
8+
* @param content The content to convert.
9+
* @param headers HTTP Headers provided with a request.
10+
*/
11+
function convertBody(content: Buffer, headers?: Headers): string {
12+
// Turn raw buffers into a single utf-8 buffer
13+
return decode(
14+
content,
15+
getCharset(content, headers),
16+
)
17+
}
18+
19+
export = convertBody

source/utils/get-charset.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import {load} from "cheerio"
2+
import parseContentType from "./parse-content-type"
3+
4+
/**
5+
Get the charset of content.
6+
@param content The content to convert.
7+
@param headers HTTP Headers provided with the request.
8+
*/
9+
function getCharset(content: Buffer, headers?: Headers) {
10+
// Resulting charset
11+
let charset: string
12+
13+
// Try to extract content-type header
14+
const contentType = headers?.get("content-type")
15+
if (contentType) {
16+
charset = parseContentType(contentType)
17+
}
18+
19+
// No charset in content type, peek at response body for at most 1024 bytes
20+
const data = content.slice(0, 1024).toString()
21+
22+
// HTML5, HTML4 and XML
23+
if (!charset && data) {
24+
const $ = load(data)
25+
26+
charset = parseContentType(
27+
$("meta[charset]").attr("charset") || // HTML5
28+
$("meta[http-equiv][content]").attr("content") || // HTML4
29+
load(data.replace(/<\?(.*)\?>/im, "<$1>"), {xmlMode: true}).root().find("xml").attr("encoding"), // XML
30+
)
31+
32+
// Prevent decode issues when sites use incorrect encoding
33+
// ref: https://hsivonen.fi/encoding-menu/
34+
if (charset && ["gb2312", "gbk"].includes(charset.toLowerCase())) {
35+
charset = "gb18030"
36+
}
37+
}
38+
39+
return charset || "utf-8"
40+
}
41+
42+
export = getCharset

source/utils/parse-content-type.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {parse} from "content-type"
2+
import niceTry from "nice-try"
3+
4+
/**
5+
Get the character set from a Content-Type header.
6+
@param contentType The Content-Type HTTP header.
7+
*/
8+
function parseContentType(contentType: string) {
9+
return niceTry(() => parse(contentType))?.parameters?.charset ?? contentType
10+
}
11+
12+
export = parseContentType

src/index.ts

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/utils/get-charset.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

tsconfig.json

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
{
2-
"compilerOptions": {
3-
"esModuleInterop": true,
4-
"sourceMap": true,
5-
"declaration": true,
6-
"outDir": "dist/",
7-
"target": "es5"
8-
},
9-
"include": [
10-
"src/**/*"
11-
]
2+
"extends": "@richienb/tsconfig",
3+
"compilerOptions": {
4+
"outDir": "dist/"
5+
},
6+
"include": [
7+
"source"
8+
]
129
}

typedoc.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
{
2-
"out": "./docs",
3-
"mode": "file",
4-
"target": "ES6",
5-
"ignoreCompilerErrors": true
2+
"extends": "node_modules/@richienb/typedoc",
3+
"out": "./docs"
64
}

0 commit comments

Comments
 (0)