From 25d98e52fbf9b4b2dd91bcea09ec7d33774cf3d9 Mon Sep 17 00:00:00 2001 From: vctqs1 Date: Sat, 12 Oct 2024 18:48:19 +0700 Subject: [PATCH 1/7] resolve export from import --- code/core/src/csf-tools/ConfigFile.test.ts | 28 ++++++++++++++++++++++ code/core/src/csf-tools/ConfigFile.ts | 27 ++++++++++++++++++++- code/core/src/csf-tools/parameters.data.ts | 1 + code/package.json | 2 +- code/vitest.config.ts | 1 + 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 code/core/src/csf-tools/parameters.data.ts diff --git a/code/core/src/csf-tools/ConfigFile.test.ts b/code/core/src/csf-tools/ConfigFile.test.ts index fe841c49f488..a540ed0d7ceb 100644 --- a/code/core/src/csf-tools/ConfigFile.test.ts +++ b/code/core/src/csf-tools/ConfigFile.test.ts @@ -1308,4 +1308,32 @@ describe('ConfigFile', () => { ); }); }); + + describe.only('parse', () => { + it("export { X } with X is import { X } from 'another-file'", () => { + const source = dedent` + import type { StorybookConfig } from '@storybook/react-webpack5'; + import { parameters } from './parameters.data'; + + export { parameters }; + + const config: StorybookConfig = { + addons: [ + 'foo', + { name: 'bar', options: {} }, + ], + "otherField": [ + "foo", + { "name": 'bar', options: {} }, + ], + } + export default config; + `; + const config = loadConfig(source).parse() + + // ensure config._exportDecls vs config._exports has 'parameters' + expect(config._exportDecls['parameters']).toBeTruthy() + expect(config._exports['parameters']).toBeTruthy() + }) + }) }); diff --git a/code/core/src/csf-tools/ConfigFile.ts b/code/core/src/csf-tools/ConfigFile.ts index 5cb0d28234eb..ba21b0bd3331 100644 --- a/code/core/src/csf-tools/ConfigFile.ts +++ b/code/core/src/csf-tools/ConfigFile.ts @@ -1,5 +1,6 @@ /* eslint-disable no-underscore-dangle */ import { readFile, writeFile } from 'node:fs/promises'; +import { readFileSync } from 'node:fs'; import { type RecastOptions, @@ -13,6 +14,7 @@ import { import { dedent } from 'ts-dedent'; import type { PrintResultType } from './PrintResultType'; +import path from 'node:path'; const logger = console; @@ -102,7 +104,24 @@ const _findVarDeclarator = ( ): t.VariableDeclarator | null | undefined => { let declarator: t.VariableDeclarator | null | undefined = null; let declarations: t.VariableDeclarator[] | null = null; + program.body.find((node: t.Node) => { + if(t.isImportDeclaration(node)) { + + node.specifiers.forEach((specifier) => { + + if(t.isImportSpecifier(specifier) && (specifier as t.ImportSpecifier).local?.name === identifier) { + const importSource = node.source.value; // the source module of the import + const importedConfig = readConfigSync(require.resolve(path.resolve(__dirname, `${importSource}.ts`))); + + const importedFileAST = importedConfig._ast.program; // Adjust this depending on how your importedConfig is structured + declarator = _findVarDeclarator(((specifier as t.ImportSpecifier).imported as t.Identifier).name, importedFileAST) + + return true; // stop looking + } + }) + } + if (t.isVariableDeclaration(node)) { declarations = node.declarations; } else if (t.isExportNamedDeclaration(node) && t.isVariableDeclaration(node.declaration)) { @@ -248,8 +267,9 @@ export class ConfigFile { ) { const { name: localName } = spec.local; const { name: exportName } = spec.exported; + const decl = _findVarDeclarator(localName, parent as t.Program) as any; - self._exports[exportName] = decl.init; + self._exports[exportName] = decl?.init; self._exportDecls[exportName] = decl; } }); @@ -899,6 +919,11 @@ export const readConfig = async (fileName: string) => { return loadConfig(code, fileName).parse(); }; +export const readConfigSync = (fileName: string) => { + const code = readFileSync(fileName, 'utf-8').toString(); + return loadConfig(code).parse(); +}; + export const writeConfig = async (config: ConfigFile, fileName?: string) => { const fname = fileName || config.fileName; diff --git a/code/core/src/csf-tools/parameters.data.ts b/code/core/src/csf-tools/parameters.data.ts new file mode 100644 index 000000000000..93e5d6e28c78 --- /dev/null +++ b/code/core/src/csf-tools/parameters.data.ts @@ -0,0 +1 @@ +export const parameters = {} \ No newline at end of file diff --git a/code/package.json b/code/package.json index 5dab4f6f2052..1f3018069ed2 100644 --- a/code/package.json +++ b/code/package.json @@ -52,7 +52,7 @@ "storybook:vitest": "yarn test:watch --project storybook-ui", "storybook:vitest:inspect": "INSPECT=true yarn test --project storybook-ui", "task": "yarn --cwd ../scripts task", - "test": "NODE_OPTIONS=--max_old_space_size=4096 vitest run", + "test": "NODE_OPTIONS=--max_old_space_size=4096 vitest run src/csf-tools/ConfigFile.test.ts", "test:watch": "NODE_OPTIONS=--max_old_space_size=4096 vitest watch" }, "husky": { diff --git a/code/vitest.config.ts b/code/vitest.config.ts index cabfb4e8b0ce..b848d9cc58bb 100644 --- a/code/vitest.config.ts +++ b/code/vitest.config.ts @@ -2,6 +2,7 @@ import { coverageConfigDefaults, defineConfig } from 'vitest/config'; export default defineConfig({ test: { + include: ["code/core/src/csf-tools/ConfigFile.test.ts"], coverage: { all: false, provider: 'istanbul', From 6a517f4135694289dabba37bbf38d6978eded9f5 Mon Sep 17 00:00:00 2001 From: vctqs1 Date: Sat, 12 Oct 2024 18:52:17 +0700 Subject: [PATCH 2/7] add step to check decl --- code/core/src/csf-tools/ConfigFile.test.ts | 8 ++++---- code/core/src/csf-tools/ConfigFile.ts | 24 ++++++---------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/code/core/src/csf-tools/ConfigFile.test.ts b/code/core/src/csf-tools/ConfigFile.test.ts index a540ed0d7ceb..d5fcfe8db80a 100644 --- a/code/core/src/csf-tools/ConfigFile.test.ts +++ b/code/core/src/csf-tools/ConfigFile.test.ts @@ -1313,9 +1313,9 @@ describe('ConfigFile', () => { it("export { X } with X is import { X } from 'another-file'", () => { const source = dedent` import type { StorybookConfig } from '@storybook/react-webpack5'; - import { parameters } from './parameters.data'; + import { path } from 'path'; - export { parameters }; + export { path }; const config: StorybookConfig = { addons: [ @@ -1332,8 +1332,8 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse() // ensure config._exportDecls vs config._exports has 'parameters' - expect(config._exportDecls['parameters']).toBeTruthy() - expect(config._exports['parameters']).toBeTruthy() + expect(config._exportDecls['path']).toBe(undefined) + expect(config._exports['path']).toBe(undefined) }) }) }); diff --git a/code/core/src/csf-tools/ConfigFile.ts b/code/core/src/csf-tools/ConfigFile.ts index ba21b0bd3331..93aabe663330 100644 --- a/code/core/src/csf-tools/ConfigFile.ts +++ b/code/core/src/csf-tools/ConfigFile.ts @@ -106,22 +106,6 @@ const _findVarDeclarator = ( let declarations: t.VariableDeclarator[] | null = null; program.body.find((node: t.Node) => { - if(t.isImportDeclaration(node)) { - - node.specifiers.forEach((specifier) => { - - if(t.isImportSpecifier(specifier) && (specifier as t.ImportSpecifier).local?.name === identifier) { - const importSource = node.source.value; // the source module of the import - const importedConfig = readConfigSync(require.resolve(path.resolve(__dirname, `${importSource}.ts`))); - - const importedFileAST = importedConfig._ast.program; // Adjust this depending on how your importedConfig is structured - declarator = _findVarDeclarator(((specifier as t.ImportSpecifier).imported as t.Identifier).name, importedFileAST) - - return true; // stop looking - } - }) - } - if (t.isVariableDeclaration(node)) { declarations = node.declarations; } else if (t.isExportNamedDeclaration(node) && t.isVariableDeclaration(node.declaration)) { @@ -269,8 +253,12 @@ export class ConfigFile { const { name: exportName } = spec.exported; const decl = _findVarDeclarator(localName, parent as t.Program) as any; - self._exports[exportName] = decl?.init; - self._exportDecls[exportName] = decl; + // decl can be empty in case X from `import { X } from ....` because it is not handled in _findVarDeclarator + if(decl) { + self._exports[exportName] = decl?.init; + self._exportDecls[exportName] = decl; + } + } }); } else { From 9faa98cacb907e26a136b093b37dde9923b3f98b Mon Sep 17 00:00:00 2001 From: vctqs1 Date: Sat, 12 Oct 2024 18:54:05 +0700 Subject: [PATCH 3/7] add step to check decl --- code/core/src/csf-tools/ConfigFile.test.ts | 2 +- code/core/src/csf-tools/ConfigFile.ts | 2 +- code/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/core/src/csf-tools/ConfigFile.test.ts b/code/core/src/csf-tools/ConfigFile.test.ts index d5fcfe8db80a..089cbaa8e6ea 100644 --- a/code/core/src/csf-tools/ConfigFile.test.ts +++ b/code/core/src/csf-tools/ConfigFile.test.ts @@ -1309,7 +1309,7 @@ describe('ConfigFile', () => { }); }); - describe.only('parse', () => { + describe('parse', () => { it("export { X } with X is import { X } from 'another-file'", () => { const source = dedent` import type { StorybookConfig } from '@storybook/react-webpack5'; diff --git a/code/core/src/csf-tools/ConfigFile.ts b/code/core/src/csf-tools/ConfigFile.ts index 93aabe663330..8d52c14bc7da 100644 --- a/code/core/src/csf-tools/ConfigFile.ts +++ b/code/core/src/csf-tools/ConfigFile.ts @@ -255,7 +255,7 @@ export class ConfigFile { const decl = _findVarDeclarator(localName, parent as t.Program) as any; // decl can be empty in case X from `import { X } from ....` because it is not handled in _findVarDeclarator if(decl) { - self._exports[exportName] = decl?.init; + self._exports[exportName] = decl.init; self._exportDecls[exportName] = decl; } diff --git a/code/package.json b/code/package.json index 1f3018069ed2..5dab4f6f2052 100644 --- a/code/package.json +++ b/code/package.json @@ -52,7 +52,7 @@ "storybook:vitest": "yarn test:watch --project storybook-ui", "storybook:vitest:inspect": "INSPECT=true yarn test --project storybook-ui", "task": "yarn --cwd ../scripts task", - "test": "NODE_OPTIONS=--max_old_space_size=4096 vitest run src/csf-tools/ConfigFile.test.ts", + "test": "NODE_OPTIONS=--max_old_space_size=4096 vitest run", "test:watch": "NODE_OPTIONS=--max_old_space_size=4096 vitest watch" }, "husky": { From 1e69f85d11d35191c2bed9508a111e62a058610f Mon Sep 17 00:00:00 2001 From: vctqs1 Date: Sat, 12 Oct 2024 19:00:27 +0700 Subject: [PATCH 4/7] add step to check decl --- code/core/src/csf-tools/ConfigFile.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/core/src/csf-tools/ConfigFile.ts b/code/core/src/csf-tools/ConfigFile.ts index 8d52c14bc7da..cfc24142d1ef 100644 --- a/code/core/src/csf-tools/ConfigFile.ts +++ b/code/core/src/csf-tools/ConfigFile.ts @@ -1,6 +1,5 @@ /* eslint-disable no-underscore-dangle */ import { readFile, writeFile } from 'node:fs/promises'; -import { readFileSync } from 'node:fs'; import { type RecastOptions, @@ -14,7 +13,6 @@ import { import { dedent } from 'ts-dedent'; import type { PrintResultType } from './PrintResultType'; -import path from 'node:path'; const logger = console; @@ -907,11 +905,6 @@ export const readConfig = async (fileName: string) => { return loadConfig(code, fileName).parse(); }; -export const readConfigSync = (fileName: string) => { - const code = readFileSync(fileName, 'utf-8').toString(); - return loadConfig(code).parse(); -}; - export const writeConfig = async (config: ConfigFile, fileName?: string) => { const fname = fileName || config.fileName; From 1bbb801d5e2b42ea6c3a74817840bdad46a995d9 Mon Sep 17 00:00:00 2001 From: vctqs1 Date: Sat, 12 Oct 2024 19:02:50 +0700 Subject: [PATCH 5/7] add step to check decl --- code/core/src/csf-tools/ConfigFile.test.ts | 1 - code/core/src/csf-tools/parameters.data.ts | 1 - code/vitest.config.ts | 1 - 3 files changed, 3 deletions(-) delete mode 100644 code/core/src/csf-tools/parameters.data.ts diff --git a/code/core/src/csf-tools/ConfigFile.test.ts b/code/core/src/csf-tools/ConfigFile.test.ts index 089cbaa8e6ea..44c6d09c6814 100644 --- a/code/core/src/csf-tools/ConfigFile.test.ts +++ b/code/core/src/csf-tools/ConfigFile.test.ts @@ -1331,7 +1331,6 @@ describe('ConfigFile', () => { `; const config = loadConfig(source).parse() - // ensure config._exportDecls vs config._exports has 'parameters' expect(config._exportDecls['path']).toBe(undefined) expect(config._exports['path']).toBe(undefined) }) diff --git a/code/core/src/csf-tools/parameters.data.ts b/code/core/src/csf-tools/parameters.data.ts deleted file mode 100644 index 93e5d6e28c78..000000000000 --- a/code/core/src/csf-tools/parameters.data.ts +++ /dev/null @@ -1 +0,0 @@ -export const parameters = {} \ No newline at end of file diff --git a/code/vitest.config.ts b/code/vitest.config.ts index b848d9cc58bb..cabfb4e8b0ce 100644 --- a/code/vitest.config.ts +++ b/code/vitest.config.ts @@ -2,7 +2,6 @@ import { coverageConfigDefaults, defineConfig } from 'vitest/config'; export default defineConfig({ test: { - include: ["code/core/src/csf-tools/ConfigFile.test.ts"], coverage: { all: false, provider: 'istanbul', From 4b3fc7b532a2c85cdb1ba7f7b06c6b098d29a385 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Wed, 16 Oct 2024 00:17:30 +0800 Subject: [PATCH 6/7] Fix linting --- code/core/src/csf-tools/ConfigFile.test.ts | 21 +++++++-------------- code/core/src/csf-tools/ConfigFile.ts | 5 ++--- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/code/core/src/csf-tools/ConfigFile.test.ts b/code/core/src/csf-tools/ConfigFile.test.ts index 44c6d09c6814..e3409d5eb681 100644 --- a/code/core/src/csf-tools/ConfigFile.test.ts +++ b/code/core/src/csf-tools/ConfigFile.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ import { describe, expect, it } from 'vitest'; import { babelPrint } from '@storybook/core/babel'; @@ -1080,7 +1081,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setImport('path', 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1099,7 +1099,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setImport('path', 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1118,7 +1117,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setImport(['dirname'], 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1139,7 +1137,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setImport(['dirname'], 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1161,7 +1158,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setRequireImport('path', 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1181,7 +1177,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setRequireImport('path', 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1200,7 +1195,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setRequireImport(['dirname'], 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1224,7 +1218,6 @@ describe('ConfigFile', () => { const config = loadConfig(source).parse(); config.setRequireImport(['dirname', 'basename'], 'path'); - // eslint-disable-next-line no-underscore-dangle const parsed = babelPrint(config._ast); expect(parsed).toMatchInlineSnapshot(` @@ -1311,7 +1304,7 @@ describe('ConfigFile', () => { describe('parse', () => { it("export { X } with X is import { X } from 'another-file'", () => { - const source = dedent` + const source = dedent` import type { StorybookConfig } from '@storybook/react-webpack5'; import { path } from 'path'; @@ -1329,10 +1322,10 @@ describe('ConfigFile', () => { } export default config; `; - const config = loadConfig(source).parse() + const config = loadConfig(source).parse(); - expect(config._exportDecls['path']).toBe(undefined) - expect(config._exports['path']).toBe(undefined) - }) - }) + expect(config._exportDecls['path']).toBe(undefined); + expect(config._exports['path']).toBe(undefined); + }); + }); }); diff --git a/code/core/src/csf-tools/ConfigFile.ts b/code/core/src/csf-tools/ConfigFile.ts index cfc24142d1ef..dc9f973d5ad6 100644 --- a/code/core/src/csf-tools/ConfigFile.ts +++ b/code/core/src/csf-tools/ConfigFile.ts @@ -102,7 +102,7 @@ const _findVarDeclarator = ( ): t.VariableDeclarator | null | undefined => { let declarator: t.VariableDeclarator | null | undefined = null; let declarations: t.VariableDeclarator[] | null = null; - + program.body.find((node: t.Node) => { if (t.isVariableDeclaration(node)) { declarations = node.declarations; @@ -252,11 +252,10 @@ export class ConfigFile { const decl = _findVarDeclarator(localName, parent as t.Program) as any; // decl can be empty in case X from `import { X } from ....` because it is not handled in _findVarDeclarator - if(decl) { + if (decl) { self._exports[exportName] = decl.init; self._exportDecls[exportName] = decl; } - } }); } else { From b769cd73dc8a1bab4c1378e50719129ff771a41c Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Wed, 16 Oct 2024 00:48:14 +0800 Subject: [PATCH 7/7] Fix lint --- code/lib/blocks/src/blocks/Canvas.stories.tsx | 5 +---- code/lib/blocks/src/components/ArgsTable/ArgControl.tsx | 6 +----- code/lib/blocks/src/examples/CanvasParameters.stories.tsx | 5 +---- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/code/lib/blocks/src/blocks/Canvas.stories.tsx b/code/lib/blocks/src/blocks/Canvas.stories.tsx index bdedf650e534..987e28678a71 100644 --- a/code/lib/blocks/src/blocks/Canvas.stories.tsx +++ b/code/lib/blocks/src/blocks/Canvas.stories.tsx @@ -93,10 +93,7 @@ export const PropAdditionalActions: Story = { { title: 'Go to documentation', onClick: () => { - window.open( - 'https://storybook.js.org/docs/essentials/controls#annotation', - '_blank' - ); + window.open('https://storybook.js.org/docs/essentials/controls#annotation', '_blank'); }, }, ], diff --git a/code/lib/blocks/src/components/ArgsTable/ArgControl.tsx b/code/lib/blocks/src/components/ArgsTable/ArgControl.tsx index e90609eb51c2..064a115dd410 100644 --- a/code/lib/blocks/src/components/ArgsTable/ArgControl.tsx +++ b/code/lib/blocks/src/components/ArgsTable/ArgControl.tsx @@ -71,11 +71,7 @@ export const ArgControl: FC = ({ row, arg, updateArgs, isHovere if (!control || control.disable) { const canBeSetup = control?.disable !== true && row?.type?.name !== 'function'; return isHovered && canBeSetup ? ( - + Setup controls ) : ( diff --git a/code/lib/blocks/src/examples/CanvasParameters.stories.tsx b/code/lib/blocks/src/examples/CanvasParameters.stories.tsx index 6f0c3cb3484c..4d4433747494 100644 --- a/code/lib/blocks/src/examples/CanvasParameters.stories.tsx +++ b/code/lib/blocks/src/examples/CanvasParameters.stories.tsx @@ -30,10 +30,7 @@ export const AdditionalActions: Story = { { title: 'Go to documentation', onClick: () => { - window.open( - 'https://storybook.js.org/docs/essentials/controls#annotation', - '_blank' - ); + window.open('https://storybook.js.org/docs/essentials/controls#annotation', '_blank'); }, }, ],