eslint-plugin-storybook
Advanced tools
Comparing version 0.0.1-alpha.0 to 0.0.1-alpha.1
@@ -10,2 +10,3 @@ /* | ||
'import/no-anonymous-default-export': 'off', | ||
'storybook/await-interactions': 'error', | ||
'storybook/use-storybook-expect': 'error', | ||
@@ -12,0 +13,0 @@ 'storybook/use-storybook-testing-library': 'error', |
@@ -13,10 +13,4 @@ /* | ||
'storybook/hierarchy-separator': 'warn', | ||
'storybook/meta-inline-properties': [ | ||
'error', | ||
{ | ||
csfVersion: 3, | ||
}, | ||
], | ||
'storybook/no-redundant-story-name': 'warn', | ||
}, | ||
} |
@@ -10,10 +10,5 @@ /* | ||
'import/no-anonymous-default-export': 'off', | ||
'storybook/await-interactions': 'error', | ||
'storybook/default-exports': 'error', | ||
'storybook/hierarchy-separator': 'warn', | ||
'storybook/meta-inline-properties': [ | ||
'error', | ||
{ | ||
csfVersion: 3, | ||
}, | ||
], | ||
'storybook/no-redundant-story-name': 'warn', | ||
@@ -20,0 +15,0 @@ 'storybook/prefer-pascal-case': 'warn', |
@@ -25,3 +25,3 @@ /** | ||
messages: { | ||
description: 'Missing component property.', | ||
missingComponentProperty: 'Missing component property.', | ||
}, | ||
@@ -61,3 +61,3 @@ fixable: null, // Or `code` or `whitespace` | ||
node, | ||
messageId: 'description', | ||
messageId: 'missingComponentProperty', | ||
}) | ||
@@ -64,0 +64,0 @@ } |
@@ -25,3 +25,3 @@ /** | ||
messages: { | ||
description: 'The file should have a default export.', | ||
shouldHaveDefaultExport: 'The file should have a default export.', | ||
}, | ||
@@ -57,3 +57,3 @@ }, | ||
loc: { start: { line: 0, column: 0 }, end: { line: 0, column: 0 } }, | ||
messageId: 'description', | ||
messageId: 'shouldHaveDefaultExport', | ||
}) | ||
@@ -60,0 +60,0 @@ } |
@@ -26,3 +26,3 @@ /** | ||
messages: { | ||
fixSuggestion: 'Use correct separators', | ||
useCorrectSeparators: 'Use correct separators', | ||
deprecatedHierarchySeparator: | ||
@@ -46,7 +46,7 @@ 'Deprecated hierachy separator in title property: {{metaTitle}}.', | ||
if (!titleNode) { | ||
if (!titleNode || !titleNode.value.type === 'Literal') { | ||
return | ||
} | ||
const metaTitle = titleNode.value.raw | ||
const metaTitle = titleNode.value.raw || '' | ||
@@ -64,3 +64,3 @@ if (metaTitle.includes('|') || metaTitle.includes('.')) { | ||
{ | ||
messageId: 'fixSuggestion', | ||
messageId: 'useCorrectSeparators', | ||
fix: function (fixer) { | ||
@@ -67,0 +67,0 @@ return fixer.replaceTextRange( |
@@ -21,2 +21,3 @@ /** | ||
recommended: true, | ||
excludeFromConfig: true, | ||
recommendedConfig: ['error', { csfVersion: 3 }], | ||
@@ -26,3 +27,3 @@ url: docsUrl('meta-inline-properties'), // URL to the documentation page for this rule | ||
messages: { | ||
description: 'Meta should only have inline properties: {{properties}}', | ||
metaShouldHaveInlineProperties: 'Meta should only have inline properties: {{property}}', | ||
}, | ||
@@ -52,3 +53,9 @@ schema: [ | ||
//---------------------------------------------------------------------- | ||
const isInline = (node) => { | ||
return ( | ||
node.value.type === 'ObjectExpression' || | ||
node.value.type === 'Literal' || | ||
node.value.type === 'ArrayExpression' | ||
) | ||
} | ||
// any helper functions should go here or else delete this section | ||
@@ -77,9 +84,4 @@ | ||
metaNodes.forEach((metaNode) => { | ||
const isDynamic = | ||
metaNode.shorthand || | ||
metaNode.value.type === 'BinaryExpression' || | ||
(metaNode.value.type === 'TemplateLiteral' && metaNode.value.expressions.length > 0) | ||
if (isDynamic) { | ||
dynamicProperties.push(metaNode.key.name) | ||
if (!isInline(metaNode)) { | ||
dynamicProperties.push(metaNode) | ||
} | ||
@@ -89,9 +91,10 @@ }) | ||
if (dynamicProperties.length > 0) { | ||
context.report({ | ||
node, | ||
loc: node.loc, | ||
messageId: 'description', | ||
data: { | ||
properties: dynamicProperties.join(', '), | ||
}, | ||
dynamicProperties.forEach((propertyNode) => { | ||
context.report({ | ||
node: propertyNode, | ||
messageId: 'metaShouldHaveInlineProperties', | ||
data: { | ||
property: propertyNode.key.name, | ||
}, | ||
}) | ||
}) | ||
@@ -98,0 +101,0 @@ } |
@@ -26,4 +26,4 @@ /** | ||
messages: { | ||
fixSuggestion: 'Remove redundant name', | ||
description: | ||
removeRedundantName: 'Remove redundant name', | ||
storyNameIsRedundant: | ||
'Named exports should not use the name annotation if it is redundant to the name that would be generated by the export name', | ||
@@ -87,6 +87,6 @@ }, | ||
node: storyNameNode, | ||
messageId: 'description', | ||
messageId: 'storyNameIsRedundant', | ||
suggest: [ | ||
{ | ||
messageId: 'fixSuggestion', | ||
messageId: 'removeRedundantName', | ||
fix: function (fixer) { | ||
@@ -93,0 +93,0 @@ return fixer.remove(storyNameNode) |
@@ -25,3 +25,3 @@ /** | ||
messages: { | ||
description: 'storiesOf is deprecated and should not be used', | ||
doNotUseStoriesOf: 'storiesOf is deprecated and should not be used', | ||
}, | ||
@@ -48,3 +48,3 @@ }, | ||
node, | ||
messageId: 'description', | ||
messageId: 'doNotUseStoriesOf', | ||
}) | ||
@@ -51,0 +51,0 @@ } |
@@ -27,4 +27,4 @@ /** | ||
messages: { | ||
fixSuggestion: 'Do not define a title in meta', | ||
description: `CSF3 does not need a title in meta`, | ||
removeTitleInMeta: 'Do not define a title in meta', | ||
noTitleInMeta: `CSF3 does not need a title in meta`, | ||
}, | ||
@@ -49,3 +49,3 @@ }, | ||
node, | ||
messageId: 'description', | ||
messageId: 'noTitleInMeta', | ||
// In case we want this to be auto fixed by --fix | ||
@@ -59,3 +59,3 @@ // fix: function (fixer) { | ||
{ | ||
messageId: 'fixSuggestion', | ||
messageId: 'removeTitleInMeta', | ||
fix: function (fixer) { | ||
@@ -62,0 +62,0 @@ // @TODO this suggestion keeps the comma and might result in error: |
@@ -24,4 +24,4 @@ /** | ||
messages: { | ||
fixSuggestion: 'Use pascal case', | ||
description: 'The story should use PascalCase notation: {{name}}', | ||
convertToPascalCase: 'Use pascal case', | ||
usePascalCase: 'The story should use PascalCase notation: {{name}}', | ||
}, | ||
@@ -75,7 +75,7 @@ }, | ||
node: identifier, | ||
messageId: 'description', | ||
messageId: 'usePascalCase', | ||
data: { name }, | ||
suggest: [ | ||
{ | ||
messageId: 'fixSuggestion', | ||
messageId: 'convertToPascalCase', | ||
fix: function (fixer) { | ||
@@ -82,0 +82,0 @@ return fixer.replaceTextRange(identifier.range, toPascalCase(name)) |
@@ -9,2 +9,8 @@ /** | ||
const { CATEGORY_ID } = require('../utils/constants') | ||
const { | ||
isExpressionStatement, | ||
isCallExpression, | ||
isMemberExpression, | ||
isIdentifier, | ||
} = require('../utils/ast') | ||
@@ -28,4 +34,4 @@ //------------------------------------------------------------------------------ | ||
messages: { | ||
fixSuggestion: 'Update imports', | ||
description: | ||
updateImports: 'Update imports', | ||
useExpectFromStorybook: | ||
'Do not use expect from jest directly in the story. You should use from `@storybook/jest` instead.', | ||
@@ -43,7 +49,13 @@ }, | ||
const getExpressionStatements = (body = []) => { | ||
return body.filter((b) => b.type === 'ExpressionStatement') | ||
return body.filter((b) => isExpressionStatement(b)) | ||
} | ||
const isExpect = (expression = {}) => { | ||
return expression.callee.object.callee.name === 'expect' | ||
return ( | ||
isCallExpression(expression) && | ||
isMemberExpression(expression.callee) && | ||
isCallExpression(expression.callee.object) && | ||
isIdentifier(expression.callee.object.callee) && | ||
expression.callee.object.callee.name === 'expect' | ||
) | ||
} | ||
@@ -71,2 +83,6 @@ | ||
AssignmentExpression(node) { | ||
if (!isExpressionStatement(node.parent)) { | ||
return null | ||
} | ||
if (isPlayFunction(node)) { | ||
@@ -88,3 +104,3 @@ const { right } = node | ||
node, | ||
messageId: 'description', | ||
messageId: 'useExpectFromStorybook', | ||
fix: function (fixer) { | ||
@@ -98,3 +114,3 @@ return fixer.insertTextAfterRange( | ||
{ | ||
messageId: 'fixSuggestion', | ||
messageId: 'updateImports', | ||
fix: function (fixer) { | ||
@@ -101,0 +117,0 @@ return fixer.insertTextAfterRange( |
@@ -27,4 +27,4 @@ /** | ||
messages: { | ||
fixSuggestion: 'Update imports', | ||
description: | ||
updateImports: 'Update imports', | ||
dontUseTestingLibraryDirectly: | ||
'Do not use `{{library}}` directly in the story. You should import the functions from `@storybook/testing-library` instead.', | ||
@@ -57,3 +57,3 @@ }, | ||
node, | ||
messageId: 'description', | ||
messageId: 'dontUseTestingLibraryDirectly', | ||
data: { | ||
@@ -70,3 +70,3 @@ library: node.source.value, | ||
{ | ||
messageId: 'fixSuggestion', | ||
messageId: 'updateImports', | ||
fix: function (fixer) { | ||
@@ -73,0 +73,0 @@ return fixer.replaceTextRange( |
{ | ||
"name": "eslint-plugin-storybook", | ||
"version": "0.0.1-alpha.0", | ||
"version": "0.0.1-alpha.1", | ||
"description": "Best practice rules for Storybook", | ||
@@ -12,2 +12,8 @@ "keywords": [ | ||
"author": "yannbf@gmail.com", | ||
"contributors": [ | ||
{ | ||
"name": "Rafael Rozon", | ||
"email": "rafaelrozon.developer@gmail.com" | ||
} | ||
], | ||
"main": "lib/index.js", | ||
@@ -38,3 +44,4 @@ "files": [ | ||
"dependencies": { | ||
"requireindex": "^1.1.0" | ||
"requireindex": "^1.1.0", | ||
"@typescript-eslint/experimental-utils": "^5.3.0" | ||
}, | ||
@@ -41,0 +48,0 @@ "devDependencies": { |
@@ -108,6 +108,6 @@ <p align="center"> | ||
| ------------------------------------------------------------------------------------------ | ------------------------------------------------- | --- | ------------------------------- | | ||
| [`storybook/await-interactions`](./docs/rules/await-interactions.md) | Interactions should be awaited | | addon-interactions, recommended | | ||
| [`storybook/csf-component`](./docs/rules/csf-component.md) | The component property should be set | | csf | | ||
| [`storybook/default-exports`](./docs/rules/default-exports.md) | Story files should have a default export | | csf, recommended | | ||
| [`storybook/hierarchy-separator`](./docs/rules/hierarchy-separator.md) | Deprecated hierachy separator in title property | 🔧 | csf, recommended | | ||
| [`storybook/meta-inline-properties`](./docs/rules/meta-inline-properties.md) | Meta should only have inline properties | | csf, recommended | | ||
| [`storybook/no-redundant-story-name`](./docs/rules/no-redundant-story-name.md) | A story should not have a redundant name property | 🔧 | csf, recommended | | ||
@@ -114,0 +114,0 @@ | [`storybook/no-stories-of`](./docs/rules/no-stories-of.md) | storiesOf is deprecated and should not be used | | csf-strict | |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
43952
21
1032
0
3
+ Added@eslint/eslintrc@2.1.4(transitive)
+ Added@eslint/js@8.57.1(transitive)
+ Added@humanwhocodes/config-array@0.13.0(transitive)
+ Added@humanwhocodes/object-schema@2.0.3(transitive)
+ Added@nodelib/fs.scandir@2.1.5(transitive)
+ Added@nodelib/fs.stat@2.0.5(transitive)
+ Added@nodelib/fs.walk@1.2.8(transitive)
+ Added@types/semver@7.5.8(transitive)
+ Added@typescript-eslint/experimental-utils@5.62.0(transitive)
+ Added@typescript-eslint/scope-manager@5.62.0(transitive)
+ Added@typescript-eslint/types@5.62.0(transitive)
+ Added@typescript-eslint/typescript-estree@5.62.0(transitive)
+ Added@typescript-eslint/utils@5.62.0(transitive)
+ Added@typescript-eslint/visitor-keys@5.62.0(transitive)
+ Added@ungap/structured-clone@1.2.0(transitive)
+ Addedansi-regex@5.0.1(transitive)
+ Addedarray-union@2.1.0(transitive)
+ Addedbraces@3.0.3(transitive)
+ Addeddir-glob@3.0.1(transitive)
+ Addeddoctrine@3.0.0(transitive)
+ Addedeslint@8.57.1(transitive)
+ Addedeslint-scope@5.1.17.2.2(transitive)
+ Addedespree@9.6.1(transitive)
+ Addedestraverse@4.3.0(transitive)
+ Addedfast-glob@3.3.2(transitive)
+ Addedfastq@1.17.1(transitive)
+ Addedfile-entry-cache@6.0.1(transitive)
+ Addedfill-range@7.1.1(transitive)
+ Addedflat-cache@3.2.0(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglob-parent@5.1.2(transitive)
+ Addedglobals@13.24.0(transitive)
+ Addedglobby@11.1.0(transitive)
+ Addedgraphemer@1.4.0(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-number@7.0.0(transitive)
+ Addedis-path-inside@3.0.3(transitive)
+ Addedmerge2@1.4.1(transitive)
+ Addedmicromatch@4.0.8(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpath-type@4.0.0(transitive)
+ Addedpicomatch@2.3.1(transitive)
+ Addedqueue-microtask@1.2.3(transitive)
+ Addedreusify@1.0.4(transitive)
+ Addedrimraf@3.0.2(transitive)
+ Addedrun-parallel@1.2.0(transitive)
+ Addedsemver@7.6.3(transitive)
+ Addedslash@3.0.0(transitive)
+ Addedstrip-ansi@6.0.1(transitive)
+ Addedto-regex-range@5.0.1(transitive)
+ Addedtslib@1.14.1(transitive)
+ Addedtsutils@3.21.0(transitive)
+ Addedtype-fest@0.20.2(transitive)
+ Addedtypescript@5.6.3(transitive)
+ Addedwrappy@1.0.2(transitive)