1- import { getStorybookInfo } from '@storybook/core-common' ;
1+ import { getStorybookInfo , serverRequire } from '@storybook/core-common' ;
22import { readConfig , writeConfig } from '@storybook/csf-tools' ;
3+ import { isAbsolute , join } from 'path' ;
34import SemVer from 'semver' ;
5+ import dedent from 'ts-dedent' ;
46
57import {
68 JsPackageManagerFactory ,
@@ -38,6 +40,21 @@ const getVersionSpecifier = (addon: string) => {
3840 return groups ? [ groups [ 1 ] , groups [ 2 ] ] : [ addon , undefined ] ;
3941} ;
4042
43+ const requireMain = ( configDir : string ) => {
44+ const absoluteConfigDir = isAbsolute ( configDir ) ? configDir : join ( process . cwd ( ) , configDir ) ;
45+ const mainFile = join ( absoluteConfigDir , 'main' ) ;
46+
47+ return serverRequire ( mainFile ) ?? { } ;
48+ } ;
49+
50+ const checkInstalled = ( addonName : string , main : any ) => {
51+ const existingAddon = main . addons ?. find ( ( entry : string | { name : string } ) => {
52+ const name = typeof entry === 'string' ? entry : entry . name ;
53+ return name ?. endsWith ( addonName ) ;
54+ } ) ;
55+ return ! ! existingAddon ;
56+ } ;
57+
4158/**
4259 * Install the given addon package and add it to main.js
4360 *
@@ -60,9 +77,16 @@ export async function add(
6077 }
6178 const packageManager = JsPackageManagerFactory . getPackageManager ( { force : pkgMgr } ) ;
6279 const packageJson = await packageManager . retrievePackageJson ( ) ;
80+ const { mainConfig, configDir } = getStorybookInfo ( packageJson ) ;
81+
82+ if ( checkInstalled ( addon , requireMain ( configDir ) ) ) {
83+ throw new Error ( dedent `
84+ Addon ${ addon } is already installed; we skipped adding it to your ${ mainConfig } .
85+ ` ) ;
86+ }
87+
6388 const [ addonName , versionSpecifier ] = getVersionSpecifier ( addon ) ;
6489
65- const { mainConfig } = getStorybookInfo ( packageJson ) ;
6690 if ( ! mainConfig ) {
6791 logger . error ( 'Unable to find storybook main.js config' ) ;
6892 return ;
0 commit comments