From 53abee62923ed3535f4de5b23e84566c57f825a6 Mon Sep 17 00:00:00 2001 From: ota-meshi Date: Wed, 2 Apr 2025 22:00:20 +0900 Subject: [PATCH 1/2] Add rules for Uint8Array to/from Base64 and Hex --- docs/configs/index.md | 28 ++++ docs/rules/index.md | 13 ++ docs/rules/no-uint8array-frombase64.md | 33 +++++ docs/rules/no-uint8array-fromhex.md | 33 +++++ .../no-uint8array-prototype-setfrombase64.md | 62 ++++++++ .../no-uint8array-prototype-setfromhex.md | 62 ++++++++ .../rules/no-uint8array-prototype-tobase64.md | 62 ++++++++ docs/rules/no-uint8array-prototype-tohex.md | 62 ++++++++ lib/configs/flat/no-arraybuffer-base64.js | 21 +++ lib/configs/flat/no-new-in-esnext.js | 6 + lib/configs/no-arraybuffer-base64.js | 17 +++ lib/configs/no-new-in-esnext.js | 6 + lib/index.js | 8 ++ .../no-nonstandard-typed-array-properties.js | 22 ++- ...andard-typed-array-prototype-properties.js | 13 +- lib/rules/no-uint8array-frombase64.js | 34 +++++ lib/rules/no-uint8array-fromhex.js | 34 +++++ .../no-uint8array-prototype-setfrombase64.js | 38 +++++ .../no-uint8array-prototype-setfromhex.js | 38 +++++ lib/rules/no-uint8array-prototype-tobase64.js | 37 +++++ lib/rules/no-uint8array-prototype-tohex.js | 37 +++++ lib/util/type-checker/es-types.js | 26 +++- lib/util/well-known-properties.js | 17 +++ scripts/new-rule.js | 2 +- scripts/proposals.js | 4 + .../no-nonstandard-typed-array-properties.js | 4 + ...andard-typed-array-prototype-properties.js | 4 + tests/lib/rules/no-uint8array-frombase64.js | 29 ++++ tests/lib/rules/no-uint8array-fromhex.js | 29 ++++ .../no-uint8array-prototype-setfrombase64.js | 135 ++++++++++++++++++ .../no-uint8array-prototype-setfromhex.js | 135 ++++++++++++++++++ .../rules/no-uint8array-prototype-tobase64.js | 135 ++++++++++++++++++ .../rules/no-uint8array-prototype-tohex.js | 135 ++++++++++++++++++ 33 files changed, 1307 insertions(+), 14 deletions(-) create mode 100644 docs/rules/no-uint8array-frombase64.md create mode 100644 docs/rules/no-uint8array-fromhex.md create mode 100644 docs/rules/no-uint8array-prototype-setfrombase64.md create mode 100644 docs/rules/no-uint8array-prototype-setfromhex.md create mode 100644 docs/rules/no-uint8array-prototype-tobase64.md create mode 100644 docs/rules/no-uint8array-prototype-tohex.md create mode 100644 lib/configs/flat/no-arraybuffer-base64.js create mode 100644 lib/configs/no-arraybuffer-base64.js create mode 100644 lib/rules/no-uint8array-frombase64.js create mode 100644 lib/rules/no-uint8array-fromhex.js create mode 100644 lib/rules/no-uint8array-prototype-setfrombase64.js create mode 100644 lib/rules/no-uint8array-prototype-setfromhex.js create mode 100644 lib/rules/no-uint8array-prototype-tobase64.js create mode 100644 lib/rules/no-uint8array-prototype-tohex.js create mode 100644 tests/lib/rules/no-uint8array-frombase64.js create mode 100644 tests/lib/rules/no-uint8array-fromhex.js create mode 100644 tests/lib/rules/no-uint8array-prototype-setfrombase64.js create mode 100644 tests/lib/rules/no-uint8array-prototype-setfromhex.js create mode 100644 tests/lib/rules/no-uint8array-prototype-tobase64.js create mode 100644 tests/lib/rules/no-uint8array-prototype-tohex.js diff --git a/docs/configs/index.md b/docs/configs/index.md index 0ab22bbf..200bafa3 100644 --- a/docs/configs/index.md +++ b/docs/configs/index.md @@ -1029,6 +1029,34 @@ export default [ } ``` +## no-arraybuffer-base64 + +disallow proposal ES2026 [Uint8Array to/from Base64 and Hex](https://github.com/tc39/proposal-arraybuffer-base64)\ +⚠️ This config will be changed in the minor versions of this plugin. + +This configs includes rules for [es-x/no-uint8array-frombase64](../rules/no-uint8array-frombase64.md), [es-x/no-uint8array-fromhex](../rules/no-uint8array-fromhex.md), [es-x/no-uint8array-prototype-setfrombase64](../rules/no-uint8array-prototype-setfrombase64.md), [es-x/no-uint8array-prototype-setfromhex](../rules/no-uint8array-prototype-setfromhex.md), [es-x/no-uint8array-prototype-tobase64](../rules/no-uint8array-prototype-tobase64.md), and [es-x/no-uint8array-prototype-tohex](../rules/no-uint8array-prototype-tohex.md). + +### [Config (Flat Config)] + +eslint.config.js: + +```js +import pluginESx from "eslint-plugin-es-x" +export default [ + pluginESx.configs['flat/no-arraybuffer-base64'] +] +``` + +### [Legacy Config] + +.eslintrc.*: + +```json +{ + "extends": ["plugin:es-x/no-arraybuffer-base64"], +} +``` + ## no-float16array disallow proposal ES2025 [Float16Array](https://github.com/tc39/proposal-float16array)\ diff --git a/docs/rules/index.md b/docs/rules/index.md index a087ad9c..bd432952 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -4,6 +4,19 @@ This plugin provides the following rules. - 🔧 mark means that the `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by the rule. +## ES2026 + +There is a config that enables the rules in this category: [`no-new-in-esnext`] + +| Rule ID | Description | | +|:--------|:------------|:--:| +| [es-x/no-uint8array-frombase64](./no-uint8array-frombase64.md) | disallow the `Uint8Array.fromBase64` method. | | +| [es-x/no-uint8array-fromhex](./no-uint8array-fromhex.md) | disallow the `Uint8Array.fromHex` method. | | +| [es-x/no-uint8array-prototype-setfrombase64](./no-uint8array-prototype-setfrombase64.md) | disallow the `Uint8Array.prototype.setFromBase64` method. | | +| [es-x/no-uint8array-prototype-setfromhex](./no-uint8array-prototype-setfromhex.md) | disallow the `Uint8Array.prototype.setFromHex` method. | | +| [es-x/no-uint8array-prototype-tobase64](./no-uint8array-prototype-tobase64.md) | disallow the `Uint8Array.prototype.toBase64` method. | | +| [es-x/no-uint8array-prototype-tohex](./no-uint8array-prototype-tohex.md) | disallow the `Uint8Array.prototype.toHex` method. | | + ## ES2025 There is a config that enables the rules in this category: [`no-new-in-esnext`] diff --git a/docs/rules/no-uint8array-frombase64.md b/docs/rules/no-uint8array-frombase64.md new file mode 100644 index 00000000..806fe61c --- /dev/null +++ b/docs/rules/no-uint8array-frombase64.md @@ -0,0 +1,33 @@ +--- +title: "es-x/no-uint8array-frombase64" +description: "disallow the `Uint8Array.fromBase64` method" +--- + +# es-x/no-uint8array-frombase64 +> disallow the `Uint8Array.fromBase64` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-arraybuffer-base64] and [no-new-in-esnext] + +This rule reports ES2026 [`Uint8Array.fromBase64` method](https://github.com/tc39/proposal-arraybuffer-base64) as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-uint8array-frombase64: error */ +Uint8Array.fromBase64(string) +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-frombase64.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-uint8array-frombase64.js) + +[no-arraybuffer-base64]: ../configs/index.md#no-arraybuffer-base64 +[no-new-in-esnext]: ../configs/index.md#no-new-in-esnext diff --git a/docs/rules/no-uint8array-fromhex.md b/docs/rules/no-uint8array-fromhex.md new file mode 100644 index 00000000..0233fbdd --- /dev/null +++ b/docs/rules/no-uint8array-fromhex.md @@ -0,0 +1,33 @@ +--- +title: "es-x/no-uint8array-fromhex" +description: "disallow the `Uint8Array.fromHex` method" +--- + +# es-x/no-uint8array-fromhex +> disallow the `Uint8Array.fromHex` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-arraybuffer-base64] and [no-new-in-esnext] + +This rule reports ES2026 [`Uint8Array.fromHex` method](https://github.com/tc39/proposal-arraybuffer-hex) as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-uint8array-fromhex: error */ +Uint8Array.fromHex(string) +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-fromhex.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-uint8array-fromhex.js) + +[no-arraybuffer-base64]: ../configs/index.md#no-arraybuffer-base64 +[no-new-in-esnext]: ../configs/index.md#no-new-in-esnext diff --git a/docs/rules/no-uint8array-prototype-setfrombase64.md b/docs/rules/no-uint8array-prototype-setfrombase64.md new file mode 100644 index 00000000..70a04262 --- /dev/null +++ b/docs/rules/no-uint8array-prototype-setfrombase64.md @@ -0,0 +1,62 @@ +--- +title: "es-x/no-uint8array-prototype-setfrombase64" +description: "disallow the `Uint8Array.prototype.setFromBase64` method" +--- + +# es-x/no-uint8array-prototype-setfrombase64 +> disallow the `Uint8Array.prototype.setFromBase64` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-arraybuffer-base64] and [no-new-in-esnext] + +This rule reports ES2026 [`Uint8Array.prototype.setFromBase64` method](https://github.com/tc39/proposal-arraybuffer-base64) as errors. + +This rule is silent by default because it's hard to know types. You need to configure [the aggressive mode](../#the-aggressive-mode) or TypeScript in order to enable this rule. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-uint8array-prototype-setfrombase64: error */ +const arr = new Uint8Array(8); +const { read, written } = target.setFromBase64('Zm9vYmFy') +``` + + + +This rule has an option. + +```jsonc +{ + "rules": { + "es-x/no-uint8array-prototype-setfrombase64": [ + "error", + { + "aggressive": false, + "allowTestedProperty": false + } + ] + } +} +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +### allowTestedProperty: boolean + +Configure the allowTestedProperty mode for only this rule. +This is prior to the `settings['es-x'].allowTestedProperty` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-prototype-setfrombase64.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-uint8array-prototype-setfrombase64.js) + +[no-arraybuffer-base64]: ../configs/index.md#no-arraybuffer-base64 +[no-new-in-esnext]: ../configs/index.md#no-new-in-esnext diff --git a/docs/rules/no-uint8array-prototype-setfromhex.md b/docs/rules/no-uint8array-prototype-setfromhex.md new file mode 100644 index 00000000..40b42595 --- /dev/null +++ b/docs/rules/no-uint8array-prototype-setfromhex.md @@ -0,0 +1,62 @@ +--- +title: "es-x/no-uint8array-prototype-setfromhex" +description: "disallow the `Uint8Array.prototype.setFromHex` method" +--- + +# es-x/no-uint8array-prototype-setfromhex +> disallow the `Uint8Array.prototype.setFromHex` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-arraybuffer-base64] and [no-new-in-esnext] + +This rule reports ES2026 [`Uint8Array.prototype.setFromHex` method](https://github.com/tc39/proposal-arraybuffer-base64) as errors. + +This rule is silent by default because it's hard to know types. You need to configure [the aggressive mode](../#the-aggressive-mode) or TypeScript in order to enable this rule. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-uint8array-prototype-setfromhex: error */ +const arr = new Uint8Array(8); +const { read, written } = target.setFromHex('Zm9vYmFy') +``` + + + +This rule has an option. + +```jsonc +{ + "rules": { + "es-x/no-uint8array-prototype-setfromhex": [ + "error", + { + "aggressive": false, + "allowTestedProperty": false + } + ] + } +} +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +### allowTestedProperty: boolean + +Configure the allowTestedProperty mode for only this rule. +This is prior to the `settings['es-x'].allowTestedProperty` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-prototype-setfromhex.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-uint8array-prototype-setfromhex.js) + +[no-arraybuffer-base64]: ../configs/index.md#no-arraybuffer-base64 +[no-new-in-esnext]: ../configs/index.md#no-new-in-esnext diff --git a/docs/rules/no-uint8array-prototype-tobase64.md b/docs/rules/no-uint8array-prototype-tobase64.md new file mode 100644 index 00000000..0456dd34 --- /dev/null +++ b/docs/rules/no-uint8array-prototype-tobase64.md @@ -0,0 +1,62 @@ +--- +title: "es-x/no-uint8array-prototype-tobase64" +description: "disallow the `Uint8Array.prototype.toBase64` method" +--- + +# es-x/no-uint8array-prototype-tobase64 +> disallow the `Uint8Array.prototype.toBase64` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-arraybuffer-base64] and [no-new-in-esnext] + +This rule reports ES2026 [`Uint8Array.prototype.toBase64` method](https://github.com/tc39/proposal-arraybuffer-base64) as errors. + +This rule is silent by default because it's hard to know types. You need to configure [the aggressive mode](../#the-aggressive-mode) or TypeScript in order to enable this rule. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-uint8array-prototype-tobase64: error */ +const arr = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); +console.log(arr.toBase64()); +``` + + + +This rule has an option. + +```jsonc +{ + "rules": { + "es-x/no-uint8array-prototype-tobase64": [ + "error", + { + "aggressive": false, + "allowTestedProperty": false + } + ] + } +} +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +### allowTestedProperty: boolean + +Configure the allowTestedProperty mode for only this rule. +This is prior to the `settings['es-x'].allowTestedProperty` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-prototype-tobase64.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-uint8array-prototype-tobase64.js) + +[no-arraybuffer-base64]: ../configs/index.md#no-arraybuffer-base64 +[no-new-in-esnext]: ../configs/index.md#no-new-in-esnext diff --git a/docs/rules/no-uint8array-prototype-tohex.md b/docs/rules/no-uint8array-prototype-tohex.md new file mode 100644 index 00000000..dea27903 --- /dev/null +++ b/docs/rules/no-uint8array-prototype-tohex.md @@ -0,0 +1,62 @@ +--- +title: "es-x/no-uint8array-prototype-tohex" +description: "disallow the `Uint8Array.prototype.toHex` method" +--- + +# es-x/no-uint8array-prototype-tohex +> disallow the `Uint8Array.prototype.toHex` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-arraybuffer-base64] and [no-new-in-esnext] + +This rule reports ES2026 [`Uint8Array.prototype.toHex` method](https://github.com/tc39/proposal-arraybuffer-base64) as errors. + +This rule is silent by default because it's hard to know types. You need to configure [the aggressive mode](../#the-aggressive-mode) or TypeScript in order to enable this rule. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-uint8array-prototype-tohex: error */ +const arr = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); +console.log(arr.toHex()); +``` + + + +This rule has an option. + +```jsonc +{ + "rules": { + "es-x/no-uint8array-prototype-tohex": [ + "error", + { + "aggressive": false, + "allowTestedProperty": false + } + ] + } +} +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +### allowTestedProperty: boolean + +Configure the allowTestedProperty mode for only this rule. +This is prior to the `settings['es-x'].allowTestedProperty` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-prototype-tohex.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-uint8array-prototype-tohex.js) + +[no-arraybuffer-base64]: ../configs/index.md#no-arraybuffer-base64 +[no-new-in-esnext]: ../configs/index.md#no-new-in-esnext diff --git a/lib/configs/flat/no-arraybuffer-base64.js b/lib/configs/flat/no-arraybuffer-base64.js new file mode 100644 index 00000000..bb5b2787 --- /dev/null +++ b/lib/configs/flat/no-arraybuffer-base64.js @@ -0,0 +1,21 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-flat-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: { + get "es-x"() { + return require("../../index.js") + }, + }, + rules: { + "es-x/no-uint8array-frombase64": "error", + "es-x/no-uint8array-fromhex": "error", + "es-x/no-uint8array-prototype-setfrombase64": "error", + "es-x/no-uint8array-prototype-setfromhex": "error", + "es-x/no-uint8array-prototype-tobase64": "error", + "es-x/no-uint8array-prototype-tohex": "error", + }, +} diff --git a/lib/configs/flat/no-new-in-esnext.js b/lib/configs/flat/no-new-in-esnext.js index e5cccf75..ab7240b2 100644 --- a/lib/configs/flat/no-new-in-esnext.js +++ b/lib/configs/flat/no-new-in-esnext.js @@ -11,6 +11,12 @@ module.exports = { }, }, rules: { + "es-x/no-uint8array-frombase64": "error", + "es-x/no-uint8array-fromhex": "error", + "es-x/no-uint8array-prototype-setfrombase64": "error", + "es-x/no-uint8array-prototype-setfromhex": "error", + "es-x/no-uint8array-prototype-tobase64": "error", + "es-x/no-uint8array-prototype-tohex": "error", "es-x/no-dataview-prototype-getfloat16-setfloat16": "error", "es-x/no-dynamic-import-options": "error", "es-x/no-float16array": "error", diff --git a/lib/configs/no-arraybuffer-base64.js b/lib/configs/no-arraybuffer-base64.js new file mode 100644 index 00000000..04462c3c --- /dev/null +++ b/lib/configs/no-arraybuffer-base64.js @@ -0,0 +1,17 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: ["es-x"], + rules: { + "es-x/no-uint8array-frombase64": "error", + "es-x/no-uint8array-fromhex": "error", + "es-x/no-uint8array-prototype-setfrombase64": "error", + "es-x/no-uint8array-prototype-setfromhex": "error", + "es-x/no-uint8array-prototype-tobase64": "error", + "es-x/no-uint8array-prototype-tohex": "error", + }, +} diff --git a/lib/configs/no-new-in-esnext.js b/lib/configs/no-new-in-esnext.js index 9dd343d4..c702dcde 100644 --- a/lib/configs/no-new-in-esnext.js +++ b/lib/configs/no-new-in-esnext.js @@ -7,6 +7,12 @@ module.exports = { plugins: ["es-x"], rules: { + "es-x/no-uint8array-frombase64": "error", + "es-x/no-uint8array-fromhex": "error", + "es-x/no-uint8array-prototype-setfrombase64": "error", + "es-x/no-uint8array-prototype-setfromhex": "error", + "es-x/no-uint8array-prototype-tobase64": "error", + "es-x/no-uint8array-prototype-tohex": "error", "es-x/no-dataview-prototype-getfloat16-setfloat16": "error", "es-x/no-dynamic-import-options": "error", "es-x/no-float16array": "error", diff --git a/lib/index.js b/lib/index.js index 03cc4988..663d5c65 100644 --- a/lib/index.js +++ b/lib/index.js @@ -11,6 +11,7 @@ module.exports = { meta: { version, name }, configs: { "flat/no-array-grouping": require("./configs/flat/no-array-grouping"), + "flat/no-arraybuffer-base64": require("./configs/flat/no-arraybuffer-base64"), "flat/no-change-array-by-copy": require("./configs/flat/no-change-array-by-copy"), "flat/no-class-fields": require("./configs/flat/no-class-fields"), "flat/no-float16array": require("./configs/flat/no-float16array"), @@ -65,6 +66,7 @@ module.exports = { "flat/restrict-to-es2023": require("./configs/flat/restrict-to-es2023"), "flat/restrict-to-es2023-intl-api": require("./configs/flat/restrict-to-es2023-intl-api"), "no-array-grouping": require("./configs/no-array-grouping"), + "no-arraybuffer-base64": require("./configs/no-arraybuffer-base64"), "no-change-array-by-copy": require("./configs/no-change-array-by-copy"), "no-class-fields": require("./configs/no-class-fields"), "no-float16array": require("./configs/no-float16array"), @@ -449,6 +451,12 @@ module.exports = { "no-trailing-dynamic-import-commas": require("./rules/no-trailing-dynamic-import-commas"), "no-trailing-function-commas": require("./rules/no-trailing-function-commas"), "no-typed-arrays": require("./rules/no-typed-arrays"), + "no-uint8array-frombase64": require("./rules/no-uint8array-frombase64"), + "no-uint8array-fromhex": require("./rules/no-uint8array-fromhex"), + "no-uint8array-prototype-setfrombase64": require("./rules/no-uint8array-prototype-setfrombase64"), + "no-uint8array-prototype-setfromhex": require("./rules/no-uint8array-prototype-setfromhex"), + "no-uint8array-prototype-tobase64": require("./rules/no-uint8array-prototype-tobase64"), + "no-uint8array-prototype-tohex": require("./rules/no-uint8array-prototype-tohex"), "no-unicode-codepoint-escapes": require("./rules/no-unicode-codepoint-escapes"), "no-weak-map": require("./rules/no-weak-map"), "no-weak-set": require("./rules/no-weak-set"), diff --git a/lib/rules/no-nonstandard-typed-array-properties.js b/lib/rules/no-nonstandard-typed-array-properties.js index e0c7c569..f90ce0b7 100644 --- a/lib/rules/no-nonstandard-typed-array-properties.js +++ b/lib/rules/no-nonstandard-typed-array-properties.js @@ -3,7 +3,10 @@ const { defineNonstandardStaticPropertiesHandler, } = require("../util/define-nonstandard-static-properties-handler") -const { typedArrayProperties } = require("../util/well-known-properties") +const { + typedArrayProperties, + uint8ArrayProperties, +} = require("../util/well-known-properties") const typedArrayList = [ "Int8Array", @@ -51,15 +54,24 @@ module.exports = { }, create(context) { /** @type {Set} */ - const allows = new Set([ + const typedArrayAllows = new Set([ ...(context.options[0]?.allow || []), ...typedArrayProperties, ]) + /** @type {Set} */ + const uint8ArrayAllows = new Set([ + ...(context.options[0]?.allow || []), + ...uint8ArrayProperties, + ]) return defineNonstandardStaticPropertiesHandler( context, - Object.fromEntries( - typedArrayList.map((typedArray) => [typedArray, allows]), - ), + Object.fromEntries([ + ...typedArrayList.map((typedArray) => [ + typedArray, + typedArrayAllows, + ]), + ["Uint8Array", uint8ArrayAllows], + ]), ) }, } diff --git a/lib/rules/no-nonstandard-typed-array-prototype-properties.js b/lib/rules/no-nonstandard-typed-array-prototype-properties.js index 9deddab4..43a96519 100644 --- a/lib/rules/no-nonstandard-typed-array-prototype-properties.js +++ b/lib/rules/no-nonstandard-typed-array-prototype-properties.js @@ -5,6 +5,7 @@ const { } = require("../util/define-nonstandard-prototype-properties-handler") const { typedArrayPrototypeProperties, + uint8ArrayPrototypeProperties, } = require("../util/well-known-properties") const typedArrayList = [ @@ -53,13 +54,21 @@ module.exports = { }, create(context) { /** @type {Set} */ - const allows = new Set([ + const typedArrayAllows = new Set([ ...(context.options[0]?.allow || []), ...typedArrayPrototypeProperties, ]) + /** @type {Set} */ + const uint8ArrayAllows = new Set([ + ...(context.options[0]?.allow || []), + ...uint8ArrayPrototypeProperties, + ]) return defineNonstandardPrototypePropertiesHandler( context, - Object.fromEntries(typedArrayList.map((name) => [name, allows])), + Object.fromEntries([ + ...typedArrayList.map((name) => [name, typedArrayAllows]), + ["Uint8Array", uint8ArrayAllows], + ]), { // Allow index properties allowsPropertyName: (name) => /^(?:[1-9]\d*|0)$/u.test(name), diff --git a/lib/rules/no-uint8array-frombase64.js b/lib/rules/no-uint8array-frombase64.js new file mode 100644 index 00000000..e99a83ef --- /dev/null +++ b/lib/rules/no-uint8array-frombase64.js @@ -0,0 +1,34 @@ +"use strict" + +const { + defineStaticPropertiesHandler, +} = require("../util/define-static-properties-handler") + +module.exports = { + meta: { + docs: { + description: "disallow the `Uint8Array.fromBase64` method.", + category: "ES2026", + recommended: false, + proposal: "arraybuffer-base64", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-uint8array-frombase64.html", + }, + fixable: null, + messages: { + forbidden: "ES2026 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { allowTestedProperty: { type: "boolean" } }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return defineStaticPropertiesHandler(context, { + Uint8Array: { fromBase64: "function" }, + }) + }, +} diff --git a/lib/rules/no-uint8array-fromhex.js b/lib/rules/no-uint8array-fromhex.js new file mode 100644 index 00000000..9cc73d9c --- /dev/null +++ b/lib/rules/no-uint8array-fromhex.js @@ -0,0 +1,34 @@ +"use strict" + +const { + defineStaticPropertiesHandler, +} = require("../util/define-static-properties-handler") + +module.exports = { + meta: { + docs: { + description: "disallow the `Uint8Array.fromHex` method.", + category: "ES2026", + recommended: false, + proposal: "arraybuffer-base64", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-uint8array-fromhex.html", + }, + fixable: null, + messages: { + forbidden: "ES2026 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { allowTestedProperty: { type: "boolean" } }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return defineStaticPropertiesHandler(context, { + Uint8Array: { fromHex: "function" }, + }) + }, +} diff --git a/lib/rules/no-uint8array-prototype-setfrombase64.js b/lib/rules/no-uint8array-prototype-setfrombase64.js new file mode 100644 index 00000000..850317a3 --- /dev/null +++ b/lib/rules/no-uint8array-prototype-setfrombase64.js @@ -0,0 +1,38 @@ +"use strict" + +const { + definePrototypePropertiesHandler, +} = require("../util/define-prototype-properties-handler") + +module.exports = { + meta: { + docs: { + description: + "disallow the `Uint8Array.prototype.setFromBase64` method.", + category: "ES2026", + recommended: false, + proposal: "arraybuffer-base64", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-uint8array-prototype-setfrombase64.html", + }, + fixable: null, + messages: { + forbidden: "ES2026 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + allowTestedProperty: { type: "boolean" }, + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypePropertiesHandler(context, { + Uint8Array: { setFromBase64: "function" }, + }) + }, +} diff --git a/lib/rules/no-uint8array-prototype-setfromhex.js b/lib/rules/no-uint8array-prototype-setfromhex.js new file mode 100644 index 00000000..8247aa4d --- /dev/null +++ b/lib/rules/no-uint8array-prototype-setfromhex.js @@ -0,0 +1,38 @@ +"use strict" + +const { + definePrototypePropertiesHandler, +} = require("../util/define-prototype-properties-handler") + +module.exports = { + meta: { + docs: { + description: + "disallow the `Uint8Array.prototype.setFromHex` method.", + category: "ES2026", + recommended: false, + proposal: "arraybuffer-base64", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-uint8array-prototype-setfromhex.html", + }, + fixable: null, + messages: { + forbidden: "ES2026 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + allowTestedProperty: { type: "boolean" }, + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypePropertiesHandler(context, { + Uint8Array: { setFromHex: "function" }, + }) + }, +} diff --git a/lib/rules/no-uint8array-prototype-tobase64.js b/lib/rules/no-uint8array-prototype-tobase64.js new file mode 100644 index 00000000..173a7e72 --- /dev/null +++ b/lib/rules/no-uint8array-prototype-tobase64.js @@ -0,0 +1,37 @@ +"use strict" + +const { + definePrototypePropertiesHandler, +} = require("../util/define-prototype-properties-handler") + +module.exports = { + meta: { + docs: { + description: "disallow the `Uint8Array.prototype.toBase64` method.", + category: "ES2026", + recommended: false, + proposal: "arraybuffer-base64", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-uint8array-prototype-tobase64.html", + }, + fixable: null, + messages: { + forbidden: "ES2026 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + allowTestedProperty: { type: "boolean" }, + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypePropertiesHandler(context, { + Uint8Array: { toBase64: "function" }, + }) + }, +} diff --git a/lib/rules/no-uint8array-prototype-tohex.js b/lib/rules/no-uint8array-prototype-tohex.js new file mode 100644 index 00000000..2f8c042d --- /dev/null +++ b/lib/rules/no-uint8array-prototype-tohex.js @@ -0,0 +1,37 @@ +"use strict" + +const { + definePrototypePropertiesHandler, +} = require("../util/define-prototype-properties-handler") + +module.exports = { + meta: { + docs: { + description: "disallow the `Uint8Array.prototype.toHex` method.", + category: "ES2026", + recommended: false, + proposal: "arraybuffer-base64", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-uint8array-prototype-tohex.html", + }, + fixable: null, + messages: { + forbidden: "ES2026 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + allowTestedProperty: { type: "boolean" }, + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypePropertiesHandler(context, { + Uint8Array: { toHex: "function" }, + }) + }, +} diff --git a/lib/util/type-checker/es-types.js b/lib/util/type-checker/es-types.js index 3ad23c49..8431b03e 100644 --- a/lib/util/type-checker/es-types.js +++ b/lib/util/type-checker/es-types.js @@ -246,7 +246,10 @@ const WELLKNOWN_GLOBALS = { }, }, Int8Array: buildGlobalTypedArrayTypeInfo("Int8Array"), - Uint8Array: buildGlobalTypedArrayTypeInfo("Uint8Array"), + Uint8Array: buildGlobalTypedArrayTypeInfo("Uint8Array", { + fromBase64: { type: "Function" }, + fromHex: { type: "Function" }, + }), Uint8ClampedArray: buildGlobalTypedArrayTypeInfo("Uint8ClampedArray"), Int16Array: buildGlobalTypedArrayTypeInfo("Int16Array"), Uint16Array: buildGlobalTypedArrayTypeInfo("Uint16Array"), @@ -709,7 +712,12 @@ const WELLKNOWN_PROTOTYPE = /** @type {WellKnownPrototypes} */ ({ then: { type: "Function", return: { type: "Promise" } }, }, Int8Array: buildTypedArrayPrototypeTypeInfo("Int8Array"), - Uint8Array: buildTypedArrayPrototypeTypeInfo("Uint8Array"), + Uint8Array: buildTypedArrayPrototypeTypeInfo("Uint8Array", { + toBase64: { type: "Function", return: { type: "String" } }, + toHex: { type: "Function", return: { type: "String" } }, + setFromBase64: { type: "Function" }, + setFromHex: { type: "Function" }, + }), Uint8ClampedArray: buildTypedArrayPrototypeTypeInfo("Uint8ClampedArray"), Int16Array: buildTypedArrayPrototypeTypeInfo("Int16Array"), Uint16Array: buildTypedArrayPrototypeTypeInfo("Uint16Array"), @@ -841,28 +849,33 @@ function getPropertyType(typeInfo, propertyName) { module.exports = { WELLKNOWN_GLOBALS, getPropertyType } /** + * @template {string} K * @param {TypeName} type + * @param {Partial>} [otherProperties] * @returns {TypeInfo} */ -function buildGlobalTypedArrayTypeInfo(type) { +function buildGlobalTypedArrayTypeInfo(type, otherProperties = {}) { return { type: "Function", return: { type }, prototypeType: type, - /** @type {Record} */ + /** @type {Record} */ properties: { BYTES_PER_ELEMENT: { type: "Number" }, from: { type: "Function", return: { type } }, of: { type: "Function", return: { type } }, + ...otherProperties, }, } } /** + * @template {string} K = never * @param {TypeName} type - * @returns {Record} + * @param {Partial>} otherProperties + * @returns {Record & Partial>} */ -function buildTypedArrayPrototypeTypeInfo(type) { +function buildTypedArrayPrototypeTypeInfo(type, otherProperties = {}) { return { at: { type: "Function" }, copyWithin: { type: "Function", return: { type } }, @@ -899,5 +912,6 @@ function buildTypedArrayPrototypeTypeInfo(type) { buffer: { type: "ArrayBuffer" }, byteLength: { type: "Number" }, byteOffset: { type: "Number" }, + ...otherProperties, } } diff --git a/lib/util/well-known-properties.js b/lib/util/well-known-properties.js index 0f5a3426..6dac0e7b 100644 --- a/lib/util/well-known-properties.js +++ b/lib/util/well-known-properties.js @@ -585,6 +585,21 @@ const typedArrayPrototypeProperties = new Set([ "constructor", ]) +const uint8ArrayProperties = new Set([ + ...typedArrayProperties, + + "fromBase64", + "fromHex", +]) +const uint8ArrayPrototypeProperties = new Set([ + ...typedArrayPrototypeProperties, + + "setFromBase64", + "setFromHex", + "toBase64", + "toHex", +]) + const mapProperties = new Set([ ...objectPrototypeProperties, ...functionPrototypeProperties, @@ -1204,6 +1219,8 @@ module.exports = { arrayPrototypeProperties, typedArrayProperties, typedArrayPrototypeProperties, + uint8ArrayProperties, + uint8ArrayPrototypeProperties, mapProperties, mapPrototypeProperties, setProperties, diff --git a/scripts/new-rule.js b/scripts/new-rule.js index 9de241ba..2e1ea01b 100644 --- a/scripts/new-rule.js +++ b/scripts/new-rule.js @@ -108,4 +108,4 @@ This rule reports ??? as errors. ${yellow}npx mocha "tests/**/${ruleId}.js" --reporter dot --timeout 60000${reset} `) -})(String(process.argv[2]).toLowerCase()) +})(String(process.argv[2]).toLowerCase().replace(/[.]/gu, "-")) diff --git a/scripts/proposals.js b/scripts/proposals.js index 4e6dcb1f..c7921215 100644 --- a/scripts/proposals.js +++ b/scripts/proposals.js @@ -1,6 +1,10 @@ "use strict" module.exports = { + "arraybuffer-base64": { + title: "Uint8Array to/from Base64 and Hex", + link: "https://github.com/tc39/proposal-arraybuffer-base64", + }, "array-grouping": { title: "Array Grouping", link: "https://github.com/tc39/proposal-array-grouping", diff --git a/tests/lib/rules/no-nonstandard-typed-array-properties.js b/tests/lib/rules/no-nonstandard-typed-array-properties.js index 0ff4b946..549f4542 100644 --- a/tests/lib/rules/no-nonstandard-typed-array-properties.js +++ b/tests/lib/rules/no-nonstandard-typed-array-properties.js @@ -4,6 +4,7 @@ const RuleTester = require("../../tester") const rule = require("../../../lib/rules/no-nonstandard-typed-array-properties.js") const { typedArrayProperties, + uint8ArrayProperties, } = require("../../../lib/util/well-known-properties") const typedArrayList = [ @@ -30,6 +31,9 @@ new RuleTester().run("no-nonstandard-typed-array-properties", rule, { options: [{ allow: ["unknown"] }], }, ]), + ...[...uint8ArrayProperties] + .filter((nm) => !typedArrayProperties.has(nm)) + .map((p) => `new Uint8Array().${p}`), ], invalid: [ ...typedArrayList.flatMap((className) => [ diff --git a/tests/lib/rules/no-nonstandard-typed-array-prototype-properties.js b/tests/lib/rules/no-nonstandard-typed-array-prototype-properties.js index daef993f..348dbd2e 100644 --- a/tests/lib/rules/no-nonstandard-typed-array-prototype-properties.js +++ b/tests/lib/rules/no-nonstandard-typed-array-prototype-properties.js @@ -5,6 +5,7 @@ const RuleTester = require("../../tester") const rule = require("../../../lib/rules/no-nonstandard-typed-array-prototype-properties.js") const { typedArrayPrototypeProperties, + uint8ArrayPrototypeProperties, } = require("../../../lib/util/well-known-properties") const ruleId = "no-nonstandard-typed-array-prototype-properties" @@ -39,6 +40,9 @@ new RuleTester().run(ruleId, rule, { options: [{ allow: ["unknown"] }], }, ]), + ...[...uint8ArrayPrototypeProperties] + .filter((nm) => !typedArrayPrototypeProperties.has(nm)) + .map((p) => `new Uint8Array().${p}`), ], invalid: [ ...typedArrayList.flatMap((className) => [ diff --git a/tests/lib/rules/no-uint8array-frombase64.js b/tests/lib/rules/no-uint8array-frombase64.js new file mode 100644 index 00000000..bef87b05 --- /dev/null +++ b/tests/lib/rules/no-uint8array-frombase64.js @@ -0,0 +1,29 @@ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-uint8array-frombase64.js") +const ruleId = "no-uint8array-frombase64" + +const method = "fromBase64" + +new RuleTester().run(ruleId, rule, { + valid: [ + "Uint8Array", + "Uint8Array.raw", + `let Uint8Array = 0; Uint8Array.${method}`, + { + code: `if (Uint8Array.${method}) { Uint8Array.${method} }`, + options: [{ allowTestedProperty: true }], + }, + ], + invalid: [ + { + code: `Uint8Array.${method}`, + errors: [`ES2026 'Uint8Array.${method}' method is forbidden.`], + }, + { + code: `if (Uint8Array.${method}) { Uint8Array.${method} }`, + errors: 2, + }, + ], +}) diff --git a/tests/lib/rules/no-uint8array-fromhex.js b/tests/lib/rules/no-uint8array-fromhex.js new file mode 100644 index 00000000..dfc4deba --- /dev/null +++ b/tests/lib/rules/no-uint8array-fromhex.js @@ -0,0 +1,29 @@ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-uint8array-fromhex.js") +const ruleId = "no-uint8array-fromhex" + +const method = "fromHex" + +new RuleTester().run(ruleId, rule, { + valid: [ + "Uint8Array", + "Uint8Array.raw", + `let Uint8Array = 0; Uint8Array.${method}`, + { + code: `if (Uint8Array.${method}) { Uint8Array.${method} }`, + options: [{ allowTestedProperty: true }], + }, + ], + invalid: [ + { + code: `Uint8Array.${method}`, + errors: [`ES2026 'Uint8Array.${method}' method is forbidden.`], + }, + { + code: `if (Uint8Array.${method}) { Uint8Array.${method} }`, + errors: 2, + }, + ], +}) diff --git a/tests/lib/rules/no-uint8array-prototype-setfrombase64.js b/tests/lib/rules/no-uint8array-prototype-setfrombase64.js new file mode 100644 index 00000000..08dd4964 --- /dev/null +++ b/tests/lib/rules/no-uint8array-prototype-setfrombase64.js @@ -0,0 +1,135 @@ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-uint8array-prototype-setfrombase64.js") +const ruleId = "no-uint8array-prototype-setfrombase64" + +const method = "setFromBase64" + +new RuleTester().run(ruleId, rule, { + valid: [ + `${method}(other)`, + `foo.${method}(other)`, + "foo.includes(other)", + { + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { code: "foo.includes(0)", settings: { "es-x": { aggressive: true } } }, + { + code: `${method}(other)`, + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + { + code: `foo.${method}(other)`, + options: [{ aggressive: true }], + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: false } }, + }, + { + code: ` + const t = new Uint8Array([]) + if (Uint8Array.prototype.${method}) { + console.log(t.${method}(other)) + } + if (typeof Uint8Array.prototype.${method} === 'undefined') { + console.log(t.${method}(other)) + } else { + console.log(t.${method}(other)) + } + const a = Uint8Array.prototype.${method} + ? t.${method}(other) + : t.${method}(other);`, + options: [{ allowTestedProperty: true }], + errors: [ + { + line: 7, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + { + line: 13, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + ], + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ + languageOptions: { + parser, + parserOptions: { + tsconfigRootDir, + project, + disallowAutomaticSingleRunInference: true, + }, + }, +}).run(`${ruleId} TS Full Types`, rule, { + valid: [ + { filename, code: `${method}(other)` }, + { filename, code: "foo.includes(other)" }, + { + filename, + code: `foo.${method}(other)`, + }, + { + filename, + code: `let foo = {}; foo.${method}(other)`, + }, + { + filename, + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.includes(other)", + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: `let foo = new Uint8Array(); foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `function f(a: T) { a.${method}(other) }`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) diff --git a/tests/lib/rules/no-uint8array-prototype-setfromhex.js b/tests/lib/rules/no-uint8array-prototype-setfromhex.js new file mode 100644 index 00000000..3cca990d --- /dev/null +++ b/tests/lib/rules/no-uint8array-prototype-setfromhex.js @@ -0,0 +1,135 @@ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-uint8array-prototype-setfromhex.js") +const ruleId = "no-uint8array-prototype-setfromhex" + +const method = "setFromHex" + +new RuleTester().run(ruleId, rule, { + valid: [ + `${method}(other)`, + `foo.${method}(other)`, + "foo.includes(other)", + { + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { code: "foo.includes(0)", settings: { "es-x": { aggressive: true } } }, + { + code: `${method}(other)`, + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + { + code: `foo.${method}(other)`, + options: [{ aggressive: true }], + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: false } }, + }, + { + code: ` + const t = new Uint8Array([]) + if (Uint8Array.prototype.${method}) { + console.log(t.${method}(other)) + } + if (typeof Uint8Array.prototype.${method} === 'undefined') { + console.log(t.${method}(other)) + } else { + console.log(t.${method}(other)) + } + const a = Uint8Array.prototype.${method} + ? t.${method}(other) + : t.${method}(other);`, + options: [{ allowTestedProperty: true }], + errors: [ + { + line: 7, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + { + line: 13, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + ], + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ + languageOptions: { + parser, + parserOptions: { + tsconfigRootDir, + project, + disallowAutomaticSingleRunInference: true, + }, + }, +}).run(`${ruleId} TS Full Types`, rule, { + valid: [ + { filename, code: `${method}(other)` }, + { filename, code: "foo.includes(other)" }, + { + filename, + code: `foo.${method}(other)`, + }, + { + filename, + code: `let foo = {}; foo.${method}(other)`, + }, + { + filename, + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.includes(other)", + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: `let foo = new Uint8Array(); foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `function f(a: T) { a.${method}(other) }`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) diff --git a/tests/lib/rules/no-uint8array-prototype-tobase64.js b/tests/lib/rules/no-uint8array-prototype-tobase64.js new file mode 100644 index 00000000..60c80013 --- /dev/null +++ b/tests/lib/rules/no-uint8array-prototype-tobase64.js @@ -0,0 +1,135 @@ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-uint8array-prototype-tobase64.js") +const ruleId = "no-uint8array-prototype-tobase64" + +const method = "toBase64" + +new RuleTester().run(ruleId, rule, { + valid: [ + `${method}(other)`, + `foo.${method}(other)`, + "foo.includes(other)", + { + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { code: "foo.includes(0)", settings: { "es-x": { aggressive: true } } }, + { + code: `${method}(other)`, + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + { + code: `foo.${method}(other)`, + options: [{ aggressive: true }], + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: false } }, + }, + { + code: ` + const t = new Uint8Array([]) + if (Uint8Array.prototype.${method}) { + console.log(t.${method}(other)) + } + if (typeof Uint8Array.prototype.${method} === 'undefined') { + console.log(t.${method}(other)) + } else { + console.log(t.${method}(other)) + } + const a = Uint8Array.prototype.${method} + ? t.${method}(other) + : t.${method}(other);`, + options: [{ allowTestedProperty: true }], + errors: [ + { + line: 7, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + { + line: 13, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + ], + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ + languageOptions: { + parser, + parserOptions: { + tsconfigRootDir, + project, + disallowAutomaticSingleRunInference: true, + }, + }, +}).run(`${ruleId} TS Full Types`, rule, { + valid: [ + { filename, code: `${method}(other)` }, + { filename, code: "foo.includes(other)" }, + { + filename, + code: `foo.${method}(other)`, + }, + { + filename, + code: `let foo = {}; foo.${method}(other)`, + }, + { + filename, + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.includes(other)", + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: `let foo = new Uint8Array(); foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `function f(a: T) { a.${method}(other) }`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) diff --git a/tests/lib/rules/no-uint8array-prototype-tohex.js b/tests/lib/rules/no-uint8array-prototype-tohex.js new file mode 100644 index 00000000..17dde900 --- /dev/null +++ b/tests/lib/rules/no-uint8array-prototype-tohex.js @@ -0,0 +1,135 @@ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-uint8array-prototype-tohex.js") +const ruleId = "no-uint8array-prototype-tohex" + +const method = "toHex" + +new RuleTester().run(ruleId, rule, { + valid: [ + `${method}(other)`, + `foo.${method}(other)`, + "foo.includes(other)", + { + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { code: "foo.includes(0)", settings: { "es-x": { aggressive: true } } }, + { + code: `${method}(other)`, + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + { + code: `foo.${method}(other)`, + options: [{ aggressive: true }], + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: false } }, + }, + { + code: ` + const t = new Uint8Array([]) + if (Uint8Array.prototype.${method}) { + console.log(t.${method}(other)) + } + if (typeof Uint8Array.prototype.${method} === 'undefined') { + console.log(t.${method}(other)) + } else { + console.log(t.${method}(other)) + } + const a = Uint8Array.prototype.${method} + ? t.${method}(other) + : t.${method}(other);`, + options: [{ allowTestedProperty: true }], + errors: [ + { + line: 7, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + { + line: 13, + message: `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + }, + ], + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ + languageOptions: { + parser, + parserOptions: { + tsconfigRootDir, + project, + disallowAutomaticSingleRunInference: true, + }, + }, +}).run(`${ruleId} TS Full Types`, rule, { + valid: [ + { filename, code: `${method}(other)` }, + { filename, code: "foo.includes(other)" }, + { + filename, + code: `foo.${method}(other)`, + }, + { + filename, + code: `let foo = {}; foo.${method}(other)`, + }, + { + filename, + code: `${method}(other)`, + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.includes(other)", + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: `let foo = new Uint8Array(); foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `function f(a: T) { a.${method}(other) }`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + }, + { + filename, + code: `foo.${method}(other)`, + errors: [ + `ES2026 'Uint8Array.prototype.${method}' method is forbidden.`, + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) From 2f6c6e85a2cbaf5faa8ec2ea33ab8adcfc82fd6e Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Sat, 5 Apr 2025 12:09:57 +0900 Subject: [PATCH 2/2] update docs --- docs/rules/no-uint8array-frombase64.md | 22 +++++++++++++++++++ docs/rules/no-uint8array-fromhex.md | 22 +++++++++++++++++++ .../no-uint8array-prototype-setfrombase64.md | 2 ++ .../no-uint8array-prototype-setfromhex.md | 2 ++ .../rules/no-uint8array-prototype-tobase64.md | 2 ++ docs/rules/no-uint8array-prototype-tohex.md | 2 ++ 6 files changed, 52 insertions(+) diff --git a/docs/rules/no-uint8array-frombase64.md b/docs/rules/no-uint8array-frombase64.md index 806fe61c..62a8930f 100644 --- a/docs/rules/no-uint8array-frombase64.md +++ b/docs/rules/no-uint8array-frombase64.md @@ -24,6 +24,28 @@ Uint8Array.fromBase64(string) +## 🔧 Options + +This rule has an option. + +```jsonc +{ + "rules": { + "es-x/no-uint8array-frombase64": [ + "error", + { + "allowTestedProperty": false + } + ] + } +} +``` + +### allowTestedProperty: boolean + +Configure the allowTestedProperty mode for only this rule. +This is prior to the `settings['es-x'].allowTestedProperty` setting. + ## 📚 References - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-frombase64.js) diff --git a/docs/rules/no-uint8array-fromhex.md b/docs/rules/no-uint8array-fromhex.md index 0233fbdd..92a96e99 100644 --- a/docs/rules/no-uint8array-fromhex.md +++ b/docs/rules/no-uint8array-fromhex.md @@ -24,6 +24,28 @@ Uint8Array.fromHex(string) +## 🔧 Options + +This rule has an option. + +```jsonc +{ + "rules": { + "es-x/no-uint8array-fromhex": [ + "error", + { + "allowTestedProperty": false + } + ] + } +} +``` + +### allowTestedProperty: boolean + +Configure the allowTestedProperty mode for only this rule. +This is prior to the `settings['es-x'].allowTestedProperty` setting. + ## 📚 References - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-uint8array-fromhex.js) diff --git a/docs/rules/no-uint8array-prototype-setfrombase64.md b/docs/rules/no-uint8array-prototype-setfrombase64.md index 70a04262..209347b0 100644 --- a/docs/rules/no-uint8array-prototype-setfrombase64.md +++ b/docs/rules/no-uint8array-prototype-setfrombase64.md @@ -27,6 +27,8 @@ const { read, written } = target.setFromBase64('Zm9vYmFy') +## 🔧 Options + This rule has an option. ```jsonc diff --git a/docs/rules/no-uint8array-prototype-setfromhex.md b/docs/rules/no-uint8array-prototype-setfromhex.md index 40b42595..55a30856 100644 --- a/docs/rules/no-uint8array-prototype-setfromhex.md +++ b/docs/rules/no-uint8array-prototype-setfromhex.md @@ -27,6 +27,8 @@ const { read, written } = target.setFromHex('Zm9vYmFy') +## 🔧 Options + This rule has an option. ```jsonc diff --git a/docs/rules/no-uint8array-prototype-tobase64.md b/docs/rules/no-uint8array-prototype-tobase64.md index 0456dd34..f40e6d7d 100644 --- a/docs/rules/no-uint8array-prototype-tobase64.md +++ b/docs/rules/no-uint8array-prototype-tobase64.md @@ -27,6 +27,8 @@ console.log(arr.toBase64()); +## 🔧 Options + This rule has an option. ```jsonc diff --git a/docs/rules/no-uint8array-prototype-tohex.md b/docs/rules/no-uint8array-prototype-tohex.md index dea27903..b6d6434b 100644 --- a/docs/rules/no-uint8array-prototype-tohex.md +++ b/docs/rules/no-uint8array-prototype-tohex.md @@ -27,6 +27,8 @@ console.log(arr.toHex()); +## 🔧 Options + This rule has an option. ```jsonc