fileoverview author Yann Braga
  import { createStorybookRule } from '../utils/create-storybook-rule' ; import { CategoryId } from '../utils/constants' ; import { getAllNamedExports , getDescriptor , getMetaObjectExpression , isValidStoryExport , } from '../utils' ; export = createStorybookRule ( { name : 'story-exports' , defaultOptions : [ ] , meta : { type : 'problem' , docs : { description : 'A story file must contain at least one story export' , categories : [ CategoryId . RECOMMENDED , CategoryId . CSF ] , recommended : 'error' , } , messages : { shouldHaveStoryExport : 'The file should have at least one story export' , addStoryExport : 'Add a story export' , } , fixable : null , schema : [ ] , } , create ( context ) { let hasStoriesOfImport = false ; let nonStoryExportsConfig = { } ; let meta ; let namedExports = [ ] ; return { ImportSpecifier ( node ) { if ( node . imported . name === 'storiesOf' ) { hasStoriesOfImport = true ; } } , ExportDefaultDeclaration : function ( node ) { meta = getMetaObjectExpression ( node , context ) ; if ( meta ) { try { nonStoryExportsConfig = { excludeStories : getDescriptor ( meta , 'excludeStories' ) , includeStories : getDescriptor ( meta , 'includeStories' ) , } ; } catch ( err ) { } } } , ExportNamedDeclaration : function ( node ) { namedExports . push ( ... getAllNamedExports ( node ) ) ; } , 'Program:exit' : function ( node ) { if ( hasStoriesOfImport || ! meta ) { return ; } const storyExports = namedExports . filter ( ( exp ) => isValidStoryExport ( exp , nonStoryExportsConfig ) ) ; if ( storyExports . length ) { return ; } context . report ( { node , messageId : 'shouldHaveStoryExport' , } ) ; } , } ; } , } ) ;