eslint-plugin-storybook
Advanced tools
Comparing version 0.2.1 to 0.2.2
@@ -38,3 +38,2 @@ "use strict"; | ||
.join(' '); | ||
// any helper functions should go here or else delete this section | ||
//---------------------------------------------------------------------- | ||
@@ -44,2 +43,3 @@ // Public | ||
return { | ||
// CSF3 | ||
ExportNamedDeclaration: function (node) { | ||
@@ -49,22 +49,47 @@ // if there are specifiers, node.declaration should be null | ||
return; | ||
const { type } = node.declaration; | ||
if (type === 'TSTypeAliasDeclaration' || | ||
type === 'TypeAlias' || | ||
type === 'TSInterfaceDeclaration' || | ||
type === 'InterfaceDeclaration') { | ||
return; | ||
const decl = node.declaration; | ||
if ((0, ast_1.isVariableDeclaration)(decl)) { | ||
const { id, init } = decl.declarations[0]; | ||
if ((0, ast_1.isIdentifier)(id) && (0, ast_1.isObjectExpression)(init)) { | ||
const storyNameNode = init.properties.find((prop) => { | ||
var _a, _b; | ||
return (0, ast_1.isProperty)(prop) && | ||
(0, ast_1.isIdentifier)(prop.key) && | ||
(((_a = prop.key) === null || _a === void 0 ? void 0 : _a.name) === 'name' || ((_b = prop.key) === null || _b === void 0 ? void 0 : _b.name) === 'storyName'); | ||
}); | ||
if (!storyNameNode) { | ||
return; | ||
} | ||
const { name } = id; | ||
const resolvedStoryName = resolveStoryName(name); | ||
//@ts-ignore | ||
if ((0, ast_1.isLiteral)(storyNameNode.value) && storyNameNode.value.value === resolvedStoryName) { | ||
context.report({ | ||
node: storyNameNode, | ||
messageId: 'storyNameIsRedundant', | ||
suggest: [ | ||
{ | ||
messageId: 'removeRedundantName', | ||
fix: function (fixer) { | ||
return fixer.remove(storyNameNode); | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
} | ||
} | ||
const { id: identifier, init: { properties }, } = node.declaration.declarations[0]; | ||
if (!properties) { | ||
}, | ||
// CSF2 | ||
AssignmentExpression: function (node) { | ||
if (!(0, ast_1.isExpressionStatement)(node.parent)) | ||
return; | ||
} | ||
const storyNameNode = properties.find( | ||
//@ts-ignore | ||
(prop) => (0, ast_1.isProperty)(prop) && prop.key.name === 'name'); | ||
if (storyNameNode) { | ||
const { name } = identifier; | ||
const resolvedStoryName = resolveStoryName(name); | ||
if (storyNameNode.value.value === resolvedStoryName) { | ||
const { left, right } = node; | ||
if ((0, ast_1.isIdentifier)(left.property) && left.property.name === 'storyName') { | ||
const propertyName = left.object.name; | ||
const propertyValue = right.value; | ||
const resolvedStoryName = resolveStoryName(propertyName); | ||
if (propertyValue === resolvedStoryName) { | ||
context.report({ | ||
node: storyNameNode, | ||
node: node, | ||
messageId: 'storyNameIsRedundant', | ||
@@ -75,3 +100,3 @@ suggest: [ | ||
fix: function (fixer) { | ||
return fixer.remove(storyNameNode); | ||
return fixer.remove(node); | ||
}, | ||
@@ -78,0 +103,0 @@ }, |
@@ -7,2 +7,4 @@ "use strict"; | ||
const ast_utils_1 = require("@typescript-eslint/experimental-utils/dist/ast-utils"); | ||
const csf_1 = require("@storybook/csf"); | ||
const utils_1 = require("../utils"); | ||
const ast_1 = require("../utils/ast"); | ||
@@ -47,6 +49,56 @@ const constants_1 = require("../utils/constants"); | ||
}; | ||
const checkAndReportError = (id, nonStoryExportsConfig = {}) => { | ||
const { name } = id; | ||
if (!(0, csf_1.isExportStory)(name, nonStoryExportsConfig)) { | ||
return null; | ||
} | ||
if (!isPascalCase(name)) { | ||
context.report({ | ||
node: id, | ||
messageId: 'usePascalCase', | ||
data: { | ||
name, | ||
}, | ||
suggest: [ | ||
{ | ||
messageId: 'convertToPascalCase', | ||
*fix(fixer) { | ||
var _a; | ||
const fullText = context.getSourceCode().text; | ||
const fullName = fullText.slice(id.range[0], id.range[1]); | ||
const suffix = fullName.substring(name.length); | ||
const pascal = toPascalCase(name); | ||
yield fixer.replaceTextRange(id.range, pascal + suffix); | ||
const scope = context.getScope().childScopes[0]; | ||
if (scope) { | ||
const variable = (0, ast_utils_1.findVariable)(scope, name); | ||
for (let i = 0; i < ((_a = variable === null || variable === void 0 ? void 0 : variable.references) === null || _a === void 0 ? void 0 : _a.length); i++) { | ||
const ref = variable.references[i]; | ||
if (!ref.init) { | ||
yield fixer.replaceTextRange(ref.identifier.range, pascal); | ||
} | ||
} | ||
} | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
}; | ||
//---------------------------------------------------------------------- | ||
// Public | ||
//---------------------------------------------------------------------- | ||
let meta; | ||
let nonStoryExportsConfig; | ||
let namedExports = []; | ||
return { | ||
ExportDefaultDeclaration: function (node) { | ||
meta = (0, utils_1.getMetaObjectExpression)(node, context); | ||
if (meta) { | ||
nonStoryExportsConfig = { | ||
excludeStories: (0, utils_1.getDescriptor)(meta, 'excludeStories'), | ||
includeStories: (0, utils_1.getDescriptor)(meta, 'includeStories'), | ||
}; | ||
} | ||
}, | ||
ExportNamedDeclaration: function (node) { | ||
@@ -60,36 +112,13 @@ // if there are specifiers, node.declaration should be null | ||
if ((0, ast_1.isIdentifier)(id)) { | ||
const { name } = id; | ||
if (!isPascalCase(name)) { | ||
context.report({ | ||
node: id, | ||
messageId: 'usePascalCase', | ||
data: { | ||
name, | ||
}, | ||
suggest: [ | ||
{ | ||
messageId: 'convertToPascalCase', | ||
*fix(fixer) { | ||
const fullText = context.getSourceCode().text; | ||
const fullName = fullText.slice(id.range[0], id.range[1]); | ||
const suffix = fullName.substring(name.length); | ||
const pascal = toPascalCase(name); | ||
yield fixer.replaceTextRange(id.range, pascal + suffix); | ||
const variable = (0, ast_utils_1.findVariable)(context.getScope(), name); | ||
for (let i = 0; i < variable.references.length; i++) { | ||
const ref = variable.references[i]; | ||
if (!ref.init) { | ||
yield fixer.replaceTextRange(ref.identifier.range, pascal); | ||
} | ||
} | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
namedExports.push(id); | ||
} | ||
} | ||
}, | ||
'Program:exit': function () { | ||
if (namedExports.length) { | ||
namedExports.forEach((n) => checkAndReportError(n, nonStoryExportsConfig)); | ||
} | ||
}, | ||
}; | ||
}, | ||
}); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getMetaObjectExpression = exports.isPlayFunction = exports.docsUrl = void 0; | ||
exports.getDescriptor = exports.getMetaObjectExpression = exports.isPlayFunction = exports.docsUrl = void 0; | ||
const ast_utils_1 = require("@typescript-eslint/experimental-utils/dist/ast-utils"); | ||
@@ -28,1 +28,23 @@ const ast_1 = require("./ast"); | ||
exports.getMetaObjectExpression = getMetaObjectExpression; | ||
const getDescriptor = (metaDeclaration, propertyName) => { | ||
const property = metaDeclaration && metaDeclaration.properties.find((p) => p.key && p.key.name === propertyName); | ||
if (!property) { | ||
return undefined; | ||
} | ||
const { type } = property.value; | ||
switch (type) { | ||
case 'ArrayExpression': | ||
return property.value.elements.map((t) => { | ||
if (!['StringLiteral', 'Literal'].includes(t.type)) { | ||
throw new Error(`Unexpected descriptor element: ${t.type}`); | ||
} | ||
return t.value; | ||
}); | ||
case 'Literal': | ||
case 'RegExpLiteral': | ||
return property.value.value; | ||
default: | ||
throw new Error(`Unexpected descriptor: ${type}`); | ||
} | ||
}; | ||
exports.getDescriptor = getDescriptor; |
{ | ||
"name": "eslint-plugin-storybook", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "Best practice rules for Storybook", | ||
@@ -48,2 +48,3 @@ "keywords": [ | ||
"dependencies": { | ||
"@storybook/csf": "^0.0.1", | ||
"@typescript-eslint/experimental-utils": "^5.3.0", | ||
@@ -50,0 +51,0 @@ "requireindex": "^1.1.0" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
56537
1090
4
+ Added@storybook/csf@^0.0.1
+ Added@storybook/csf@0.0.1(transitive)
+ Addedlodash@4.17.21(transitive)