diff --git a/code/lib/csf-tools/src/ConfigFile.test.ts b/code/lib/csf-tools/src/ConfigFile.test.ts index 6b4db4f65c97..6b4d6ce6e111 100644 --- a/code/lib/csf-tools/src/ConfigFile.test.ts +++ b/code/lib/csf-tools/src/ConfigFile.test.ts @@ -870,45 +870,90 @@ describe('ConfigFile', () => { }); describe('satisfies', () => { - it(`supports an array with string literal and object expression with name property`, () => { - const source = dedent` - import type { StorybookConfig } from '@storybook/react-webpack5'; - - const config = { - addons: [ - 'foo', - { name: 'bar', options: {} }, - ], - "otherField": [ - "foo", - { "name": 'bar', options: {} }, - ], - } satisfies StorybookConfig - export default config; - `; - const config = loadConfig(source).parse(); - expect(config.getNamesFromPath(['addons'])).toEqual(['foo', 'bar']); - expect(config.getNamesFromPath(['otherField'])).toEqual(['foo', 'bar']); + describe('default export', () => { + it(`supports an array with string literal and object expression with name property`, () => { + const source = dedent` + import type { StorybookConfig } from '@storybook/react-webpack5'; + + const config = { + addons: [ + 'foo', + { name: 'bar', options: {} }, + ], + "otherField": [ + "foo", + { "name": 'bar', options: {} }, + ], + } satisfies StorybookConfig + export default config; + `; + const config = loadConfig(source).parse(); + expect(config.getNamesFromPath(['addons'])).toEqual(['foo', 'bar']); + expect(config.getNamesFromPath(['otherField'])).toEqual(['foo', 'bar']); + }); + + it(`supports an array with string literal and object expression with name property without variable`, () => { + const source = dedent` + import type { StorybookConfig } from '@storybook/react-webpack5'; + + export default { + addons: [ + 'foo', + { name: 'bar', options: {} }, + ], + "otherField": [ + "foo", + { "name": 'bar', options: {} }, + ], + } satisfies StorybookConfig; + `; + const config = loadConfig(source).parse(); + expect(config.getNamesFromPath(['addons'])).toEqual(['foo', 'bar']); + expect(config.getNamesFromPath(['otherField'])).toEqual(['foo', 'bar']); + }); }); - it(`supports an array with string literal and object expression with name property without variable`, () => { - const source = dedent` - import type { StorybookConfig } from '@storybook/react-webpack5'; - - export default { - addons: [ - 'foo', - { name: 'bar', options: {} }, - ], - "otherField": [ - "foo", - { "name": 'bar', options: {} }, - ], - } satisfies StorybookConfig; - `; - const config = loadConfig(source).parse(); - expect(config.getNamesFromPath(['addons'])).toEqual(['foo', 'bar']); - expect(config.getNamesFromPath(['otherField'])).toEqual(['foo', 'bar']); + describe('module exports', () => { + it(`supports an array with string literal and object expression with name property`, () => { + const source = dedent` + import type { StorybookConfig } from '@storybook/react-webpack5'; + + const config = { + addons: [ + 'foo', + { name: 'bar', options: {} }, + ], + "otherField": [ + "foo", + { "name": 'bar', options: {} }, + ], + } satisfies StorybookConfig + module.exports = config; + `; + const config = loadConfig(source).parse(); + expect(config.getNamesFromPath(['addons'])).toEqual(['foo', 'bar']); + expect(config.getNamesFromPath(['otherField'])).toEqual(['foo', 'bar']); + }); + + it(`supports an array with string literal and object expression with name property without variable`, () => { + const source = dedent` + import type { StorybookConfig } from '@storybook/react-webpack5'; + + module.exports = { + addons: [ + 'foo', + { name: 'bar', options: {} }, + ], + "otherField": [ + "foo", + { "name": 'bar', options: {} }, + ], + } satisfies StorybookConfig; + `; + const config = loadConfig(source).parse(); + expect(config.getNamesFromPath(['addons'])).toEqual(['foo', 'bar']); + expect(config.getNamesFromPath(['otherField'])).toEqual(['foo', 'bar']); + }); }); }); }); diff --git a/code/lib/csf-tools/src/ConfigFile.ts b/code/lib/csf-tools/src/ConfigFile.ts index 4d5bafea8fdb..6f8edd6604a8 100644 --- a/code/lib/csf-tools/src/ConfigFile.ts +++ b/code/lib/csf-tools/src/ConfigFile.ts @@ -138,6 +138,7 @@ export class ConfigFile { t.isIdentifier(node.declaration) && t.isProgram(parent) ? _findVarInitialization(node.declaration.name, parent) : node.declaration; + if (t.isTSAsExpression(decl) || t.isTSSatisfiesExpression(decl)) { decl = decl.expression; } @@ -193,6 +194,11 @@ export class ConfigFile { if (t.isIdentifier(right)) { exportObject = _findVarInitialization(right.name, parent as t.Program) as any; } + + if (t.isTSAsExpression(exportObject) || t.isTSSatisfiesExpression(exportObject)) { + exportObject = exportObject.expression; + } + if (t.isObjectExpression(exportObject)) { self._exportsObject = exportObject; (exportObject.properties as t.ObjectProperty[]).forEach((p) => {