mirror of
https://github.com/cheeriojs/cheerio.git
synced 2026-02-21 20:31:35 +00:00
Bump dev deps, use @typescript-eslint type checked style preset (#4313)
This commit is contained in:
@@ -90,7 +90,8 @@
|
||||
"extends": [
|
||||
"plugin:expect-type/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-type-checked",
|
||||
"plugin:@typescript-eslint/stylistic-type-checked",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
|
||||
@@ -18,12 +18,17 @@ const benchmarkFilter = filterIndex >= 0 ? process.argv[filterIndex] : '';
|
||||
|
||||
const cheerioOnly = process.argv.includes('--cheerio-only');
|
||||
|
||||
interface SuiteOptions<T> {
|
||||
test($: CheerioAPI, data: T): void;
|
||||
setup($: CheerioAPI): T;
|
||||
}
|
||||
type SuiteOptions<T> = T extends void
|
||||
? {
|
||||
test(this: void, $: CheerioAPI): void;
|
||||
setup?: (this: void, $: CheerioAPI) => T;
|
||||
}
|
||||
: {
|
||||
test(this: void, $: CheerioAPI, data: T): void;
|
||||
setup(this: void, $: CheerioAPI): T;
|
||||
};
|
||||
|
||||
async function benchmark<T>(
|
||||
async function benchmark<T = void>(
|
||||
name: string,
|
||||
fileName: string,
|
||||
options: SuiteOptions<T>,
|
||||
@@ -40,7 +45,7 @@ async function benchmark<T>(
|
||||
|
||||
// Add Cheerio test
|
||||
const $ = load(markup);
|
||||
const setupData: T = setup($);
|
||||
const setupData = setup?.($) as T;
|
||||
|
||||
bench.add('cheerio', () => {
|
||||
test($, setupData);
|
||||
@@ -52,23 +57,20 @@ async function benchmark<T>(
|
||||
|
||||
jQueryScript.runInContext(dom.getInternalVMContext());
|
||||
|
||||
const setupData: T = setup(dom.window['$']);
|
||||
const setupData = setup?.(dom.window['$'] as CheerioAPI) as T;
|
||||
|
||||
bench.add('jsdom', () => test(dom.window['$'], setupData));
|
||||
bench.add('jsdom', () => test(dom.window['$'] as CheerioAPI, setupData));
|
||||
}
|
||||
|
||||
await bench.warmup(); // Make results more reliable, ref: https://github.com/tinylibs/tinybench/pull/50
|
||||
await bench.run();
|
||||
|
||||
console.table(bench.table());
|
||||
}
|
||||
|
||||
await benchmark<void>('Select all', 'jquery.html', {
|
||||
setup() {},
|
||||
await benchmark('Select all', 'jquery.html', {
|
||||
test: ($) => $('*').length,
|
||||
});
|
||||
await benchmark<void>('Select some', 'jquery.html', {
|
||||
setup() {},
|
||||
await benchmark('Select some', 'jquery.html', {
|
||||
test: ($) => $('li').length,
|
||||
});
|
||||
|
||||
@@ -116,7 +118,7 @@ await benchmark<Cheerio<Element>>('manipulation - remove', 'jquery.html', {
|
||||
},
|
||||
});
|
||||
|
||||
await benchmark<void>('manipulation - replaceWith', 'jquery.html', {
|
||||
await benchmark('manipulation - replaceWith', 'jquery.html', {
|
||||
setup($) {
|
||||
$('body').append('<div id="foo">');
|
||||
},
|
||||
@@ -147,8 +149,7 @@ await benchmark<Cheerio<Element>>('manipulation - html render', 'jquery.html', {
|
||||
|
||||
const HTML_INDEPENDENT_MARKUP =
|
||||
'<div class="foo"><div id="bar">bat<hr>baz</div> </div>'.repeat(6);
|
||||
await benchmark<void>('manipulation - html independent', 'jquery.html', {
|
||||
setup() {},
|
||||
await benchmark('manipulation - html independent', 'jquery.html', {
|
||||
test: ($) => $(HTML_INDEPENDENT_MARKUP).html(),
|
||||
});
|
||||
await benchmark<Cheerio<Element>>('manipulation - text', 'jquery.html', {
|
||||
|
||||
245
package-lock.json
generated
245
package-lock.json
generated
@@ -35,19 +35,19 @@
|
||||
"eslint-plugin-expect-type": "^0.6.2",
|
||||
"eslint-plugin-jsdoc": "^50.6.1",
|
||||
"eslint-plugin-n": "^17.15.1",
|
||||
"eslint-plugin-unicorn": "^55.0.0",
|
||||
"eslint-plugin-unicorn": "^56.0.1",
|
||||
"eslint-plugin-vitest": "^0.5.4",
|
||||
"husky": "^9.1.7",
|
||||
"jquery": "^3.7.1",
|
||||
"jsdom": "^24.1.1",
|
||||
"jsdom": "^25.0.1",
|
||||
"lint-staged": "^15.2.11",
|
||||
"prettier": "^3.4.2",
|
||||
"prettier-plugin-jsdoc": "^1.3.0",
|
||||
"tinybench": "^2.9.0",
|
||||
"tinybench": "^3.1.0",
|
||||
"tshy": "^3.0.2",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.5.4",
|
||||
"vitest": "^2.0.5"
|
||||
"typescript": "^5.7.2",
|
||||
"vitest": "^2.1.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
@@ -2282,9 +2282,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
|
||||
"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
|
||||
"version": "4.24.3",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
|
||||
"integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -2300,11 +2300,12 @@
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001587",
|
||||
"electron-to-chromium": "^1.4.668",
|
||||
"node-releases": "^2.0.14",
|
||||
"update-browserslist-db": "^1.0.13"
|
||||
"caniuse-lite": "^1.0.30001688",
|
||||
"electron-to-chromium": "^1.5.73",
|
||||
"node-releases": "^2.0.19",
|
||||
"update-browserslist-db": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
@@ -2344,9 +2345,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001609",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001609.tgz",
|
||||
"integrity": "sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==",
|
||||
"version": "1.0.30001690",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
|
||||
"integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -2361,7 +2362,8 @@
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/chai": {
|
||||
"version": "5.1.2",
|
||||
@@ -2609,13 +2611,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/core-js-compat": {
|
||||
"version": "3.37.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz",
|
||||
"integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==",
|
||||
"version": "3.39.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz",
|
||||
"integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.0"
|
||||
"browserslist": "^4.24.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -2623,10 +2625,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -2672,12 +2675,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cssstyle": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz",
|
||||
"integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz",
|
||||
"integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"rrweb-cssom": "^0.6.0"
|
||||
"rrweb-cssom": "^0.7.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
@@ -2862,10 +2866,11 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.736",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz",
|
||||
"integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==",
|
||||
"dev": true
|
||||
"version": "1.5.75",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz",
|
||||
"integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "10.4.0",
|
||||
@@ -2979,10 +2984,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
|
||||
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -3214,18 +3220,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-unicorn": {
|
||||
"version": "55.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-55.0.0.tgz",
|
||||
"integrity": "sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==",
|
||||
"version": "56.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz",
|
||||
"integrity": "sha512-FwVV0Uwf8XPfVnKSGpMg7NtlZh0G0gBarCaFcMUOoqPxXryxdYxTRRv4kH6B9TFCVIrjRXG+emcxIk2ayZilog==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.24.5",
|
||||
"@babel/helper-validator-identifier": "^7.24.7",
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"ci-info": "^4.0.0",
|
||||
"clean-regexp": "^1.0.0",
|
||||
"core-js-compat": "^3.37.0",
|
||||
"esquery": "^1.5.0",
|
||||
"globals": "^15.7.0",
|
||||
"core-js-compat": "^3.38.1",
|
||||
"esquery": "^1.6.0",
|
||||
"globals": "^15.9.0",
|
||||
"indent-string": "^4.0.0",
|
||||
"is-builtin-module": "^3.2.1",
|
||||
"jsesc": "^3.0.2",
|
||||
@@ -3233,7 +3240,7 @@
|
||||
"read-pkg-up": "^7.0.1",
|
||||
"regexp-tree": "^0.1.27",
|
||||
"regjsparser": "^0.10.0",
|
||||
"semver": "^7.6.1",
|
||||
"semver": "^7.6.3",
|
||||
"strip-indent": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3247,10 +3254,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-unicorn/node_modules/globals": {
|
||||
"version": "15.8.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz",
|
||||
"integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==",
|
||||
"version": "15.14.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz",
|
||||
"integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -4120,12 +4128,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom": {
|
||||
"version": "24.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz",
|
||||
"integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==",
|
||||
"version": "25.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz",
|
||||
"integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssstyle": "^4.0.1",
|
||||
"cssstyle": "^4.1.0",
|
||||
"data-urls": "^5.0.0",
|
||||
"decimal.js": "^10.4.3",
|
||||
"form-data": "^4.0.0",
|
||||
@@ -4138,7 +4147,7 @@
|
||||
"rrweb-cssom": "^0.7.1",
|
||||
"saxes": "^6.0.0",
|
||||
"symbol-tree": "^3.2.4",
|
||||
"tough-cookie": "^4.1.4",
|
||||
"tough-cookie": "^5.0.0",
|
||||
"w3c-xmlserializer": "^5.0.0",
|
||||
"webidl-conversions": "^7.0.0",
|
||||
"whatwg-encoding": "^3.1.1",
|
||||
@@ -4159,13 +4168,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom/node_modules/rrweb-cssom": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
|
||||
"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jsesc": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
|
||||
@@ -5225,10 +5227,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
|
||||
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
|
||||
"dev": true
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
||||
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
@@ -5649,13 +5652,6 @@
|
||||
"prettier": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/psl": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
||||
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
@@ -5665,13 +5661,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/querystringify": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@@ -5837,13 +5826,6 @@
|
||||
"jsesc": "bin/jsesc"
|
||||
}
|
||||
},
|
||||
"node_modules/requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.8",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
||||
@@ -6023,10 +6005,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rrweb-cssom": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
|
||||
"integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
|
||||
"dev": true
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
|
||||
"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
@@ -6516,11 +6499,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tinybench": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
|
||||
"integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-3.1.0.tgz",
|
||||
"integrity": "sha512-Km+oMh2xqNCxuyoUsqbRmHgFSd8sATh7v7xreP+kHN6x67w28Pawr83WmBxcaORvxkc0Ex6zgqK951yBnTFaaQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyexec": {
|
||||
"version": "0.3.1",
|
||||
@@ -6556,6 +6542,26 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tldts": {
|
||||
"version": "6.1.69",
|
||||
"resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.69.tgz",
|
||||
"integrity": "sha512-Oh/CqRQ1NXNY7cy9NkTPUauOWiTro0jEYZTioGbOmcQh6EC45oribyIMJp0OJO3677r13tO6SKdWoGZUx2BDFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tldts-core": "^6.1.69"
|
||||
},
|
||||
"bin": {
|
||||
"tldts": "bin/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/tldts-core": {
|
||||
"version": "6.1.69",
|
||||
"resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.69.tgz",
|
||||
"integrity": "sha512-nygxy9n2PBUFQUtAXAc122gGo+04/j5qr5TGQFZTHafTKYvmARVXt2cA5rgero2/dnXUfkdPtiJoKmrd3T+wdA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
@@ -6570,29 +6576,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
|
||||
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz",
|
||||
"integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.33",
|
||||
"punycode": "^2.1.1",
|
||||
"universalify": "^0.2.0",
|
||||
"url-parse": "^1.5.3"
|
||||
"tldts": "^6.1.32"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie/node_modules/universalify": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
@@ -7176,10 +7169,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
|
||||
"integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -7238,9 +7232,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.0.13",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
|
||||
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
||||
"integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -7256,9 +7250,10 @@
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"escalade": "^3.1.1",
|
||||
"picocolors": "^1.0.0"
|
||||
"escalade": "^3.2.0",
|
||||
"picocolors": "^1.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"update-browserslist-db": "cli.js"
|
||||
@@ -7276,17 +7271,6 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/url-parse": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||
@@ -7453,6 +7437,13 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vitest/node_modules/tinybench": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
|
||||
"integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/w3c-xmlserializer": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
||||
|
||||
10
package.json
10
package.json
@@ -141,19 +141,19 @@
|
||||
"eslint-plugin-expect-type": "^0.6.2",
|
||||
"eslint-plugin-jsdoc": "^50.6.1",
|
||||
"eslint-plugin-n": "^17.15.1",
|
||||
"eslint-plugin-unicorn": "^55.0.0",
|
||||
"eslint-plugin-unicorn": "^56.0.1",
|
||||
"eslint-plugin-vitest": "^0.5.4",
|
||||
"husky": "^9.1.7",
|
||||
"jquery": "^3.7.1",
|
||||
"jsdom": "^24.1.1",
|
||||
"jsdom": "^25.0.1",
|
||||
"lint-staged": "^15.2.11",
|
||||
"prettier": "^3.4.2",
|
||||
"prettier-plugin-jsdoc": "^1.3.0",
|
||||
"tinybench": "^2.9.0",
|
||||
"tinybench": "^3.1.0",
|
||||
"tshy": "^3.0.2",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.5.4",
|
||||
"vitest": "^2.0.5"
|
||||
"typescript": "^5.7.2",
|
||||
"vitest": "^2.1.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
|
||||
@@ -9,7 +9,11 @@ import { domEach, camelCase, cssCase } from '../utils.js';
|
||||
import { isTag, type AnyNode, type Element } from 'domhandler';
|
||||
import type { Cheerio } from '../cheerio.js';
|
||||
import { innerText, textContent } from 'domutils';
|
||||
const hasOwn = Object.prototype.hasOwnProperty;
|
||||
const hasOwn =
|
||||
// @ts-expect-error `hasOwn` is a standard object method
|
||||
(Object.hasOwn as (object: unknown, prop: string) => boolean) ??
|
||||
((object: unknown, prop: string) =>
|
||||
Object.prototype.hasOwnProperty.call(object, prop));
|
||||
const rspace = /\s+/;
|
||||
const dataAttrPrefix = 'data-';
|
||||
|
||||
@@ -56,7 +60,7 @@ function getAttr(
|
||||
return elem.attribs;
|
||||
}
|
||||
|
||||
if (hasOwn.call(elem.attribs, name)) {
|
||||
if (hasOwn(elem.attribs, name)) {
|
||||
// Get the (decoded) attribute
|
||||
return !xmlMode && rboolean.test(name) ? name : elem.attribs[name];
|
||||
}
|
||||
@@ -209,14 +213,14 @@ export function attr<T extends AnyNode>(
|
||||
setAttr(el, objName, objValue);
|
||||
}
|
||||
} else {
|
||||
setAttr(el, name as string, value as string);
|
||||
setAttr(el, name!, value!);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return arguments.length > 1
|
||||
? this
|
||||
: getAttr(this[0], name as string, this.options.xmlMode);
|
||||
: getAttr(this[0], name!, this.options.xmlMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,10 +237,10 @@ function getProp(
|
||||
el: Element,
|
||||
name: string,
|
||||
xmlMode?: boolean,
|
||||
): string | undefined | Element[keyof Element] {
|
||||
): string | undefined | boolean | Element[keyof Element] {
|
||||
return name in el
|
||||
? // @ts-expect-error TS doesn't like us accessing the value directly here.
|
||||
el[name]
|
||||
(el[name] as string | undefined)
|
||||
: !xmlMode && rboolean.test(name)
|
||||
? getAttr(el, name, false) !== undefined
|
||||
: getAttr(el, name, xmlMode);
|
||||
@@ -259,7 +263,11 @@ function setProp(el: Element, name: string, value: unknown, xmlMode?: boolean) {
|
||||
setAttr(
|
||||
el,
|
||||
name,
|
||||
!xmlMode && rboolean.test(name) ? (value ? '' : null) : `${value}`,
|
||||
!xmlMode && rboolean.test(name)
|
||||
? value
|
||||
? ''
|
||||
: null
|
||||
: `${value as string}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -396,14 +404,15 @@ export function prop<T extends AnyNode>(this: Cheerio<T>, name: string): string;
|
||||
export function prop<T extends AnyNode>(
|
||||
this: Cheerio<T>,
|
||||
name: string | Record<string, string | Element[keyof Element] | boolean>,
|
||||
value?:
|
||||
| ((
|
||||
this: Element,
|
||||
i: number,
|
||||
prop: string | undefined,
|
||||
) => string | Element[keyof Element] | boolean)
|
||||
| unknown,
|
||||
): Cheerio<T> | string | undefined | null | Element[keyof Element] | StyleProp {
|
||||
value?: unknown,
|
||||
):
|
||||
| Cheerio<T>
|
||||
| string
|
||||
| boolean
|
||||
| undefined
|
||||
| null
|
||||
| Element[keyof Element]
|
||||
| StyleProp {
|
||||
if (typeof name === 'string' && value === undefined) {
|
||||
const el = this[0];
|
||||
|
||||
@@ -552,7 +561,7 @@ function readAllData(el: DataElement): unknown {
|
||||
|
||||
const jsName = camelCase(domName.slice(dataAttrPrefix.length));
|
||||
|
||||
if (!hasOwn.call(el.data, jsName)) {
|
||||
if (!hasOwn(el.data, jsName)) {
|
||||
el.data![jsName] = parseDataValue(el.attribs[domName]);
|
||||
}
|
||||
}
|
||||
@@ -574,11 +583,11 @@ function readData(el: DataElement, name: string): unknown {
|
||||
const domName = dataAttrPrefix + cssCase(name);
|
||||
const data = el.data!;
|
||||
|
||||
if (hasOwn.call(data, name)) {
|
||||
if (hasOwn(data, name)) {
|
||||
return data[name];
|
||||
}
|
||||
|
||||
if (hasOwn.call(el.attribs, domName)) {
|
||||
if (hasOwn(el.attribs, domName)) {
|
||||
return (data[name] = parseDataValue(el.attribs[domName]));
|
||||
}
|
||||
|
||||
@@ -629,7 +638,7 @@ function parseDataValue(value: string): unknown {
|
||||
export function data<T extends AnyNode>(
|
||||
this: Cheerio<T>,
|
||||
name: string,
|
||||
): unknown | undefined;
|
||||
): unknown;
|
||||
/**
|
||||
* Method for getting all of an element's data attributes, for only the first
|
||||
* element in the matched set.
|
||||
@@ -698,7 +707,7 @@ export function data<T extends AnyNode>(
|
||||
this: Cheerio<T>,
|
||||
name?: string | Record<string, unknown>,
|
||||
value?: unknown,
|
||||
): unknown | Cheerio<T> | undefined | Record<string, unknown> {
|
||||
): unknown {
|
||||
const elem = this[0];
|
||||
|
||||
if (!elem || !isTag(elem)) return;
|
||||
@@ -716,7 +725,7 @@ export function data<T extends AnyNode>(
|
||||
domEach(this, (el) => {
|
||||
if (isTag(el)) {
|
||||
if (typeof name === 'object') setData(el, name);
|
||||
else setData(el, name, value as unknown);
|
||||
else setData(el, name, value);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
@@ -816,7 +825,7 @@ export function val<T extends AnyNode>(
|
||||
* @param name - Name of the attribute to remove.
|
||||
*/
|
||||
function removeAttribute(elem: Element, name: string) {
|
||||
if (!elem.attribs || !hasOwn.call(elem.attribs, name)) return;
|
||||
if (!elem.attribs || !hasOwn(elem.attribs, name)) return;
|
||||
|
||||
delete elem.attribs[name];
|
||||
}
|
||||
@@ -1030,7 +1039,7 @@ export function removeClass<T extends AnyNode, R extends ArrayLike<T>>(
|
||||
for (let j = 0; j < numClasses; j++) {
|
||||
const index = elClasses.indexOf(classes[j]);
|
||||
|
||||
if (index >= 0) {
|
||||
if (index !== -1) {
|
||||
elClasses.splice(index, 1);
|
||||
changed = true;
|
||||
|
||||
@@ -1115,9 +1124,9 @@ export function toggleClass<T extends AnyNode, R extends ArrayLike<T>>(
|
||||
const index = elementClasses.indexOf(classNames[j]);
|
||||
|
||||
// Add if stateValue === true or we are toggling and there is no value
|
||||
if (state >= 0 && index < 0) {
|
||||
if (state >= 0 && index === -1) {
|
||||
elementClasses.push(classNames[j]);
|
||||
} else if (state <= 0 && index >= 0) {
|
||||
} else if (state <= 0 && index !== -1) {
|
||||
// Otherwise remove but only if the item exists
|
||||
elementClasses.splice(index, 1);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@ interface ExtractDescriptor {
|
||||
|
||||
type ExtractValue = string | ExtractDescriptor | [string | ExtractDescriptor];
|
||||
|
||||
export interface ExtractMap {
|
||||
[key: string]: ExtractValue;
|
||||
}
|
||||
export type ExtractMap = Record<string, ExtractValue>;
|
||||
|
||||
type ExtractedValue<V extends ExtractValue, M extends ExtractMap> = V extends [
|
||||
string | ExtractDescriptor,
|
||||
|
||||
@@ -82,7 +82,7 @@ export function serializeArray<T extends AnyNode>(
|
||||
}
|
||||
>((_, elem) => {
|
||||
const $elem = this._make(elem);
|
||||
const name = $elem.attr('name') as string; // We have filtered for elements with a name before.
|
||||
const name = $elem.attr('name')!; // We have filtered for elements with a name before.
|
||||
// If there is no value set (e.g. `undefined`, `null`), then default value to empty
|
||||
const value = $elem.val() ?? '';
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import { domEach, isHtml, isCheerio } from '../utils.js';
|
||||
import { removeElement } from 'domutils';
|
||||
import type { Cheerio } from '../cheerio.js';
|
||||
import type { BasicAcceptedElems, AcceptedElems } from '../types.js';
|
||||
import { ElementType } from 'htmlparser2';
|
||||
|
||||
/**
|
||||
* Create an array of nodes, recursing into arrays and parsing strings if
|
||||
@@ -129,7 +130,7 @@ function uniqueSplice(
|
||||
newElems: AnyNode[],
|
||||
parent: ParentNode,
|
||||
): AnyNode[] {
|
||||
const spliceArgs: Parameters<typeof Array.prototype.splice> = [
|
||||
const spliceArgs: Parameters<AnyNode[]['splice']> = [
|
||||
spliceIdx,
|
||||
spliceCount,
|
||||
...newElems,
|
||||
@@ -152,7 +153,7 @@ function uniqueSplice(
|
||||
const oldSiblings: AnyNode[] = oldParent.children;
|
||||
const prevIdx = oldSiblings.indexOf(node);
|
||||
|
||||
if (prevIdx > -1) {
|
||||
if (prevIdx !== -1) {
|
||||
oldParent.children.splice(prevIdx, 1);
|
||||
if (parent === oldParent && spliceIdx > prevIdx) {
|
||||
spliceArgs[0]--;
|
||||
@@ -588,7 +589,9 @@ export function wrapAll<T extends AnyNode>(
|
||||
let elInsertLocation: Element | undefined;
|
||||
|
||||
for (let i = 0; i < wrap.length; i++) {
|
||||
if (wrap[i].type === 'tag') elInsertLocation = wrap[i] as Element;
|
||||
if (wrap[i].type === ElementType.Tag) {
|
||||
elInsertLocation = wrap[i] as Element;
|
||||
}
|
||||
}
|
||||
|
||||
let j = 0;
|
||||
@@ -599,8 +602,8 @@ export function wrapAll<T extends AnyNode>(
|
||||
*/
|
||||
while (elInsertLocation && j < elInsertLocation.children.length) {
|
||||
const child = elInsertLocation.children[j];
|
||||
if (child.type === 'tag') {
|
||||
elInsertLocation = child as Element;
|
||||
if (child.type === ElementType.Tag) {
|
||||
elInsertLocation = child;
|
||||
j = 0;
|
||||
} else {
|
||||
j++;
|
||||
@@ -652,7 +655,7 @@ export function after<T extends AnyNode>(
|
||||
|
||||
// If not found, move on
|
||||
/* istanbul ignore next */
|
||||
if (index < 0) return;
|
||||
if (index === -1) return;
|
||||
|
||||
const domSrc =
|
||||
typeof elems[0] === 'function'
|
||||
@@ -711,7 +714,7 @@ export function insertAfter<T extends AnyNode>(
|
||||
|
||||
// If not found, move on
|
||||
/* istanbul ignore next */
|
||||
if (index < 0) continue;
|
||||
if (index === -1) continue;
|
||||
|
||||
// Add cloned `this` element(s) after target element
|
||||
uniqueSplice(siblings, index + 1, 0, clonedSelf, parent);
|
||||
@@ -761,7 +764,7 @@ export function before<T extends AnyNode>(
|
||||
|
||||
// If not found, move on
|
||||
/* istanbul ignore next */
|
||||
if (index < 0) return;
|
||||
if (index === -1) return;
|
||||
|
||||
const domSrc =
|
||||
typeof elems[0] === 'function'
|
||||
@@ -818,7 +821,7 @@ export function insertBefore<T extends AnyNode>(
|
||||
|
||||
// If not found, move on
|
||||
/* istanbul ignore next */
|
||||
if (index < 0) return;
|
||||
if (index === -1) return;
|
||||
|
||||
// Add cloned `this` element(s) after target element
|
||||
uniqueSplice(siblings, index, 0, clonedSelf, parent);
|
||||
@@ -1097,8 +1100,9 @@ export function text<T extends AnyNode>(
|
||||
* @see {@link https://api.jquery.com/clone/}
|
||||
*/
|
||||
export function clone<T extends AnyNode>(this: Cheerio<T>): Cheerio<T> {
|
||||
const clone = Array.prototype.map.call(this.get(), (el) =>
|
||||
cloneNode(el, true),
|
||||
const clone = Array.prototype.map.call(
|
||||
this.get(),
|
||||
(el) => cloneNode(el, true) as T,
|
||||
) as T[];
|
||||
|
||||
// Add a root node around the cloned nodes
|
||||
|
||||
@@ -30,7 +30,8 @@ describe('$(...)', () => {
|
||||
describe('.load', () => {
|
||||
it('should throw a TypeError if given invalid input', () => {
|
||||
expect(() => {
|
||||
(load as any)();
|
||||
// @ts-expect-error Testing invalid input
|
||||
load();
|
||||
}).toThrow('cheerio.load() expects a string');
|
||||
});
|
||||
});
|
||||
@@ -858,7 +859,7 @@ describe('$(...)', () => {
|
||||
it('should yield each element', () => {
|
||||
// The equivalent of: for (const element of $('li')) ...
|
||||
const $li = $('li');
|
||||
const iterator = $li[Symbol.iterator]();
|
||||
const iterator = $li[Symbol.iterator]() as Iterator<Element, Element>;
|
||||
expect(iterator.next().value.attribs).toHaveProperty('class', 'apple');
|
||||
expect(iterator.next().value.attribs).toHaveProperty('class', 'orange');
|
||||
expect(iterator.next().value.attribs).toHaveProperty('class', 'pear');
|
||||
|
||||
@@ -1025,7 +1025,7 @@ export function get<T>(this: Cheerio<T>, i?: number): T | T[] {
|
||||
* @returns The contained items.
|
||||
*/
|
||||
export function toArray<T>(this: Cheerio<T>): T[] {
|
||||
return Array.prototype.slice.call(this);
|
||||
return (Array.prototype as T[]).slice.call(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1097,7 +1097,7 @@ export function slice<T>(
|
||||
start?: number,
|
||||
end?: number,
|
||||
): Cheerio<T> {
|
||||
return this._make(Array.prototype.slice.call(this, start, end));
|
||||
return this._make<T>(Array.prototype.slice.call(this, start, end));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1116,7 +1116,7 @@ export function slice<T>(
|
||||
* @see {@link https://api.jquery.com/end/}
|
||||
*/
|
||||
export function end<T>(this: Cheerio<T>): Cheerio<AnyNode> {
|
||||
return this.prevObject ?? this._make([]);
|
||||
return (this.prevObject as Cheerio<AnyNode> | null) ?? this._make([]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1166,6 +1166,8 @@ export function addBack<T extends AnyNode>(
|
||||
selector?: string,
|
||||
): Cheerio<AnyNode> {
|
||||
return this.prevObject
|
||||
? this.add(selector ? this.prevObject.filter(selector) : this.prevObject)
|
||||
? this.add<AnyNode, T>(
|
||||
selector ? this.prevObject.filter(selector) : this.prevObject,
|
||||
)
|
||||
: this;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
|
||||
import { parseDOM } from 'htmlparser2';
|
||||
import { type Cheerio } from './index.js';
|
||||
import { cheerio, fruits, food, noscript } from './__fixtures__/fixtures.js';
|
||||
import type { Element } from 'domhandler';
|
||||
import type { AnyNode, Element } from 'domhandler';
|
||||
|
||||
declare module './index.js' {
|
||||
interface Cheerio<T> {
|
||||
@@ -10,7 +10,7 @@ declare module './index.js' {
|
||||
context: Cheerio<T>;
|
||||
args: unknown[];
|
||||
};
|
||||
foo(): void;
|
||||
foo(this: void): void;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,17 +221,23 @@ describe('cheerio', () => {
|
||||
});
|
||||
|
||||
it('(extended Array) should not interfere with prototype methods (issue #119)', () => {
|
||||
const extended: any = [];
|
||||
const extended: AnyNode[] = [];
|
||||
// @ts-expect-error - Ignore for testing
|
||||
extended.find =
|
||||
// @ts-expect-error - Ignore for testing
|
||||
extended.children =
|
||||
// @ts-expect-error - Ignore for testing
|
||||
extended.each =
|
||||
function () {
|
||||
/* Ignore */
|
||||
};
|
||||
const $empty = cheerio(extended);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
expect($empty.find).toBe(cheerio.prototype.find);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
expect($empty.children).toBe(cheerio.prototype.children);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
expect($empty.each).toBe(cheerio.prototype.each);
|
||||
});
|
||||
|
||||
@@ -360,7 +366,9 @@ describe('cheerio', () => {
|
||||
it('should honor extensions defined on `prototype` property', () => {
|
||||
const $ = cheerio.load('<div>');
|
||||
|
||||
$.prototype.myPlugin = function (...args: unknown[]) {
|
||||
($.prototype as Cheerio<AnyNode>).myPlugin = function (
|
||||
...args: unknown[]
|
||||
) {
|
||||
return {
|
||||
context: this,
|
||||
args,
|
||||
@@ -394,7 +402,7 @@ describe('cheerio', () => {
|
||||
const $a = cheerio.load('<div>');
|
||||
const $b = cheerio.load('<div>');
|
||||
|
||||
$a.prototype.foo = function () {
|
||||
($a.prototype as Cheerio<AnyNode>).foo = function () {
|
||||
/* Ignore */
|
||||
};
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ function noop() {
|
||||
|
||||
// Returns a promise and a resolve function
|
||||
function getPromise() {
|
||||
let cb: (error: Error | null | undefined, $: cheerio.CheerioAPI) => void;
|
||||
let cb!: (error: Error | null | undefined, $: cheerio.CheerioAPI) => void;
|
||||
const promise = new Promise<cheerio.CheerioAPI>((resolve, reject) => {
|
||||
cb = (error, $) => (error ? reject(error) : resolve($));
|
||||
});
|
||||
|
||||
return { promise, cb: cb! };
|
||||
return { promise, cb };
|
||||
}
|
||||
|
||||
const TEST_HTML = '<h1>Hello World</h1>';
|
||||
|
||||
@@ -228,10 +228,11 @@ export async function fromURL(
|
||||
|
||||
const promise = new Promise<CheerioAPI>((resolve, reject) => {
|
||||
undiciStream = undici.stream(url, requestOptions, (res) => {
|
||||
const contentType = res.headers['content-type'] ?? 'text/html';
|
||||
const mimeType = new MIMEType(
|
||||
Array.isArray(contentType) ? contentType[0] : contentType,
|
||||
);
|
||||
const contentTypeHeader = res.headers['content-type'] ?? 'text/html';
|
||||
const contentType = Array.isArray(contentTypeHeader)
|
||||
? contentTypeHeader[0]
|
||||
: contentTypeHeader;
|
||||
const mimeType = new MIMEType(contentType);
|
||||
|
||||
if (!mimeType.isHTML() && !mimeType.isXML()) {
|
||||
throw new RangeError(
|
||||
|
||||
19
src/load.ts
19
src/load.ts
@@ -8,6 +8,7 @@ import { Cheerio } from './cheerio.js';
|
||||
import { isHtml, isCheerio } from './utils.js';
|
||||
import type { AnyNode, Document, Element, ParentNode } from 'domhandler';
|
||||
import type { SelectorType, BasicAcceptedElems } from './types.js';
|
||||
import { ElementType } from 'htmlparser2';
|
||||
|
||||
type StaticType = typeof staticMethods;
|
||||
|
||||
@@ -104,7 +105,7 @@ export interface CheerioAPI extends StaticType {
|
||||
}
|
||||
|
||||
export function getLoad(
|
||||
parse: typeof Cheerio.prototype._parse,
|
||||
parse: Cheerio<AnyNode>['_parse'],
|
||||
render: (
|
||||
dom: AnyNode | ArrayLike<AnyNode>,
|
||||
options: InternalOptions,
|
||||
@@ -209,7 +210,7 @@ export function getLoad(
|
||||
const instance = new LoadedCheerio(elements, rootInstance, options);
|
||||
|
||||
if (elements) {
|
||||
return instance as any;
|
||||
return instance as Cheerio<Result>;
|
||||
}
|
||||
|
||||
if (typeof selector !== 'string') {
|
||||
@@ -243,7 +244,7 @@ export function getLoad(
|
||||
: rootInstance;
|
||||
|
||||
// If we still don't have a context, return
|
||||
if (!searchContext) return instance as any;
|
||||
if (!searchContext) return instance as Cheerio<Result>;
|
||||
|
||||
/*
|
||||
* #id, .class, tag
|
||||
@@ -267,11 +268,15 @@ export function getLoad(
|
||||
};
|
||||
}
|
||||
|
||||
function isNode(obj: any): obj is AnyNode {
|
||||
function isNode(obj: unknown): obj is AnyNode {
|
||||
return (
|
||||
// @ts-expect-error: TS doesn't know about the `name` property.
|
||||
!!obj.name ||
|
||||
obj.type === 'root' ||
|
||||
obj.type === 'text' ||
|
||||
obj.type === 'comment'
|
||||
// @ts-expect-error: TS doesn't know about the `type` property.
|
||||
obj.type === ElementType.Root ||
|
||||
// @ts-expect-error: TS doesn't know about the `type` property.
|
||||
obj.type === ElementType.Text ||
|
||||
// @ts-expect-error: TS doesn't know about the `type` property.
|
||||
obj.type === ElementType.Comment
|
||||
);
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ describe('parse', () => {
|
||||
expect(childNodes[0].previousSibling).toBe(null);
|
||||
expect(childNodes[0].nextSibling).toBe(childNodes[1]);
|
||||
expect(childNodes[0].parentNode).toBe(root);
|
||||
expect((childNodes[0] as Element).childNodes).toHaveLength(0);
|
||||
expect(childNodes[0].childNodes).toHaveLength(0);
|
||||
expect(childNodes[0].firstChild).toBe(null);
|
||||
expect(childNodes[0].lastChild).toBe(null);
|
||||
|
||||
@@ -335,23 +335,17 @@ describe('parse', () => {
|
||||
false,
|
||||
null,
|
||||
);
|
||||
const childNodes = root.childNodes as Element[];
|
||||
|
||||
expect(childNodes[0].tagName).toBe('table');
|
||||
expect(childNodes[0].childNodes.length).toBe(1);
|
||||
expect(childNodes[0].childNodes[0]).toHaveProperty('tagName', 'tbody');
|
||||
expect((childNodes[0] as any).childNodes[0].childNodes[0]).toHaveProperty(
|
||||
'tagName',
|
||||
'tr',
|
||||
);
|
||||
expect(
|
||||
(childNodes[0] as any).childNodes[0].childNodes[0].childNodes[0]
|
||||
.tagName,
|
||||
).toBe('td');
|
||||
expect(
|
||||
(childNodes[0] as any).childNodes[0].childNodes[0].childNodes[0]
|
||||
.childNodes[0].data,
|
||||
).toBe('bar');
|
||||
const table = root.childNodes[0] as Element;
|
||||
expect(table.tagName).toBe('table');
|
||||
expect(table.childNodes.length).toBe(1);
|
||||
const tbody = table.childNodes[0] as Element;
|
||||
expect(table.childNodes[0]).toHaveProperty('tagName', 'tbody');
|
||||
const tr = tbody.childNodes[0] as Element;
|
||||
expect(tr).toHaveProperty('tagName', 'tr');
|
||||
const td = tr.childNodes[0] as Element;
|
||||
expect(td).toHaveProperty('tagName', 'td');
|
||||
expect(td.childNodes[0]).toHaveProperty('data', 'bar');
|
||||
});
|
||||
|
||||
it('Should parse custom tag <line>', () => {
|
||||
|
||||
@@ -152,14 +152,14 @@ export function text(
|
||||
export function parseHTML(
|
||||
this: CheerioAPI,
|
||||
data: string,
|
||||
context?: unknown | boolean,
|
||||
context?: unknown,
|
||||
keepScripts?: boolean,
|
||||
): AnyNode[];
|
||||
export function parseHTML(this: CheerioAPI, data?: '' | null): null;
|
||||
export function parseHTML(
|
||||
this: CheerioAPI,
|
||||
data?: string | null,
|
||||
context?: unknown | boolean,
|
||||
context?: unknown,
|
||||
keepScripts = typeof context === 'boolean' ? context : false,
|
||||
): AnyNode[] | null {
|
||||
if (!data || typeof data !== 'string') {
|
||||
|
||||
20
src/utils.ts
20
src/utils.ts
@@ -8,8 +8,10 @@ import type { Cheerio } from './cheerio.js';
|
||||
* @param maybeCheerio - The object to check.
|
||||
* @returns Whether the object is a Cheerio instance.
|
||||
*/
|
||||
export function isCheerio<T>(maybeCheerio: any): maybeCheerio is Cheerio<T> {
|
||||
return maybeCheerio.cheerio != null;
|
||||
export function isCheerio<T>(
|
||||
maybeCheerio: unknown,
|
||||
): maybeCheerio is Cheerio<T> {
|
||||
return (maybeCheerio as Cheerio<T>).cheerio != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21,7 +23,7 @@ export function isCheerio<T>(maybeCheerio: any): maybeCheerio is Cheerio<T> {
|
||||
* @returns String in camel case notation.
|
||||
*/
|
||||
export function camelCase(str: string): string {
|
||||
return str.replace(/[._-](\w|$)/g, (_, x) => x.toUpperCase());
|
||||
return str.replace(/[._-](\w|$)/g, (_, x) => (x as string).toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +60,7 @@ export function domEach<
|
||||
return array;
|
||||
}
|
||||
|
||||
const enum CharacterCodes {
|
||||
const enum CharacterCode {
|
||||
LowerA = 97,
|
||||
LowerZ = 122,
|
||||
UpperA = 65,
|
||||
@@ -80,14 +82,14 @@ const enum CharacterCodes {
|
||||
export function isHtml(str: string): boolean {
|
||||
const tagStart = str.indexOf('<');
|
||||
|
||||
if (tagStart < 0 || tagStart > str.length - 3) return false;
|
||||
if (tagStart === -1 || tagStart > str.length - 3) return false;
|
||||
|
||||
const tagChar = str.charCodeAt(tagStart + 1);
|
||||
const tagChar = str.charCodeAt(tagStart + 1) as CharacterCode;
|
||||
|
||||
return (
|
||||
((tagChar >= CharacterCodes.LowerA && tagChar <= CharacterCodes.LowerZ) ||
|
||||
(tagChar >= CharacterCodes.UpperA && tagChar <= CharacterCodes.UpperZ) ||
|
||||
tagChar === CharacterCodes.Exclamation) &&
|
||||
((tagChar >= CharacterCode.LowerA && tagChar <= CharacterCode.LowerZ) ||
|
||||
(tagChar >= CharacterCode.UpperA && tagChar <= CharacterCode.UpperZ) ||
|
||||
tagChar === CharacterCode.Exclamation) &&
|
||||
str.includes('>', tagStart + 2)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import { defineConfig, type ViteUserConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
const config: ViteUserConfig = defineConfig({
|
||||
test: {
|
||||
coverage: {
|
||||
exclude: [
|
||||
@@ -13,3 +13,5 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default config;
|
||||
|
||||
Reference in New Issue
Block a user