Skip to content

Commit

Permalink
fix: support node: prefix (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
teppeis authored Aug 22, 2023
1 parent 23ae475 commit fde2ba6
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 17 deletions.
12 changes: 9 additions & 3 deletions lib/rules/no-deprecated-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ const {
const enumeratePropertyNames = require("../util/enumerate-property-names")
const getConfiguredNodeVersion = require("../util/get-configured-node-version")
const getSemverRange = require("../util/get-semver-range")
const extendTrackmapWithNodePrefix = require("../util/extend-trackmap-with-node-prefix")
const unprefixNodeColon = require("../util/unprefix-node-colon")

const modules = {
const rawModules = {
_linklist: {
[READ]: { since: "5.0.0", replacedBy: null },
},
Expand Down Expand Up @@ -567,6 +569,8 @@ const modules = {
},
},
}
const modules = extendTrackmapWithNodePrefix(rawModules)

const globals = {
Buffer: {
[CONSTRUCT]: {
Expand Down Expand Up @@ -660,7 +664,7 @@ function toReplaceMessage(replacedBy, version) {
* @returns {string} The name.
*/
function toName(type, path) {
const baseName = path.join(".")
const baseName = unprefixNodeColon(path.join("."))
return type === ReferenceTracker.CALL
? `${baseName}()`
: type === ReferenceTracker.CONSTRUCT
Expand Down Expand Up @@ -701,7 +705,9 @@ module.exports = {
ignoreModuleItems: {
type: "array",
items: {
enum: Array.from(enumeratePropertyNames(modules)),
enum: Array.from(
enumeratePropertyNames(rawModules)
),
},
additionalItems: false,
uniqueItems: true,
Expand Down
4 changes: 4 additions & 0 deletions lib/rules/no-unsupported-features/node-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const {
} = require("../../util/check-unsupported-builtins")
const enumeratePropertyNames = require("../../util/enumerate-property-names")
const getConfiguredNodeVersion = require("../../util/get-configured-node-version")
const extendTrackMapWithNodePrefix = require("../../util/extend-trackmap-with-node-prefix")

const trackMap = {
globals: {
Expand Down Expand Up @@ -368,6 +369,9 @@ Object.assign(trackMap.globals, {
console: trackMap.modules.console,
process: trackMap.modules.process,
})

trackMap.modules = extendTrackMapWithNodePrefix(trackMap.modules)

/*eslint-enable camelcase */

module.exports = {
Expand Down
1 change: 1 addition & 0 deletions lib/rules/prefer-promises/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const trackMap = {
setServers: { [CALL]: true },
},
}
trackMap["node:dns"] = trackMap.dns

module.exports = {
meta: {
Expand Down
1 change: 1 addition & 0 deletions lib/rules/prefer-promises/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const trackMap = {
readFile: { [CALL]: true },
},
}
trackMap["node:fs"] = trackMap.fs

module.exports = {
meta: {
Expand Down
11 changes: 2 additions & 9 deletions lib/util/check-prefer-global.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"use strict"

const { ReferenceTracker } = require("@eslint-community/eslint-utils")
const extendTrackmapWithNodePrefix = require("./extend-trackmap-with-node-prefix")

/**
* Verifier for `prefer-global/*` rules.
Expand Down Expand Up @@ -34,15 +35,7 @@ class Verifier {
mode: "legacy",
})

const modules = {
...trackMap.modules,
...Object.fromEntries(
Object.entries(trackMap.modules).map(([name, value]) => [
`node:${name}`,
value,
])
),
}
const modules = extendTrackmapWithNodePrefix(trackMap.modules)

for (const { node } of [
...tracker.iterateCjsReferences(modules),
Expand Down
3 changes: 2 additions & 1 deletion lib/util/check-unsupported-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { Range, lt, major } = require("semver") // eslint-disable-line no-unused-
const { ReferenceTracker } = require("@eslint-community/eslint-utils")
const getConfiguredNodeVersion = require("./get-configured-node-version")
const getSemverRange = require("./get-semver-range")
const unprefixNodeColon = require("./unprefix-node-colon")

/**
* @typedef {Object} SupportInfo
Expand Down Expand Up @@ -92,7 +93,7 @@ module.exports.checkUnsupportedBuiltins = function checkUnsupportedBuiltins(
]

for (const { node, path, info } of references) {
const name = path.join(".")
const name = unprefixNodeColon(path.join("."))
const supported = isSupported(info, options.version)

if (!supported && !options.ignores.has(name)) {
Expand Down
9 changes: 5 additions & 4 deletions lib/util/enumerate-property-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"use strict"

const { CALL, CONSTRUCT, READ } = require("@eslint-community/eslint-utils")
const unprefixNodeColon = require("./unprefix-node-colon")

/**
* Enumerate property names of a given object recursively.
Expand All @@ -18,17 +19,17 @@ function* enumeratePropertyNames(trackMap, path = []) {
if (typeof value !== "object") {
continue
}

path.push(key)

const name = unprefixNodeColon(path.join("."))
if (value[CALL]) {
yield `${path.join(".")}()`
yield `${name}()`
}
if (value[CONSTRUCT]) {
yield `new ${path.join(".")}()`
yield `new ${name}()`
}
if (value[READ]) {
yield path.join(".")
yield name
}
yield* enumeratePropertyNames(value, path)

Expand Down
21 changes: 21 additions & 0 deletions lib/util/extend-trackmap-with-node-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use strict"

const isCoreModule = require("is-core-module")

/**
* Extend trackMap.modules with `node:` prefixed modules
* @param {Object} modules Like `{assert: foo}`
* @returns {Object} Like `{assert: foo}, "node:assert": foo}`
*/
module.exports = function extendTrackMapWithNodePrefix(modules) {
const ret = {
...modules,
...Object.fromEntries(
Object.entries(modules)
.map(([name, value]) => [`node:${name}`, value])
// Note: "999" arbitrary to check current/future Node.js version
.filter(([name]) => isCoreModule(name, "999"))
),
}
return ret
}
13 changes: 13 additions & 0 deletions lib/util/unprefix-node-colon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use strict"

/**
* Remove `node:` prefix from module name
* @param {string} name The module name such as `node:assert` or `assert`.
* @returns {string} The unprefixed module name like `assert`.
*/
module.exports = function unprefixNodeColon(name) {
if (name.startsWith("node:")) {
return name.slice(5)
}
return name
}
47 changes: 47 additions & 0 deletions tests/lib/rules/no-deprecated-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ ruleTester.run("no-deprecated-api", rule, {
code: "require('buffer').Buffer",
env: { node: true },
},
{
code: "require('node:buffer').Buffer",
env: { node: true },
},
{
code: "foo(require('buffer').Buffer)",
env: { node: true },
Expand Down Expand Up @@ -93,6 +97,16 @@ ruleTester.run("no-deprecated-api", rule, {
],
env: { node: true },
},
{
code: "require('node:buffer').Buffer()",
options: [
{
//
ignoreModuleItems: ["buffer.Buffer()"],
},
],
env: { node: true },
},
{
code: "require('domain');",
options: [
Expand Down Expand Up @@ -189,6 +203,14 @@ ruleTester.run("no-deprecated-api", rule, {
"'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.",
],
},
{
code: "new (require('node:buffer').Buffer)()",
options: [{ version: "6.0.0" }],
env: { node: true },
errors: [
"'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.",
],
},
{
code: "require('buffer').Buffer()",
options: [{ version: "6.0.0" }],
Expand All @@ -197,6 +219,14 @@ ruleTester.run("no-deprecated-api", rule, {
"'buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.",
],
},
{
code: "require('node:buffer').Buffer()",
options: [{ version: "6.0.0" }],
env: { node: true },
errors: [
"'buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.",
],
},
{
code: "var b = require('buffer'); new b.Buffer()",
options: [{ version: "6.0.0" }],
Expand Down Expand Up @@ -278,6 +308,14 @@ ruleTester.run("no-deprecated-api", rule, {
"'buffer.SlowBuffer' was deprecated since v6.0.0. Use 'buffer.Buffer.allocUnsafeSlow()' instead.",
],
},
{
code: "require('node:buffer').SlowBuffer",
options: [{ version: "6.0.0" }],
env: { node: true },
errors: [
"'buffer.SlowBuffer' was deprecated since v6.0.0. Use 'buffer.Buffer.allocUnsafeSlow()' instead.",
],
},
{
code: "var b = require('buffer'); b.SlowBuffer",
options: [{ version: "6.0.0" }],
Expand Down Expand Up @@ -713,6 +751,15 @@ ruleTester.run("no-deprecated-api", rule, {
"'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.",
],
},
{
code: "import b from 'node:buffer'; new b.Buffer()",
options: [{ version: "6.0.0" }],
parserOptions: { sourceType: "module" },
env: { es6: true },
errors: [
"'new buffer.Buffer()' was deprecated since v6.0.0. Use 'buffer.Buffer.alloc()' or 'buffer.Buffer.from()' instead.",
],
},
{
code: "import * as b from 'buffer'; new b.Buffer()",
options: [{ version: "6.0.0" }],
Expand Down
Loading

0 comments on commit fde2ba6

Please sign in to comment.