| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782 | /** * @author Toru Nagashima * See LICENSE file in root directory for full license. */"use strict"const { CALL, CONSTRUCT, READ, ReferenceTracker } = require("eslint-utils")const enumeratePropertyNames = require("../util/enumerate-property-names")const getConfiguredNodeVersion = require("../util/get-configured-node-version")const getSemverRange = require("../util/get-semver-range")const modules = {    _linklist: {        [READ]: { since: "5.0.0", replacedBy: null },    },    //eslint-disable-next-line camelcase    _stream_wrap: {        [READ]: { since: "12.0.0", replacedBy: null },    },    //eslint-disable-next-line camelcase    async_hooks: {        currentId: {            [READ]: {                since: "8.2.0",                replacedBy: [                    {                        name: "'async_hooks.executionAsyncId()'",                        supported: "8.1.0",                    },                ],            },        },        triggerId: {            [READ]: {                since: "8.2.0",                replacedBy: "'async_hooks.triggerAsyncId()'",            },        },    },    buffer: {        Buffer: {            [CONSTRUCT]: {                since: "6.0.0",                replacedBy: [                    { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" },                    { name: "'buffer.Buffer.from()'", supported: "5.10.0" },                ],            },            [CALL]: {                since: "6.0.0",                replacedBy: [                    { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" },                    { name: "'buffer.Buffer.from()'", supported: "5.10.0" },                ],            },        },        SlowBuffer: {            [READ]: {                since: "6.0.0",                replacedBy: [                    {                        name: "'buffer.Buffer.allocUnsafeSlow()'",                        supported: "5.12.0",                    },                ],            },        },    },    constants: {        [READ]: {            since: "6.3.0",            replacedBy: "'constants' property of each module",        },    },    crypto: {        _toBuf: {            [READ]: { since: "11.0.0", replacedBy: null },        },        Credentials: {            [READ]: { since: "0.12.0", replacedBy: "'tls.SecureContext'" },        },        DEFAULT_ENCODING: {            [READ]: { since: "10.0.0", replacedBy: null },        },        createCipher: {            [READ]: {                since: "10.0.0",                replacedBy: [                    { name: "'crypto.createCipheriv()'", supported: "0.1.94" },                ],            },        },        createCredentials: {            [READ]: {                since: "0.12.0",                replacedBy: [                    {                        name: "'tls.createSecureContext()'",                        supported: "0.11.13",                    },                ],            },        },        createDecipher: {            [READ]: {                since: "10.0.0",                replacedBy: [                    {                        name: "'crypto.createDecipheriv()'",                        supported: "0.1.94",                    },                ],            },        },        fips: {            [READ]: {                since: "10.0.0",                replacedBy: [                    {                        name: "'crypto.getFips()' and 'crypto.setFips()'",                        supported: "10.0.0",                    },                ],            },        },        prng: {            [READ]: {                since: "11.0.0",                replacedBy: [                    { name: "'crypto.randomBytes()'", supported: "0.5.8" },                ],            },        },        pseudoRandomBytes: {            [READ]: {                since: "11.0.0",                replacedBy: [                    { name: "'crypto.randomBytes()'", supported: "0.5.8" },                ],            },        },        rng: {            [READ]: {                since: "11.0.0",                replacedBy: [                    { name: "'crypto.randomBytes()'", supported: "0.5.8" },                ],            },        },    },    domain: {        [READ]: { since: "4.0.0", replacedBy: null },    },    events: {        EventEmitter: {            listenerCount: {                [READ]: {                    since: "4.0.0",                    replacedBy: [                        {                            name: "'events.EventEmitter#listenerCount()'",                            supported: "3.2.0",                        },                    ],                },            },        },        listenerCount: {            [READ]: {                since: "4.0.0",                replacedBy: [                    {                        name: "'events.EventEmitter#listenerCount()'",                        supported: "3.2.0",                    },                ],            },        },    },    freelist: {        [READ]: { since: "4.0.0", replacedBy: null },    },    fs: {        SyncWriteStream: {            [READ]: { since: "4.0.0", replacedBy: null },        },        exists: {            [READ]: {                since: "4.0.0",                replacedBy: [                    { name: "'fs.stat()'", supported: "0.0.2" },                    { name: "'fs.access()'", supported: "0.11.15" },                ],            },        },        lchmod: {            [READ]: { since: "0.4.0", replacedBy: null },        },        lchmodSync: {            [READ]: { since: "0.4.0", replacedBy: null },        },    },    http: {        createClient: {            [READ]: {                since: "0.10.0",                replacedBy: [{ name: "'http.request()'", supported: "0.3.6" }],            },        },    },    module: {        Module: {            createRequireFromPath: {                [READ]: {                    since: "12.2.0",                    replacedBy: [                        {                            name: "'module.createRequire()'",                            supported: "12.2.0",                        },                    ],                },            },            requireRepl: {                [READ]: {                    since: "6.0.0",                    replacedBy: "'require(\"repl\")'",                },            },            _debug: {                [READ]: { since: "9.0.0", replacedBy: null },            },        },        createRequireFromPath: {            [READ]: {                since: "12.2.0",                replacedBy: [                    {                        name: "'module.createRequire()'",                        supported: "12.2.0",                    },                ],            },        },        requireRepl: {            [READ]: {                since: "6.0.0",                replacedBy: "'require(\"repl\")'",            },        },        _debug: {            [READ]: { since: "9.0.0", replacedBy: null },        },    },    net: {        _setSimultaneousAccepts: {            [READ]: { since: "12.0.0", replacedBy: null },        },    },    os: {        getNetworkInterfaces: {            [READ]: {                since: "0.6.0",                replacedBy: [                    { name: "'os.networkInterfaces()'", supported: "0.6.0" },                ],            },        },        tmpDir: {            [READ]: {                since: "7.0.0",                replacedBy: [{ name: "'os.tmpdir()'", supported: "0.9.9" }],            },        },    },    path: {        _makeLong: {            [READ]: {                since: "9.0.0",                replacedBy: [                    { name: "'path.toNamespacedPath()'", supported: "9.0.0" },                ],            },        },    },    process: {        EventEmitter: {            [READ]: {                since: "0.6.0",                replacedBy: "'require(\"events\")'",            },        },        assert: {            [READ]: {                since: "10.0.0",                replacedBy: "'require(\"assert\")'",            },        },        binding: {            [READ]: { since: "10.9.0", replacedBy: null },        },        env: {            NODE_REPL_HISTORY_FILE: {                [READ]: {                    since: "4.0.0",                    replacedBy: "'NODE_REPL_HISTORY'",                },            },        },        report: {            triggerReport: {                [READ]: {                    since: "11.12.0",                    replacedBy: "'process.report.writeReport()'",                },            },        },    },    punycode: {        [READ]: {            since: "7.0.0",            replacedBy: "'https://www.npmjs.com/package/punycode'",        },    },    readline: {        codePointAt: {            [READ]: { since: "4.0.0", replacedBy: null },        },        getStringWidth: {            [READ]: { since: "6.0.0", replacedBy: null },        },        isFullWidthCodePoint: {            [READ]: { since: "6.0.0", replacedBy: null },        },        stripVTControlCharacters: {            [READ]: { since: "6.0.0", replacedBy: null },        },    },    // safe-buffer.Buffer function/constructror is just a re-export of buffer.Buffer    // and should be deprecated likewise.    "safe-buffer": {        Buffer: {            [CONSTRUCT]: {                since: "6.0.0",                replacedBy: [                    { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" },                    { name: "'buffer.Buffer.from()'", supported: "5.10.0" },                ],            },            [CALL]: {                since: "6.0.0",                replacedBy: [                    { name: "'buffer.Buffer.alloc()'", supported: "5.10.0" },                    { name: "'buffer.Buffer.from()'", supported: "5.10.0" },                ],            },        },        SlowBuffer: {            [READ]: {                since: "6.0.0",                replacedBy: [                    {                        name: "'buffer.Buffer.allocUnsafeSlow()'",                        supported: "5.12.0",                    },                ],            },        },    },    sys: {        [READ]: {            since: "0.3.0",            replacedBy: "'util' module",        },    },    timers: {        enroll: {            [READ]: {                since: "10.0.0",                replacedBy: [                    { name: "'setTimeout()'", supported: "0.0.1" },                    { name: "'setInterval()'", supported: "0.0.1" },                ],            },        },        unenroll: {            [READ]: {                since: "10.0.0",                replacedBy: [                    { name: "'clearTimeout()'", supported: "0.0.1" },                    { name: "'clearInterval()'", supported: "0.0.1" },                ],            },        },    },    tls: {        CleartextStream: {            [READ]: { since: "0.10.0", replacedBy: null },        },        CryptoStream: {            [READ]: {                since: "0.12.0",                replacedBy: [{ name: "'tls.TLSSocket'", supported: "0.11.4" }],            },        },        SecurePair: {            [READ]: {                since: "6.0.0",                replacedBy: [{ name: "'tls.TLSSocket'", supported: "0.11.4" }],            },        },        convertNPNProtocols: {            [READ]: { since: "10.0.0", replacedBy: null },        },        createSecurePair: {            [READ]: {                since: "6.0.0",                replacedBy: [{ name: "'tls.TLSSocket'", supported: "0.11.4" }],            },        },        parseCertString: {            [READ]: {                since: "8.6.0",                replacedBy: [                    { name: "'querystring.parse()'", supported: "0.1.25" },                ],            },        },    },    tty: {        setRawMode: {            [READ]: {                since: "0.10.0",                replacedBy:                    "'tty.ReadStream#setRawMode()' (e.g. 'process.stdin.setRawMode()')",            },        },    },    url: {        parse: {            [READ]: {                since: "11.0.0",                replacedBy: [                    { name: "'url.URL' constructor", supported: "6.13.0" },                ],            },        },        resolve: {            [READ]: {                since: "11.0.0",                replacedBy: [                    { name: "'url.URL' constructor", supported: "6.13.0" },                ],            },        },    },    util: {        debug: {            [READ]: {                since: "0.12.0",                replacedBy: [                    { name: "'console.error()'", supported: "0.1.100" },                ],            },        },        error: {            [READ]: {                since: "0.12.0",                replacedBy: [                    { name: "'console.error()'", supported: "0.1.100" },                ],            },        },        isArray: {            [READ]: {                since: "4.0.0",                replacedBy: [                    { name: "'Array.isArray()'", supported: "0.1.100" },                ],            },        },        isBoolean: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isBuffer: {            [READ]: {                since: "4.0.0",                replacedBy: [                    { name: "'Buffer.isBuffer()'", supported: "0.1.101" },                ],            },        },        isDate: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isError: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isFunction: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isNull: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isNullOrUndefined: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isNumber: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isObject: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isPrimitive: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isRegExp: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isString: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isSymbol: {            [READ]: { since: "4.0.0", replacedBy: null },        },        isUndefined: {            [READ]: { since: "4.0.0", replacedBy: null },        },        log: {            [READ]: { since: "6.0.0", replacedBy: "a third party module" },        },        print: {            [READ]: {                since: "0.12.0",                replacedBy: [{ name: "'console.log()'", supported: "0.1.100" }],            },        },        pump: {            [READ]: {                since: "0.10.0",                replacedBy: [                    { name: "'stream.Readable#pipe()'", supported: "0.9.4" },                ],            },        },        puts: {            [READ]: {                since: "0.12.0",                replacedBy: [{ name: "'console.log()'", supported: "0.1.100" }],            },        },        _extend: {            [READ]: {                since: "6.0.0",                replacedBy: [{ name: "'Object.assign()'", supported: "4.0.0" }],            },        },    },    vm: {        runInDebugContext: {            [READ]: { since: "8.0.0", replacedBy: null },        },    },}const globals = {    Buffer: {        [CONSTRUCT]: {            since: "6.0.0",            replacedBy: [                { name: "'Buffer.alloc()'", supported: "5.10.0" },                { name: "'Buffer.from()'", supported: "5.10.0" },            ],        },        [CALL]: {            since: "6.0.0",            replacedBy: [                { name: "'Buffer.alloc()'", supported: "5.10.0" },                { name: "'Buffer.from()'", supported: "5.10.0" },            ],        },    },    COUNTER_NET_SERVER_CONNECTION: {        [READ]: { since: "11.0.0", replacedBy: null },    },    COUNTER_NET_SERVER_CONNECTION_CLOSE: {        [READ]: { since: "11.0.0", replacedBy: null },    },    COUNTER_HTTP_SERVER_REQUEST: {        [READ]: { since: "11.0.0", replacedBy: null },    },    COUNTER_HTTP_SERVER_RESPONSE: {        [READ]: { since: "11.0.0", replacedBy: null },    },    COUNTER_HTTP_CLIENT_REQUEST: {        [READ]: { since: "11.0.0", replacedBy: null },    },    COUNTER_HTTP_CLIENT_RESPONSE: {        [READ]: { since: "11.0.0", replacedBy: null },    },    GLOBAL: {        [READ]: {            since: "6.0.0",            replacedBy: [{ name: "'global'", supported: "0.1.27" }],        },    },    Intl: {        v8BreakIterator: {            [READ]: { since: "7.0.0", replacedBy: null },        },    },    require: {        extensions: {            [READ]: {                since: "0.12.0",                replacedBy: "compiling them ahead of time",            },        },    },    root: {        [READ]: {            since: "6.0.0",            replacedBy: [{ name: "'global'", supported: "0.1.27" }],        },    },    process: modules.process,}/** * Makes a replacement message. * * @param {string|array|null} replacedBy - The text of substitute way. * @param {Range} version - The configured version range * @returns {string} Replacement message. */function toReplaceMessage(replacedBy, version) {    let message = replacedBy    if (Array.isArray(replacedBy)) {        message = replacedBy            .filter(                ({ supported }) =>                    !version.intersects(getSemverRange(`<${supported}`))            )            .map(({ name }) => name)            .join(" or ")    }    return message ? `. Use ${message} instead` : ""}/** * Convert a given path to name. * @param {symbol} type The report type. * @param {string[]} path The property access path. * @returns {string} The name. */function toName(type, path) {    const baseName = path.join(".")    return type === ReferenceTracker.CALL        ? `${baseName}()`        : type === ReferenceTracker.CONSTRUCT            ? `new ${baseName}()`            : baseName}/** * Parses the options. * @param {RuleContext} context The rule context. * @returns {{version:Range,ignoredGlobalItems:Set<string>,ignoredModuleItems:Set<string>}} Parsed *     value. */function parseOptions(context) {    const raw = context.options[0] || {}    const filePath = context.getFilename()    const version = getConfiguredNodeVersion(raw.version, filePath)    const ignoredModuleItems = new Set(raw.ignoreModuleItems || [])    const ignoredGlobalItems = new Set(raw.ignoreGlobalItems || [])    return Object.freeze({ version, ignoredGlobalItems, ignoredModuleItems })}module.exports = {    meta: {        docs: {            description: "disallow deprecated APIs",            category: "Best Practices",            recommended: true,            url:                "https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-deprecated-api.md",        },        type: "problem",        fixable: null,        schema: [            {                type: "object",                properties: {                    version: {                        type: "string",                    },                    ignoreModuleItems: {                        type: "array",                        items: {                            enum: Array.from(enumeratePropertyNames(modules)),                        },                        additionalItems: false,                        uniqueItems: true,                    },                    ignoreGlobalItems: {                        type: "array",                        items: {                            enum: Array.from(enumeratePropertyNames(globals)),                        },                        additionalItems: false,                        uniqueItems: true,                    },                    // Deprecated since v4.2.0                    ignoreIndirectDependencies: { type: "boolean" },                },                additionalProperties: false,            },        ],    },    create(context) {        const {            ignoredModuleItems,            ignoredGlobalItems,            version,        } = parseOptions(context)        /**         * Reports a use of a deprecated API.         *         * @param {ASTNode} node - A node to report.         * @param {string} name - The name of a deprecated API.         * @param {{since: number, replacedBy: string}} info - Information of the API.         * @returns {void}         */        function reportItem(node, name, info) {            context.report({                node,                loc: node.loc,                message:                    "{{name}} was deprecated since v{{version}}{{replace}}.",                data: {                    name,                    version: info.since,                    replace: toReplaceMessage(info.replacedBy, version),                },            })        }        return {            "Program:exit"() {                const tracker = new ReferenceTracker(context.getScope(), {                    mode: "legacy",                })                for (const report of tracker.iterateGlobalReferences(globals)) {                    const { node, path, type, info } = report                    const name = toName(type, path)                    if (!ignoredGlobalItems.has(name)) {                        reportItem(node, `'${name}'`, info)                    }                }                for (const report of [                    ...tracker.iterateCjsReferences(modules),                    ...tracker.iterateEsmReferences(modules),                ]) {                    const { node, path, type, info } = report                    const name = toName(type, path)                    const suffix = path.length === 1 ? " module" : ""                    if (!ignoredModuleItems.has(name)) {                        reportItem(node, `'${name}'${suffix}`, info)                    }                }            },        }    },}
 |