Socket
Socket
Sign inDemoInstall

eslint-plugin-node

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-node - npm Package Compare versions

Comparing version 7.0.0-beta.0 to 7.0.0

lib/util/check-prefer-global.js

2

lib/rules/exports-style.js

@@ -149,3 +149,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/exports-style.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/exports-style.md",
},

@@ -152,0 +152,0 @@ fixable: null,

@@ -7,64 +7,386 @@ /**

const { ReferenceTracker } = require("eslint-utils")
const { globals, modules } = require("../util/deprecated-apis")
const { CALL, CONSTRUCT, READ, ReferenceTracker } = require("eslint-utils")
const enumeratePropertyNames = require("../util/enumerate-property-names")
const MODULE_ITEMS = listNames(modules)
const GLOBAL_ITEMS = listNames(globals)
/**
* Gets the array of deprecated items.
*
* These are names which are concatenated by dots.
* E.g. `buffer.Buffer`, `events.EventEmitter.listenerCount`
*
* @param {object} definition - The definition of deprecated APIs.
* @param {string[]} result - The array of the result.
* @param {string[]} stack - The array to manage the stack of paths.
* @returns {string[]} `result`.
*/
function listNames(definition, result = [], stack = []) {
for (const key of Object.keys(definition)) {
stack.push(key)
try {
const item = definition[key]
let stop = false
if (item[ReferenceTracker.READ]) {
result.push(stack.join("."))
stop = true
}
if (item[ReferenceTracker.CALL]) {
result.push(`${stack.join(".")}()`)
stop = true
}
if (item[ReferenceTracker.CONSTRUCT]) {
result.push(`new ${stack.join(".")}()`)
stop = true
}
if (!stop) {
listNames(item, result, stack)
}
} finally {
stack.pop()
}
}
return result
const modules = {
_linklist: {
[READ]: { since: "5.0.0", replacedBy: null },
},
assert: {
deepEqual: {
[READ]: {
since: "10.0.0",
replacedBy:
"'assert.deepStrictEqual' or 'assert.strict.deepEqual'",
},
},
equal: {
[READ]: {
since: "10.0.0",
replacedBy: "'assert.strictEqual' or 'assert.strict.equal'",
},
},
notDeepEqual: {
[READ]: {
since: "10.0.0",
replacedBy:
"'assert.notDeepStrictEqual' or 'assert.strict.notDeepEqual'",
},
},
notEqual: {
[READ]: {
since: "10.0.0",
replacedBy:
"'assert.notStrictEqual' or 'assert.strict.notEqual'",
},
},
},
//eslint-disable-next-line camelcase
async_hooks: {
currentId: {
[READ]: {
since: "8.2.0",
replacedBy: "'async_hooks.executionAsyncId()'",
},
},
triggerId: {
[READ]: {
since: "8.2.0",
replacedBy: "'async_hooks.triggerAsyncId()'",
},
},
},
buffer: {
Buffer: {
[CONSTRUCT]: {
since: "6.0.0",
replacedBy: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'",
},
[CALL]: {
since: "6.0.0",
replacedBy: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'",
},
},
SlowBuffer: {
[READ]: {
since: "6.0.0",
replacedBy: "'buffer.Buffer.allocUnsafeSlow()'",
},
},
},
constants: {
[READ]: {
since: "6.3.0",
replacedBy: "'constants' property of each module",
},
},
crypto: {
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: "'tls.createCipheriv()'" },
},
createCredentials: {
[READ]: {
since: "0.12.0",
replacedBy: "'tls.createSecureContext()'",
},
},
createDecipher: {
[READ]: { since: "10.0.0", replacedBy: "'tls.createDecipheriv()'" },
},
fips: {
[READ]: {
since: "10.0.0",
replacedBy: "'crypto.getFips()' and 'crypto.setFips()'",
},
},
},
domain: {
[READ]: { since: "4.0.0", replacedBy: null },
},
events: {
EventEmitter: {
listenerCount: {
[READ]: {
since: "4.0.0",
replacedBy: "'events.EventEmitter#listenerCount()'",
},
},
},
listenerCount: {
[READ]: {
since: "4.0.0",
replacedBy: "'events.EventEmitter#listenerCount()'",
},
},
},
freelist: {
[READ]: { since: "4.0.0", replacedBy: null },
},
fs: {
SyncWriteStream: {
[READ]: { since: "4.0.0", replacedBy: null },
},
exists: {
[READ]: {
since: "4.0.0",
replacedBy: "'fs.stat()' or 'fs.access()'",
},
},
lchmod: {
[READ]: { since: "0.4.0", replacedBy: null },
},
lchmodSync: {
[READ]: { since: "0.4.0", replacedBy: null },
},
lchown: {
[READ]: { since: "0.4.0", replacedBy: null },
},
lchownSync: {
[READ]: { since: "0.4.0", replacedBy: null },
},
},
http: {
createClient: {
[READ]: { since: "0.10.0", replacedBy: "'http.request()'" },
},
},
module: {
Module: {
requireRepl: {
[READ]: { since: "6.0.0", replacedBy: "'require(\"repl\")'" },
},
_debug: {
[READ]: { since: "9.0.0", replacedBy: null },
},
},
requireRepl: {
[READ]: { since: "6.0.0", replacedBy: "'require(\"repl\")'" },
},
_debug: {
[READ]: { since: "9.0.0", replacedBy: null },
},
},
os: {
getNetworkInterfaces: {
[READ]: { since: "0.6.0", replacedBy: "'os.networkInterfaces()'" },
},
tmpDir: {
[READ]: { since: "7.0.0", replacedBy: "'os.tmpdir()'" },
},
},
path: {
_makeLong: {
[READ]: { since: "9.0.0", replacedBy: "'path.toNamespacedPath()'" },
},
},
process: {
EventEmitter: {
[READ]: { since: "0.6.0", replacedBy: "'require(\"events\")'" },
},
assert: {
[READ]: { since: "10.0.0", replacedBy: "'require(\"assert\")'" },
},
env: {
NODE_REPL_HISTORY_FILE: {
[READ]: { since: "4.0.0", replacedBy: "'NODE_REPL_HISTORY'" },
},
},
},
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: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'",
},
[CALL]: {
since: "6.0.0",
replacedBy: "'buffer.Buffer.alloc()' or 'buffer.Buffer.from()'",
},
},
SlowBuffer: {
[READ]: {
since: "6.0.0",
replacedBy: "'buffer.Buffer.allocUnsafeSlow()'",
},
},
},
sys: {
[READ]: { since: "0.3.0", replacedBy: "'util' module" },
},
timers: {
enroll: {
[READ]: {
since: "10.0.0",
replacedBy: "'setTimeout()' or 'setInterval()'",
},
},
unenroll: {
[READ]: {
since: "10.0.0",
replacedBy: "'clearTimeout()' or 'clearInterval()'",
},
},
},
tls: {
CleartextStream: {
[READ]: { since: "0.10.0", replacedBy: null },
},
CryptoStream: {
[READ]: { since: "0.12.0", replacedBy: "'tls.TLSSocket'" },
},
SecurePair: {
[READ]: { since: "6.0.0", replacedBy: "'tls.TLSSocket'" },
},
convertNPNProtocols: {
[READ]: { since: "10.0.0", replacedBy: null },
},
createSecurePair: {
[READ]: { since: "6.0.0", replacedBy: "'tls.TLSSocket'" },
},
parseCertString: {
[READ]: { since: "8.6.0", replacedBy: "'querystring.parse()'" },
},
},
tty: {
setRawMode: {
[READ]: {
since: "0.10.0",
replacedBy:
"'tty.ReadStream#setRawMode()' (e.g. 'process.stdin.setRawMode()')",
},
},
},
util: {
debug: {
[READ]: { since: "0.12.0", replacedBy: "'console.error()'" },
},
error: {
[READ]: { since: "0.12.0", replacedBy: "'console.error()'" },
},
isArray: {
[READ]: { since: "4.0.0", replacedBy: "'Array.isArray()'" },
},
isBoolean: {
[READ]: { since: "4.0.0", replacedBy: null },
},
isBuffer: {
[READ]: { since: "4.0.0", replacedBy: "'Buffer.isBuffer()'" },
},
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: "'console.log()'" },
},
pump: {
[READ]: { since: "0.10.0", replacedBy: "'stream.Readable#pipe()'" },
},
puts: {
[READ]: { since: "0.12.0", replacedBy: "'console.log()'" },
},
_extend: {
[READ]: { since: "6.0.0", replacedBy: "'Object.assign()'" },
},
},
vm: {
runInDebugContext: {
[READ]: { since: "8.0.0", replacedBy: null },
},
},
}
/**
* Converts from a version number to a version text to display.
*
* @param {number} value - A version number to convert.
* @returns {string} Covnerted text.
*/
function toVersionText(value) {
if (value <= 0.12) {
return value.toFixed(2)
}
if (value < 1) {
return value.toFixed(1)
}
return String(value)
const globals = {
Buffer: {
[CONSTRUCT]: {
since: "6.0.0",
replacedBy: "'Buffer.alloc()' or 'Buffer.from()'",
},
[CALL]: {
since: "6.0.0",
replacedBy: "'Buffer.alloc()' or 'Buffer.from()'",
},
},
GLOBAL: {
[READ]: { since: "6.0.0", replacedBy: "'global'" },
},
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: "'global'" },
},
process: modules.process,
}

