import { isExportStory } from '@storybook/csf' ; import { ExportDefaultDeclaration } from '@typescript-eslint/types/dist/ast-spec' ; import { findVariable } from '@typescript-eslint/experimental-utils/dist/ast-utils' ; import { isFunctionDeclaration , isIdentifier , isObjectExpression , isTSAsExpression , isVariableDeclaration , isVariableDeclarator , } from './ast' ; export const docsUrl = ( ruleName ) => `https://github.com/storybookjs/eslint-plugin-storybook/blob/main/docs/rules/${ ruleName }.md` ; export const isPlayFunction = ( node ) => { const propertyName = node . left && node . left . property && node . left . property . name ; return propertyName === 'play' ; } ; export const getMetaObjectExpression = ( node , context ) => { let meta = node . declaration ; if ( isIdentifier ( meta ) ) { const variable = findVariable ( context . getScope ( ) , meta . name ) ; const decl = variable && variable . defs . find ( ( def ) => isVariableDeclarator ( def . node ) ) ; if ( decl && isVariableDeclarator ( decl . node ) ) { meta = decl . node . init ; } } if ( isTSAsExpression ( meta ) ) { meta = meta . expression ; } return isObjectExpression ( meta ) ? meta : null ; } ; export 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 }` ) ; } } ; export const isValidStoryExport = ( node , nonStoryExportsConfig ) => isExportStory ( node . name , nonStoryExportsConfig ) && node . name !== '__namedExportsOrder' ; export const getAllNamedExports = ( node ) => { if ( ! node . declaration && node . specifiers ) { return node . specifiers . reduce ( ( acc , specifier ) => { if ( isIdentifier ( specifier . exported ) ) { acc . push ( specifier . exported ) ; } return acc ; } , [ ] ) ; } const decl = node . declaration ; if ( isVariableDeclaration ( decl ) ) { const { id } = decl . declarations [ 0 ] ; if ( isIdentifier ( id ) ) { return [ id ] ; } } if ( isFunctionDeclaration ( decl ) ) { if ( isIdentifier ( decl . id ) ) { return [ decl . id ] ; } } return [ ] ; } ;