Fix: Prevent parseForESLint() behavior from changing after parse() is called (fixes babel/babel-eslint#558)(babel/babel-eslint#559)
* Prevent parseForESLint() behavior from changing after parse() is called (fixes https://github.com/babel/babel-eslint/issues/558, fixes https://github.com/eslint/eslint/issues/9767) * Avoid using the enhanced referencer after monkeypatching * Chore: add test for babel/babel-eslint#558 * Pass correct scope analyzer options * fix escope patch and improve tests * remove process.exit(1)
This commit is contained in:
parent
5b08714a4d
commit
e988a88af0
@ -318,9 +318,16 @@ module.exports = function(ast, parserOptions) {
|
||||
impliedStrict: false,
|
||||
sourceType: ast.sourceType,
|
||||
ecmaVersion: parserOptions.ecmaVersion || 6,
|
||||
childVisitorKeys,
|
||||
fallback,
|
||||
};
|
||||
|
||||
if (OriginalReferencer._babelEslintPatched) {
|
||||
require("./patch-eslint-scope")(parserOptions);
|
||||
return escope.analyze(ast, options);
|
||||
}
|
||||
|
||||
options.childVisitorKeys = childVisitorKeys;
|
||||
|
||||
const scopeManager = new escope.ScopeManager(options);
|
||||
const referencer = new Referencer(options, scopeManager);
|
||||
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
"use strict";
|
||||
|
||||
let patched = false;
|
||||
|
||||
exports.parse = function(code, options) {
|
||||
patched = true;
|
||||
return require("./parse-with-patch")(code, options);
|
||||
return exports.parseForESLint(code, options).ast;
|
||||
};
|
||||
|
||||
exports.parseForESLint = function(code, options) {
|
||||
if (!patched && options.eslintVisitorKeys && options.eslintScopeManager) {
|
||||
options = options || {};
|
||||
options.ecmaVersion = options.ecmaVersion || 6;
|
||||
options.sourceType = options.sourceType || "module";
|
||||
options.allowImportExportEverywhere =
|
||||
options.allowImportExportEverywhere || false;
|
||||
|
||||
if (options.eslintVisitorKeys && options.eslintScopeManager) {
|
||||
return require("./parse-with-scope")(code, options);
|
||||
}
|
||||
|
||||
patched = true;
|
||||
return { ast: require("./parse-with-patch")(code, options) };
|
||||
};
|
||||
|
||||
|
||||
@ -1,381 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var parse = require("./parse");
|
||||
var Module = require("module");
|
||||
var path = require("path");
|
||||
var t = require("@babel/types");
|
||||
var hasPatched = false;
|
||||
var eslintOptions = {};
|
||||
|
||||
function getModules() {
|
||||
try {
|
||||
// avoid importing a local copy of eslint, try to find a peer dependency
|
||||
var eslintLoc = Module._resolveFilename("eslint", module.parent);
|
||||
} catch (err) {
|
||||
try {
|
||||
// avoids breaking in jest where module.parent is undefined
|
||||
eslintLoc = require.resolve("eslint");
|
||||
} catch (err) {
|
||||
throw new ReferenceError("couldn't resolve eslint");
|
||||
}
|
||||
}
|
||||
|
||||
// get modules relative to what eslint will load
|
||||
var eslintMod = new Module(eslintLoc);
|
||||
eslintMod.filename = eslintLoc;
|
||||
eslintMod.paths = Module._nodeModulePaths(path.dirname(eslintLoc));
|
||||
|
||||
try {
|
||||
var escope = eslintMod.require("eslint-scope");
|
||||
var Definition = eslintMod.require("eslint-scope/lib/definition")
|
||||
.Definition;
|
||||
var referencer = eslintMod.require("eslint-scope/lib/referencer");
|
||||
} catch (err) {
|
||||
escope = eslintMod.require("escope");
|
||||
Definition = eslintMod.require("escope/lib/definition").Definition;
|
||||
referencer = eslintMod.require("escope/lib/referencer");
|
||||
}
|
||||
|
||||
var estraverse = eslintMod.require("estraverse");
|
||||
|
||||
if (referencer.__esModule) referencer = referencer.default;
|
||||
|
||||
return {
|
||||
Definition,
|
||||
escope,
|
||||
estraverse,
|
||||
referencer,
|
||||
};
|
||||
}
|
||||
|
||||
function monkeypatch(modules) {
|
||||
var Definition = modules.Definition;
|
||||
var escope = modules.escope;
|
||||
var estraverse = modules.estraverse;
|
||||
var referencer = modules.referencer;
|
||||
|
||||
Object.assign(estraverse.VisitorKeys, t.VISITOR_KEYS);
|
||||
estraverse.VisitorKeys.MethodDefinition.push("decorators");
|
||||
estraverse.VisitorKeys.Property.push("decorators");
|
||||
|
||||
var analyze = escope.analyze;
|
||||
escope.analyze = function(ast, opts) {
|
||||
opts = opts || {};
|
||||
opts.ecmaVersion = eslintOptions.ecmaVersion;
|
||||
opts.sourceType = eslintOptions.sourceType;
|
||||
if (eslintOptions.globalReturn !== undefined) {
|
||||
opts.nodejsScope = eslintOptions.globalReturn;
|
||||
}
|
||||
|
||||
var results = analyze.call(this, ast, opts);
|
||||
return results;
|
||||
};
|
||||
|
||||
// if there are decorators, then visit each
|
||||
function visitDecorators(node) {
|
||||
if (!node.decorators) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < node.decorators.length; i++) {
|
||||
if (node.decorators[i].expression) {
|
||||
this.visit(node.decorators[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate through part of t.VISITOR_KEYS
|
||||
var flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
||||
"ArrayPattern",
|
||||
"ClassDeclaration",
|
||||
"ClassExpression",
|
||||
"FunctionDeclaration",
|
||||
"FunctionExpression",
|
||||
"Identifier",
|
||||
"ObjectPattern",
|
||||
"RestElement",
|
||||
]);
|
||||
var visitorKeysMap = Object.keys(t.VISITOR_KEYS).reduce(function(acc, key) {
|
||||
var value = t.VISITOR_KEYS[key];
|
||||
if (flowFlippedAliasKeys.indexOf(value) === -1) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
var propertyTypes = {
|
||||
// loops
|
||||
callProperties: { type: "loop", values: ["value"] },
|
||||
indexers: { type: "loop", values: ["key", "value"] },
|
||||
properties: { type: "loop", values: ["argument", "value"] },
|
||||
types: { type: "loop" },
|
||||
params: { type: "loop" },
|
||||
// single property
|
||||
argument: { type: "single" },
|
||||
elementType: { type: "single" },
|
||||
qualification: { type: "single" },
|
||||
rest: { type: "single" },
|
||||
returnType: { type: "single" },
|
||||
// others
|
||||
typeAnnotation: { type: "typeAnnotation" },
|
||||
typeParameters: { type: "typeParameters" },
|
||||
id: { type: "id" },
|
||||
};
|
||||
|
||||
function visitTypeAnnotation(node) {
|
||||
// get property to check (params, id, etc...)
|
||||
var visitorValues = visitorKeysMap[node.type];
|
||||
if (!visitorValues) {
|
||||
return;
|
||||
}
|
||||
|
||||
// can have multiple properties
|
||||
for (var i = 0; i < visitorValues.length; i++) {
|
||||
var visitorValue = visitorValues[i];
|
||||
var propertyType = propertyTypes[visitorValue];
|
||||
var nodeProperty = node[visitorValue];
|
||||
// check if property or type is defined
|
||||
if (propertyType == null || nodeProperty == null) {
|
||||
continue;
|
||||
}
|
||||
if (propertyType.type === "loop") {
|
||||
for (var j = 0; j < nodeProperty.length; j++) {
|
||||
if (Array.isArray(propertyType.values)) {
|
||||
for (var k = 0; k < propertyType.values.length; k++) {
|
||||
var loopPropertyNode = nodeProperty[j][propertyType.values[k]];
|
||||
if (loopPropertyNode) {
|
||||
checkIdentifierOrVisit.call(this, loopPropertyNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
checkIdentifierOrVisit.call(this, nodeProperty[j]);
|
||||
}
|
||||
}
|
||||
} else if (propertyType.type === "single") {
|
||||
checkIdentifierOrVisit.call(this, nodeProperty);
|
||||
} else if (propertyType.type === "typeAnnotation") {
|
||||
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||
} else if (propertyType.type === "typeParameters") {
|
||||
for (var l = 0; l < node.typeParameters.params.length; l++) {
|
||||
checkIdentifierOrVisit.call(this, node.typeParameters.params[l]);
|
||||
}
|
||||
} else if (propertyType.type === "id") {
|
||||
if (node.id.type === "Identifier") {
|
||||
checkIdentifierOrVisit.call(this, node.id);
|
||||
} else {
|
||||
visitTypeAnnotation.call(this, node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkIdentifierOrVisit(node) {
|
||||
if (node.typeAnnotation) {
|
||||
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||
} else if (node.type === "Identifier") {
|
||||
this.visit(node);
|
||||
} else {
|
||||
visitTypeAnnotation.call(this, node);
|
||||
}
|
||||
}
|
||||
|
||||
function nestTypeParamScope(manager, node) {
|
||||
var parentScope = manager.__currentScope;
|
||||
var scope = new escope.Scope(
|
||||
manager,
|
||||
"type-parameters",
|
||||
parentScope,
|
||||
node,
|
||||
false
|
||||
);
|
||||
manager.__nestScope(scope);
|
||||
for (var j = 0; j < node.typeParameters.params.length; j++) {
|
||||
var name = node.typeParameters.params[j];
|
||||
scope.__define(name, new Definition("TypeParameter", name, name));
|
||||
if (name.typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, name);
|
||||
}
|
||||
}
|
||||
scope.__define = function() {
|
||||
return parentScope.__define.apply(parentScope, arguments);
|
||||
};
|
||||
return scope;
|
||||
}
|
||||
|
||||
// visit decorators that are in: ClassDeclaration / ClassExpression
|
||||
var visitClass = referencer.prototype.visitClass;
|
||||
referencer.prototype.visitClass = function(node) {
|
||||
visitDecorators.call(this, node);
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
// visit flow type: ClassImplements
|
||||
if (node.implements) {
|
||||
for (var i = 0; i < node.implements.length; i++) {
|
||||
checkIdentifierOrVisit.call(this, node.implements[i]);
|
||||
}
|
||||
}
|
||||
if (node.superTypeParameters) {
|
||||
for (var k = 0; k < node.superTypeParameters.params.length; k++) {
|
||||
checkIdentifierOrVisit.call(this, node.superTypeParameters.params[k]);
|
||||
}
|
||||
}
|
||||
visitClass.call(this, node);
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
// visit decorators that are in: Property / MethodDefinition
|
||||
var visitProperty = referencer.prototype.visitProperty;
|
||||
referencer.prototype.visitProperty = function(node) {
|
||||
if (node.value && node.value.type === "TypeCastExpression") {
|
||||
visitTypeAnnotation.call(this, node.value);
|
||||
}
|
||||
visitDecorators.call(this, node);
|
||||
visitProperty.call(this, node);
|
||||
};
|
||||
|
||||
function visitClassProperty(node) {
|
||||
if (node.typeAnnotation) {
|
||||
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||
}
|
||||
this.visitProperty(node);
|
||||
}
|
||||
|
||||
// visit ClassProperty as a Property.
|
||||
referencer.prototype.ClassProperty = visitClassProperty;
|
||||
|
||||
// visit ClassPrivateProperty as a Property.
|
||||
referencer.prototype.ClassPrivateProperty = visitClassProperty;
|
||||
|
||||
// visit flow type in FunctionDeclaration, FunctionExpression, ArrowFunctionExpression
|
||||
var visitFunction = referencer.prototype.visitFunction;
|
||||
referencer.prototype.visitFunction = function(node) {
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
if (node.returnType) {
|
||||
checkIdentifierOrVisit.call(this, node.returnType);
|
||||
}
|
||||
// only visit if function parameters have types
|
||||
if (node.params) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
var param = node.params[i];
|
||||
if (param.typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, param);
|
||||
} else if (t.isAssignmentPattern(param)) {
|
||||
if (param.left.typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, param.left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// set ArrayPattern/ObjectPattern visitor keys back to their original. otherwise
|
||||
// escope will traverse into them and include the identifiers within as declarations
|
||||
estraverse.VisitorKeys.ObjectPattern = ["properties"];
|
||||
estraverse.VisitorKeys.ArrayPattern = ["elements"];
|
||||
visitFunction.call(this, node);
|
||||
// set them back to normal...
|
||||
estraverse.VisitorKeys.ObjectPattern = t.VISITOR_KEYS.ObjectPattern;
|
||||
estraverse.VisitorKeys.ArrayPattern = t.VISITOR_KEYS.ArrayPattern;
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
// visit flow type in VariableDeclaration
|
||||
var variableDeclaration = referencer.prototype.VariableDeclaration;
|
||||
referencer.prototype.VariableDeclaration = function(node) {
|
||||
if (node.declarations) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var id = node.declarations[i].id;
|
||||
var typeAnnotation = id.typeAnnotation;
|
||||
if (typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, typeAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
variableDeclaration.call(this, node);
|
||||
};
|
||||
|
||||
function createScopeVariable(node, name) {
|
||||
this.currentScope().variableScope.__define(
|
||||
name,
|
||||
new Definition("Variable", name, node, null, null, null)
|
||||
);
|
||||
}
|
||||
|
||||
referencer.prototype.InterfaceDeclaration = function(node) {
|
||||
createScopeVariable.call(this, node, node.id);
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
// TODO: Handle mixins
|
||||
for (var i = 0; i < node.extends.length; i++) {
|
||||
visitTypeAnnotation.call(this, node.extends[i]);
|
||||
}
|
||||
visitTypeAnnotation.call(this, node.body);
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
referencer.prototype.TypeAlias = function(node) {
|
||||
createScopeVariable.call(this, node, node.id);
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
if (node.right) {
|
||||
visitTypeAnnotation.call(this, node.right);
|
||||
}
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
referencer.prototype.DeclareModule = referencer.prototype.DeclareFunction = referencer.prototype.DeclareVariable = referencer.prototype.DeclareClass = function(
|
||||
node
|
||||
) {
|
||||
if (node.id) {
|
||||
createScopeVariable.call(this, node, node.id);
|
||||
}
|
||||
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
}
|
||||
var patchEscope = require("./patch-eslint-scope");
|
||||
|
||||
module.exports = function(code, options) {
|
||||
options = options || {};
|
||||
eslintOptions.ecmaVersion = options.ecmaVersion = options.ecmaVersion || 6;
|
||||
eslintOptions.sourceType = options.sourceType =
|
||||
options.sourceType || "module";
|
||||
eslintOptions.allowImportExportEverywhere = options.allowImportExportEverywhere =
|
||||
options.allowImportExportEverywhere || false;
|
||||
if (options.sourceType === "module") {
|
||||
eslintOptions.globalReturn = false;
|
||||
} else {
|
||||
delete eslintOptions.globalReturn;
|
||||
}
|
||||
|
||||
if (!hasPatched) {
|
||||
hasPatched = true;
|
||||
try {
|
||||
monkeypatch(getModules());
|
||||
} catch (err) {
|
||||
console.error(err.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
patchEscope(options);
|
||||
return parse(code, options);
|
||||
};
|
||||
|
||||
@ -5,12 +5,6 @@ const analyzeScope = require("./analyze-scope");
|
||||
const parse = require("./parse");
|
||||
|
||||
module.exports = function(code, options) {
|
||||
options = options || {};
|
||||
options.ecmaVersion = options.ecmaVersion || 6;
|
||||
options.sourceType = options.sourceType || "module";
|
||||
options.allowImportExportEverywhere =
|
||||
options.allowImportExportEverywhere || false;
|
||||
|
||||
const ast = parse(code, options);
|
||||
const scopeManager = analyzeScope(ast, options);
|
||||
const visitorKeys = t.VISITOR_KEYS;
|
||||
|
||||
370
eslint/babel-eslint-parser/lib/patch-eslint-scope.js
Normal file
370
eslint/babel-eslint-parser/lib/patch-eslint-scope.js
Normal file
@ -0,0 +1,370 @@
|
||||
"use strict";
|
||||
|
||||
var Module = require("module");
|
||||
var path = require("path");
|
||||
var t = require("@babel/types");
|
||||
|
||||
function getModules() {
|
||||
try {
|
||||
// avoid importing a local copy of eslint, try to find a peer dependency
|
||||
var eslintLoc = Module._resolveFilename("eslint", module.parent);
|
||||
} catch (err) {
|
||||
try {
|
||||
// avoids breaking in jest where module.parent is undefined
|
||||
eslintLoc = require.resolve("eslint");
|
||||
} catch (err) {
|
||||
throw new ReferenceError("couldn't resolve eslint");
|
||||
}
|
||||
}
|
||||
|
||||
// get modules relative to what eslint will load
|
||||
var eslintMod = new Module(eslintLoc);
|
||||
eslintMod.filename = eslintLoc;
|
||||
eslintMod.paths = Module._nodeModulePaths(path.dirname(eslintLoc));
|
||||
|
||||
try {
|
||||
var escope = eslintMod.require("eslint-scope");
|
||||
var Definition = eslintMod.require("eslint-scope/lib/definition")
|
||||
.Definition;
|
||||
var referencer = eslintMod.require("eslint-scope/lib/referencer");
|
||||
} catch (err) {
|
||||
escope = eslintMod.require("escope");
|
||||
Definition = eslintMod.require("escope/lib/definition").Definition;
|
||||
referencer = eslintMod.require("escope/lib/referencer");
|
||||
}
|
||||
|
||||
var estraverse = eslintMod.require("estraverse");
|
||||
|
||||
if (referencer.__esModule) referencer = referencer.default;
|
||||
|
||||
return {
|
||||
Definition,
|
||||
escope,
|
||||
estraverse,
|
||||
referencer,
|
||||
};
|
||||
}
|
||||
|
||||
function monkeypatch(modules) {
|
||||
var Definition = modules.Definition;
|
||||
var escope = modules.escope;
|
||||
var estraverse = modules.estraverse;
|
||||
var referencer = modules.referencer;
|
||||
|
||||
Object.assign(estraverse.VisitorKeys, t.VISITOR_KEYS);
|
||||
estraverse.VisitorKeys.MethodDefinition.push("decorators");
|
||||
estraverse.VisitorKeys.Property.push("decorators");
|
||||
|
||||
// if there are decorators, then visit each
|
||||
function visitDecorators(node) {
|
||||
if (!node.decorators) {
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < node.decorators.length; i++) {
|
||||
if (node.decorators[i].expression) {
|
||||
this.visit(node.decorators[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate through part of t.VISITOR_KEYS
|
||||
var flowFlippedAliasKeys = t.FLIPPED_ALIAS_KEYS.Flow.concat([
|
||||
"ArrayPattern",
|
||||
"ClassDeclaration",
|
||||
"ClassExpression",
|
||||
"FunctionDeclaration",
|
||||
"FunctionExpression",
|
||||
"Identifier",
|
||||
"ObjectPattern",
|
||||
"RestElement",
|
||||
]);
|
||||
var visitorKeysMap = Object.keys(t.VISITOR_KEYS).reduce(function(acc, key) {
|
||||
var value = t.VISITOR_KEYS[key];
|
||||
if (flowFlippedAliasKeys.indexOf(value) === -1) {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
var propertyTypes = {
|
||||
// loops
|
||||
callProperties: { type: "loop", values: ["value"] },
|
||||
indexers: { type: "loop", values: ["key", "value"] },
|
||||
properties: { type: "loop", values: ["argument", "value"] },
|
||||
types: { type: "loop" },
|
||||
params: { type: "loop" },
|
||||
// single property
|
||||
argument: { type: "single" },
|
||||
elementType: { type: "single" },
|
||||
qualification: { type: "single" },
|
||||
rest: { type: "single" },
|
||||
returnType: { type: "single" },
|
||||
// others
|
||||
typeAnnotation: { type: "typeAnnotation" },
|
||||
typeParameters: { type: "typeParameters" },
|
||||
id: { type: "id" },
|
||||
};
|
||||
|
||||
function visitTypeAnnotation(node) {
|
||||
// get property to check (params, id, etc...)
|
||||
var visitorValues = visitorKeysMap[node.type];
|
||||
if (!visitorValues) {
|
||||
return;
|
||||
}
|
||||
|
||||
// can have multiple properties
|
||||
for (var i = 0; i < visitorValues.length; i++) {
|
||||
var visitorValue = visitorValues[i];
|
||||
var propertyType = propertyTypes[visitorValue];
|
||||
var nodeProperty = node[visitorValue];
|
||||
// check if property or type is defined
|
||||
if (propertyType == null || nodeProperty == null) {
|
||||
continue;
|
||||
}
|
||||
if (propertyType.type === "loop") {
|
||||
for (var j = 0; j < nodeProperty.length; j++) {
|
||||
if (Array.isArray(propertyType.values)) {
|
||||
for (var k = 0; k < propertyType.values.length; k++) {
|
||||
var loopPropertyNode = nodeProperty[j][propertyType.values[k]];
|
||||
if (loopPropertyNode) {
|
||||
checkIdentifierOrVisit.call(this, loopPropertyNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
checkIdentifierOrVisit.call(this, nodeProperty[j]);
|
||||
}
|
||||
}
|
||||
} else if (propertyType.type === "single") {
|
||||
checkIdentifierOrVisit.call(this, nodeProperty);
|
||||
} else if (propertyType.type === "typeAnnotation") {
|
||||
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||
} else if (propertyType.type === "typeParameters") {
|
||||
for (var l = 0; l < node.typeParameters.params.length; l++) {
|
||||
checkIdentifierOrVisit.call(this, node.typeParameters.params[l]);
|
||||
}
|
||||
} else if (propertyType.type === "id") {
|
||||
if (node.id.type === "Identifier") {
|
||||
checkIdentifierOrVisit.call(this, node.id);
|
||||
} else {
|
||||
visitTypeAnnotation.call(this, node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkIdentifierOrVisit(node) {
|
||||
if (node.typeAnnotation) {
|
||||
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||
} else if (node.type === "Identifier") {
|
||||
this.visit(node);
|
||||
} else {
|
||||
visitTypeAnnotation.call(this, node);
|
||||
}
|
||||
}
|
||||
|
||||
function nestTypeParamScope(manager, node) {
|
||||
var parentScope = manager.__currentScope;
|
||||
var scope = new escope.Scope(
|
||||
manager,
|
||||
"type-parameters",
|
||||
parentScope,
|
||||
node,
|
||||
false
|
||||
);
|
||||
manager.__nestScope(scope);
|
||||
for (var j = 0; j < node.typeParameters.params.length; j++) {
|
||||
var name = node.typeParameters.params[j];
|
||||
scope.__define(name, new Definition("TypeParameter", name, name));
|
||||
if (name.typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, name);
|
||||
}
|
||||
}
|
||||
scope.__define = function() {
|
||||
return parentScope.__define.apply(parentScope, arguments);
|
||||
};
|
||||
return scope;
|
||||
}
|
||||
|
||||
// visit decorators that are in: ClassDeclaration / ClassExpression
|
||||
var visitClass = referencer.prototype.visitClass;
|
||||
referencer.prototype.visitClass = function(node) {
|
||||
visitDecorators.call(this, node);
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
// visit flow type: ClassImplements
|
||||
if (node.implements) {
|
||||
for (var i = 0; i < node.implements.length; i++) {
|
||||
checkIdentifierOrVisit.call(this, node.implements[i]);
|
||||
}
|
||||
}
|
||||
if (node.superTypeParameters) {
|
||||
for (var k = 0; k < node.superTypeParameters.params.length; k++) {
|
||||
checkIdentifierOrVisit.call(this, node.superTypeParameters.params[k]);
|
||||
}
|
||||
}
|
||||
visitClass.call(this, node);
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
// visit decorators that are in: Property / MethodDefinition
|
||||
var visitProperty = referencer.prototype.visitProperty;
|
||||
referencer.prototype.visitProperty = function(node) {
|
||||
if (node.value && node.value.type === "TypeCastExpression") {
|
||||
visitTypeAnnotation.call(this, node.value);
|
||||
}
|
||||
visitDecorators.call(this, node);
|
||||
visitProperty.call(this, node);
|
||||
};
|
||||
|
||||
function visitClassProperty(node) {
|
||||
if (node.typeAnnotation) {
|
||||
visitTypeAnnotation.call(this, node.typeAnnotation);
|
||||
}
|
||||
this.visitProperty(node);
|
||||
}
|
||||
|
||||
// visit ClassProperty as a Property.
|
||||
referencer.prototype.ClassProperty = visitClassProperty;
|
||||
|
||||
// visit ClassPrivateProperty as a Property.
|
||||
referencer.prototype.ClassPrivateProperty = visitClassProperty;
|
||||
|
||||
// visit flow type in FunctionDeclaration, FunctionExpression, ArrowFunctionExpression
|
||||
var visitFunction = referencer.prototype.visitFunction;
|
||||
referencer.prototype.visitFunction = function(node) {
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
if (node.returnType) {
|
||||
checkIdentifierOrVisit.call(this, node.returnType);
|
||||
}
|
||||
// only visit if function parameters have types
|
||||
if (node.params) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
var param = node.params[i];
|
||||
if (param.typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, param);
|
||||
} else if (t.isAssignmentPattern(param)) {
|
||||
if (param.left.typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, param.left);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// set ArrayPattern/ObjectPattern visitor keys back to their original. otherwise
|
||||
// escope will traverse into them and include the identifiers within as declarations
|
||||
estraverse.VisitorKeys.ObjectPattern = ["properties"];
|
||||
estraverse.VisitorKeys.ArrayPattern = ["elements"];
|
||||
visitFunction.call(this, node);
|
||||
// set them back to normal...
|
||||
estraverse.VisitorKeys.ObjectPattern = t.VISITOR_KEYS.ObjectPattern;
|
||||
estraverse.VisitorKeys.ArrayPattern = t.VISITOR_KEYS.ArrayPattern;
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
// visit flow type in VariableDeclaration
|
||||
var variableDeclaration = referencer.prototype.VariableDeclaration;
|
||||
referencer.prototype.VariableDeclaration = function(node) {
|
||||
if (node.declarations) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var id = node.declarations[i].id;
|
||||
var typeAnnotation = id.typeAnnotation;
|
||||
if (typeAnnotation) {
|
||||
checkIdentifierOrVisit.call(this, typeAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
variableDeclaration.call(this, node);
|
||||
};
|
||||
|
||||
function createScopeVariable(node, name) {
|
||||
this.currentScope().variableScope.__define(
|
||||
name,
|
||||
new Definition("Variable", name, node, null, null, null)
|
||||
);
|
||||
}
|
||||
|
||||
referencer.prototype.InterfaceDeclaration = function(node) {
|
||||
createScopeVariable.call(this, node, node.id);
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
// TODO: Handle mixins
|
||||
for (var i = 0; i < node.extends.length; i++) {
|
||||
visitTypeAnnotation.call(this, node.extends[i]);
|
||||
}
|
||||
visitTypeAnnotation.call(this, node.body);
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
referencer.prototype.TypeAlias = function(node) {
|
||||
createScopeVariable.call(this, node, node.id);
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
if (node.right) {
|
||||
visitTypeAnnotation.call(this, node.right);
|
||||
}
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
referencer.prototype.DeclareModule = referencer.prototype.DeclareFunction = referencer.prototype.DeclareVariable = referencer.prototype.DeclareClass = function(
|
||||
node
|
||||
) {
|
||||
if (node.id) {
|
||||
createScopeVariable.call(this, node, node.id);
|
||||
}
|
||||
|
||||
var typeParamScope;
|
||||
if (node.typeParameters) {
|
||||
typeParamScope = nestTypeParamScope.call(this, this.scopeManager, node);
|
||||
}
|
||||
if (typeParamScope) {
|
||||
this.close(node);
|
||||
}
|
||||
};
|
||||
|
||||
referencer._babelEslintPatched = true;
|
||||
}
|
||||
|
||||
// To patch for each call.
|
||||
var escope = null;
|
||||
var escopeAnalyze = null;
|
||||
|
||||
module.exports = function(parserOptions) {
|
||||
// Patch `Referencer.prototype` once.
|
||||
if (!escope) {
|
||||
const modules = getModules();
|
||||
monkeypatch(modules);
|
||||
|
||||
// Store to patch for each call.
|
||||
escope = modules.escope;
|
||||
escopeAnalyze = modules.escope.analyze;
|
||||
}
|
||||
|
||||
// Patch `escope.analyze` based on the current parserOptions.
|
||||
escope.analyze = function(ast, opts) {
|
||||
opts = opts || {};
|
||||
opts.ecmaVersion = parserOptions.ecmaVersion;
|
||||
opts.sourceType = parserOptions.sourceType;
|
||||
opts.nodejsScope =
|
||||
ast.sourceType === "script" &&
|
||||
(parserOptions.ecmaFeatures &&
|
||||
parserOptions.ecmaFeatures.globalReturn) === true;
|
||||
|
||||
return escopeAnalyze.call(this, ast, opts);
|
||||
};
|
||||
};
|
||||
@ -20,7 +20,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"test": "npm run lint && npm run test-only",
|
||||
"test-only": "mocha",
|
||||
"test-only": "mocha && mocha --require test/fixtures/preprocess-to-patch.js && mocha --require test/fixtures/use-eslint-old.js",
|
||||
"lint": "eslint index.js babylon-to-espree test",
|
||||
"fix": "eslint index.js babylon-to-espree test --fix",
|
||||
"precommit": "lint-staged",
|
||||
@ -39,9 +39,11 @@
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^8.0.0",
|
||||
"dedent": "^0.7.0",
|
||||
"eslint": "^4.12.1",
|
||||
"eslint": "^4.14.0",
|
||||
"eslint-config-babel": "^7.0.1",
|
||||
"eslint-old": "npm:eslint@4.13.1",
|
||||
"eslint-plugin-flowtype": "^2.30.3",
|
||||
"eslint-plugin-import": "^2.8.0",
|
||||
"eslint-plugin-prettier": "^2.1.2",
|
||||
"espree": "^3.4.0",
|
||||
"husky": "^0.14.0",
|
||||
|
||||
@ -4,48 +4,7 @@ var espree = require("espree");
|
||||
var escope = require("eslint-scope");
|
||||
var util = require("util");
|
||||
var unpad = require("dedent");
|
||||
|
||||
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
|
||||
function assertImplementsAST(target, source, path) {
|
||||
if (!path) {
|
||||
path = [];
|
||||
}
|
||||
|
||||
function error(text) {
|
||||
var err = new Error(`At ${path.join(".")}: ${text}:`);
|
||||
err.depth = path.length + 1;
|
||||
throw err;
|
||||
}
|
||||
|
||||
var typeA = target === null ? "null" : typeof target;
|
||||
var typeB = source === null ? "null" : typeof source;
|
||||
if (typeA !== typeB) {
|
||||
error(
|
||||
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`
|
||||
);
|
||||
} else if (
|
||||
typeA === "object" &&
|
||||
["RegExp"].indexOf(target.constructor.name) !== -1 &&
|
||||
target.constructor.name !== source.constructor.name
|
||||
) {
|
||||
error(
|
||||
`object have different constructors (${target.constructor
|
||||
.name} !== ${source.constructor.name}`
|
||||
);
|
||||
} else if (typeA === "object") {
|
||||
var keysTarget = Object.keys(target);
|
||||
for (var i in keysTarget) {
|
||||
var key = keysTarget[i];
|
||||
path.push(key);
|
||||
assertImplementsAST(target[key], source[key], path);
|
||||
path.pop();
|
||||
}
|
||||
} else if (target !== source) {
|
||||
error(
|
||||
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`
|
||||
);
|
||||
}
|
||||
}
|
||||
var assertImplementsAST = require("./fixtures/assert-implements-ast");
|
||||
|
||||
function lookup(obj, keypath, backwardsDepth) {
|
||||
if (!keypath) {
|
||||
|
||||
41
eslint/babel-eslint-parser/test/fixtures/assert-implements-ast.js
vendored
Normal file
41
eslint/babel-eslint-parser/test/fixtures/assert-implements-ast.js
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
// Checks if the source ast implements the target ast. Ignores extra keys on source ast
|
||||
module.exports = function assertImplementsAST(target, source, path) {
|
||||
if (!path) {
|
||||
path = [];
|
||||
}
|
||||
|
||||
function error(text) {
|
||||
var err = new Error(`At ${path.join(".")}: ${text}:`);
|
||||
err.depth = path.length + 1;
|
||||
throw err;
|
||||
}
|
||||
|
||||
var typeA = target === null ? "null" : typeof target;
|
||||
var typeB = source === null ? "null" : typeof source;
|
||||
if (typeA !== typeB) {
|
||||
error(
|
||||
`have different types (${typeA} !== ${typeB}) (${target} !== ${source})`
|
||||
);
|
||||
} else if (
|
||||
typeA === "object" &&
|
||||
["RegExp"].indexOf(target.constructor.name) !== -1 &&
|
||||
target.constructor.name !== source.constructor.name
|
||||
) {
|
||||
error(
|
||||
`object have different constructors (${target.constructor
|
||||
.name} !== ${source.constructor.name}`
|
||||
);
|
||||
} else if (typeA === "object") {
|
||||
var keysTarget = Object.keys(target);
|
||||
for (var i in keysTarget) {
|
||||
var key = keysTarget[i];
|
||||
path.push(key);
|
||||
assertImplementsAST(target[key], source[key], path);
|
||||
path.pop();
|
||||
}
|
||||
} else if (target !== source) {
|
||||
error(
|
||||
`are different (${JSON.stringify(target)} !== ${JSON.stringify(source)})`
|
||||
);
|
||||
}
|
||||
};
|
||||
11
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/.eslintrc.yml
vendored
Normal file
11
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/.eslintrc.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
root: true
|
||||
|
||||
# babel-eslint
|
||||
parser: ../../../lib/index.js
|
||||
|
||||
# use eslint-plugin-import
|
||||
plugins:
|
||||
- import
|
||||
rules:
|
||||
import/no-named-as-default: error
|
||||
no-unused-vars: error
|
||||
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/a.js
vendored
Normal file
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/a.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
export default function foo() { }
|
||||
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/b.js
vendored
Normal file
1
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/b.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
import foo from './a.js';
|
||||
4
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/c.js
vendored
Normal file
4
eslint/babel-eslint-parser/test/fixtures/eslint-plugin-import/c.js
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
// @flow
|
||||
type Foo = {};
|
||||
|
||||
const FlowTypeButton = ({ }: Foo) => { };
|
||||
5
eslint/babel-eslint-parser/test/fixtures/preprocess-to-patch.js
vendored
Normal file
5
eslint/babel-eslint-parser/test/fixtures/preprocess-to-patch.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
"use strict"
|
||||
const babelEslint = require("../..")
|
||||
|
||||
// Apply monkeypatch to eslint-scope.
|
||||
babelEslint.parse("var x = 0;")
|
||||
12
eslint/babel-eslint-parser/test/fixtures/use-eslint-old.js
vendored
Normal file
12
eslint/babel-eslint-parser/test/fixtures/use-eslint-old.js
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
"use strict"
|
||||
|
||||
var Module = require('module');
|
||||
var originalRequire = Module.prototype.require;
|
||||
|
||||
// Override to eslint-old
|
||||
Module.prototype.require = function () {
|
||||
if (arguments[0] === "eslint") {
|
||||
arguments[0] = "eslint-old";
|
||||
}
|
||||
return originalRequire.apply(this, arguments);
|
||||
};
|
||||
@ -3,12 +3,13 @@
|
||||
var eslint = require("eslint");
|
||||
var unpad = require("dedent");
|
||||
|
||||
function verifyAndAssertMessages(
|
||||
function verifyAndAssertMessagesWithSpecificESLint(
|
||||
code,
|
||||
rules,
|
||||
expectedMessages,
|
||||
sourceType,
|
||||
overrideConfig
|
||||
overrideConfig,
|
||||
linter
|
||||
) {
|
||||
var config = {
|
||||
parser: require.resolve(".."),
|
||||
@ -34,7 +35,7 @@ function verifyAndAssertMessages(
|
||||
}
|
||||
}
|
||||
|
||||
var messages = eslint.linter.verify(code, config);
|
||||
var messages = linter.verify(code, config);
|
||||
|
||||
if (messages.length !== expectedMessages.length) {
|
||||
throw new Error(
|
||||
@ -62,6 +63,23 @@ function verifyAndAssertMessages(
|
||||
});
|
||||
}
|
||||
|
||||
function verifyAndAssertMessages(
|
||||
code,
|
||||
rules,
|
||||
expectedMessages,
|
||||
sourceType,
|
||||
overrideConfig
|
||||
) {
|
||||
verifyAndAssertMessagesWithSpecificESLint(
|
||||
code,
|
||||
rules,
|
||||
expectedMessages,
|
||||
sourceType,
|
||||
overrideConfig,
|
||||
new eslint.Linter()
|
||||
);
|
||||
}
|
||||
|
||||
describe("verify", () => {
|
||||
it("arrow function support (issue #1)", () => {
|
||||
verifyAndAssertMessages("describe('stuff', () => {});", {}, []);
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
"use strict";
|
||||
|
||||
const eslint = require("eslint");
|
||||
const assert = require("assert");
|
||||
const babelEslint = require("..");
|
||||
const espree = require("espree");
|
||||
var assertImplementsAST = require("./fixtures/assert-implements-ast");
|
||||
|
||||
describe("https://github.com/babel/babel-eslint/issues/558", () => {
|
||||
it("don't crash with eslint-plugin-import", () => {
|
||||
const engine = new eslint.CLIEngine({ ignore: false });
|
||||
engine.executeOnFiles([
|
||||
"test/fixtures/eslint-plugin-import/a.js",
|
||||
"test/fixtures/eslint-plugin-import/b.js",
|
||||
"test/fixtures/eslint-plugin-import/c.js",
|
||||
]);
|
||||
});
|
||||
|
||||
/*
|
||||
* This test ensures that the enhanced referencer does not get used if eslint-scope has already been
|
||||
* monkeypatched, because this causes some correctness issues. For example, if the enhanced referencer
|
||||
* is used after the original referencer is monkeypatched, type annotation references are counted twice.
|
||||
*/
|
||||
it("does not visit type annotations multiple times after monkeypatching and calling parseForESLint()", () => {
|
||||
assertImplementsAST(
|
||||
espree.parse("foo", { sourceType: "module" }),
|
||||
babelEslint.parse("foo", {})
|
||||
);
|
||||
const parseResult = babelEslint.parseForESLint(
|
||||
"type Foo = {}; function x(): Foo {}",
|
||||
{
|
||||
eslintVisitorKeys: true,
|
||||
eslintScopeManager: true,
|
||||
}
|
||||
);
|
||||
assert(parseResult.visitorKeys);
|
||||
assert(parseResult.scopeManager);
|
||||
|
||||
const fooVariable = parseResult.scopeManager.getDeclaredVariables(
|
||||
parseResult.ast.body[0]
|
||||
)[0];
|
||||
|
||||
assert.strictEqual(fooVariable.references.length, 1);
|
||||
});
|
||||
});
|
||||
@ -241,6 +241,10 @@ browser-stdout@1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
|
||||
|
||||
builtin-modules@^1.0.0, builtin-modules@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
|
||||
|
||||
caller-path@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
|
||||
@ -352,6 +356,10 @@ concat-stream@^1.6.0:
|
||||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
contains-path@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
@ -381,12 +389,18 @@ date-fns@^1.27.2:
|
||||
version "1.28.5"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.28.5.tgz#257cfc45d322df45ef5658665967ee841cd73faf"
|
||||
|
||||
debug@3.1.0:
|
||||
debug@3.1.0, debug@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^2.6.8:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.1.tgz#0564c612b521dc92d9f2988f0549e34f9c98db64"
|
||||
@ -417,6 +431,13 @@ diff@3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75"
|
||||
|
||||
doctrine@1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
isarray "^1.0.0"
|
||||
|
||||
doctrine@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075"
|
||||
@ -441,12 +462,83 @@ eslint-config-babel@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-babel/-/eslint-config-babel-7.0.1.tgz#aac7b79f2f06f52358a5a764fdc01fde23718572"
|
||||
|
||||
eslint-import-resolver-node@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc"
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
resolve "^1.2.0"
|
||||
|
||||
eslint-module-utils@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449"
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
pkg-dir "^1.0.0"
|
||||
|
||||
"eslint-old@npm:eslint@4.13.1":
|
||||
version "4.13.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.13.1.tgz#0055e0014464c7eb7878caf549ef2941992b444f"
|
||||
dependencies:
|
||||
ajv "^5.3.0"
|
||||
babel-code-frame "^6.22.0"
|
||||
chalk "^2.1.0"
|
||||
concat-stream "^1.6.0"
|
||||
cross-spawn "^5.1.0"
|
||||
debug "^3.0.1"
|
||||
doctrine "^2.0.2"
|
||||
eslint-scope "^3.7.1"
|
||||
espree "^3.5.2"
|
||||
esquery "^1.0.0"
|
||||
estraverse "^4.2.0"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^2.0.0"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
glob "^7.1.2"
|
||||
globals "^11.0.1"
|
||||
ignore "^3.3.3"
|
||||
imurmurhash "^0.1.4"
|
||||
inquirer "^3.0.6"
|
||||
is-resolvable "^1.0.0"
|
||||
js-yaml "^3.9.1"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.3.0"
|
||||
lodash "^4.17.4"
|
||||
minimatch "^3.0.2"
|
||||
mkdirp "^0.5.1"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.8.2"
|
||||
path-is-inside "^1.0.2"
|
||||
pluralize "^7.0.0"
|
||||
progress "^2.0.0"
|
||||
require-uncached "^1.0.3"
|
||||
semver "^5.3.0"
|
||||
strip-ansi "^4.0.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
table "^4.0.1"
|
||||
text-table "~0.2.0"
|
||||
|
||||
eslint-plugin-flowtype@^2.30.3:
|
||||
version "2.34.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.34.0.tgz#b9875f314652e5081623c9d2b18a346bbb759c09"
|
||||
dependencies:
|
||||
lodash "^4.15.0"
|
||||
|
||||
eslint-plugin-import@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894"
|
||||
dependencies:
|
||||
builtin-modules "^1.1.1"
|
||||
contains-path "^0.1.0"
|
||||
debug "^2.6.8"
|
||||
doctrine "1.5.0"
|
||||
eslint-import-resolver-node "^0.3.1"
|
||||
eslint-module-utils "^2.1.1"
|
||||
has "^1.0.1"
|
||||
lodash.cond "^4.3.0"
|
||||
minimatch "^3.0.3"
|
||||
read-pkg-up "^2.0.0"
|
||||
|
||||
eslint-plugin-prettier@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.1.2.tgz#4b90f4ee7f92bfbe2e926017e1ca40eb628965ea"
|
||||
@ -465,21 +557,21 @@ eslint-visitor-keys@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
|
||||
|
||||
eslint@^4.12.1:
|
||||
version "4.12.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.12.1.tgz#5ec1973822b4a066b353770c3c6d69a2a188e880"
|
||||
eslint@^4.14.0:
|
||||
version "4.14.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.14.0.tgz#96609768d1dd23304faba2d94b7fefe5a5447a82"
|
||||
dependencies:
|
||||
ajv "^5.3.0"
|
||||
babel-code-frame "^6.22.0"
|
||||
chalk "^2.1.0"
|
||||
concat-stream "^1.6.0"
|
||||
cross-spawn "^5.1.0"
|
||||
debug "^3.0.1"
|
||||
debug "^3.1.0"
|
||||
doctrine "^2.0.2"
|
||||
eslint-scope "^3.7.1"
|
||||
eslint-visitor-keys "^1.0.0"
|
||||
espree "^3.5.2"
|
||||
esquery "^1.0.0"
|
||||
estraverse "^4.2.0"
|
||||
esutils "^2.0.2"
|
||||
file-entry-cache "^2.0.0"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
@ -610,6 +702,19 @@ file-entry-cache@^2.0.0:
|
||||
flat-cache "^1.2.1"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
find-up@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
|
||||
dependencies:
|
||||
path-exists "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
find-up@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
|
||||
dependencies:
|
||||
locate-path "^2.0.0"
|
||||
|
||||
flat-cache@^1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96"
|
||||
@ -623,6 +728,10 @@ fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
||||
function-bind@^1.0.2:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
|
||||
functional-red-black-tree@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
@ -683,10 +792,20 @@ has-flag@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
|
||||
|
||||
has@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
|
||||
dependencies:
|
||||
function-bind "^1.0.2"
|
||||
|
||||
he@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
|
||||
|
||||
husky@^0.14.0:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.1.tgz#8edba33e728ceed75343e88bb8002e4cbd8d1b40"
|
||||
@ -757,6 +876,12 @@ is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
|
||||
is-builtin-module@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe"
|
||||
dependencies:
|
||||
builtin-modules "^1.0.0"
|
||||
|
||||
is-ci@^1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e"
|
||||
@ -809,7 +934,7 @@ is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
|
||||
isarray@~1.0.0:
|
||||
isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
||||
@ -929,10 +1054,30 @@ listr@^0.12.0:
|
||||
stream-to-observable "^0.1.0"
|
||||
strip-ansi "^3.0.1"
|
||||
|
||||
load-json-file@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
parse-json "^2.2.0"
|
||||
pify "^2.0.0"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
locate-path@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
|
||||
dependencies:
|
||||
p-locate "^2.0.0"
|
||||
path-exists "^3.0.0"
|
||||
|
||||
lodash.chunk@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc"
|
||||
|
||||
lodash.cond@^4.3.0:
|
||||
version "4.5.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5"
|
||||
|
||||
lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0:
|
||||
version "4.17.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||
@ -967,7 +1112,7 @@ mimic-fn@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
|
||||
|
||||
minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4:
|
||||
minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
dependencies:
|
||||
@ -1014,6 +1159,15 @@ natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
|
||||
normalize-package-data@^2.3.2:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f"
|
||||
dependencies:
|
||||
hosted-git-info "^2.1.4"
|
||||
is-builtin-module "^1.0.0"
|
||||
semver "2 || 3 || 4 || 5"
|
||||
validate-npm-package-license "^3.0.1"
|
||||
|
||||
normalize-path@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379"
|
||||
@ -1094,6 +1248,16 @@ p-finally@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
|
||||
|
||||
p-limit@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
|
||||
|
||||
p-locate@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
|
||||
dependencies:
|
||||
p-limit "^1.1.0"
|
||||
|
||||
p-map@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a"
|
||||
@ -1104,6 +1268,16 @@ parse-json@^2.2.0:
|
||||
dependencies:
|
||||
error-ex "^1.2.0"
|
||||
|
||||
path-exists@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
|
||||
dependencies:
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
path-exists@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
@ -1116,6 +1290,16 @@ path-key@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
|
||||
path-parse@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
|
||||
|
||||
path-type@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
|
||||
dependencies:
|
||||
pify "^2.0.0"
|
||||
|
||||
pify@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
@ -1130,6 +1314,12 @@ pinkie@^2.0.0:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||
|
||||
pkg-dir@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
|
||||
dependencies:
|
||||
find-up "^1.0.0"
|
||||
|
||||
pluralize@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
||||
@ -1154,6 +1344,21 @@ pseudomap@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
|
||||
|
||||
read-pkg-up@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
|
||||
dependencies:
|
||||
find-up "^2.0.0"
|
||||
read-pkg "^2.0.0"
|
||||
|
||||
read-pkg@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
|
||||
dependencies:
|
||||
load-json-file "^2.0.0"
|
||||
normalize-package-data "^2.3.2"
|
||||
path-type "^2.0.0"
|
||||
|
||||
readable-stream@^2.2.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.2.tgz#5a04df05e4f57fe3f0dc68fdd11dc5c97c7e6f4d"
|
||||
@ -1187,6 +1392,12 @@ resolve-from@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
|
||||
|
||||
resolve@^1.2.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
restore-cursor@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
|
||||
@ -1233,7 +1444,7 @@ safe-buffer@~5.1.0:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||
|
||||
semver@^5.3.0:
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.3.0:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
|
||||
|
||||
@ -1255,6 +1466,20 @@ slice-ansi@0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
|
||||
|
||||
spdx-correct@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
|
||||
dependencies:
|
||||
spdx-license-ids "^1.0.2"
|
||||
|
||||
spdx-expression-parse@~1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
|
||||
|
||||
spdx-license-ids@^1.0.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@ -1300,6 +1525,10 @@ strip-ansi@^4.0.0:
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
|
||||
strip-eof@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
||||
@ -1379,6 +1608,13 @@ util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
||||
validate-npm-package-license@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
|
||||
dependencies:
|
||||
spdx-correct "~1.0.0"
|
||||
spdx-expression-parse "~1.0.0"
|
||||
|
||||
which@^1.2.10, which@^1.2.9:
|
||||
version "1.2.14"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user