@@ -104,3 +426,3 @@

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-deprecated-api.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-deprecated-api.md",
},

@@ -114,3 +436,5 @@ fixable: null,

type: "array",
items: { enum: MODULE_ITEMS },
items: {
enum: Array.from(enumeratePropertyNames(modules)),
},
additionalItems: false,

@@ -121,3 +445,5 @@ uniqueItems: true,

type: "array",
items: { enum: GLOBAL_ITEMS },
items: {
enum: Array.from(enumeratePropertyNames(globals)),
},
additionalItems: false,

@@ -136,4 +462,4 @@ uniqueItems: true,

const options = context.options[0] || {}
const ignoredModuleItems = options.ignoreModuleItems || []
const ignoredGlobalItems = options.ignoreGlobalItems || []
const ignoredModuleItems = new Set(options.ignoreModuleItems || [])
const ignoredGlobalItems = new Set(options.ignoreGlobalItems || [])

@@ -156,3 +482,3 @@ /**

name,
version: toVersionText(info.since),
version: info.since,
replace: toReplaceMessage(info.replacedBy),

@@ -173,7 +499,10 @@ },

if (!ignoredGlobalItems.includes(name)) {
if (!ignoredGlobalItems.has(name)) {
reportItem(node, `'${name}'`, info)
}
}
for (const report of tracker.iterateCjsReferences(modules)) {
for (const report of [
...tracker.iterateCjsReferences(modules),
...tracker.iterateEsmReferences(modules),
]) {
const { node, path, type, info } = report

@@ -183,15 +512,6 @@ const name = toName(type, path)

if (!ignoredModuleItems.includes(name)) {
if (!ignoredModuleItems.has(name)) {
reportItem(node, `'${name}'${suffix}`, info)
}
}
for (const report of tracker.iterateEsmReferences(modules)) {
const { node, path, type, info } = report
const name = toName(type, path)
const suffix = path.length === 1 ? " module" : ""
if (!ignoredModuleItems.includes(name)) {
reportItem(node, `'${name}'${suffix}`, info)
}
}
},

@@ -198,0 +518,0 @@ }

@@ -21,3 +21,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-extraneous-import.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-extraneous-import.md",
},

@@ -24,0 +24,0 @@ fixable: null,

@@ -21,3 +21,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-extraneous-require.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-extraneous-require.md",
},

@@ -24,0 +24,0 @@ fixable: null,

@@ -58,3 +58,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-hide-core-modules.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-hide-core-modules.md",
},

@@ -61,0 +61,0 @@ deprecated: true,

@@ -20,3 +20,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-missing-import.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-missing-import.md",
},

@@ -23,0 +23,0 @@ fixable: null,

@@ -20,3 +20,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-missing-require.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-missing-require.md",
},

@@ -23,0 +23,0 @@ fixable: null,

@@ -39,3 +39,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-unpublished-bin.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-unpublished-bin.md",
},

@@ -42,0 +42,0 @@ fixable: null,

@@ -21,3 +21,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-unpublished-import.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-unpublished-import.md",
},

@@ -24,0 +24,0 @@ fixable: null,

@@ -21,3 +21,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-unpublished-require.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-unpublished-require.md",
},

@@ -24,0 +24,0 @@ fixable: null,

@@ -9,3 +9,2 @@ /**

const { getInnermostScope, getPropertyName } = require("eslint-utils")
const features = require("../util/features")
const getPackageJson = require("../util/get-package-json")

@@ -37,3 +36,2 @@

const DEFAULT_VERSION = "4.0.0"
const OPTIONS = Object.keys(features)
const FUNC_TYPE = /^(?:Arrow)?Function(?:Declaration|Expression)$/

@@ -151,3 +149,721 @@ const CLASS_TYPE = /^Class(?:Declaration|Expression)$/

const REGEXP_UNICODE_PROPERTY = /(\\*)\\[pP]{.+?}/
const FEATURES = {
defaultParameters: {
alias: ["syntax"],
name: "Default parameters",
node: "6.0.0",
},
restParameters: {
alias: ["syntax"],
name: "Rest parameters",
node: "6.0.0",
},
spreadOperators: {
alias: ["syntax"],
name: "Spread operators",
node: "5.0.0",
},
objectLiteralExtensions: {
alias: ["syntax"],
name: "Object literal extensions",
node: "4.0.0",
},
objectPropertyShorthandOfGetSet: {
alias: ["syntax", "objectLiteralExtensions"],
name: "Property shorthand of 'get' and 'set'",
node: "6.0.0",
},
forOf: {
alias: ["syntax"],
name: "'for..of' loops",
node: "0.12.0",
},
binaryNumberLiterals: {
alias: ["syntax"],
name: "Binary number literals",
node: "4.0.0",
},
octalNumberLiterals: {
alias: ["syntax"],
name: "Octal number literals",
node: "4.0.0",
},
templateStrings: {
alias: ["syntax"],
name: "Template strings",
node: "4.0.0",
},
regexpY: {
alias: ["syntax"],
name: "RegExp 'y' flags",
node: "6.0.0",
},
regexpU: {
alias: ["syntax"],
name: "RegExp 'u' flags",
node: "6.0.0",
},
destructuring: {
alias: ["syntax"],
name: "Destructuring",
node: "6.0.0",
},
unicodeCodePointEscapes: {
alias: ["syntax"],
name: "Unicode code point escapes",
node: "4.0.0",
},
"new.target": {
alias: ["syntax"],
name: "'new.target'",
node: "5.0.0",
},
const: {
alias: ["syntax"],
name: "'const' declarations",
node: {
sloppy: "6.0.0",
strict: "4.0.0",
},
},
let: {
alias: ["syntax"],
name: "'let' declarations",
node: {
sloppy: "6.0.0",
strict: "4.0.0",
},
},
blockScopedFunctions: {
alias: ["syntax"],
name: "Block-scoped functions",
node: {
sloppy: "6.0.0",
strict: "4.0.0",
},
},
arrowFunctions: {
alias: ["syntax"],
name: "Arrow functions",
node: "4.0.0",
},
generatorFunctions: {
alias: ["syntax"],
name: "Generator functions",
node: "4.0.0",
},
classes: {
alias: ["syntax"],
name: "Classes",
node: {
sloppy: "6.0.0",
strict: "4.0.0",
},
},
modules: {
alias: ["syntax"],
name: "Import and export declarations",
node: null,
},
exponentialOperators: {
alias: ["syntax"],
name: "Exponential operators (**)",
node: "7.0.0",
},
asyncAwait: {
alias: ["syntax"],
name: "Async functions",
node: "7.6.0",
},
trailingCommasInFunctions: {
alias: ["syntax"],
name: "Trailing commas in functions",
node: "8.0.0",
},
//------------------------------------------
templateLiteralRevision: {
alias: ["syntax"],
name: "Illegal escape sequences in taggled templates",
node: "9.0.0",
},
regexpS: {
alias: ["syntax"],
name: "RegExp 's' flags",
node: "9.0.0",
},
regexpNamedCaptureGroups: {
alias: ["syntax"],
name: "RegExp named capture groups",
node: "10.0.0",
},
regexpLookbehind: {
alias: ["syntax"],
name: "RegExp lookbehind assertions",
node: "9.0.0",
},
regexpUnicodeProperties: {
alias: ["syntax"],
name: "RegExp Unicode property escapes",
node: "10.0.0",
},
restProperties: {
alias: ["syntax"],
name: "Rest properties",
node: "8.3.0",
},
spreadProperties: {
alias: ["syntax"],
name: "Spread properties",
node: "8.3.0",
},
asyncGenerators: {
alias: ["syntax"],
name: "Async generators",
node: "10.0.0",
},
forAwaitOf: {
alias: ["syntax"],
name: "for-await-of loops",
node: "10.0.0",
},
Int8Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Int8Array'",
singular: true,
node: "0.12.0",
},
Uint8Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Uint8Array'",
singular: true,
node: "0.12.0",
},
Uint8ClampedArray: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Uint8ClampedArray'",
singular: true,
node: "0.12.0",
},
Int16Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Int16Array'",
singular: true,
node: "0.12.0",
},
Uint16Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Uint16Array'",
singular: true,
node: "0.12.0",
},
Int32Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Int32Array'",
singular: true,
node: "0.12.0",
},
Uint32Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Uint32Array'",
singular: true,
node: "0.12.0",
},
Float32Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Float32Array'",
singular: true,
node: "0.12.0",
},
Float64Array: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'Float64Array'",
singular: true,
node: "0.12.0",
},
DataView: {
alias: ["runtime", "globalObjects", "typedArrays"],
name: "'DataView'",
singular: true,
node: "0.12.0",
},
Map: {
alias: ["runtime", "globalObjects"],
name: "'Map'",
singular: true,
node: "0.12.0",
},
Set: {
alias: ["runtime", "globalObjects"],
name: "'Set'",
singular: true,
node: "0.12.0",
},
WeakMap: {
alias: ["runtime", "globalObjects"],
name: "'WeakMap'",
singular: true,
node: "0.12.0",
},
WeakSet: {
alias: ["runtime", "globalObjects"],
name: "'WeakSet'",
singular: true,
node: "0.12.0",
},
Proxy: {
alias: ["runtime", "globalObjects"],
name: "'Proxy'",
singular: true,
node: "6.0.0",
},
Reflect: {
alias: ["runtime", "globalObjects"],
name: "'Reflect'",
singular: true,
node: "6.0.0",
},
Promise: {
alias: ["runtime", "globalObjects"],
name: "'Promise'",
singular: true,
node: "0.12.0",
},
Symbol: {
alias: ["runtime", "globalObjects"],
name: "'Symbol'",
singular: true,
node: "0.12.0",
},
SharedArrayBuffer: {
alias: ["runtime", "globalObjects"],
name: "'SharedArrayBuffer'",
singular: true,
node: "9.0.0",
},
Atomics: {
alias: ["runtime", "globalObjects"],
name: "'Atomics'",
singular: true,
node: "9.0.0",
},
"Object.assign": {
alias: ["runtime", "staticMethods", "Object.*"],
name: "'Object.assign'",
singular: true,
node: "4.0.0",
},
"Object.is": {
alias: ["runtime", "staticMethods", "Object.*"],
name: "'Object.is'",
singular: true,
node: "0.12.0",
},
"Object.getOwnPropertySymbols": {
alias: ["runtime", "staticMethods", "Object.*"],
name: "'Object.getOwnPropertySymbols'",
singular: true,
node: "0.12.0",
},
"Object.setPrototypeOf": {
alias: ["runtime", "staticMethods", "Object.*"],
name: "'Object.setPrototypeOf'",
singular: true,
node: "0.12.0",
},
"Object.values": {
alias: ["runtime", "staticMethods", "Object.*"],
name: "'Object.values'",
singular: true,
node: "7.0.0",
},
"Object.entries": {
alias: ["runtime", "staticMethods", "Object.*"],
name: "'Object.entries'",
singular: true,
node: "7.0.0",
},
"Object.getOwnPropertyDescriptors": {
alias: ["runtime", "staticMethods", "Object.*"],
name: "'Object.getOwnPropertyDescriptors'",
singular: true,
node: "7.0.0",
},
"String.raw": {
alias: ["runtime", "staticMethods", "String.*"],
name: "'String.raw'",
singular: true,
node: "4.0.0",
},
"String.fromCodePoint": {
alias: ["runtime", "staticMethods", "String.*"],
name: "'String.fromCodePoint'",
singular: true,
node: "4.0.0",
},
"Array.from": {
alias: ["runtime", "staticMethods", "Array.*"],
name: "'Array.from'",
singular: true,
node: "4.0.0",
},
"Array.of": {
alias: ["runtime", "staticMethods", "Array.*"],
name: "'Array.of'",
singular: true,
node: "4.0.0",
},
"Number.isFinite": {
alias: ["runtime", "staticMethods", "Number.*"],
name: "'Number.isFinite'",
singular: true,
node: "0.10.0",
},
"Number.isInteger": {
alias: ["runtime", "staticMethods", "Number.*"],
name: "'Number.isInteger'",
singular: true,
node: "0.12.0",
},
"Number.isSafeInteger": {
alias: ["runtime", "staticMethods", "Number.*"],
name: "'Number.isSafeInteger'",
singular: true,
node: "0.12.0",
},
"Number.isNaN": {
alias: ["runtime", "staticMethods", "Number.*"],
name: "'Number.isNaN'",
singular: true,
node: "0.10.0",
},
"Number.EPSILON": {
alias: ["runtime", "staticMethods", "Number.*"],
name: "'Number.EPSILON'",
singular: true,
node: "0.12.0",
},
"Number.MIN_SAFE_INTEGER": {
alias: ["runtime", "staticMethods", "Number.*"],
name: "'Number.MIN_SAFE_INTEGER'",
singular: true,
node: "0.12.0",
},
"Number.MAX_SAFE_INTEGER": {
alias: ["runtime", "staticMethods", "Number.*"],
name: "'Number.MAX_SAFE_INTEGER'",
singular: true,
node: "0.12.0",
},
"Math.clz32": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.clz32'",
singular: true,
node: "0.12.0",
},
"Math.imul": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.imul'",
singular: true,
node: "0.12.0",
},
"Math.sign": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.sign'",
singular: true,
node: "0.12.0",
},
"Math.log10": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.log10'",
singular: true,
node: "0.12.0",
},
"Math.log2": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.log2'",
singular: true,
node: "0.12.0",
},
"Math.log1p": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.log1p'",
singular: true,
node: "0.12.0",
},
"Math.expm1": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.expm1'",
singular: true,
node: "0.12.0",
},
"Math.cosh": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.cosh'",
singular: true,
node: "0.12.0",
},
"Math.sinh": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.sinh'",
singular: true,
node: "0.12.0",
},
"Math.tanh": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.tanh'",
singular: true,
node: "0.12.0",
},
"Math.acosh": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.acosh'",
singular: true,
node: "0.12.0",
},
"Math.asinh": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.asinh'",
singular: true,
node: "0.12.0",
},
"Math.atanh": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.atanh'",
singular: true,
node: "0.12.0",
},
"Math.trunc": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.trunc'",
singular: true,
node: "0.12.0",
},
"Math.fround": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.fround'",
singular: true,
node: "0.12.0",
},
"Math.cbrt": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.cbrt'",
singular: true,
node: "0.12.0",
},
"Math.hypot": {
alias: ["runtime", "staticMethods", "Math.*"],
name: "'Math.hypot'",
singular: true,
node: "0.12.0",
},
"Symbol.hasInstance": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.hasInstance'",
singular: true,
node: "6.5.0",
},
"Symbol.isConcatSpreadablec": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.isConcatSpreadablec'",
singular: true,
node: "6.0.0",
},
"Symbol.iterator": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.iterator'",
singular: true,
node: "0.12.0",
},
"Symbol.species": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.species'",
singular: true,
node: "6.5.0",
},
"Symbol.replace": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.replace'",
singular: true,
node: "6.0.0",
},
"Symbol.search": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.search'",
singular: true,
node: "6.0.0",
},
"Symbol.split": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.split'",
singular: true,
node: "6.0.0",
},
"Symbol.match": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.match'",
singular: true,
node: "6.0.0",
},
"Symbol.toPrimitive": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.toPrimitive'",
singular: true,
node: "6.0.0",
},
"Symbol.toStringTag": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.toStringTag'",
singular: true,
node: "6.0.0",
},
"Symbol.unscopables": {
alias: ["runtime", "staticMethods", "Symbol.*"],
name: "'Symbol.unscopables'",
singular: true,
node: "4.0.0",
},
"Atomics.add": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.add'",
singular: true,
node: "9.0.0",
},
"Atomics.and": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.and'",
singular: true,
node: "9.0.0",
},
"Atomics.compareExchange": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.compareExchange'",
singular: true,
node: "9.0.0",
},
"Atomics.exchange": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.exchange'",
singular: true,
node: "9.0.0",
},
"Atomics.wait": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.wait'",
singular: true,
node: "9.0.0",
},
"Atomics.wake": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.wake'",
singular: true,
node: "9.0.0",
},
"Atomics.isLockFree": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.isLockFree'",
singular: true,
node: "9.0.0",
},
"Atomics.load": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.load'",
singular: true,
node: "9.0.0",
},
"Atomics.or": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.or'",
singular: true,
node: "9.0.0",
},
"Atomics.store": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.store'",
singular: true,
node: "9.0.0",
},
"Atomics.sub": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.sub'",
singular: true,
node: "9.0.0",
},
"Atomics.xor": {
alias: ["runtime", "staticMethods", "Atomics.*"],
name: "'Atomics.xor'",
singular: true,
node: "9.0.0",
},
extendsArray: {
alias: ["runtime", "extends"],
name: "Subclassing of 'Array'",
singular: true,
node: "6.0.0",
},
extendsRegExp: {
alias: ["runtime", "extends"],
name: "Subclassing of 'RegExp'",
singular: true,
node: "5.0.0",
},
extendsFunction: {
alias: ["runtime", "extends"],
name: "Subclassing of 'Function'",
singular: true,
node: "6.0.0",
},
extendsPromise: {
alias: ["runtime", "extends"],
name: "Subclassing of 'Promise'",
singular: true,
node: "5.0.0",
},
extendsBoolean: {
alias: ["runtime", "extends"],
name: "Subclassing of 'Boolean'",
singular: true,
node: "4.0.0",
},
extendsNumber: {
alias: ["runtime", "extends"],
name: "Subclassing of 'Number'",
singular: true,
node: "4.0.0",
},
extendsString: {
alias: ["runtime", "extends"],
name: "Subclassing of 'String'",
singular: true,
node: "4.0.0",
},
extendsMap: {
alias: ["runtime", "extends"],
name: "Subclassing of 'Map'",
singular: true,
node: "4.0.0",
},
extendsSet: {
alias: ["runtime", "extends"],
name: "Subclassing of 'Set'",
singular: true,
node: "4.0.0",
},
extendsNull: {
alias: ["runtime", "extends"],
name: "'extends null'",
singular: true,
node: null,
},
}
const OPTIONS = Object.keys(FEATURES)
/**

@@ -177,3 +893,3 @@ * Gets default version configuration of this rule.

OPTIONS.reduce((retv, key) => {
for (const alias of features[key].alias) {
for (const alias of FEATURES[key].alias) {
retv[alias] = true

@@ -197,3 +913,3 @@ }

ignores.indexOf(key) !== -1 ||
features[key].alias.some(alias => ignores.indexOf(alias) !== -1)
FEATURES[key].alias.some(alias => ignores.indexOf(alias) !== -1)
)

@@ -236,3 +952,3 @@ }

OPTIONS.reduce((retv, key) => {
const feature = features[key]
const feature = FEATURES[key]

@@ -341,3 +1057,3 @@ if (isIgnored(key, ignores)) {

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-unsupported-features.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-unsupported-features.md",
},

@@ -344,0 +1060,0 @@ deprecated: true,

@@ -8,3 +8,3 @@ /**

const { READ } = require("eslint-utils")
const defineUnsupportedModuleHandlers = require("../../util/define-unsupported-module-handlers")
const checkUnsupportedBuiltins = require("../../util/check-unsupported-builtins")
const enumeratePropertyNames = require("../../util/enumerate-property-names")

@@ -132,3 +132,3 @@

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-unsupported-features/es-builtins.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-unsupported-features/es-builtins.md",
},

@@ -162,4 +162,8 @@ fixable: null,

create(context) {
return defineUnsupportedModuleHandlers(context, trackMap)
return {
"Program:exit"() {
checkUnsupportedBuiltins(context, trackMap)
},
}
},
}

@@ -9,4 +9,5 @@ /**

const { getInnermostScope } = require("eslint-utils")
const semver = require("semver")
const getEnginesNode = require("../../util/get-engines-node")
const { Range } = require("semver") //eslint-disable-line no-unused-vars
const getConfiguredNodeVersion = require("../../util/get-configured-node-version")
const getSemverRange = require("../../util/get-semver-range")

@@ -357,10 +358,10 @@ const getOrSet = /^(?:g|s)et$/

* Parses the options.
* @param {object|undefined} options - An option object to parse.
* @param {string} defaultVersion - The default version to use if the version option was omitted.
* @returns {{version:string,ignores:Set<string>}} Parsed value.
* @param {RuleContext} context The rule context.
* @returns {{version:Range,ignores:Set<string>}} Parsed value.
*/
function parseOptions(options, defaultVersion) {
const version =
semver.validRange(options && options.version) || defaultVersion
const ignores = new Set((options && options.ignores) || [])
function parseOptions(context) {
const raw = context.options[0] || {}
const filePath = context.getFilename()
const version = getConfiguredNodeVersion(raw.version, filePath)
const ignores = new Set(raw.ignores || [])

@@ -371,26 +372,2 @@ return Object.freeze({ version, ignores })

/**
* Define the case selector with given information.
* @param {RuleContext} context The rule context to get scopes.
* @param {string} version The configured version range.
* @param {Node|null} node The node at the current location, for additional conditions.
* @returns {function(aCase:object):boolean} The case selector.
*/
function defineSelector(context, version, node) {
return aCase =>
// Version.
(!aCase.supported ||
semver.intersects(`<${aCase.supported}`, version)) &&
// Additional conditions.
(!aCase.test ||
aCase.test({
node,
get isStrict() {
return Boolean(
node && nomalizeScope(context.getScope(), node).isStrict
)
},
}))
}
/**
* Find the scope that a given node belongs to.

@@ -449,6 +426,35 @@ * @param {Scope} initialScope The initial scope to find.

* @param {RuleContext} context The rule context.
* @param {{version:string,ignores:Set<string>}} options The options.
* @param {{version:Range,ignores:Set<string>}} options The options.
* @returns {object} The defined visitor.
*/
function defineVisitor(context, options) {
const testInfoPrototype = {
get isStrict() {
return nomalizeScope(context.getScope(), this.node).isStrict
},
}
/**
* Check whether a given case object is full-supported on the configured node version.
* @param {{supported:string}} aCase The case object to check.
* @returns {boolean} `true` if it's supporting.
*/
function isNotSupportingVersion(aCase) {
return (
!aCase.supported ||
options.version.intersects(getSemverRange(`<${aCase.supported}`))
)
}
/**
* Define the predicate function to check whether a given case object is supported on the configured node version.
* @param {Node} node The node which is reported.
* @returns {function(aCase:{supported:string}):boolean} The predicate function.
*/
function isNotSupportingOn(node) {
return aCase =>
isNotSupportingVersion(aCase) &&
(!aCase.test || aCase.test({ node, __proto__: testInfoPrototype }))
}
return (

@@ -461,10 +467,3 @@ keywords

!options.ignores.has(keyword) &&
features[keyword].cases.some(
c =>
!c.supported ||
semver.intersects(
options.version,
`<${c.supported}`
)
)
features[keyword].cases.some(isNotSupportingVersion)
)

@@ -484,5 +483,5 @@ // Merge remaining features with overriding `context.report()`.

if (descriptor.data) {
descriptor.data.version = options.version
descriptor.data.version = options.version.raw
} else {
descriptor.data = { version: options.version }
descriptor.data = { version: options.version.raw }
}

@@ -492,9 +491,4 @@ descriptor.fix = undefined

// Test and report.
const hitCase = cases.find(
defineSelector(
this,
options.version,
descriptor.node
)
)
const node = descriptor.node
const hitCase = cases.find(isNotSupportingOn(node))
if (hitCase) {

@@ -520,3 +514,3 @@ descriptor.messageId = hitCase.messageId

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-unsupported-features/es-syntax.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-unsupported-features/es-syntax.md",
},

@@ -639,6 +633,4 @@ fixable: null,

create(context) {
const defaultVersion = getEnginesNode(context.getFilename())
const options = parseOptions(context.options[0], defaultVersion)
return defineVisitor(context, options)
return defineVisitor(context, parseOptions(context))
},
}

@@ -8,3 +8,3 @@ /**

const { READ } = require("eslint-utils")
const defineUnsupportedModuleHandlers = require("../../util/define-unsupported-module-handlers")
const checkUnsupportedBuiltins = require("../../util/check-unsupported-builtins")
const enumeratePropertyNames = require("../../util/enumerate-property-names")

@@ -216,3 +216,3 @@

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/no-unsupported-features/node-builtins.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/no-unsupported-features/node-builtins.md",
},

@@ -249,4 +249,8 @@ fixable: null,

create(context) {
return defineUnsupportedModuleHandlers(context, trackMap)
return {
"Program:exit"() {
checkUnsupportedBuiltins(context, trackMap)
},
}
},
}

@@ -8,4 +8,15 @@ /**

const { READ } = require("eslint-utils")
const defineHandlers = require("../../util/define-prefer-global-handlers")
const checkForPreferGlobal = require("../../util/check-prefer-global")
const trackMap = {
globals: {
Buffer: { [READ]: true },
},
modules: {
buffer: {
Buffer: { [READ]: true },
},
},
}
module.exports = {

@@ -19,3 +30,3 @@ meta: {

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/prefer-global/buffer.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/prefer-global/buffer.md",
},

@@ -33,13 +44,8 @@ fixable: null,

create(context) {
return defineHandlers(context, {
globals: {
Buffer: { [READ]: true },
return {
"Program:exit"() {
checkForPreferGlobal(context, trackMap)
},
modules: {
buffer: {
Buffer: { [READ]: true },
},
},
})
}
},
}

@@ -8,4 +8,13 @@ /**

const { READ } = require("eslint-utils")
const defineHandlers = require("../../util/define-prefer-global-handlers")
const checkForPreferGlobal = require("../../util/check-prefer-global")
const trackMap = {
globals: {
console: { [READ]: true },
},
modules: {
console: { [READ]: true },
},
}
module.exports = {

@@ -18,3 +27,3 @@ meta: {

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/prefer-global/console.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/prefer-global/console.md",
},

@@ -32,11 +41,8 @@ fixable: null,

create(context) {
return defineHandlers(context, {
globals: {
console: { [READ]: true },
return {
"Program:exit"() {
checkForPreferGlobal(context, trackMap)
},
modules: {
console: { [READ]: true },
},
})
}
},
}

@@ -8,4 +8,13 @@ /**

const { READ } = require("eslint-utils")
const defineHandlers = require("../../util/define-prefer-global-handlers")
const checkForPreferGlobal = require("../../util/check-prefer-global")
const trackMap = {
globals: {
process: { [READ]: true },
},
modules: {
process: { [READ]: true },
},
}
module.exports = {

@@ -18,3 +27,3 @@ meta: {

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/prefer-global/process.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/prefer-global/process.md",
},

@@ -32,11 +41,8 @@ fixable: null,

create(context) {
return defineHandlers(context, {
globals: {
process: { [READ]: true },
return {
"Program:exit"() {
checkForPreferGlobal(context, trackMap)
},
modules: {
process: { [READ]: true },
},
})
}
},
}

@@ -8,4 +8,15 @@ /**

const { READ } = require("eslint-utils")
const defineHandlers = require("../../util/define-prefer-global-handlers")
const checkForPreferGlobal = require("../../util/check-prefer-global")
const trackMap = {
globals: {
URLSearchParams: { [READ]: true },
},
modules: {
url: {
URLSearchParams: { [READ]: true },
},
},
}
module.exports = {

@@ -19,3 +30,3 @@ meta: {

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/prefer-global/url-search-params.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/prefer-global/url-search-params.md",
},

@@ -33,13 +44,8 @@ fixable: null,

create(context) {
return defineHandlers(context, {
globals: {
URLSearchParams: { [READ]: true },
return {
"Program:exit"() {
checkForPreferGlobal(context, trackMap)
},
modules: {
url: {
URLSearchParams: { [READ]: true },
},
},
})
}
},
}

@@ -8,4 +8,15 @@ /**

const { READ } = require("eslint-utils")
const defineHandlers = require("../../util/define-prefer-global-handlers")
const checkForPreferGlobal = require("../../util/check-prefer-global")
const trackMap = {
globals: {
URL: { [READ]: true },
},
modules: {
url: {
URL: { [READ]: true },
},
},
}
module.exports = {

@@ -18,3 +29,3 @@ meta: {

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/prefer-global/url.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/prefer-global/url.md",
},

@@ -32,13 +43,8 @@ fixable: null,

create(context) {
return defineHandlers(context, {
globals: {
URL: { [READ]: true },
return {
"Program:exit"() {
checkForPreferGlobal(context, trackMap)
},
modules: {
url: {
URL: { [READ]: true },
},
},
})
}
},
}

@@ -147,3 +147,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/process-exit-as-throw.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/process-exit-as-throw.md",
},

@@ -150,0 +150,0 @@ fixable: null,

@@ -61,3 +61,3 @@ /**

url:
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0-beta.0/docs/rules/shebang.md",
"https://github.com/mysticatea/eslint-plugin-node/blob/v7.0.0/docs/rules/shebang.md",
},

@@ -64,0 +64,0 @@ fixable: "code",

@@ -24,3 +24,9 @@ /**

if (value[CALL] || value[CONSTRUCT] || value[READ]) {
if (value[CALL]) {
yield `${path.join(".")}()`
}
if (value[CONSTRUCT]) {
yield `new ${path.join(".")}()`
}
if (value[READ]) {
yield path.join(".")

@@ -27,0 +33,0 @@ }

{
"name": "eslint-plugin-node",
"version": "7.0.0-beta.0",
"version": "7.0.0",
"description": "Additional ESLint's rules for Node.js",

@@ -5,0 +5,0 @@ "engines": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc