From 3a3542860940c25e88c08e8975d0532a7d10dc88 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 2 Apr 2024 11:48:29 +0200 Subject: [PATCH 01/42] Implement draft version of the file search --- code/addons/controls/package.json | 8 +++ code/addons/controls/preset.js | 1 + code/addons/controls/src/constants.ts | 2 + code/addons/controls/src/preset.ts | 38 ++++++++++++ .../src/utils/__tests__/src/common.js | 0 .../src/utils/__tests__/src/esmodule.js | 0 .../src/utils/__tests__/src/ignored.js | 0 code/addons/controls/src/utils/filesearch.ts | 58 +++++++++++++++++++ code/addons/controls/src/utils/parser.ts | 23 ++++++++ .../addons/controls/src/utils/parser/react.ts | 36 ++++++++++++ code/yarn.lock | 47 ++++++++++++++- 11 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 code/addons/controls/preset.js create mode 100644 code/addons/controls/src/preset.ts create mode 100644 code/addons/controls/src/utils/__tests__/src/common.js create mode 100644 code/addons/controls/src/utils/__tests__/src/esmodule.js create mode 100644 code/addons/controls/src/utils/__tests__/src/ignored.js create mode 100644 code/addons/controls/src/utils/filesearch.ts create mode 100644 code/addons/controls/src/utils/parser.ts create mode 100644 code/addons/controls/src/utils/parser/react.ts diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index d13ea6560843..e7f1a604bffa 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -33,6 +33,7 @@ "import": "./dist/index.mjs" }, "./manager": "./dist/manager.js", + "./preset": "./dist/preset.js", "./register": "./dist/manager.js", "./package.json": "./package.json" }, @@ -52,6 +53,10 @@ }, "dependencies": { "@storybook/blocks": "workspace:*", + "cjs-module-lexer": "^1.2.3", + "es-module-lexer": "^1.5.0", + "glob": "^10.3.12", + "globby": "^14.0.1", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" }, @@ -71,6 +76,9 @@ "access": "public" }, "bundler": { + "nodeEntries": [ + "./src/preset.ts" + ], "exportEntries": [ "./src/index.ts" ], diff --git a/code/addons/controls/preset.js b/code/addons/controls/preset.js new file mode 100644 index 000000000000..a83f95279e7f --- /dev/null +++ b/code/addons/controls/preset.js @@ -0,0 +1 @@ +module.exports = require('./dist/preset'); diff --git a/code/addons/controls/src/constants.ts b/code/addons/controls/src/constants.ts index a2360dfff87c..fc0f91e21ec8 100644 --- a/code/addons/controls/src/constants.ts +++ b/code/addons/controls/src/constants.ts @@ -1,2 +1,4 @@ export const ADDON_ID = 'addon-controls' as const; export const PARAM_KEY = 'controls' as const; +export const FILE_COMPONENT_SEARCH = 'file-component-search' as const; +export const FILE_COMPONENT_SEARCH_RESULT = 'file-component-search-result' as const; diff --git a/code/addons/controls/src/preset.ts b/code/addons/controls/src/preset.ts new file mode 100644 index 000000000000..84f39990cb1f --- /dev/null +++ b/code/addons/controls/src/preset.ts @@ -0,0 +1,38 @@ +import type { Options } from '@storybook/types'; +import type { Channel } from '@storybook/channels'; +import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from './constants'; + +enum ErrorCode {} + +interface Data { + // A regular string or a glob pattern + searchQuery: string; +} + +interface SearchResult { + success: true | false; + files: Array<{ + // The filepath relative to the project root + filepath: string; + // The search query - Helps to identify the event on the frontend + searchQuery: string; + // A list of exported components + exportedComponents: Array<{ + // the name of the exported component + name: string; + // True, if the exported component is a default export + default: boolean; + }>; + }>; + error: null | ErrorCode; +} + +// eslint-disable-next-line @typescript-eslint/naming-convention +export const experimental_serverChannel = async (channel: Channel, options: Options) => { + channel.on(FILE_COMPONENT_SEARCH, async (data: Data) => { + // Emit an event using the search results + channel.emit(FILE_COMPONENT_SEARCH_RESULT, { result: {} as SearchResult }); + }); + + return channel; +}; diff --git a/code/addons/controls/src/utils/__tests__/src/common.js b/code/addons/controls/src/utils/__tests__/src/common.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/__tests__/src/esmodule.js b/code/addons/controls/src/utils/__tests__/src/esmodule.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/__tests__/src/ignored.js b/code/addons/controls/src/utils/__tests__/src/ignored.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts new file mode 100644 index 000000000000..f115ade901b1 --- /dev/null +++ b/code/addons/controls/src/utils/filesearch.ts @@ -0,0 +1,58 @@ +import { globby } from 'globby'; +import type { SupportedRenderer } from './parser'; +import { getParser } from './parser'; + +export interface Data { + searchQuery: string; +} + +export interface SearchResult { + success: boolean; + files: null | Array<{ + filepath: string; + searchQuery: string; + exportedComponents: Array<{ + name: string; + default: boolean; + }>; + }>; + error: null | string; +} + +export async function searchFiles( + data: Data, + cwd: string, + renderer: SupportedRenderer +): Promise { + try { + const entries = await globby(data.searchQuery, { + ignore: ['**/node_modules/**'], + gitignore: true, + cwd, + objectMode: true, + }); + + const files = entries.map(async (entry) => { + const parser = getParser(renderer); + const info = await parser.parse(entry.path); + + return { + filepath: entry.path, + searchQuery: data.searchQuery, + exportedComponents: info.exports, + }; + }); + + return { + success: true, + files: await Promise.all(files), + error: null, + }; + } catch (e) { + return { + success: false, + files: null, + error: 'An error occurred while searching for files', + }; + } +} diff --git a/code/addons/controls/src/utils/parser.ts b/code/addons/controls/src/utils/parser.ts new file mode 100644 index 000000000000..e6e82ff521db --- /dev/null +++ b/code/addons/controls/src/utils/parser.ts @@ -0,0 +1,23 @@ +import { ReactParser } from './parser/react'; + +export type SupportedRenderer = 'react'; + +export type ParserResult = { + exports: Array<{ + name: string; + default: boolean; + }>; +}; + +export interface Parser { + parse: (content: string) => Promise; +} + +export function getParser(renderer: SupportedRenderer): Parser { + switch (renderer) { + case 'react': + return new ReactParser(); + default: + throw new Error(`Unsupported renderer: ${renderer}`); + } +} diff --git a/code/addons/controls/src/utils/parser/react.ts b/code/addons/controls/src/utils/parser/react.ts new file mode 100644 index 000000000000..38b99b8175a0 --- /dev/null +++ b/code/addons/controls/src/utils/parser/react.ts @@ -0,0 +1,36 @@ +import { parse as parseCjs, init as initCjsParser } from 'cjs-module-lexer'; +import { parse as parseEs } from 'es-module-lexer'; + +import type { Parser } from '../parser'; + +export class ReactParser implements Parser { + async parse(source: string) { + try { + // Do NOT remove await here. The types are wrong! It has to be awaited, + // otherwise it will return a Promise> when wasm isn't loaded. + const [, exports] = await parseEs(source); + + return { + exports: (exports ?? []).map((e) => { + const name = source.substring(e.s, e.e); + return { + name, + default: name === 'default', + }; + }), + }; + // Try to parse as CJS module + } catch { + await initCjsParser(); + + const exports = (parseCjs(source).exports ?? []).filter((e: string) => e !== '__esModule'); + + return { + exports: (exports ?? []).map((name) => ({ + name, + default: name === 'default', + })), + }; + } + } +} diff --git a/code/yarn.lock b/code/yarn.lock index 472dd503b241..9fd0e6014754 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -4796,6 +4796,10 @@ __metadata: "@storybook/preview-api": "workspace:*" "@storybook/theming": "workspace:*" "@storybook/types": "workspace:*" + cjs-module-lexer: "npm:^1.2.3" + es-module-lexer: "npm:^1.5.0" + glob: "npm:^10.3.12" + globby: "npm:^14.0.1" lodash: "npm:^4.17.21" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" @@ -13631,6 +13635,13 @@ __metadata: languageName: node linkType: hard +"es-module-lexer@npm:^1.5.0": + version: 1.5.0 + resolution: "es-module-lexer@npm:1.5.0" + checksum: 10c0/d199853404f3381801eb102befb84a8fc48f93ed86b852c2461c2c4ad4bbbc91128f3d974ff9b8718628260ae3f36e661295ab3e419222868aa31269284e34c9 + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.2": version: 2.0.3 resolution: "es-set-tostringtag@npm:2.0.3" @@ -15839,6 +15850,21 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.3.12": + version: 10.3.12 + resolution: "glob@npm:10.3.12" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.3.6" + minimatch: "npm:^9.0.1" + minipass: "npm:^7.0.4" + path-scurry: "npm:^1.10.2" + bin: + glob: dist/esm/bin.mjs + checksum: 10c0/f60cefdc1cf3f958b2bb5823e1b233727f04916d489dc4641d76914f016e6704421e06a83cbb68b0cb1cb9382298b7a88075b844ad2127fc9727ea22b18b0711 + languageName: node + linkType: hard + "glob@npm:^5.0.10": version: 5.0.15 resolution: "glob@npm:5.0.15" @@ -17857,7 +17883,7 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5": +"jackspeak@npm:^2.3.5, jackspeak@npm:^2.3.6": version: 2.3.6 resolution: "jackspeak@npm:2.3.6" dependencies: @@ -19030,6 +19056,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^10.2.0": + version: 10.2.0 + resolution: "lru-cache@npm:10.2.0" + checksum: 10c0/c9847612aa2daaef102d30542a8d6d9b2c2bb36581c1bf0dc3ebf5e5f3352c772a749e604afae2e46873b930a9e9523743faac4e5b937c576ab29196774712ee + languageName: node + linkType: hard + "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -20661,7 +20694,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": version: 7.0.4 resolution: "minipass@npm:7.0.4" checksum: 10c0/6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 @@ -22333,6 +22366,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^1.10.2": + version: 1.10.2 + resolution: "path-scurry@npm:1.10.2" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10c0/d723777fbf9627f201e64656680f66ebd940957eebacf780e6cce1c2919c29c116678b2d7dbf8821b3a2caa758d125f4444005ccec886a25c8f324504e48e601 + languageName: node + linkType: hard + "path-to-regexp@npm:0.1.7": version: 0.1.7 resolution: "path-to-regexp@npm:0.1.7" From 5199da51282f2556b3a40d778f531c2d03f6da11 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 2 Apr 2024 11:56:32 +0200 Subject: [PATCH 02/42] Add test files --- code/addons/controls/src/utils/__tests__/.gitignore | 2 ++ code/addons/controls/src/utils/__tests__/src/common.js | 0 .../controls/src/utils/__tests__/src/commonjs-default.js | 3 +++ code/addons/controls/src/utils/__tests__/src/commonjs.js | 6 ++++++ code/addons/controls/src/utils/__tests__/src/esmodule.js | 5 +++++ .../src/utils/__tests__/src/node_modules/file-in-common.js | 3 +++ code/addons/controls/src/utils/parser.ts | 6 ++---- .../controls/src/utils/parser/{react.ts => common.ts} | 2 +- 8 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 code/addons/controls/src/utils/__tests__/.gitignore delete mode 100644 code/addons/controls/src/utils/__tests__/src/common.js create mode 100644 code/addons/controls/src/utils/__tests__/src/commonjs-default.js create mode 100644 code/addons/controls/src/utils/__tests__/src/commonjs.js create mode 100644 code/addons/controls/src/utils/__tests__/src/node_modules/file-in-common.js rename code/addons/controls/src/utils/parser/{react.ts => common.ts} (95%) diff --git a/code/addons/controls/src/utils/__tests__/.gitignore b/code/addons/controls/src/utils/__tests__/.gitignore new file mode 100644 index 000000000000..95ef72e99f83 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/.gitignore @@ -0,0 +1,2 @@ +src/ignored.js +!node_modules \ No newline at end of file diff --git a/code/addons/controls/src/utils/__tests__/src/common.js b/code/addons/controls/src/utils/__tests__/src/common.js deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs-default.js b/code/addons/controls/src/utils/__tests__/src/commonjs-default.js new file mode 100644 index 000000000000..363ddea237f1 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/commonjs-default.js @@ -0,0 +1,3 @@ +module.exports = () => { + return 'commonjs-default'; +}; diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs.js b/code/addons/controls/src/utils/__tests__/src/commonjs.js new file mode 100644 index 000000000000..cfceeb00b1e3 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/commonjs.js @@ -0,0 +1,6 @@ +const Component1 = ''; + +module.exports = { + Component2: '', + Component1, +}; diff --git a/code/addons/controls/src/utils/__tests__/src/esmodule.js b/code/addons/controls/src/utils/__tests__/src/esmodule.js index e69de29bb2d1..a3ed90231391 100644 --- a/code/addons/controls/src/utils/__tests__/src/esmodule.js +++ b/code/addons/controls/src/utils/__tests__/src/esmodule.js @@ -0,0 +1,5 @@ +const Component1 = ''; + +export const Component2 = ''; + +export default Component1; diff --git a/code/addons/controls/src/utils/__tests__/src/node_modules/file-in-common.js b/code/addons/controls/src/utils/__tests__/src/node_modules/file-in-common.js new file mode 100644 index 000000000000..1626d1e76d96 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/node_modules/file-in-common.js @@ -0,0 +1,3 @@ +export default () => { + return 'commonjs-default'; +} \ No newline at end of file diff --git a/code/addons/controls/src/utils/parser.ts b/code/addons/controls/src/utils/parser.ts index e6e82ff521db..4f29aac3af7c 100644 --- a/code/addons/controls/src/utils/parser.ts +++ b/code/addons/controls/src/utils/parser.ts @@ -1,4 +1,4 @@ -import { ReactParser } from './parser/react'; +import { CommonParser } from './parser/common'; export type SupportedRenderer = 'react'; @@ -15,9 +15,7 @@ export interface Parser { export function getParser(renderer: SupportedRenderer): Parser { switch (renderer) { - case 'react': - return new ReactParser(); default: - throw new Error(`Unsupported renderer: ${renderer}`); + return new CommonParser(); } } diff --git a/code/addons/controls/src/utils/parser/react.ts b/code/addons/controls/src/utils/parser/common.ts similarity index 95% rename from code/addons/controls/src/utils/parser/react.ts rename to code/addons/controls/src/utils/parser/common.ts index 38b99b8175a0..7bc8e891595f 100644 --- a/code/addons/controls/src/utils/parser/react.ts +++ b/code/addons/controls/src/utils/parser/common.ts @@ -3,7 +3,7 @@ import { parse as parseEs } from 'es-module-lexer'; import type { Parser } from '../parser'; -export class ReactParser implements Parser { +export class CommonParser implements Parser { async parse(source: string) { try { // Do NOT remove await here. The types are wrong! It has to be awaited, From df6e16c514da269ef181bb98b24b9e3d455dd2f0 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 2 Apr 2024 11:56:59 +0200 Subject: [PATCH 03/42] Remove node_modules from gitignore --- code/addons/controls/src/utils/__tests__/.gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/addons/controls/src/utils/__tests__/.gitignore b/code/addons/controls/src/utils/__tests__/.gitignore index 95ef72e99f83..7e4e8f40e4f1 100644 --- a/code/addons/controls/src/utils/__tests__/.gitignore +++ b/code/addons/controls/src/utils/__tests__/.gitignore @@ -1,2 +1 @@ -src/ignored.js -!node_modules \ No newline at end of file +src/ignored.js \ No newline at end of file From d0a68b229ab5f32453d85fa2f79eb83e67d5c2ce Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 13:51:02 +0200 Subject: [PATCH 04/42] Add normalize-path helper util --- .../core-common/src/utils/normalize-path.test.ts | 10 ++++++++++ code/lib/core-common/src/utils/normalize-path.ts | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 code/lib/core-common/src/utils/normalize-path.test.ts create mode 100644 code/lib/core-common/src/utils/normalize-path.ts diff --git a/code/lib/core-common/src/utils/normalize-path.test.ts b/code/lib/core-common/src/utils/normalize-path.test.ts new file mode 100644 index 000000000000..5c10c487d5af --- /dev/null +++ b/code/lib/core-common/src/utils/normalize-path.test.ts @@ -0,0 +1,10 @@ +import { normalizePath } from './normalize-path'; +import { describe, expect, it } from 'vitest'; + +describe('normalize-path', () => { + it('should normalize paths', () => { + expect(normalizePath('path/to/../file')).toBe('path/file'); + expect(normalizePath('path/to/./file')).toBe('path/to/file'); + expect(normalizePath('path\\to\\file')).toBe('path/to/file'); + }); +}); diff --git a/code/lib/core-common/src/utils/normalize-path.ts b/code/lib/core-common/src/utils/normalize-path.ts new file mode 100644 index 000000000000..7407ace285ca --- /dev/null +++ b/code/lib/core-common/src/utils/normalize-path.ts @@ -0,0 +1,14 @@ +import path from 'path'; + +/** + * Normalize a path to use forward slashes and remove .. and . + * @param p The path to normalize + * @returns The normalized path + * @example + * normalizePath('path/to/../file') // => 'path/file' + * normalizePath('path/to/./file') // => 'path/to/file' + * normalizePath('path\\to\\file') // => 'path/to/file' + */ +export function normalizePath(p: string) { + return path.normalize(p).replace(/\\/g, '/'); +} From abeaac68a347b13f0add9f4c08e9c304a2323898 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 13:51:38 +0200 Subject: [PATCH 05/42] Adjust test files in controls --- .../utils/__tests__/src/commonjs-default.js | 4 +--- .../src/utils/__tests__/src/commonjs.js | 23 +++++++++++++++---- .../src/utils/__tests__/src/esmodule.js | 15 +++++++++--- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs-default.js b/code/addons/controls/src/utils/__tests__/src/commonjs-default.js index 363ddea237f1..aed903ea7003 100644 --- a/code/addons/controls/src/utils/__tests__/src/commonjs-default.js +++ b/code/addons/controls/src/utils/__tests__/src/commonjs-default.js @@ -1,3 +1 @@ -module.exports = () => { - return 'commonjs-default'; -}; +module.exports = require('./commonjs'); diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs.js b/code/addons/controls/src/utils/__tests__/src/commonjs.js index cfceeb00b1e3..7146ed966336 100644 --- a/code/addons/controls/src/utils/__tests__/src/commonjs.js +++ b/code/addons/controls/src/utils/__tests__/src/commonjs.js @@ -1,6 +1,19 @@ -const Component1 = ''; +// named exports detection +module.exports.a = 'a'; -module.exports = { - Component2: '', - Component1, -}; +(function () { + exports.b = 'b'; +})(); + +Object.defineProperty(exports, 'c', { value: 'c' }); +/* exports.d = 'not detected'; */ + +// reexports detection +if (maybe) module.exports = require('./dep1.js'); +if (another) module.exports = require('./dep2.js'); + +// literal exports assignments +module.exports = { a, b: c, d, e: f }; + +// __esModule detection +Object.defineProperty(module.exports, '__esModule', { value: true }); diff --git a/code/addons/controls/src/utils/__tests__/src/esmodule.js b/code/addons/controls/src/utils/__tests__/src/esmodule.js index a3ed90231391..e4785feb4fd1 100644 --- a/code/addons/controls/src/utils/__tests__/src/esmodule.js +++ b/code/addons/controls/src/utils/__tests__/src/esmodule.js @@ -1,5 +1,14 @@ -const Component1 = ''; +/* eslint-disable import/no-unresolved */ +import * as ns from 'external2'; -export const Component2 = ''; +export var p = 5; -export default Component1; +export function q() {} + +export { x as externalName } from 'external'; + +export { ns }; + +export default function () { + return 'default'; +} From f0eec0a77575cf16ca45ee12da88bc143c607ac1 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 13:52:04 +0200 Subject: [PATCH 06/42] Finalized filesearch in controls --- .../controls/src/utils/filesearch.test.ts | 37 ++++++++ code/addons/controls/src/utils/filesearch.ts | 89 ++++++++++--------- 2 files changed, 83 insertions(+), 43 deletions(-) create mode 100644 code/addons/controls/src/utils/filesearch.test.ts diff --git a/code/addons/controls/src/utils/filesearch.test.ts b/code/addons/controls/src/utils/filesearch.test.ts new file mode 100644 index 000000000000..7291edd137ca --- /dev/null +++ b/code/addons/controls/src/utils/filesearch.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, it } from 'vitest'; +import path from 'path'; +import { searchFiles } from './filesearch'; + +describe('filesearch', () => { + describe('search result', () => { + it('should automatically convert normal search to a glob search', async (t) => { + const files = await searchFiles('commonjs', path.join(__dirname, '__tests__'), 'react'); + + expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-default.js', 'src/commonjs.js']); + }); + + it('should work with glob search patterns', async (t) => { + const files = await searchFiles('**/commonjs.js', path.join(__dirname, '__tests__'), 'react'); + + expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs.js']); + }); + + it('should ignore node_modules', async (t) => { + const files = await searchFiles( + 'file-in-common.js', + path.join(__dirname, '__tests__'), + 'react' + ); + + expect(files).toEqual([]); + }); + }); + + describe('exported components', () => { + it('should correctly return the exported components', async (t) => { + const files = await searchFiles('commonjs.js', path.join(__dirname, '__tests__'), 'react'); + + expect(files?.flatMap((f) => f.exportedComponents)).toHaveLength(5); + }); + }); +}); diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index f115ade901b1..45ba992ed8f6 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -1,58 +1,61 @@ import { globby } from 'globby'; -import type { SupportedRenderer } from './parser'; -import { getParser } from './parser'; +import path from 'path'; +import fs from 'fs'; -export interface Data { - searchQuery: string; -} +import type { SupportedRenderer } from './parser/types'; +import { getParser } from './parser'; +import { isNotNull } from './ts-utils'; -export interface SearchResult { - success: boolean; - files: null | Array<{ - filepath: string; - searchQuery: string; - exportedComponents: Array<{ - name: string; - default: boolean; - }>; +export type SearchResult = Array<{ + filepath: string; + exportedComponents: Array<{ + name: string; + default: boolean; }>; - error: null | string; -} +}>; + +/** + * Characters that are used in glob patterns to identify search queries that are not just filenames + */ +const globPatternChars = ['*', '+(', '@(', '?(', '!(', '[', ']']; +/** + * Search for files in a directory that match the search query + * @param searchQuery The search query. This can be a glob pattern + * @param cwd The directory to search in + * @param renderer The renderer to use for parsing the files + * @returns A list of files that match the search query and has exports + */ export async function searchFiles( - data: Data, + searchQuery: string, cwd: string, renderer: SupportedRenderer ): Promise { - try { - const entries = await globby(data.searchQuery, { - ignore: ['**/node_modules/**'], - gitignore: true, - cwd, - objectMode: true, - }); - - const files = entries.map(async (entry) => { - const parser = getParser(renderer); - const info = await parser.parse(entry.path); + const hasGlobChars = globPatternChars.some((char) => searchQuery.includes(char)); + + const globbedSearchQuery = hasGlobChars ? searchQuery : `**/${searchQuery}**`; + + const entries = await globby(globbedSearchQuery, { + ignore: ['**/node_modules/**'], + gitignore: true, + cwd, + objectMode: true, + }); + + const files = entries.map(async (entry) => { + const parser = getParser(renderer); + const content = fs.readFileSync(path.join(cwd, entry.path), 'utf-8'); + + try { + const info = await parser.parse(content); return { filepath: entry.path, - searchQuery: data.searchQuery, exportedComponents: info.exports, }; - }); - - return { - success: true, - files: await Promise.all(files), - error: null, - }; - } catch (e) { - return { - success: false, - files: null, - error: 'An error occurred while searching for files', - }; - } + } catch (e) { + return null; + } + }); + return (await Promise.all(files)).filter(isNotNull); } From b696c7827692d78fac298f23d77b920780a8999d Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 13:52:45 +0200 Subject: [PATCH 07/42] Finalized parser API --- code/addons/controls/src/utils/parser.ts | 21 ------ .../controls/src/utils/parser/common.ts | 36 ---------- .../src/utils/parser/generic-parser.test.ts | 66 +++++++++++++++++++ .../src/utils/parser/generic-parser.ts | 56 ++++++++++++++++ .../addons/controls/src/utils/parser/index.ts | 14 ++++ .../addons/controls/src/utils/parser/types.ts | 20 ++++++ 6 files changed, 156 insertions(+), 57 deletions(-) delete mode 100644 code/addons/controls/src/utils/parser.ts delete mode 100644 code/addons/controls/src/utils/parser/common.ts create mode 100644 code/addons/controls/src/utils/parser/generic-parser.test.ts create mode 100644 code/addons/controls/src/utils/parser/generic-parser.ts create mode 100644 code/addons/controls/src/utils/parser/index.ts create mode 100644 code/addons/controls/src/utils/parser/types.ts diff --git a/code/addons/controls/src/utils/parser.ts b/code/addons/controls/src/utils/parser.ts deleted file mode 100644 index 4f29aac3af7c..000000000000 --- a/code/addons/controls/src/utils/parser.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { CommonParser } from './parser/common'; - -export type SupportedRenderer = 'react'; - -export type ParserResult = { - exports: Array<{ - name: string; - default: boolean; - }>; -}; - -export interface Parser { - parse: (content: string) => Promise; -} - -export function getParser(renderer: SupportedRenderer): Parser { - switch (renderer) { - default: - return new CommonParser(); - } -} diff --git a/code/addons/controls/src/utils/parser/common.ts b/code/addons/controls/src/utils/parser/common.ts deleted file mode 100644 index 7bc8e891595f..000000000000 --- a/code/addons/controls/src/utils/parser/common.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { parse as parseCjs, init as initCjsParser } from 'cjs-module-lexer'; -import { parse as parseEs } from 'es-module-lexer'; - -import type { Parser } from '../parser'; - -export class CommonParser implements Parser { - async parse(source: string) { - try { - // Do NOT remove await here. The types are wrong! It has to be awaited, - // otherwise it will return a Promise> when wasm isn't loaded. - const [, exports] = await parseEs(source); - - return { - exports: (exports ?? []).map((e) => { - const name = source.substring(e.s, e.e); - return { - name, - default: name === 'default', - }; - }), - }; - // Try to parse as CJS module - } catch { - await initCjsParser(); - - const exports = (parseCjs(source).exports ?? []).filter((e: string) => e !== '__esModule'); - - return { - exports: (exports ?? []).map((name) => ({ - name, - default: name === 'default', - })), - }; - } - } -} diff --git a/code/addons/controls/src/utils/parser/generic-parser.test.ts b/code/addons/controls/src/utils/parser/generic-parser.test.ts new file mode 100644 index 000000000000..9f9e98391e16 --- /dev/null +++ b/code/addons/controls/src/utils/parser/generic-parser.test.ts @@ -0,0 +1,66 @@ +import { describe, expect, it } from 'vitest'; +import path from 'path'; +import { GenericParser } from './generic-parser'; +import fs from 'fs'; + +const genericParser = new GenericParser(); + +const TEST_DIR = path.join(__dirname, '..', '__tests__'); + +describe('generic-parser', () => { + it('should correctly return exports from CommonJS files', async () => { + const content = fs.readFileSync(path.join(TEST_DIR, 'src', 'commonjs.js'), 'utf-8'); + const { exports } = await genericParser.parse(content); + + expect(exports).toEqual([ + { + default: false, + name: 'a', + }, + { + default: false, + name: 'b', + }, + { + default: false, + name: 'c', + }, + { + default: false, + name: 'd', + }, + { + default: false, + name: 'e', + }, + ]); + }); + + it('should correctly return exports from ES modules', async () => { + const content = fs.readFileSync(path.join(TEST_DIR, 'src', 'esmodule.js'), 'utf-8'); + const { exports } = await genericParser.parse(content); + + expect(exports).toEqual([ + { + default: false, + name: 'p', + }, + { + default: false, + name: 'q', + }, + { + default: false, + name: 'externalName', + }, + { + default: false, + name: 'ns', + }, + { + default: true, + name: 'default', + }, + ]); + }); +}); diff --git a/code/addons/controls/src/utils/parser/generic-parser.ts b/code/addons/controls/src/utils/parser/generic-parser.ts new file mode 100644 index 000000000000..30562128eb1d --- /dev/null +++ b/code/addons/controls/src/utils/parser/generic-parser.ts @@ -0,0 +1,56 @@ +import { parse as parseCjs, init as initCjsParser } from 'cjs-module-lexer'; +import { parse as parseEs } from 'es-module-lexer'; +import assert from 'node:assert'; + +import type { Parser } from './types'; + +/** + * A generic parser that can parse both ES and CJS modules. + */ +export class GenericParser implements Parser { + /** + * Parse the content of a file and return the exports + * @param content The content of the file + * @returns The exports of the file + */ + async parse(content: string) { + try { + // Do NOT remove await here. The types are wrong! It has to be awaited, + // otherwise it will return a Promise> when wasm isn't loaded. + const [, exports] = await parseEs(content); + + assert( + exports.length > 0, + 'No named exports found. Very likely that this is not a ES module.' + ); + + return { + exports: (exports ?? []).map((e) => { + const name = content.substring(e.s, e.e); + return { + name, + default: name === 'default', + }; + }), + }; + // Try to parse as CJS module + } catch { + await initCjsParser(); + + const { exports, reexports } = parseCjs(content); + const filteredExports = [...exports, ...reexports].filter((e: string) => e !== '__esModule'); + + assert( + filteredExports.length > 0, + 'No named exports found. Very likely that this is not a CJS module.' + ); + + return { + exports: (filteredExports ?? []).map((name) => ({ + name, + default: name === 'default', + })), + }; + } + } +} diff --git a/code/addons/controls/src/utils/parser/index.ts b/code/addons/controls/src/utils/parser/index.ts new file mode 100644 index 000000000000..1d17272bb13d --- /dev/null +++ b/code/addons/controls/src/utils/parser/index.ts @@ -0,0 +1,14 @@ +import { GenericParser } from './generic-parser'; +import type { Parser, SupportedRenderer } from './types'; + +/** + * Get the parser for a given renderer + * @param renderer The renderer to get the parser for + * @returns The parser for the renderer + */ +export function getParser(renderer: SupportedRenderer): Parser { + switch (renderer) { + default: + return new GenericParser(); + } +} diff --git a/code/addons/controls/src/utils/parser/types.ts b/code/addons/controls/src/utils/parser/types.ts new file mode 100644 index 000000000000..47529b441825 --- /dev/null +++ b/code/addons/controls/src/utils/parser/types.ts @@ -0,0 +1,20 @@ +export type SupportedRenderer = 'react'; + +export type ParserResult = { + exports: Array<{ + name: string; + default: boolean; + }>; +}; + +/** + * A parser that can parse the exports of a file + */ +export interface Parser { + /** + * Parse the content of a file and return the exports + * @param content The content of the file + * @returns The result of the parsing. Contains the exports of the file + */ + parse: (content: string) => Promise; +} From 4aaa5b6c46d269490316279e1021770824a86b8a Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 13:52:56 +0200 Subject: [PATCH 08/42] Add isNotNull function to ts-utils.ts --- code/addons/controls/src/utils/ts-utils.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 code/addons/controls/src/utils/ts-utils.ts diff --git a/code/addons/controls/src/utils/ts-utils.ts b/code/addons/controls/src/utils/ts-utils.ts new file mode 100644 index 000000000000..e3d720f8e17c --- /dev/null +++ b/code/addons/controls/src/utils/ts-utils.ts @@ -0,0 +1,8 @@ +/** + * Check if a value is not null. This is a type guard for TypeScript usually used in conjunction with array filter. + * @param value - The value to check + * @returns Whether the value is not null + */ +export function isNotNull(value: T | null): value is T { + return value !== null; +} From 48f0f3b0e982fbc3f7761c3acd887d61c8d6f661 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 13:55:29 +0200 Subject: [PATCH 09/42] API Doc: Add fallback for renderer name if not set --- code/lib/core-common/src/utils/get-renderer-name.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/code/lib/core-common/src/utils/get-renderer-name.ts b/code/lib/core-common/src/utils/get-renderer-name.ts index ce4a14891086..3127e5db1204 100644 --- a/code/lib/core-common/src/utils/get-renderer-name.ts +++ b/code/lib/core-common/src/utils/get-renderer-name.ts @@ -3,6 +3,7 @@ import { getFrameworkName } from './get-framework-name'; /** * Render is set as a string on core. It must be set by the framework + * It falls back to the framework name if not set */ export async function getRendererName(options: Options) { const core = await options.presets.apply('core', {}, options); From efec0b54c40b48ac2532ce7228514a226a501611 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 13:56:08 +0200 Subject: [PATCH 10/42] Extract util to extract proper framework name --- .../src/automigrate/helpers/mainConfigFile.ts | 7 ++----- .../src/utils/get-framework-name.test.ts | 18 ++++++++++++++++++ .../src/utils/get-framework-name.ts | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 code/lib/core-common/src/utils/get-framework-name.test.ts diff --git a/code/lib/cli/src/automigrate/helpers/mainConfigFile.ts b/code/lib/cli/src/automigrate/helpers/mainConfigFile.ts index 3fd56fc8107b..11a13c127e0e 100644 --- a/code/lib/cli/src/automigrate/helpers/mainConfigFile.ts +++ b/code/lib/cli/src/automigrate/helpers/mainConfigFile.ts @@ -4,6 +4,7 @@ import { rendererPackages, frameworkPackages, builderPackages, + extractProperFrameworkName, } from '@storybook/core-common'; import type { StorybookConfigRaw, StorybookConfig } from '@storybook/types'; import type { ConfigFile } from '@storybook/csf-tools'; @@ -30,11 +31,7 @@ export const getFrameworkPackageName = (mainConfig?: StorybookConfigRaw) => { return null; } - const normalizedPath = path.normalize(packageNameOrPath).replace(new RegExp(/\\/, 'g'), '/'); - - return ( - Object.keys(frameworkPackages).find((pkg) => normalizedPath.endsWith(pkg)) || packageNameOrPath - ); + return extractProperFrameworkName(packageNameOrPath); }; /** diff --git a/code/lib/core-common/src/utils/get-framework-name.test.ts b/code/lib/core-common/src/utils/get-framework-name.test.ts new file mode 100644 index 000000000000..9f6a95ba19e7 --- /dev/null +++ b/code/lib/core-common/src/utils/get-framework-name.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from 'vitest'; +import { extractProperFrameworkName } from './get-framework-name'; + +describe('get-framework-name', () => { + describe('extractProperFrameworkName', () => { + it('should extract the proper framework name from the given framework field', () => { + expect(extractProperFrameworkName('@storybook/angular')).toBe('@storybook/angular'); + expect(extractProperFrameworkName('/path/to/@storybook/angular')).toBe('@storybook/angular'); + expect(extractProperFrameworkName('\\path\\to\\@storybook\\angular')).toBe( + '@storybook/angular' + ); + }); + + it('should return the given framework name if it is a third-party framework', () => { + expect(extractProperFrameworkName('@third-party/framework')).toBe('@third-party/framework'); + }); + }); +}); diff --git a/code/lib/core-common/src/utils/get-framework-name.ts b/code/lib/core-common/src/utils/get-framework-name.ts index e7191545b5a4..fcfef2efee42 100644 --- a/code/lib/core-common/src/utils/get-framework-name.ts +++ b/code/lib/core-common/src/utils/get-framework-name.ts @@ -1,5 +1,7 @@ import { dedent } from 'ts-dedent'; import type { Options } from '@storybook/types'; +import { frameworkPackages } from './get-storybook-info'; +import { normalizePath } from './normalize-path'; /** * Framework can be a string or an object. This utility always returns the string name. @@ -17,3 +19,17 @@ export async function getFrameworkName(options: Options) { return typeof framework === 'object' ? framework.name : framework; } + +/** + * Extracts the proper framework name from the given framework field. + * The framework field can be the framework package name or a path to the framework package. + * @example + * extractProperFrameworkName('/path/to/@storybook/angular') // => '@storybook/angular' + * extractProperFrameworkName('@third-party/framework') // => '@third-party/framework' + */ +export const extractProperFrameworkName = (framework: string) => { + const normalizedPath = normalizePath(framework); + const frameworkName = Object.keys(frameworkPackages).find((pkg) => normalizedPath.endsWith(pkg)); + + return frameworkName ?? framework; +}; From 6654fd6d1ddf216940b9521f24c3d6047a312360 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 14:09:11 +0200 Subject: [PATCH 11/42] Extract utils and types into @storybook/core-common and @storybook/types --- code/lib/cli/src/helpers.ts | 50 ++++--------------- code/lib/cli/src/project_types.ts | 23 +++------ code/lib/core-common/src/index.ts | 1 + .../src/utils/framework-to-renderer.ts | 36 +++++++++++++ code/lib/types/src/index.ts | 1 + code/lib/types/src/modules/renderers.ts | 14 ++++++ 6 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 code/lib/core-common/src/utils/framework-to-renderer.ts create mode 100644 code/lib/types/src/modules/renderers.ts diff --git a/code/lib/cli/src/helpers.ts b/code/lib/cli/src/helpers.ts index ab3bf239592c..5c8351cca7b0 100644 --- a/code/lib/cli/src/helpers.ts +++ b/code/lib/cli/src/helpers.ts @@ -8,13 +8,13 @@ import stripJsonComments from 'strip-json-comments'; import findUp from 'find-up'; import invariant from 'tiny-invariant'; import { getCliDir, getRendererDir } from './dirs'; -import type { - JsPackageManager, - PackageJson, - PackageJsonWithDepsAndDevDeps, +import { + type JsPackageManager, + type PackageJson, + type PackageJsonWithDepsAndDevDeps, + frameworkToRenderer as CoreFrameworkToRenderer, } from '@storybook/core-common'; -import type { SupportedFrameworks } from '@storybook/types'; -import type { SupportedRenderers } from './project_types'; +import type { SupportedFrameworks, SupportedRenderers } from '@storybook/types'; import { CoreBuilder } from './project_types'; import { SupportedLanguage } from './project_types'; import { versions as storybookMonorepoPackages } from '@storybook/core-common'; @@ -132,40 +132,10 @@ type CopyTemplateFilesOptions = { destination?: string; }; -export const frameworkToRenderer: Record< - SupportedFrameworks | SupportedRenderers, - SupportedRenderers | 'vue' -> = { - // frameworks - angular: 'angular', - ember: 'ember', - 'html-vite': 'html', - 'html-webpack5': 'html', - nextjs: 'react', - 'preact-vite': 'preact', - 'preact-webpack5': 'preact', - qwik: 'qwik', - 'react-vite': 'react', - 'react-webpack5': 'react', - 'server-webpack5': 'server', - solid: 'solid', - 'svelte-vite': 'svelte', - 'svelte-webpack5': 'svelte', - sveltekit: 'svelte', - 'vue3-vite': 'vue3', - 'vue3-webpack5': 'vue3', - 'web-components-vite': 'web-components', - 'web-components-webpack5': 'web-components', - // renderers - html: 'html', - preact: 'preact', - 'react-native': 'react-native', - react: 'react', - server: 'server', - svelte: 'svelte', - vue3: 'vue3', - 'web-components': 'web-components', -}; +/** + * @deprecated Please use `frameworkToRenderer` from `@storybook/core-common` instead + */ +export const frameworkToRenderer = CoreFrameworkToRenderer; export const frameworkToDefaultBuilder: Record = { angular: CoreBuilder.Webpack5, diff --git a/code/lib/cli/src/project_types.ts b/code/lib/cli/src/project_types.ts index 3a5cda3781ef..f8f6973ab31a 100644 --- a/code/lib/cli/src/project_types.ts +++ b/code/lib/cli/src/project_types.ts @@ -1,5 +1,8 @@ import { minVersion, validRange } from 'semver'; -import type { SupportedFrameworks } from '@storybook/types'; +import type { + SupportedFrameworks, + SupportedRenderers as CoreSupportedFrameworks, +} from '@storybook/types'; function eqMajor(versionRange: string, major: number) { // Uses validRange to avoid a throw from minVersion if an invalid range gets passed @@ -22,20 +25,10 @@ export const externalFrameworks: ExternalFramework[] = [ { name: 'solid', frameworks: ['storybook-solidjs-vite'], renderer: 'storybook-solidjs' }, ]; -// Should match @storybook/ -export type SupportedRenderers = - | 'react' - | 'react-native' - | 'vue3' - | 'angular' - | 'ember' - | 'preact' - | 'svelte' - | 'qwik' - | 'html' - | 'web-components' - | 'server' - | 'solid'; +/** + * @deprecated Please use `SupportedFrameworks` from `@storybook/types` instead + */ +export type SupportedRenderers = CoreSupportedFrameworks; export const SUPPORTED_RENDERERS: SupportedRenderers[] = [ 'react', diff --git a/code/lib/core-common/src/index.ts b/code/lib/core-common/src/index.ts index e8f02195ba9d..a568fa70ba4a 100644 --- a/code/lib/core-common/src/index.ts +++ b/code/lib/core-common/src/index.ts @@ -7,6 +7,7 @@ export * from './utils/cli'; export * from './utils/check-addon-order'; export * from './utils/envs'; export * from './utils/common-glob-options'; +export * from './utils/framework-to-renderer'; export * from './utils/get-builder-options'; export * from './utils/get-framework-name'; export * from './utils/get-renderer-name'; diff --git a/code/lib/core-common/src/utils/framework-to-renderer.ts b/code/lib/core-common/src/utils/framework-to-renderer.ts new file mode 100644 index 000000000000..a7c8532529a1 --- /dev/null +++ b/code/lib/core-common/src/utils/framework-to-renderer.ts @@ -0,0 +1,36 @@ +import type { SupportedFrameworks, SupportedRenderers } from '@storybook/types'; + +export const frameworkToRenderer: Record< + SupportedFrameworks | SupportedRenderers, + SupportedRenderers | 'vue' +> = { + // frameworks + angular: 'angular', + ember: 'ember', + 'html-vite': 'html', + 'html-webpack5': 'html', + nextjs: 'react', + 'preact-vite': 'preact', + 'preact-webpack5': 'preact', + qwik: 'qwik', + 'react-vite': 'react', + 'react-webpack5': 'react', + 'server-webpack5': 'server', + solid: 'solid', + 'svelte-vite': 'svelte', + 'svelte-webpack5': 'svelte', + sveltekit: 'svelte', + 'vue3-vite': 'vue3', + 'vue3-webpack5': 'vue3', + 'web-components-vite': 'web-components', + 'web-components-webpack5': 'web-components', + // renderers + html: 'html', + preact: 'preact', + 'react-native': 'react-native', + react: 'react', + server: 'server', + svelte: 'svelte', + vue3: 'vue3', + 'web-components': 'web-components', +}; diff --git a/code/lib/types/src/index.ts b/code/lib/types/src/index.ts index 21a5f9ea000c..523f2c3c184b 100644 --- a/code/lib/types/src/index.ts +++ b/code/lib/types/src/index.ts @@ -10,3 +10,4 @@ export * from './modules/indexer'; export * from './modules/composedStory'; export * from './modules/channelApi'; export * from './modules/frameworks'; +export * from './modules/renderers'; diff --git a/code/lib/types/src/modules/renderers.ts b/code/lib/types/src/modules/renderers.ts new file mode 100644 index 000000000000..4fcf0be99d87 --- /dev/null +++ b/code/lib/types/src/modules/renderers.ts @@ -0,0 +1,14 @@ +// Should match @storybook/ +export type SupportedRenderers = + | 'react' + | 'react-native' + | 'vue3' + | 'angular' + | 'ember' + | 'preact' + | 'svelte' + | 'qwik' + | 'html' + | 'web-components' + | 'server' + | 'solid'; From e86e004b2ac99f082d17e632480b530dfbce63c0 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 14:13:04 +0200 Subject: [PATCH 12/42] Add new function extractProperRendererNameFromFramework --- .../src/utils/get-renderer-name.test.ts | 17 +++++++++++++ .../src/utils/get-renderer-name.ts | 24 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 code/lib/core-common/src/utils/get-renderer-name.test.ts diff --git a/code/lib/core-common/src/utils/get-renderer-name.test.ts b/code/lib/core-common/src/utils/get-renderer-name.test.ts new file mode 100644 index 000000000000..f5d10959405c --- /dev/null +++ b/code/lib/core-common/src/utils/get-renderer-name.test.ts @@ -0,0 +1,17 @@ +import { it } from 'node:test'; +import { describe, expect } from 'vitest'; +import { extractProperRendererNameFromFramework } from './get-renderer-name'; + +describe('get-renderer-name', () => { + describe('extractProperRendererNameFromFramework', () => { + it('should return the renderer name for a known framework', async () => { + const renderer = await extractProperRendererNameFromFramework('@storybook/react'); + expect(renderer).toEqual('react'); + }); + + it('should return null for an unknown framework', async () => { + const renderer = await extractProperRendererNameFromFramework('@third-party/framework'); + expect(renderer).toBeNull(); + }); + }); +}); diff --git a/code/lib/core-common/src/utils/get-renderer-name.ts b/code/lib/core-common/src/utils/get-renderer-name.ts index 3127e5db1204..2acdcc6421bc 100644 --- a/code/lib/core-common/src/utils/get-renderer-name.ts +++ b/code/lib/core-common/src/utils/get-renderer-name.ts @@ -1,5 +1,7 @@ import type { Options } from '@storybook/types'; -import { getFrameworkName } from './get-framework-name'; +import { extractProperFrameworkName, getFrameworkName } from './get-framework-name'; +import { frameworkPackages } from './get-storybook-info'; +import { frameworkToRenderer } from './framework-to-renderer'; /** * Render is set as a string on core. It must be set by the framework @@ -16,3 +18,23 @@ export async function getRendererName(options: Options) { return core.renderer; } + +/** + * Extracts the proper renderer name from the given framework name. + * @param frameworkName The name of the framework. + * @returns The name of the renderer. + * @example + * extractProperRendererNameFromFramework('@storybook/react') // => 'react' + * extractProperRendererNameFromFramework('@storybook/angular') // => 'angular' + * extractProperRendererNameFromFramework('@third-party/framework') // => null + */ +export async function extractProperRendererNameFromFramework(frameworkName: string) { + const extractedFrameworkName = extractProperFrameworkName(frameworkName); + const framework = frameworkPackages[extractedFrameworkName]; + + if (!framework) { + return null; + } + + return frameworkToRenderer[framework as keyof typeof frameworkToRenderer]; +} From 0ee1d50d5c41356ab9c4271e11151ac0d43c708c Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 15:24:45 +0200 Subject: [PATCH 13/42] Implement file-search channel --- code/addons/controls/src/preset.ts | 34 +---- .../file-search-channel.test.ts | 130 ++++++++++++++++++ .../src/server-channel/file-search-channel.ts | 86 ++++++++++++ code/addons/controls/src/utils/filesearch.ts | 4 +- .../addons/controls/src/utils/parser/index.ts | 5 +- .../addons/controls/src/utils/parser/types.ts | 2 - 6 files changed, 223 insertions(+), 38 deletions(-) create mode 100644 code/addons/controls/src/server-channel/file-search-channel.test.ts create mode 100644 code/addons/controls/src/server-channel/file-search-channel.ts diff --git a/code/addons/controls/src/preset.ts b/code/addons/controls/src/preset.ts index 84f39990cb1f..0eea2c3485f4 100644 --- a/code/addons/controls/src/preset.ts +++ b/code/addons/controls/src/preset.ts @@ -1,38 +1,8 @@ import type { Options } from '@storybook/types'; import type { Channel } from '@storybook/channels'; -import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from './constants'; - -enum ErrorCode {} - -interface Data { - // A regular string or a glob pattern - searchQuery: string; -} - -interface SearchResult { - success: true | false; - files: Array<{ - // The filepath relative to the project root - filepath: string; - // The search query - Helps to identify the event on the frontend - searchQuery: string; - // A list of exported components - exportedComponents: Array<{ - // the name of the exported component - name: string; - // True, if the exported component is a default export - default: boolean; - }>; - }>; - error: null | ErrorCode; -} +import { initFileSearchChannel } from './server-channel/file-search-channel'; // eslint-disable-next-line @typescript-eslint/naming-convention export const experimental_serverChannel = async (channel: Channel, options: Options) => { - channel.on(FILE_COMPONENT_SEARCH, async (data: Data) => { - // Emit an event using the search results - channel.emit(FILE_COMPONENT_SEARCH_RESULT, { result: {} as SearchResult }); - }); - - return channel; + initFileSearchChannel(channel, options); }; diff --git a/code/addons/controls/src/server-channel/file-search-channel.test.ts b/code/addons/controls/src/server-channel/file-search-channel.test.ts new file mode 100644 index 000000000000..44b983f6f69e --- /dev/null +++ b/code/addons/controls/src/server-channel/file-search-channel.test.ts @@ -0,0 +1,130 @@ +import type { ChannelTransport } from '@storybook/channels'; +import { Channel } from '@storybook/channels'; +import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '../constants'; +import { initFileSearchChannel } from './file-search-channel'; +import { beforeEach, describe, expect, vi, it } from 'vitest'; + +const mocks = vi.hoisted(() => { + return { + searchFiles: vi.fn(), + }; +}); + +vi.mock('../utils/filesearch', () => { + return { + searchFiles: mocks.searchFiles, + }; +}); + +vi.mock('@storybook/core-common', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + getFrameworkName: vi.fn().mockResolvedValue('@storybook/react'), + extractProperRendererNameFromFramework: vi.fn().mockResolvedValue('react'), + getProjectRoot: vi + .fn() + .mockReturnValue(require('path').join(__dirname, '..', 'utils', '__tests__')), + }; +}); + +describe('file-search-channel', () => { + const transport = { setHandler: vi.fn(), send: vi.fn() } satisfies ChannelTransport; + const mockChannel = new Channel({ transport }); + const searchResultChannelListener = vi.fn(); + + beforeEach(() => { + transport.setHandler.mockClear(); + transport.send.mockClear(); + searchResultChannelListener.mockClear(); + }); + + describe('initFileSearchChannel', async () => { + it('should emit search result event with the search result', async () => { + const mockOptions = {}; + const data = { searchQuery: 'commonjs' }; + + initFileSearchChannel(mockChannel, mockOptions as any); + + mockChannel.addListener(FILE_COMPONENT_SEARCH_RESULT, searchResultChannelListener); + mockChannel.emit(FILE_COMPONENT_SEARCH, data); + + mocks.searchFiles.mockImplementation(async (...args) => { + // @ts-expect-error Ignore type issue + return (await vi.importActual('../utils/filesearch')).searchFiles(...args); + }); + + await vi.waitFor(() => { + expect(searchResultChannelListener).toHaveBeenCalled(); + }); + + expect(searchResultChannelListener).toHaveBeenCalledWith({ + error: null, + result: { + files: [ + { + exportedComponents: [ + { + default: false, + name: './commonjs', + }, + ], + filepath: 'src/commonjs-default.js', + }, + { + exportedComponents: [ + { + default: false, + name: 'a', + }, + { + default: false, + name: 'b', + }, + { + default: false, + name: 'c', + }, + { + default: false, + name: 'd', + }, + { + default: false, + name: 'e', + }, + ], + filepath: 'src/commonjs.js', + }, + ], + searchQuery: 'commonjs', + }, + success: true, + }); + }); + + it('should emit an error message if an error occurs while searching for components in the project', async () => { + const mockOptions = {}; + const data = { searchQuery: 'commonjs' }; + + initFileSearchChannel(mockChannel, mockOptions as any); + + mockChannel.addListener(FILE_COMPONENT_SEARCH_RESULT, searchResultChannelListener); + + mockChannel.emit(FILE_COMPONENT_SEARCH, data); + + mocks.searchFiles.mockRejectedValue(new Error('ENOENT: no such file or directory')); + + await vi.waitFor(() => { + expect(searchResultChannelListener).toHaveBeenCalled(); + }); + + expect(searchResultChannelListener).toHaveBeenCalledWith({ + error: + 'An error occurred while searching for components in the project.\nENOENT: no such file or directory', + result: null, + success: false, + }); + }); + }); +}); diff --git a/code/addons/controls/src/server-channel/file-search-channel.ts b/code/addons/controls/src/server-channel/file-search-channel.ts new file mode 100644 index 000000000000..75880af04d9d --- /dev/null +++ b/code/addons/controls/src/server-channel/file-search-channel.ts @@ -0,0 +1,86 @@ +import type { Options, SupportedRenderers } from '@storybook/types'; +import type { Channel } from '@storybook/channels'; +import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '../constants'; +import { searchFiles } from '../utils/filesearch'; +import { + extractProperRendererNameFromFramework, + getFrameworkName, + getProjectRoot, +} from '@storybook/core-common'; +import dedent from 'ts-dedent'; +import assert from 'node:assert'; + +interface Data { + // A regular string or a glob pattern + searchQuery?: string; +} + +interface SearchResult { + success: true | false; + result: null | { + searchQuery: string; + files: Array<{ + // The filepath relative to the project root + filepath: string; + // The search query - Helps to identify the event on the frontend + searchQuery: string; + // A list of exported components + exportedComponents: Array<{ + // the name of the exported component + name: string; + // True, if the exported component is a default export + default: boolean; + }>; + }> | null; + }; + error: null | string; +} + +export function initFileSearchChannel(channel: Channel, options: Options) { + /** + * Listenes for a search query event and searches for files in the project + */ + channel.on(FILE_COMPONENT_SEARCH, async (data: Data) => { + try { + const searchQuery = data?.searchQuery; + + assert(searchQuery, 'searchQuery is required'); + + const frameworkName = await getFrameworkName(options); + + const rendererName = (await extractProperRendererNameFromFramework( + frameworkName + )) as SupportedRenderers; + + const projectRoot = getProjectRoot(); + + const files = await searchFiles(searchQuery, projectRoot, rendererName); + + /** + * Emits the search result event with the search result + */ + channel.emit(FILE_COMPONENT_SEARCH_RESULT, { + success: true, + result: { + searchQuery, + files, + }, + error: null, + } as SearchResult); + } catch (e: any) { + /** + * Emits the search result event with an error message + */ + channel.emit(FILE_COMPONENT_SEARCH_RESULT, { + success: false, + result: null, + error: dedent` + An error occurred while searching for components in the project. + ${e?.message} + `, + } as SearchResult); + } + }); + + return channel; +} diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index 45ba992ed8f6..f20cfac2cfb5 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -2,9 +2,9 @@ import { globby } from 'globby'; import path from 'path'; import fs from 'fs'; -import type { SupportedRenderer } from './parser/types'; import { getParser } from './parser'; import { isNotNull } from './ts-utils'; +import type { SupportedRenderers } from '@storybook/types'; export type SearchResult = Array<{ filepath: string; @@ -29,7 +29,7 @@ const globPatternChars = ['*', '+(', '@(', '?(', '!(', '[', ']']; export async function searchFiles( searchQuery: string, cwd: string, - renderer: SupportedRenderer + renderer: SupportedRenderers | null ): Promise { const hasGlobChars = globPatternChars.some((char) => searchQuery.includes(char)); diff --git a/code/addons/controls/src/utils/parser/index.ts b/code/addons/controls/src/utils/parser/index.ts index 1d17272bb13d..8f5183a49538 100644 --- a/code/addons/controls/src/utils/parser/index.ts +++ b/code/addons/controls/src/utils/parser/index.ts @@ -1,12 +1,13 @@ +import type { SupportedRenderers } from '@storybook/types'; import { GenericParser } from './generic-parser'; -import type { Parser, SupportedRenderer } from './types'; +import type { Parser } from './types'; /** * Get the parser for a given renderer * @param renderer The renderer to get the parser for * @returns The parser for the renderer */ -export function getParser(renderer: SupportedRenderer): Parser { +export function getParser(renderer: SupportedRenderers | null): Parser { switch (renderer) { default: return new GenericParser(); diff --git a/code/addons/controls/src/utils/parser/types.ts b/code/addons/controls/src/utils/parser/types.ts index 47529b441825..c3c664abc27d 100644 --- a/code/addons/controls/src/utils/parser/types.ts +++ b/code/addons/controls/src/utils/parser/types.ts @@ -1,5 +1,3 @@ -export type SupportedRenderer = 'react'; - export type ParserResult = { exports: Array<{ name: string; From 492a43b134d31c48738d1070f4e12eb7a9313df0 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 15:55:08 +0200 Subject: [PATCH 14/42] Adjust globbification of search query --- code/addons/controls/src/utils/filesearch.test.ts | 2 +- code/addons/controls/src/utils/filesearch.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/addons/controls/src/utils/filesearch.test.ts b/code/addons/controls/src/utils/filesearch.test.ts index 7291edd137ca..d97fed425aaa 100644 --- a/code/addons/controls/src/utils/filesearch.test.ts +++ b/code/addons/controls/src/utils/filesearch.test.ts @@ -5,7 +5,7 @@ import { searchFiles } from './filesearch'; describe('filesearch', () => { describe('search result', () => { it('should automatically convert normal search to a glob search', async (t) => { - const files = await searchFiles('commonjs', path.join(__dirname, '__tests__'), 'react'); + const files = await searchFiles('ommonjs', path.join(__dirname, '__tests__'), 'react'); expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-default.js', 'src/commonjs.js']); }); diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index f20cfac2cfb5..3b9c31a51275 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -33,7 +33,7 @@ export async function searchFiles( ): Promise { const hasGlobChars = globPatternChars.some((char) => searchQuery.includes(char)); - const globbedSearchQuery = hasGlobChars ? searchQuery : `**/${searchQuery}**`; + const globbedSearchQuery = hasGlobChars ? searchQuery : `**/*${searchQuery}**`; const entries = await globby(globbedSearchQuery, { ignore: ['**/node_modules/**'], From 272c3d53481bc57029f6d01029dd87947001f334 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 15:58:04 +0200 Subject: [PATCH 15/42] Add dependencies and remove unused dependency in package.json and yarn.lock --- code/addons/controls/package.json | 3 +-- code/yarn.lock | 37 ++----------------------------- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index e7f1a604bffa..74bc77b72a22 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -53,9 +53,9 @@ }, "dependencies": { "@storybook/blocks": "workspace:*", + "@storybook/core-common": "workspace:*", "cjs-module-lexer": "^1.2.3", "es-module-lexer": "^1.5.0", - "glob": "^10.3.12", "globby": "^14.0.1", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" @@ -63,7 +63,6 @@ "devDependencies": { "@storybook/client-logger": "workspace:*", "@storybook/components": "workspace:*", - "@storybook/core-common": "workspace:*", "@storybook/manager-api": "workspace:*", "@storybook/node-logger": "workspace:*", "@storybook/preview-api": "workspace:*", diff --git a/code/yarn.lock b/code/yarn.lock index 9fd0e6014754..c7b50b3f06cb 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -4798,7 +4798,6 @@ __metadata: "@storybook/types": "workspace:*" cjs-module-lexer: "npm:^1.2.3" es-module-lexer: "npm:^1.5.0" - glob: "npm:^10.3.12" globby: "npm:^14.0.1" lodash: "npm:^4.17.21" react: "npm:^18.2.0" @@ -15850,21 +15849,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.3.12": - version: 10.3.12 - resolution: "glob@npm:10.3.12" - dependencies: - foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.6" - minimatch: "npm:^9.0.1" - minipass: "npm:^7.0.4" - path-scurry: "npm:^1.10.2" - bin: - glob: dist/esm/bin.mjs - checksum: 10c0/f60cefdc1cf3f958b2bb5823e1b233727f04916d489dc4641d76914f016e6704421e06a83cbb68b0cb1cb9382298b7a88075b844ad2127fc9727ea22b18b0711 - languageName: node - linkType: hard - "glob@npm:^5.0.10": version: 5.0.15 resolution: "glob@npm:5.0.15" @@ -17883,7 +17867,7 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5, jackspeak@npm:^2.3.6": +"jackspeak@npm:^2.3.5": version: 2.3.6 resolution: "jackspeak@npm:2.3.6" dependencies: @@ -19056,13 +19040,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.2.0": - version: 10.2.0 - resolution: "lru-cache@npm:10.2.0" - checksum: 10c0/c9847612aa2daaef102d30542a8d6d9b2c2bb36581c1bf0dc3ebf5e5f3352c772a749e604afae2e46873b930a9e9523743faac4e5b937c576ab29196774712ee - languageName: node - linkType: hard - "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -20694,7 +20671,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": version: 7.0.4 resolution: "minipass@npm:7.0.4" checksum: 10c0/6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 @@ -22366,16 +22343,6 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.2": - version: 1.10.2 - resolution: "path-scurry@npm:1.10.2" - dependencies: - lru-cache: "npm:^10.2.0" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: 10c0/d723777fbf9627f201e64656680f66ebd940957eebacf780e6cce1c2919c29c116678b2d7dbf8821b3a2caa758d125f4444005ccec886a25c8f324504e48e601 - languageName: node - linkType: hard - "path-to-regexp@npm:0.1.7": version: 0.1.7 resolution: "path-to-regexp@npm:0.1.7" From 7e79e80070f99d0b6172e3bcb237a59931d63d43 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 16:14:11 +0200 Subject: [PATCH 16/42] Improve glob search pattern for file search --- code/addons/controls/src/utils/filesearch.test.ts | 10 ++++++++++ code/addons/controls/src/utils/filesearch.ts | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/code/addons/controls/src/utils/filesearch.test.ts b/code/addons/controls/src/utils/filesearch.test.ts index d97fed425aaa..9bb8ebafc057 100644 --- a/code/addons/controls/src/utils/filesearch.test.ts +++ b/code/addons/controls/src/utils/filesearch.test.ts @@ -10,6 +10,16 @@ describe('filesearch', () => { expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-default.js', 'src/commonjs.js']); }); + it('should return all files if the search query matches the parent folder', async (t) => { + const files = await searchFiles('src', path.join(__dirname, '__tests__'), 'react'); + + expect(files?.map((f) => f.filepath)).toEqual([ + 'src/commonjs-default.js', + 'src/commonjs.js', + 'src/esmodule.js', + ]); + }); + it('should work with glob search patterns', async (t) => { const files = await searchFiles('**/commonjs.js', path.join(__dirname, '__tests__'), 'react'); diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index 3b9c31a51275..a71ceb8913bf 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -33,7 +33,9 @@ export async function searchFiles( ): Promise { const hasGlobChars = globPatternChars.some((char) => searchQuery.includes(char)); - const globbedSearchQuery = hasGlobChars ? searchQuery : `**/*${searchQuery}**`; + const globbedSearchQuery = hasGlobChars + ? searchQuery + : [`**/*${searchQuery}*`, `**/*${searchQuery}*/**`]; const entries = await globby(globbedSearchQuery, { ignore: ['**/node_modules/**'], From 3ae848c3bc5c437a6503a66e73912a94d1373bd7 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 16:29:09 +0200 Subject: [PATCH 17/42] Update yarn install command to exclude immutable flag --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b23edd89ef69..ad07b40429a4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -596,7 +596,7 @@ jobs: at: . - run: name: Install dependencies - command: yarn install + command: yarn install --no-immutable working_directory: test-storybooks/portable-stories-kitchen-sink/<< parameters.directory >> - run: name: Run Jest tests From 75b487380d8ea1b8d0cef17fefbc22431bd89660 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Wed, 3 Apr 2024 16:31:50 +0200 Subject: [PATCH 18/42] Update yarn.lock --- code/yarn.lock | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/yarn.lock b/code/yarn.lock index c7b50b3f06cb..e50a89d526de 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -13634,13 +13634,6 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^1.5.0": - version: 1.5.0 - resolution: "es-module-lexer@npm:1.5.0" - checksum: 10c0/d199853404f3381801eb102befb84a8fc48f93ed86b852c2461c2c4ad4bbbc91128f3d974ff9b8718628260ae3f36e661295ab3e419222868aa31269284e34c9 - languageName: node - linkType: hard - "es-set-tostringtag@npm:^2.0.2": version: 2.0.3 resolution: "es-set-tostringtag@npm:2.0.3" From 871699efcbbe541d74a2ef2963f593ed8c7a96b1 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 10:46:09 +0200 Subject: [PATCH 19/42] import globby dynamically because it is a pure ESM module --- code/addons/controls/src/utils/filesearch.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index a71ceb8913bf..75dffbd3f0d3 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -1,4 +1,3 @@ -import { globby } from 'globby'; import path from 'path'; import fs from 'fs'; @@ -37,6 +36,9 @@ export async function searchFiles( ? searchQuery : [`**/*${searchQuery}*`, `**/*${searchQuery}*/**`]; + // Dynamically import globby because it is a pure ESM module + const { globby } = await import('globby'); + const entries = await globby(globbedSearchQuery, { ignore: ['**/node_modules/**'], gitignore: true, From ca397190ac47c6ee13fea1b8f5ece71d00a66e5b Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 13:24:51 +0200 Subject: [PATCH 20/42] Bump esmodule-lexer --- .../nextjs/yarn.lock | 20 +++++++++++-------- .../react/yarn.lock | 6 +++++- .../svelte/yarn.lock | 11 ++++++++++ .../vue3/yarn.lock | 11 ++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock index 64f5d683addd..e621c6f62567 100644 --- a/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock +++ b/test-storybooks/portable-stories-kitchen-sink/nextjs/yarn.lock @@ -2404,12 +2404,16 @@ __metadata: "@storybook/addon-controls@file:../../../code/addons/controls::locator=portable-stories-nextjs%40workspace%3A.": version: 8.1.0-alpha.5 - resolution: "@storybook/addon-controls@file:../../../code/addons/controls#../../../code/addons/controls::hash=b0a330&locator=portable-stories-nextjs%40workspace%3A." + resolution: "@storybook/addon-controls@file:../../../code/addons/controls#../../../code/addons/controls::hash=358687&locator=portable-stories-nextjs%40workspace%3A." dependencies: "@storybook/blocks": "workspace:*" + "@storybook/core-common": "workspace:*" + cjs-module-lexer: "npm:^1.2.3" + es-module-lexer: "npm:^1.5.0" + globby: "npm:^14.0.1" lodash: "npm:^4.17.21" ts-dedent: "npm:^2.0.0" - checksum: 10/dcdc61154006c8575e612d77b7cfa0e2266f12429e2560afe49d4ca74b56a40ba4823e2b2a55e6803006e5fbad8ea848ed4d1ec753063763f01b53236b7ba223 + checksum: 10/feb098e18f942562769dfdfb4afc70655f67f11e6d14acf8e3ca4cfe9a22e09e89ede9f17be6ff1c07a56bed8a6fa1961fa044137a3e7a34471345bcccd091f2 languageName: node linkType: hard @@ -2644,7 +2648,7 @@ __metadata: "@storybook/cli@file:../../../code/lib/cli::locator=portable-stories-nextjs%40workspace%3A.": version: 8.1.0-alpha.5 - resolution: "@storybook/cli@file:../../../code/lib/cli#../../../code/lib/cli::hash=d07615&locator=portable-stories-nextjs%40workspace%3A." + resolution: "@storybook/cli@file:../../../code/lib/cli#../../../code/lib/cli::hash=49e395&locator=portable-stories-nextjs%40workspace%3A." dependencies: "@babel/core": "npm:^7.23.0" "@babel/types": "npm:^7.23.0" @@ -2685,7 +2689,7 @@ __metadata: bin: getstorybook: ./bin/index.js sb: ./bin/index.js - checksum: 10/ca2d93c888ae68445728b0dfad15917ca75e7f193c3da8e2e115386cee359246a701d4cad9edd71ebb1377bebaecf9147a267963e972c4085f10082ec4cccf93 + checksum: 10/37be78e7b11cfb9d712f9b948e3017665fcee970e1b3a4806f3f8307ea9db7e39f4b12fa919086a53efbe4e24a5e6196b2daafb958c11145e9e5d224fa70af55 languageName: node linkType: hard @@ -2743,7 +2747,7 @@ __metadata: "@storybook/core-common@file:../../../code/lib/core-common::locator=portable-stories-nextjs%40workspace%3A.": version: 8.1.0-alpha.5 - resolution: "@storybook/core-common@file:../../../code/lib/core-common#../../../code/lib/core-common::hash=d6f826&locator=portable-stories-nextjs%40workspace%3A." + resolution: "@storybook/core-common@file:../../../code/lib/core-common#../../../code/lib/core-common::hash=55d292&locator=portable-stories-nextjs%40workspace%3A." dependencies: "@storybook/core-events": "workspace:*" "@storybook/csf-tools": "workspace:*" @@ -2773,7 +2777,7 @@ __metadata: tiny-invariant: "npm:^1.3.1" ts-dedent: "npm:^2.0.0" util: "npm:^0.12.4" - checksum: 10/5a82e69805fd612b9bb7eaf370d93bbadf34f18401b96b16a1b33eaf8dc9c472fa143ab9dc62f0ca82c27555ac73245bb0fc681264d3485a281132de98458089 + checksum: 10/e9308c3683651e2c925823e4bee0f91156ba544b0dc72ee6291810e7bd2e17690bce3f426c10d942fd5e18eb545589e5a3347cd02eb6ecceb058dad7a56bb775 languageName: node linkType: hard @@ -3239,12 +3243,12 @@ __metadata: "@storybook/types@file:../../../code/lib/types::locator=portable-stories-nextjs%40workspace%3A.": version: 8.1.0-alpha.5 - resolution: "@storybook/types@file:../../../code/lib/types#../../../code/lib/types::hash=22b151&locator=portable-stories-nextjs%40workspace%3A." + resolution: "@storybook/types@file:../../../code/lib/types#../../../code/lib/types::hash=0524c9&locator=portable-stories-nextjs%40workspace%3A." dependencies: "@storybook/channels": "workspace:*" "@types/express": "npm:^4.7.0" file-system-cache: "npm:2.3.0" - checksum: 10/9029701cc4326e000e4f2866601633e54c3167bf5363c97b5190cec9ea762750dcbbc09767695a225bf0804cff6d0e8b9eb55143ef9207798800c6c1dfe7856a + checksum: 10/b2835c9386c22e535e62263fe03ead9c43a1c9762b6524ed8a9b1954887e8853311d580caa7711d57a1eecc9ce30cd7cfd9d814a45723e8434397b7adced1871 languageName: node linkType: hard diff --git a/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock index ca0b7a5ede87..e56c0e31080a 100644 --- a/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock +++ b/test-storybooks/portable-stories-kitchen-sink/react/yarn.lock @@ -2583,6 +2583,10 @@ __metadata: resolution: "@storybook/addon-controls@portal:../../../code/addons/controls::locator=portable-stories-react%40workspace%3A." dependencies: "@storybook/blocks": "workspace:*" + "@storybook/core-common": "workspace:*" + cjs-module-lexer: "npm:^1.2.3" + es-module-lexer: "npm:^1.5.0" + globby: "npm:^14.0.1" lodash: "npm:^4.17.21" ts-dedent: "npm:^2.0.0" languageName: node @@ -5117,7 +5121,7 @@ __metadata: languageName: node linkType: hard -"cjs-module-lexer@npm:^1.0.0": +"cjs-module-lexer@npm:^1.0.0, cjs-module-lexer@npm:^1.2.3": version: 1.2.3 resolution: "cjs-module-lexer@npm:1.2.3" checksum: 10/f96a5118b0a012627a2b1c13bd2fcb92509778422aaa825c5da72300d6dcadfb47134dd2e9d97dfa31acd674891dd91642742772d19a09a8adc3e56bd2f5928c diff --git a/test-storybooks/portable-stories-kitchen-sink/svelte/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/svelte/yarn.lock index c741bf702794..24ddbf299123 100644 --- a/test-storybooks/portable-stories-kitchen-sink/svelte/yarn.lock +++ b/test-storybooks/portable-stories-kitchen-sink/svelte/yarn.lock @@ -2217,6 +2217,10 @@ __metadata: resolution: "@storybook/addon-controls@portal:../../../code/addons/controls::locator=portable-stories-svelte%40workspace%3A." dependencies: "@storybook/blocks": "workspace:*" + "@storybook/core-common": "workspace:*" + cjs-module-lexer: "npm:^1.2.3" + es-module-lexer: "npm:^1.5.0" + globby: "npm:^14.0.1" lodash: "npm:^4.17.21" ts-dedent: "npm:^2.0.0" languageName: node @@ -4110,6 +4114,13 @@ __metadata: languageName: node linkType: hard +"cjs-module-lexer@npm:^1.2.3": + version: 1.2.3 + resolution: "cjs-module-lexer@npm:1.2.3" + checksum: 10/f96a5118b0a012627a2b1c13bd2fcb92509778422aaa825c5da72300d6dcadfb47134dd2e9d97dfa31acd674891dd91642742772d19a09a8adc3e56bd2f5928c + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" diff --git a/test-storybooks/portable-stories-kitchen-sink/vue3/yarn.lock b/test-storybooks/portable-stories-kitchen-sink/vue3/yarn.lock index 6a3a4679f469..bab162b80aac 100644 --- a/test-storybooks/portable-stories-kitchen-sink/vue3/yarn.lock +++ b/test-storybooks/portable-stories-kitchen-sink/vue3/yarn.lock @@ -2249,6 +2249,10 @@ __metadata: resolution: "@storybook/addon-controls@portal:../../../code/addons/controls::locator=portable-stories-vue3%40workspace%3A." dependencies: "@storybook/blocks": "workspace:*" + "@storybook/core-common": "workspace:*" + cjs-module-lexer: "npm:^1.2.3" + es-module-lexer: "npm:^1.5.0" + globby: "npm:^14.0.1" lodash: "npm:^4.17.21" ts-dedent: "npm:^2.0.0" languageName: node @@ -4473,6 +4477,13 @@ __metadata: languageName: node linkType: hard +"cjs-module-lexer@npm:^1.2.3": + version: 1.2.3 + resolution: "cjs-module-lexer@npm:1.2.3" + checksum: 10/f96a5118b0a012627a2b1c13bd2fcb92509778422aaa825c5da72300d6dcadfb47134dd2e9d97dfa31acd674891dd91642742772d19a09a8adc3e56bd2f5928c + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" From a1305c33619a41f19a39c62db021724310be1382 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 15:38:23 +0200 Subject: [PATCH 21/42] Only search for specific file extensions --- .../src/utils/__tests__/src/assets/asset.css | 0 .../src/utils/__tests__/src/assets/asset.json | 0 .../src/utils/__tests__/src/assets/asset.png | 0 ...-default.js => commonjs-module-default.js} | 0 .../src/{commonjs.js => commonjs-module.js} | 0 .../src/{esmodule.js => es-module.js} | 0 .../src/file-extensions/extension.cjs | 3 ++ .../src/file-extensions/extension.cts | 3 ++ .../src/file-extensions/extension.js | 3 ++ .../src/file-extensions/extension.jsx | 3 ++ .../src/file-extensions/extension.mts | 3 ++ .../src/file-extensions/extension.ts | 3 ++ .../src/file-extensions/extension.tsx | 3 ++ .../controls/src/utils/filesearch.test.ts | 41 +++++++++++++++---- code/addons/controls/src/utils/filesearch.ts | 25 +++++++---- 15 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 code/addons/controls/src/utils/__tests__/src/assets/asset.css create mode 100644 code/addons/controls/src/utils/__tests__/src/assets/asset.json create mode 100644 code/addons/controls/src/utils/__tests__/src/assets/asset.png rename code/addons/controls/src/utils/__tests__/src/{commonjs-default.js => commonjs-module-default.js} (100%) rename code/addons/controls/src/utils/__tests__/src/{commonjs.js => commonjs-module.js} (100%) rename code/addons/controls/src/utils/__tests__/src/{esmodule.js => es-module.js} (100%) create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cjs create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cts create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.js create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.jsx create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mts create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.ts create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.tsx diff --git a/code/addons/controls/src/utils/__tests__/src/assets/asset.css b/code/addons/controls/src/utils/__tests__/src/assets/asset.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/__tests__/src/assets/asset.json b/code/addons/controls/src/utils/__tests__/src/assets/asset.json new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/__tests__/src/assets/asset.png b/code/addons/controls/src/utils/__tests__/src/assets/asset.png new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs-default.js b/code/addons/controls/src/utils/__tests__/src/commonjs-module-default.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/commonjs-default.js rename to code/addons/controls/src/utils/__tests__/src/commonjs-module-default.js diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs.js b/code/addons/controls/src/utils/__tests__/src/commonjs-module.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/commonjs.js rename to code/addons/controls/src/utils/__tests__/src/commonjs-module.js diff --git a/code/addons/controls/src/utils/__tests__/src/esmodule.js b/code/addons/controls/src/utils/__tests__/src/es-module.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/esmodule.js rename to code/addons/controls/src/utils/__tests__/src/es-module.js diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cjs b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cjs new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cjs @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cts b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cts new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cts @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.js b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.js new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.js @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.jsx b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.jsx new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.jsx @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mts b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mts new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mts @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.ts b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.ts new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.ts @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.tsx b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.tsx new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.tsx @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/filesearch.test.ts b/code/addons/controls/src/utils/filesearch.test.ts index 9bb8ebafc057..f6a9918e0bf1 100644 --- a/code/addons/controls/src/utils/filesearch.test.ts +++ b/code/addons/controls/src/utils/filesearch.test.ts @@ -4,26 +4,45 @@ import { searchFiles } from './filesearch'; describe('filesearch', () => { describe('search result', () => { - it('should automatically convert normal search to a glob search', async (t) => { + it('should automatically convert static search to a dynamic glob search', async (t) => { const files = await searchFiles('ommonjs', path.join(__dirname, '__tests__'), 'react'); - expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-default.js', 'src/commonjs.js']); + expect(files?.map((f) => f.filepath)).toEqual([ + 'src/commonjs-module-default.js', + 'src/commonjs-module.js', + ]); + }); + + it('should automatically convert static search to a dynamic glob search (with file extension)', async (t) => { + const files = await searchFiles('module.js', path.join(__dirname, '__tests__'), 'react'); + + expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-module.js', 'src/es-module.js']); }); it('should return all files if the search query matches the parent folder', async (t) => { - const files = await searchFiles('src', path.join(__dirname, '__tests__'), 'react'); + const files = await searchFiles('module', path.join(__dirname, '__tests__'), 'react'); expect(files?.map((f) => f.filepath)).toEqual([ - 'src/commonjs-default.js', - 'src/commonjs.js', - 'src/esmodule.js', + 'src/commonjs-module-default.js', + 'src/commonjs-module.js', + 'src/es-module.js', ]); }); + it('should ignore files that do not have the allowed extensions', async (t) => { + const files = await searchFiles('asset', path.join(__dirname, '__tests__'), 'react'); + + expect(files).toEqual([]); + }); + it('should work with glob search patterns', async (t) => { - const files = await searchFiles('**/commonjs.js', path.join(__dirname, '__tests__'), 'react'); + const files = await searchFiles( + '**/commonjs-module.js', + path.join(__dirname, '__tests__'), + 'react' + ); - expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs.js']); + expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-module.js']); }); it('should ignore node_modules', async (t) => { @@ -39,7 +58,11 @@ describe('filesearch', () => { describe('exported components', () => { it('should correctly return the exported components', async (t) => { - const files = await searchFiles('commonjs.js', path.join(__dirname, '__tests__'), 'react'); + const files = await searchFiles( + 'commonjs-module.js', + path.join(__dirname, '__tests__'), + 'react' + ); expect(files?.flatMap((f) => f.exportedComponents)).toHaveLength(5); }); diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index 75dffbd3f0d3..1445afbfd7f1 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -14,9 +14,9 @@ export type SearchResult = Array<{ }>; /** - * Characters that are used in glob patterns to identify search queries that are not just filenames + * File extensions that should be searched for */ -const globPatternChars = ['*', '+(', '@(', '?(', '!(', '[', ']']; +const fileExtensions = ['js', 'mjs', 'cjs', 'jsx', 'mts', 'ts', 'tsx', 'cts']; /** * Search for files in a directory that match the search query @@ -30,14 +30,23 @@ export async function searchFiles( cwd: string, renderer: SupportedRenderers | null ): Promise { - const hasGlobChars = globPatternChars.some((char) => searchQuery.includes(char)); + // Dynamically import globby because it is a pure ESM module + const { globby, isDynamicPattern } = await import('globby'); - const globbedSearchQuery = hasGlobChars - ? searchQuery - : [`**/*${searchQuery}*`, `**/*${searchQuery}*/**`]; + const hasSearchSpecialGlobChars = isDynamicPattern(searchQuery, { cwd }); - // Dynamically import globby because it is a pure ESM module - const { globby } = await import('globby'); + const hasFileExtensionRegex = /(\.[a-z]+)$/i; + const searchQueryHasExtension = hasFileExtensionRegex.test(searchQuery); + const fileExtensionsPattern = `{${fileExtensions.join(',')}}`; + + const globbedSearchQuery = hasSearchSpecialGlobChars + ? searchQuery + : searchQueryHasExtension + ? [`**/*${searchQuery}*`, `**/*${searchQuery}*/**`] + : [ + `**/*${searchQuery}*.${fileExtensionsPattern}`, + `**/*${searchQuery}*/**/*.${fileExtensionsPattern}`, + ]; const entries = await globby(globbedSearchQuery, { ignore: ['**/node_modules/**'], From 7431a0e390073f682cb819aff5e1af86ef951adc Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 15:41:09 +0200 Subject: [PATCH 22/42] Ignore test files in filesearch --- .../controls/src/utils/__tests__/src/tests/some.spec.ts | 0 .../controls/src/utils/__tests__/src/tests/some.test.ts | 0 code/addons/controls/src/utils/filesearch.test.ts | 6 ++++++ code/addons/controls/src/utils/filesearch.ts | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 code/addons/controls/src/utils/__tests__/src/tests/some.spec.ts create mode 100644 code/addons/controls/src/utils/__tests__/src/tests/some.test.ts diff --git a/code/addons/controls/src/utils/__tests__/src/tests/some.spec.ts b/code/addons/controls/src/utils/__tests__/src/tests/some.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/__tests__/src/tests/some.test.ts b/code/addons/controls/src/utils/__tests__/src/tests/some.test.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/filesearch.test.ts b/code/addons/controls/src/utils/filesearch.test.ts index f6a9918e0bf1..adba15c34513 100644 --- a/code/addons/controls/src/utils/filesearch.test.ts +++ b/code/addons/controls/src/utils/filesearch.test.ts @@ -35,6 +35,12 @@ describe('filesearch', () => { expect(files).toEqual([]); }); + it('should ignore test files (*.spec.*, *.test.*)', async (t) => { + const files = await searchFiles('tests', path.join(__dirname, '__tests__'), 'react'); + + expect(files).toEqual([]); + }); + it('should work with glob search patterns', async (t) => { const files = await searchFiles( '**/commonjs-module.js', diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index 1445afbfd7f1..909faf93c59d 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -49,7 +49,7 @@ export async function searchFiles( ]; const entries = await globby(globbedSearchQuery, { - ignore: ['**/node_modules/**'], + ignore: ['**/node_modules/**', '**/*.spec.*', '**/*.test.*'], gitignore: true, cwd, objectMode: true, From 7095732703120df488513d22aca239209313ca69 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 15:45:44 +0200 Subject: [PATCH 23/42] Fix tests --- code/addons/controls/src/utils/parser/generic-parser.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/addons/controls/src/utils/parser/generic-parser.test.ts b/code/addons/controls/src/utils/parser/generic-parser.test.ts index 9f9e98391e16..02dce49436f1 100644 --- a/code/addons/controls/src/utils/parser/generic-parser.test.ts +++ b/code/addons/controls/src/utils/parser/generic-parser.test.ts @@ -9,7 +9,7 @@ const TEST_DIR = path.join(__dirname, '..', '__tests__'); describe('generic-parser', () => { it('should correctly return exports from CommonJS files', async () => { - const content = fs.readFileSync(path.join(TEST_DIR, 'src', 'commonjs.js'), 'utf-8'); + const content = fs.readFileSync(path.join(TEST_DIR, 'src', 'commonjs-module.js'), 'utf-8'); const { exports } = await genericParser.parse(content); expect(exports).toEqual([ @@ -37,7 +37,7 @@ describe('generic-parser', () => { }); it('should correctly return exports from ES modules', async () => { - const content = fs.readFileSync(path.join(TEST_DIR, 'src', 'esmodule.js'), 'utf-8'); + const content = fs.readFileSync(path.join(TEST_DIR, 'src', 'es-module.js'), 'utf-8'); const { exports } = await genericParser.parse(content); expect(exports).toEqual([ From e4a49f88c54535221471711339d3adec3b14be34 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 16:11:08 +0200 Subject: [PATCH 24/42] Fix test --- .../controls/src/server-channel/file-search-channel.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/addons/controls/src/server-channel/file-search-channel.test.ts b/code/addons/controls/src/server-channel/file-search-channel.test.ts index 44b983f6f69e..d6fa31085b76 100644 --- a/code/addons/controls/src/server-channel/file-search-channel.test.ts +++ b/code/addons/controls/src/server-channel/file-search-channel.test.ts @@ -69,7 +69,7 @@ describe('file-search-channel', () => { name: './commonjs', }, ], - filepath: 'src/commonjs-default.js', + filepath: 'src/commonjs-module-default.js', }, { exportedComponents: [ @@ -94,7 +94,7 @@ describe('file-search-channel', () => { name: 'e', }, ], - filepath: 'src/commonjs.js', + filepath: 'src/commonjs-module.js', }, ], searchQuery: 'commonjs', From 061dbf9d1eb422d7baa089661d91a331cc0ee2d2 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 16:13:03 +0200 Subject: [PATCH 25/42] Return null for files which cannot be parsed --- .../controls/src/utils/__tests__/src/no-export.js | 0 code/addons/controls/src/utils/filesearch.test.ts | 11 +++++++++++ code/addons/controls/src/utils/filesearch.ts | 11 +++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 code/addons/controls/src/utils/__tests__/src/no-export.js diff --git a/code/addons/controls/src/utils/__tests__/src/no-export.js b/code/addons/controls/src/utils/__tests__/src/no-export.js new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/code/addons/controls/src/utils/filesearch.test.ts b/code/addons/controls/src/utils/filesearch.test.ts index adba15c34513..e517b4708f8c 100644 --- a/code/addons/controls/src/utils/filesearch.test.ts +++ b/code/addons/controls/src/utils/filesearch.test.ts @@ -72,5 +72,16 @@ describe('filesearch', () => { expect(files?.flatMap((f) => f.exportedComponents)).toHaveLength(5); }); + + it('should return null for exportedComponents if parsing fails', async (t) => { + const files = await searchFiles('no-export.js', path.join(__dirname, '__tests__'), 'react'); + + expect(files).toEqual([ + { + exportedComponents: null, + filepath: 'src/no-export.js', + }, + ]); + }); }); }); diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/filesearch.ts index 909faf93c59d..f375e983200a 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/filesearch.ts @@ -6,11 +6,15 @@ import { isNotNull } from './ts-utils'; import type { SupportedRenderers } from '@storybook/types'; export type SearchResult = Array<{ + /** The path to the file relative to the project root */ filepath: string; + /** + * The exported components in the file. + * It is null if the file couldn't be parsed or doesn't have any exports */ exportedComponents: Array<{ name: string; default: boolean; - }>; + }> | null; }>; /** @@ -67,7 +71,10 @@ export async function searchFiles( exportedComponents: info.exports, }; } catch (e) { - return null; + return { + filepath: entry.path, + exportedComponents: null, + }; } }); return (await Promise.all(files)).filter(isNotNull); From e79979b145db8ad114d71c19bc8eafbca01b7de1 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 16:31:17 +0200 Subject: [PATCH 26/42] Add .eslintignore changes and exclude __tests__ directory --- code/.eslintignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/.eslintignore b/code/.eslintignore index 3319047075e6..beba5132a1e5 100644 --- a/code/.eslintignore +++ b/code/.eslintignore @@ -17,4 +17,5 @@ ember-output !.eslintrc.js !.eslintrc-markdown.js !.storybook -lib/core-common/templates/base-preview-head.html \ No newline at end of file +lib/core-common/templates/base-preview-head.html +__tests__ \ No newline at end of file From 8adf047daca8de5e67483be9cf1966eb55d042eb Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 17:49:33 +0200 Subject: [PATCH 27/42] Increase timeout in test --- .../src/server-channel/file-search-channel.test.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/code/addons/controls/src/server-channel/file-search-channel.test.ts b/code/addons/controls/src/server-channel/file-search-channel.test.ts index d6fa31085b76..62a521afec78 100644 --- a/code/addons/controls/src/server-channel/file-search-channel.test.ts +++ b/code/addons/controls/src/server-channel/file-search-channel.test.ts @@ -54,9 +54,12 @@ describe('file-search-channel', () => { return (await vi.importActual('../utils/filesearch')).searchFiles(...args); }); - await vi.waitFor(() => { - expect(searchResultChannelListener).toHaveBeenCalled(); - }); + await vi.waitFor( + () => { + expect(searchResultChannelListener).toHaveBeenCalled(); + }, + { timeout: 2000 } + ); expect(searchResultChannelListener).toHaveBeenCalledWith({ error: null, From d01541957884d15a7e3678c569151ac874bfe5af Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 8 Apr 2024 14:35:53 +0200 Subject: [PATCH 28/42] Apply requested changes --- .../file-search-channel.test.ts | 35 ++++++- .../src/server-channel/file-search-channel.ts | 50 +++++++--- .../src/utils/__tests__/src/assets/asset.png | Bin 0 -> 95 bytes .../src/utils/__tests__/src/es-module.js | 2 + .../src/file-extensions/extension.mjs | 3 + .../controls/src/utils/filesearch.test.ts | 87 ------------------ .../src/utils/parser/generic-parser.test.ts | 4 + .../src/utils/parser/generic-parser.ts | 5 +- .../controls/src/utils/search-files.test.ts | 86 +++++++++++++++++ .../utils/{filesearch.ts => search-files.ts} | 53 ++--------- code/addons/controls/src/utils/ts-utils.ts | 8 -- .../src/utils/normalize-path.test.ts | 1 + .../core-common/src/utils/normalize-path.ts | 2 +- 13 files changed, 176 insertions(+), 160 deletions(-) create mode 100644 code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mjs delete mode 100644 code/addons/controls/src/utils/filesearch.test.ts create mode 100644 code/addons/controls/src/utils/search-files.test.ts rename code/addons/controls/src/utils/{filesearch.ts => search-files.ts} (50%) delete mode 100644 code/addons/controls/src/utils/ts-utils.ts diff --git a/code/addons/controls/src/server-channel/file-search-channel.test.ts b/code/addons/controls/src/server-channel/file-search-channel.test.ts index 62a521afec78..b2d6b2db1b06 100644 --- a/code/addons/controls/src/server-channel/file-search-channel.test.ts +++ b/code/addons/controls/src/server-channel/file-search-channel.test.ts @@ -10,7 +10,7 @@ const mocks = vi.hoisted(() => { }; }); -vi.mock('../utils/filesearch', () => { +vi.mock('../utils/search-files', () => { return { searchFiles: mocks.searchFiles, }; @@ -51,7 +51,7 @@ describe('file-search-channel', () => { mocks.searchFiles.mockImplementation(async (...args) => { // @ts-expect-error Ignore type issue - return (await vi.importActual('../utils/filesearch')).searchFiles(...args); + return (await vi.importActual('../utils/search-files')).searchFiles(...args); }); await vi.waitFor( @@ -106,6 +106,37 @@ describe('file-search-channel', () => { }); }); + it('should emit search result event with an empty search result', async () => { + const mockOptions = {}; + const data = { searchQuery: 'no-file-for-search-query' }; + + initFileSearchChannel(mockChannel, mockOptions as any); + + mockChannel.addListener(FILE_COMPONENT_SEARCH_RESULT, searchResultChannelListener); + mockChannel.emit(FILE_COMPONENT_SEARCH, data); + + mocks.searchFiles.mockImplementation(async (...args) => { + // @ts-expect-error Ignore type issue + return (await vi.importActual('../utils/search-files')).searchFiles(...args); + }); + + await vi.waitFor( + () => { + expect(searchResultChannelListener).toHaveBeenCalled(); + }, + { timeout: 2000 } + ); + + expect(searchResultChannelListener).toHaveBeenCalledWith({ + error: null, + result: { + files: [], + searchQuery: 'no-file-for-search-query', + }, + success: true, + }); + }); + it('should emit an error message if an error occurs while searching for components in the project', async () => { const mockOptions = {}; const data = { searchQuery: 'commonjs' }; diff --git a/code/addons/controls/src/server-channel/file-search-channel.ts b/code/addons/controls/src/server-channel/file-search-channel.ts index 75880af04d9d..e1786fe57a8a 100644 --- a/code/addons/controls/src/server-channel/file-search-channel.ts +++ b/code/addons/controls/src/server-channel/file-search-channel.ts @@ -1,14 +1,16 @@ import type { Options, SupportedRenderers } from '@storybook/types'; import type { Channel } from '@storybook/channels'; -import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '../constants'; -import { searchFiles } from '../utils/filesearch'; import { extractProperRendererNameFromFramework, getFrameworkName, getProjectRoot, } from '@storybook/core-common'; -import dedent from 'ts-dedent'; -import assert from 'node:assert'; +import path from 'path'; +import fs from 'fs/promises'; + +import { getParser } from '../utils/parser'; +import { searchFiles } from '../utils/search-files'; +import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '../constants'; interface Data { // A regular string or a glob pattern @@ -38,13 +40,15 @@ interface SearchResult { export function initFileSearchChannel(channel: Channel, options: Options) { /** - * Listenes for a search query event and searches for files in the project + * Listens for a search query event and searches for files in the project */ channel.on(FILE_COMPONENT_SEARCH, async (data: Data) => { try { const searchQuery = data?.searchQuery; - assert(searchQuery, 'searchQuery is required'); + if (!searchQuery) { + return; + } const frameworkName = await getFrameworkName(options); @@ -54,16 +58,35 @@ export function initFileSearchChannel(channel: Channel, options: Options) { const projectRoot = getProjectRoot(); - const files = await searchFiles(searchQuery, projectRoot, rendererName); + const files = await searchFiles({ + searchQuery, + cwd: projectRoot, + }); + + const entries = files.map(async (file) => { + const parser = getParser(rendererName); + + try { + const content = await fs.readFile(path.join(projectRoot, file), 'utf-8'); + const info = await parser.parse(content); + + return { + filepath: file, + exportedComponents: info.exports, + }; + } catch (e) { + return { + filepath: file, + exportedComponents: null, + }; + } + }); - /** - * Emits the search result event with the search result - */ channel.emit(FILE_COMPONENT_SEARCH_RESULT, { success: true, result: { searchQuery, - files, + files: await Promise.all(entries), }, error: null, } as SearchResult); @@ -74,10 +97,7 @@ export function initFileSearchChannel(channel: Channel, options: Options) { channel.emit(FILE_COMPONENT_SEARCH_RESULT, { success: false, result: null, - error: dedent` - An error occurred while searching for components in the project. - ${e?.message} - `, + error: `An error occurred while searching for components in the project.\n${e?.message}`, } as SearchResult); } }); diff --git a/code/addons/controls/src/utils/__tests__/src/assets/asset.png b/code/addons/controls/src/utils/__tests__/src/assets/asset.png index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1914264c08781d1f30ee0b8482bccf44586f2dc1 100644 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga%mF?ju0VQumF+E%TuG2$FoVOh l8)-lem#2$k2*>s01R$Gz9%CSj!PC{xWt~$(697H@6ZHT9 literal 0 HcmV?d00001 diff --git a/code/addons/controls/src/utils/__tests__/src/es-module.js b/code/addons/controls/src/utils/__tests__/src/es-module.js index e4785feb4fd1..34fc39774ae6 100644 --- a/code/addons/controls/src/utils/__tests__/src/es-module.js +++ b/code/addons/controls/src/utils/__tests__/src/es-module.js @@ -5,6 +5,8 @@ export var p = 5; export function q() {} +export class C {} + export { x as externalName } from 'external'; export { ns }; diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mjs b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mjs new file mode 100644 index 000000000000..970afab48505 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mjs @@ -0,0 +1,3 @@ +export default function () { + return 'default'; +} diff --git a/code/addons/controls/src/utils/filesearch.test.ts b/code/addons/controls/src/utils/filesearch.test.ts deleted file mode 100644 index e517b4708f8c..000000000000 --- a/code/addons/controls/src/utils/filesearch.test.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import path from 'path'; -import { searchFiles } from './filesearch'; - -describe('filesearch', () => { - describe('search result', () => { - it('should automatically convert static search to a dynamic glob search', async (t) => { - const files = await searchFiles('ommonjs', path.join(__dirname, '__tests__'), 'react'); - - expect(files?.map((f) => f.filepath)).toEqual([ - 'src/commonjs-module-default.js', - 'src/commonjs-module.js', - ]); - }); - - it('should automatically convert static search to a dynamic glob search (with file extension)', async (t) => { - const files = await searchFiles('module.js', path.join(__dirname, '__tests__'), 'react'); - - expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-module.js', 'src/es-module.js']); - }); - - it('should return all files if the search query matches the parent folder', async (t) => { - const files = await searchFiles('module', path.join(__dirname, '__tests__'), 'react'); - - expect(files?.map((f) => f.filepath)).toEqual([ - 'src/commonjs-module-default.js', - 'src/commonjs-module.js', - 'src/es-module.js', - ]); - }); - - it('should ignore files that do not have the allowed extensions', async (t) => { - const files = await searchFiles('asset', path.join(__dirname, '__tests__'), 'react'); - - expect(files).toEqual([]); - }); - - it('should ignore test files (*.spec.*, *.test.*)', async (t) => { - const files = await searchFiles('tests', path.join(__dirname, '__tests__'), 'react'); - - expect(files).toEqual([]); - }); - - it('should work with glob search patterns', async (t) => { - const files = await searchFiles( - '**/commonjs-module.js', - path.join(__dirname, '__tests__'), - 'react' - ); - - expect(files?.map((f) => f.filepath)).toEqual(['src/commonjs-module.js']); - }); - - it('should ignore node_modules', async (t) => { - const files = await searchFiles( - 'file-in-common.js', - path.join(__dirname, '__tests__'), - 'react' - ); - - expect(files).toEqual([]); - }); - }); - - describe('exported components', () => { - it('should correctly return the exported components', async (t) => { - const files = await searchFiles( - 'commonjs-module.js', - path.join(__dirname, '__tests__'), - 'react' - ); - - expect(files?.flatMap((f) => f.exportedComponents)).toHaveLength(5); - }); - - it('should return null for exportedComponents if parsing fails', async (t) => { - const files = await searchFiles('no-export.js', path.join(__dirname, '__tests__'), 'react'); - - expect(files).toEqual([ - { - exportedComponents: null, - filepath: 'src/no-export.js', - }, - ]); - }); - }); -}); diff --git a/code/addons/controls/src/utils/parser/generic-parser.test.ts b/code/addons/controls/src/utils/parser/generic-parser.test.ts index 02dce49436f1..df450fd797df 100644 --- a/code/addons/controls/src/utils/parser/generic-parser.test.ts +++ b/code/addons/controls/src/utils/parser/generic-parser.test.ts @@ -49,6 +49,10 @@ describe('generic-parser', () => { default: false, name: 'q', }, + { + default: false, + name: 'C', + }, { default: false, name: 'externalName', diff --git a/code/addons/controls/src/utils/parser/generic-parser.ts b/code/addons/controls/src/utils/parser/generic-parser.ts index 30562128eb1d..e297c1e92eed 100644 --- a/code/addons/controls/src/utils/parser/generic-parser.ts +++ b/code/addons/controls/src/utils/parser/generic-parser.ts @@ -40,10 +40,7 @@ export class GenericParser implements Parser { const { exports, reexports } = parseCjs(content); const filteredExports = [...exports, ...reexports].filter((e: string) => e !== '__esModule'); - assert( - filteredExports.length > 0, - 'No named exports found. Very likely that this is not a CJS module.' - ); + assert(filteredExports.length > 0, 'No named exports found'); return { exports: (filteredExports ?? []).map((name) => ({ diff --git a/code/addons/controls/src/utils/search-files.test.ts b/code/addons/controls/src/utils/search-files.test.ts new file mode 100644 index 000000000000..54e32858a63e --- /dev/null +++ b/code/addons/controls/src/utils/search-files.test.ts @@ -0,0 +1,86 @@ +import { describe, expect, it } from 'vitest'; +import path from 'path'; +import { searchFiles } from './search-files'; + +describe('search-files', () => { + it('should automatically convert static search to a dynamic glob search', async (t) => { + const files = await searchFiles({ + searchQuery: 'ommonjs', + cwd: path.join(__dirname, '__tests__'), + }); + + expect(files).toEqual(['src/commonjs-module-default.js', 'src/commonjs-module.js']); + }); + + it('should automatically convert static search to a dynamic glob search (with file extension)', async (t) => { + const files = await searchFiles({ + searchQuery: 'module.js', + cwd: path.join(__dirname, '__tests__'), + }); + + expect(files).toEqual(['src/commonjs-module.js', 'src/es-module.js']); + }); + + it('should return all files if the search query matches the parent folder', async (t) => { + const files = await searchFiles({ + searchQuery: 'file-extensions', + cwd: path.join(__dirname, '__tests__'), + }); + + expect(files).toEqual([ + 'src/file-extensions/extension.cjs', + 'src/file-extensions/extension.cts', + 'src/file-extensions/extension.js', + 'src/file-extensions/extension.jsx', + 'src/file-extensions/extension.mjs', + 'src/file-extensions/extension.mts', + 'src/file-extensions/extension.ts', + 'src/file-extensions/extension.tsx', + ]); + }); + + it('should ignore files that do not have the allowed extensions', async (t) => { + const files = await searchFiles({ + searchQuery: 'asset', + cwd: path.join(__dirname, '__tests__'), + }); + + expect(files).toEqual([]); + }); + + it('should ignore test files (*.spec.*, *.test.*)', async (t) => { + const files = await searchFiles({ + searchQuery: 'tests', + cwd: path.join(__dirname, '__tests__'), + }); + + expect(files).toEqual([]); + }); + + it('should work with glob search patterns', async (t) => { + const files = await searchFiles({ + searchQuery: '**/commonjs-module.js', + cwd: path.join(__dirname, '__tests__'), + }); + + expect(files).toEqual(['src/commonjs-module.js']); + }); + + it('should ignore node_modules', async (t) => { + const files = await searchFiles({ + searchQuery: 'file-in-common.js', + cwd: path.join(__dirname, '__tests__'), + }); + + expect(files).toEqual([]); + }); + + it('should not return files outside of project root', async (t) => { + await expect(() => + searchFiles({ + searchQuery: '../**/*', + cwd: path.join(__dirname, '__tests__'), + }) + ).rejects.toThrowError(); + }); +}); diff --git a/code/addons/controls/src/utils/filesearch.ts b/code/addons/controls/src/utils/search-files.ts similarity index 50% rename from code/addons/controls/src/utils/filesearch.ts rename to code/addons/controls/src/utils/search-files.ts index f375e983200a..b6f1bd89ab25 100644 --- a/code/addons/controls/src/utils/filesearch.ts +++ b/code/addons/controls/src/utils/search-files.ts @@ -1,21 +1,4 @@ -import path from 'path'; -import fs from 'fs'; - -import { getParser } from './parser'; -import { isNotNull } from './ts-utils'; -import type { SupportedRenderers } from '@storybook/types'; - -export type SearchResult = Array<{ - /** The path to the file relative to the project root */ - filepath: string; - /** - * The exported components in the file. - * It is null if the file couldn't be parsed or doesn't have any exports */ - exportedComponents: Array<{ - name: string; - default: boolean; - }> | null; -}>; +export type SearchResult = Array; /** * File extensions that should be searched for @@ -27,13 +10,15 @@ const fileExtensions = ['js', 'mjs', 'cjs', 'jsx', 'mts', 'ts', 'tsx', 'cts']; * @param searchQuery The search query. This can be a glob pattern * @param cwd The directory to search in * @param renderer The renderer to use for parsing the files - * @returns A list of files that match the search query and has exports + * @returns A list of files that match the search query */ -export async function searchFiles( - searchQuery: string, - cwd: string, - renderer: SupportedRenderers | null -): Promise { +export async function searchFiles({ + searchQuery, + cwd, +}: { + searchQuery: string; + cwd: string; +}): Promise { // Dynamically import globby because it is a pure ESM module const { globby, isDynamicPattern } = await import('globby'); @@ -59,23 +44,5 @@ export async function searchFiles( objectMode: true, }); - const files = entries.map(async (entry) => { - const parser = getParser(renderer); - const content = fs.readFileSync(path.join(cwd, entry.path), 'utf-8'); - - try { - const info = await parser.parse(content); - - return { - filepath: entry.path, - exportedComponents: info.exports, - }; - } catch (e) { - return { - filepath: entry.path, - exportedComponents: null, - }; - } - }); - return (await Promise.all(files)).filter(isNotNull); + return entries.map((entry) => entry.path); } diff --git a/code/addons/controls/src/utils/ts-utils.ts b/code/addons/controls/src/utils/ts-utils.ts deleted file mode 100644 index e3d720f8e17c..000000000000 --- a/code/addons/controls/src/utils/ts-utils.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Check if a value is not null. This is a type guard for TypeScript usually used in conjunction with array filter. - * @param value - The value to check - * @returns Whether the value is not null - */ -export function isNotNull(value: T | null): value is T { - return value !== null; -} diff --git a/code/lib/core-common/src/utils/normalize-path.test.ts b/code/lib/core-common/src/utils/normalize-path.test.ts index 5c10c487d5af..b2688660b6ef 100644 --- a/code/lib/core-common/src/utils/normalize-path.test.ts +++ b/code/lib/core-common/src/utils/normalize-path.test.ts @@ -6,5 +6,6 @@ describe('normalize-path', () => { expect(normalizePath('path/to/../file')).toBe('path/file'); expect(normalizePath('path/to/./file')).toBe('path/to/file'); expect(normalizePath('path\\to\\file')).toBe('path/to/file'); + expect(normalizePath('foo\\..\\bar')).toBe('bar'); }); }); diff --git a/code/lib/core-common/src/utils/normalize-path.ts b/code/lib/core-common/src/utils/normalize-path.ts index 7407ace285ca..782e792c1011 100644 --- a/code/lib/core-common/src/utils/normalize-path.ts +++ b/code/lib/core-common/src/utils/normalize-path.ts @@ -10,5 +10,5 @@ import path from 'path'; * normalizePath('path\\to\\file') // => 'path/to/file' */ export function normalizePath(p: string) { - return path.normalize(p).replace(/\\/g, '/'); + return path.normalize(p.replace(/\\/g, '/')); } From 7fec522a3cad5d23c08e680929b7a0e8f9f4546b Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 8 Apr 2024 14:42:20 +0200 Subject: [PATCH 29/42] Only eslintignore specific __tests__ directory --- code/.eslintignore | 2 +- code/addons/controls/src/utils/__tests__/README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 code/addons/controls/src/utils/__tests__/README.md diff --git a/code/.eslintignore b/code/.eslintignore index beba5132a1e5..11f8af7fff77 100644 --- a/code/.eslintignore +++ b/code/.eslintignore @@ -18,4 +18,4 @@ ember-output !.eslintrc-markdown.js !.storybook lib/core-common/templates/base-preview-head.html -__tests__ \ No newline at end of file +code/addons/controls/src/utils/__tests__ \ No newline at end of file diff --git a/code/addons/controls/src/utils/__tests__/README.md b/code/addons/controls/src/utils/__tests__/README.md new file mode 100644 index 000000000000..926c54d82404 --- /dev/null +++ b/code/addons/controls/src/utils/__tests__/README.md @@ -0,0 +1 @@ +The parent directory "\_\_tests\_\_ was created to unit test the search-file functionality From e36a1c0ad6bdcb6fa70e6ae808046a0629077955 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 8 Apr 2024 15:27:59 +0200 Subject: [PATCH 30/42] Fix eslintignore pattern --- code/.eslintignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/.eslintignore b/code/.eslintignore index 11f8af7fff77..bcc715b171a8 100644 --- a/code/.eslintignore +++ b/code/.eslintignore @@ -18,4 +18,4 @@ ember-output !.eslintrc-markdown.js !.storybook lib/core-common/templates/base-preview-head.html -code/addons/controls/src/utils/__tests__ \ No newline at end of file +addons/controls/src/utils/__tests__ \ No newline at end of file From 926472884e7e75f379ddd980478f59663c1ed23c Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 8 Apr 2024 16:01:42 +0200 Subject: [PATCH 31/42] Fix loading of experimental channel for essential addons --- code/addons/controls/src/preset.ts | 2 ++ code/addons/essentials/package.json | 3 +++ code/addons/essentials/preset.js | 1 + code/addons/essentials/src/preset.ts | 10 ++++++++++ code/yarn.lock | 2 ++ 5 files changed, 18 insertions(+) create mode 100644 code/addons/essentials/preset.js create mode 100644 code/addons/essentials/src/preset.ts diff --git a/code/addons/controls/src/preset.ts b/code/addons/controls/src/preset.ts index 0eea2c3485f4..cc227c5b6ccd 100644 --- a/code/addons/controls/src/preset.ts +++ b/code/addons/controls/src/preset.ts @@ -1,8 +1,10 @@ import type { Options } from '@storybook/types'; import type { Channel } from '@storybook/channels'; import { initFileSearchChannel } from './server-channel/file-search-channel'; +import { initCreateNewStoryChannel } from './server-channel/create-new-story-channel'; // eslint-disable-next-line @typescript-eslint/naming-convention export const experimental_serverChannel = async (channel: Channel, options: Options) => { + initCreateNewStoryChannel(channel, options); initFileSearchChannel(channel, options); }; diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index 2d22b284ac3d..c38ca9845ab1 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -98,10 +98,12 @@ "@storybook/addon-outline": "workspace:*", "@storybook/addon-toolbars": "workspace:*", "@storybook/addon-viewport": "workspace:*", + "@storybook/channels": "workspace:*", "@storybook/core-common": "workspace:*", "@storybook/manager-api": "workspace:*", "@storybook/node-logger": "workspace:*", "@storybook/preview-api": "workspace:*", + "@storybook/types": "workspace:*", "ts-dedent": "^2.0.0" }, "devDependencies": { @@ -113,6 +115,7 @@ "bundler": { "nodeEntries": [ "./src/index.ts", + "./src/preset.ts", "./src/docs/preset.ts", "./src/docs/mdx-react-shim.ts" ], diff --git a/code/addons/essentials/preset.js b/code/addons/essentials/preset.js new file mode 100644 index 000000000000..a83f95279e7f --- /dev/null +++ b/code/addons/essentials/preset.js @@ -0,0 +1 @@ +module.exports = require('./dist/preset'); diff --git a/code/addons/essentials/src/preset.ts b/code/addons/essentials/src/preset.ts new file mode 100644 index 000000000000..3e6004741ac7 --- /dev/null +++ b/code/addons/essentials/src/preset.ts @@ -0,0 +1,10 @@ +// @ts-expect-error no types +import { experimental_serverChannel as experimentalServerChannelControls } from '@storybook/addon-controls/dist/preset'; + +import type { Channel } from '@storybook/channels'; +import type { Options } from '@storybook/types'; + +// eslint-disable-next-line @typescript-eslint/naming-convention +export const experimental_serverChannel = async (channel: Channel, options: Options) => { + experimentalServerChannelControls(channel, options); +}; diff --git a/code/yarn.lock b/code/yarn.lock index e50a89d526de..7b3b1ceb2a00 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -4874,10 +4874,12 @@ __metadata: "@storybook/addon-outline": "workspace:*" "@storybook/addon-toolbars": "workspace:*" "@storybook/addon-viewport": "workspace:*" + "@storybook/channels": "workspace:*" "@storybook/core-common": "workspace:*" "@storybook/manager-api": "workspace:*" "@storybook/node-logger": "workspace:*" "@storybook/preview-api": "workspace:*" + "@storybook/types": "workspace:*" ts-dedent: "npm:^2.0.0" typescript: "npm:^5.3.2" languageName: unknown From 8cbb7fa200e8a0d766b8ee38872eeb0e5edf8a35 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 8 Apr 2024 16:52:38 +0200 Subject: [PATCH 32/42] Fix server channel registration --- code/addons/controls/src/preset.ts | 2 ++ code/addons/essentials/package.json | 1 + code/addons/essentials/src/preset.ts | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/addons/controls/src/preset.ts b/code/addons/controls/src/preset.ts index cc227c5b6ccd..a9593da44adc 100644 --- a/code/addons/controls/src/preset.ts +++ b/code/addons/controls/src/preset.ts @@ -7,4 +7,6 @@ import { initCreateNewStoryChannel } from './server-channel/create-new-story-cha export const experimental_serverChannel = async (channel: Channel, options: Options) => { initCreateNewStoryChannel(channel, options); initFileSearchChannel(channel, options); + + return channel; }; diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index c38ca9845ab1..e4056091d3bd 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -59,6 +59,7 @@ "require": "./dist/measure/preview.js" }, "./measure/manager": "./dist/measure/manager.js", + "./preset": "./dist/preset.js", "./outline/preview": { "types": "./dist/outline/preview.d.ts", "import": "./dist/outline/preview.mjs", diff --git a/code/addons/essentials/src/preset.ts b/code/addons/essentials/src/preset.ts index 3e6004741ac7..2e5ebcd07df4 100644 --- a/code/addons/essentials/src/preset.ts +++ b/code/addons/essentials/src/preset.ts @@ -1,5 +1,5 @@ // @ts-expect-error no types -import { experimental_serverChannel as experimentalServerChannelControls } from '@storybook/addon-controls/dist/preset'; +import { experimental_serverChannel as experimentalServerChannelControls } from '@storybook/addon-controls/preset'; import type { Channel } from '@storybook/channels'; import type { Options } from '@storybook/types'; @@ -7,4 +7,6 @@ import type { Options } from '@storybook/types'; // eslint-disable-next-line @typescript-eslint/naming-convention export const experimental_serverChannel = async (channel: Channel, options: Options) => { experimentalServerChannelControls(channel, options); + + return channel; }; From 58c9c7818479b8eeab8d23eabf0279fc1cddfe83 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 8 Apr 2024 16:54:24 +0200 Subject: [PATCH 33/42] Cleanup --- code/addons/controls/src/preset.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/addons/controls/src/preset.ts b/code/addons/controls/src/preset.ts index a9593da44adc..88cfe074eaf9 100644 --- a/code/addons/controls/src/preset.ts +++ b/code/addons/controls/src/preset.ts @@ -1,11 +1,9 @@ import type { Options } from '@storybook/types'; import type { Channel } from '@storybook/channels'; import { initFileSearchChannel } from './server-channel/file-search-channel'; -import { initCreateNewStoryChannel } from './server-channel/create-new-story-channel'; // eslint-disable-next-line @typescript-eslint/naming-convention export const experimental_serverChannel = async (channel: Channel, options: Options) => { - initCreateNewStoryChannel(channel, options); initFileSearchChannel(channel, options); return channel; From 23fce6f5c8177819d25630afad2989eadbb52a39 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 10:14:37 +0200 Subject: [PATCH 34/42] Fix normalization on windows --- code/lib/core-common/src/utils/normalize-path.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/core-common/src/utils/normalize-path.ts b/code/lib/core-common/src/utils/normalize-path.ts index 782e792c1011..a6db3aa2c9de 100644 --- a/code/lib/core-common/src/utils/normalize-path.ts +++ b/code/lib/core-common/src/utils/normalize-path.ts @@ -10,5 +10,5 @@ import path from 'path'; * normalizePath('path\\to\\file') // => 'path/to/file' */ export function normalizePath(p: string) { - return path.normalize(p.replace(/\\/g, '/')); + return path.posix.normalize(p.replace(/\\/g, '/')); } From 7b6e966543e6ab6d4404140788c5c009d0e0ca78 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 13:02:05 +0200 Subject: [PATCH 35/42] Move code to core-server --- code/addons/controls/package.json | 8 -------- code/addons/controls/preset.js | 1 - code/addons/controls/src/preset.ts | 10 ---------- code/addons/controls/src/utils/__tests__/.gitignore | 1 - code/addons/essentials/preset.js | 1 - code/addons/essentials/src/preset.ts | 12 ------------ code/lib/core-events/src/index.ts | 4 ++++ code/lib/core-server/package.json | 2 ++ .../src/server-channel/file-search-channel.test.ts | 2 +- .../src/server-channel/file-search-channel.ts | 2 +- .../src/utils/__search-files-tests__/.gitignore | 1 + .../src/utils/__search-files-tests__}/README.md | 0 .../__search-files-tests__}/src/assets/asset.css | 0 .../__search-files-tests__}/src/assets/asset.json | 0 .../__search-files-tests__}/src/assets/asset.png | Bin .../src/commonjs-module-default.js | 0 .../__search-files-tests__}/src/commonjs-module.js | 0 .../utils/__search-files-tests__}/src/es-module.js | 0 .../src/file-extensions/extension.cjs | 0 .../src/file-extensions/extension.cts | 0 .../src/file-extensions/extension.js | 0 .../src/file-extensions/extension.jsx | 0 .../src/file-extensions/extension.mjs | 0 .../src/file-extensions/extension.mts | 0 .../src/file-extensions/extension.ts | 0 .../src/file-extensions/extension.tsx | 0 .../utils/__search-files-tests__}/src/ignored.js | 0 .../utils/__search-files-tests__}/src/no-export.js | 0 .../src/node_modules/file-in-common.js | 0 .../__search-files-tests__}/src/tests/some.spec.ts | 0 .../__search-files-tests__}/src/tests/some.test.ts | 0 .../src/utils/parser/generic-parser.test.ts | 0 .../core-server}/src/utils/parser/generic-parser.ts | 0 .../core-server}/src/utils/parser/index.ts | 0 .../core-server}/src/utils/parser/types.ts | 0 .../core-server}/src/utils/search-files.test.ts | 0 .../core-server}/src/utils/search-files.ts | 0 code/yarn.lock | 6 ++---- 38 files changed, 11 insertions(+), 39 deletions(-) delete mode 100644 code/addons/controls/preset.js delete mode 100644 code/addons/controls/src/preset.ts delete mode 100644 code/addons/controls/src/utils/__tests__/.gitignore delete mode 100644 code/addons/essentials/preset.js delete mode 100644 code/addons/essentials/src/preset.ts rename code/{addons/controls => lib/core-server}/src/server-channel/file-search-channel.test.ts (99%) rename code/{addons/controls => lib/core-server}/src/server-channel/file-search-channel.ts (98%) create mode 100644 code/lib/core-server/src/utils/__search-files-tests__/.gitignore rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/README.md (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/assets/asset.css (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/assets/asset.json (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/assets/asset.png (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/commonjs-module-default.js (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/commonjs-module.js (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/es-module.js (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.cjs (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.cts (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.js (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.jsx (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.mjs (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.mts (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.ts (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/file-extensions/extension.tsx (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/ignored.js (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/no-export.js (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/node_modules/file-in-common.js (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/tests/some.spec.ts (100%) rename code/{addons/controls/src/utils/__tests__ => lib/core-server/src/utils/__search-files-tests__}/src/tests/some.test.ts (100%) rename code/{addons/controls => lib/core-server}/src/utils/parser/generic-parser.test.ts (100%) rename code/{addons/controls => lib/core-server}/src/utils/parser/generic-parser.ts (100%) rename code/{addons/controls => lib/core-server}/src/utils/parser/index.ts (100%) rename code/{addons/controls => lib/core-server}/src/utils/parser/types.ts (100%) rename code/{addons/controls => lib/core-server}/src/utils/search-files.test.ts (100%) rename code/{addons/controls => lib/core-server}/src/utils/search-files.ts (100%) diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index 74bc77b72a22..d0ae7fea7e3f 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -33,7 +33,6 @@ "import": "./dist/index.mjs" }, "./manager": "./dist/manager.js", - "./preset": "./dist/preset.js", "./register": "./dist/manager.js", "./package.json": "./package.json" }, @@ -53,10 +52,6 @@ }, "dependencies": { "@storybook/blocks": "workspace:*", - "@storybook/core-common": "workspace:*", - "cjs-module-lexer": "^1.2.3", - "es-module-lexer": "^1.5.0", - "globby": "^14.0.1", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" }, @@ -75,9 +70,6 @@ "access": "public" }, "bundler": { - "nodeEntries": [ - "./src/preset.ts" - ], "exportEntries": [ "./src/index.ts" ], diff --git a/code/addons/controls/preset.js b/code/addons/controls/preset.js deleted file mode 100644 index a83f95279e7f..000000000000 --- a/code/addons/controls/preset.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/preset'); diff --git a/code/addons/controls/src/preset.ts b/code/addons/controls/src/preset.ts deleted file mode 100644 index 88cfe074eaf9..000000000000 --- a/code/addons/controls/src/preset.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { Options } from '@storybook/types'; -import type { Channel } from '@storybook/channels'; -import { initFileSearchChannel } from './server-channel/file-search-channel'; - -// eslint-disable-next-line @typescript-eslint/naming-convention -export const experimental_serverChannel = async (channel: Channel, options: Options) => { - initFileSearchChannel(channel, options); - - return channel; -}; diff --git a/code/addons/controls/src/utils/__tests__/.gitignore b/code/addons/controls/src/utils/__tests__/.gitignore deleted file mode 100644 index 7e4e8f40e4f1..000000000000 --- a/code/addons/controls/src/utils/__tests__/.gitignore +++ /dev/null @@ -1 +0,0 @@ -src/ignored.js \ No newline at end of file diff --git a/code/addons/essentials/preset.js b/code/addons/essentials/preset.js deleted file mode 100644 index a83f95279e7f..000000000000 --- a/code/addons/essentials/preset.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/preset'); diff --git a/code/addons/essentials/src/preset.ts b/code/addons/essentials/src/preset.ts deleted file mode 100644 index 2e5ebcd07df4..000000000000 --- a/code/addons/essentials/src/preset.ts +++ /dev/null @@ -1,12 +0,0 @@ -// @ts-expect-error no types -import { experimental_serverChannel as experimentalServerChannelControls } from '@storybook/addon-controls/preset'; - -import type { Channel } from '@storybook/channels'; -import type { Options } from '@storybook/types'; - -// eslint-disable-next-line @typescript-eslint/naming-convention -export const experimental_serverChannel = async (channel: Channel, options: Options) => { - experimentalServerChannelControls(channel, options); - - return channel; -}; diff --git a/code/lib/core-events/src/index.ts b/code/lib/core-events/src/index.ts index 7542d0aa4e57..112a6f99ac23 100644 --- a/code/lib/core-events/src/index.ts +++ b/code/lib/core-events/src/index.ts @@ -73,6 +73,8 @@ enum events { SET_WHATS_NEW_CACHE = 'setWhatsNewCache', TOGGLE_WHATS_NEW_NOTIFICATIONS = 'toggleWhatsNewNotifications', TELEMETRY_ERROR = 'telemetryError', + FILE_COMPONENT_SEARCH = 'fileComponentSearch', + FILE_COMPONENT_SEARCH_RESULT = 'fileComponentSearchResult', } // Enables: `import Events from ...` @@ -87,6 +89,8 @@ export const { CURRENT_STORY_WAS_SET, DOCS_PREPARED, DOCS_RENDERED, + FILE_COMPONENT_SEARCH_RESULT, + FILE_COMPONENT_SEARCH, FORCE_RE_RENDER, FORCE_REMOUNT, GLOBALS_UPDATED, diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index 58f6be3c9d46..64c7893f8523 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -78,9 +78,11 @@ "@types/semver": "^7.3.4", "better-opn": "^3.0.2", "chalk": "^4.1.0", + "cjs-module-lexer": "^1.2.3", "cli-table3": "^0.6.1", "compression": "^1.7.4", "detect-port": "^1.3.0", + "es-module-lexer": "^1.5.0", "express": "^4.17.3", "fs-extra": "^11.1.0", "globby": "^14.0.1", diff --git a/code/addons/controls/src/server-channel/file-search-channel.test.ts b/code/lib/core-server/src/server-channel/file-search-channel.test.ts similarity index 99% rename from code/addons/controls/src/server-channel/file-search-channel.test.ts rename to code/lib/core-server/src/server-channel/file-search-channel.test.ts index b2d6b2db1b06..33c2e234329b 100644 --- a/code/addons/controls/src/server-channel/file-search-channel.test.ts +++ b/code/lib/core-server/src/server-channel/file-search-channel.test.ts @@ -1,6 +1,6 @@ import type { ChannelTransport } from '@storybook/channels'; import { Channel } from '@storybook/channels'; -import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '../constants'; +import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '@storybook/core-events'; import { initFileSearchChannel } from './file-search-channel'; import { beforeEach, describe, expect, vi, it } from 'vitest'; diff --git a/code/addons/controls/src/server-channel/file-search-channel.ts b/code/lib/core-server/src/server-channel/file-search-channel.ts similarity index 98% rename from code/addons/controls/src/server-channel/file-search-channel.ts rename to code/lib/core-server/src/server-channel/file-search-channel.ts index e1786fe57a8a..3f2884867447 100644 --- a/code/addons/controls/src/server-channel/file-search-channel.ts +++ b/code/lib/core-server/src/server-channel/file-search-channel.ts @@ -10,7 +10,7 @@ import fs from 'fs/promises'; import { getParser } from '../utils/parser'; import { searchFiles } from '../utils/search-files'; -import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '../constants'; +import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '@storybook/core-events'; interface Data { // A regular string or a glob pattern diff --git a/code/lib/core-server/src/utils/__search-files-tests__/.gitignore b/code/lib/core-server/src/utils/__search-files-tests__/.gitignore new file mode 100644 index 000000000000..736e8ae58ad8 --- /dev/null +++ b/code/lib/core-server/src/utils/__search-files-tests__/.gitignore @@ -0,0 +1 @@ +!node_modules \ No newline at end of file diff --git a/code/addons/controls/src/utils/__tests__/README.md b/code/lib/core-server/src/utils/__search-files-tests__/README.md similarity index 100% rename from code/addons/controls/src/utils/__tests__/README.md rename to code/lib/core-server/src/utils/__search-files-tests__/README.md diff --git a/code/addons/controls/src/utils/__tests__/src/assets/asset.css b/code/lib/core-server/src/utils/__search-files-tests__/src/assets/asset.css similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/assets/asset.css rename to code/lib/core-server/src/utils/__search-files-tests__/src/assets/asset.css diff --git a/code/addons/controls/src/utils/__tests__/src/assets/asset.json b/code/lib/core-server/src/utils/__search-files-tests__/src/assets/asset.json similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/assets/asset.json rename to code/lib/core-server/src/utils/__search-files-tests__/src/assets/asset.json diff --git a/code/addons/controls/src/utils/__tests__/src/assets/asset.png b/code/lib/core-server/src/utils/__search-files-tests__/src/assets/asset.png similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/assets/asset.png rename to code/lib/core-server/src/utils/__search-files-tests__/src/assets/asset.png diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs-module-default.js b/code/lib/core-server/src/utils/__search-files-tests__/src/commonjs-module-default.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/commonjs-module-default.js rename to code/lib/core-server/src/utils/__search-files-tests__/src/commonjs-module-default.js diff --git a/code/addons/controls/src/utils/__tests__/src/commonjs-module.js b/code/lib/core-server/src/utils/__search-files-tests__/src/commonjs-module.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/commonjs-module.js rename to code/lib/core-server/src/utils/__search-files-tests__/src/commonjs-module.js diff --git a/code/addons/controls/src/utils/__tests__/src/es-module.js b/code/lib/core-server/src/utils/__search-files-tests__/src/es-module.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/es-module.js rename to code/lib/core-server/src/utils/__search-files-tests__/src/es-module.js diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cjs b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.cjs similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cjs rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.cjs diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cts b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.cts similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.cts rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.cts diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.js b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.js rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.js diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.jsx b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.jsx similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.jsx rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.jsx diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mjs b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.mjs similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mjs rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.mjs diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mts b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.mts similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.mts rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.mts diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.ts b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.ts similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.ts rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.ts diff --git a/code/addons/controls/src/utils/__tests__/src/file-extensions/extension.tsx b/code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.tsx similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/file-extensions/extension.tsx rename to code/lib/core-server/src/utils/__search-files-tests__/src/file-extensions/extension.tsx diff --git a/code/addons/controls/src/utils/__tests__/src/ignored.js b/code/lib/core-server/src/utils/__search-files-tests__/src/ignored.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/ignored.js rename to code/lib/core-server/src/utils/__search-files-tests__/src/ignored.js diff --git a/code/addons/controls/src/utils/__tests__/src/no-export.js b/code/lib/core-server/src/utils/__search-files-tests__/src/no-export.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/no-export.js rename to code/lib/core-server/src/utils/__search-files-tests__/src/no-export.js diff --git a/code/addons/controls/src/utils/__tests__/src/node_modules/file-in-common.js b/code/lib/core-server/src/utils/__search-files-tests__/src/node_modules/file-in-common.js similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/node_modules/file-in-common.js rename to code/lib/core-server/src/utils/__search-files-tests__/src/node_modules/file-in-common.js diff --git a/code/addons/controls/src/utils/__tests__/src/tests/some.spec.ts b/code/lib/core-server/src/utils/__search-files-tests__/src/tests/some.spec.ts similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/tests/some.spec.ts rename to code/lib/core-server/src/utils/__search-files-tests__/src/tests/some.spec.ts diff --git a/code/addons/controls/src/utils/__tests__/src/tests/some.test.ts b/code/lib/core-server/src/utils/__search-files-tests__/src/tests/some.test.ts similarity index 100% rename from code/addons/controls/src/utils/__tests__/src/tests/some.test.ts rename to code/lib/core-server/src/utils/__search-files-tests__/src/tests/some.test.ts diff --git a/code/addons/controls/src/utils/parser/generic-parser.test.ts b/code/lib/core-server/src/utils/parser/generic-parser.test.ts similarity index 100% rename from code/addons/controls/src/utils/parser/generic-parser.test.ts rename to code/lib/core-server/src/utils/parser/generic-parser.test.ts diff --git a/code/addons/controls/src/utils/parser/generic-parser.ts b/code/lib/core-server/src/utils/parser/generic-parser.ts similarity index 100% rename from code/addons/controls/src/utils/parser/generic-parser.ts rename to code/lib/core-server/src/utils/parser/generic-parser.ts diff --git a/code/addons/controls/src/utils/parser/index.ts b/code/lib/core-server/src/utils/parser/index.ts similarity index 100% rename from code/addons/controls/src/utils/parser/index.ts rename to code/lib/core-server/src/utils/parser/index.ts diff --git a/code/addons/controls/src/utils/parser/types.ts b/code/lib/core-server/src/utils/parser/types.ts similarity index 100% rename from code/addons/controls/src/utils/parser/types.ts rename to code/lib/core-server/src/utils/parser/types.ts diff --git a/code/addons/controls/src/utils/search-files.test.ts b/code/lib/core-server/src/utils/search-files.test.ts similarity index 100% rename from code/addons/controls/src/utils/search-files.test.ts rename to code/lib/core-server/src/utils/search-files.test.ts diff --git a/code/addons/controls/src/utils/search-files.ts b/code/lib/core-server/src/utils/search-files.ts similarity index 100% rename from code/addons/controls/src/utils/search-files.ts rename to code/lib/core-server/src/utils/search-files.ts diff --git a/code/yarn.lock b/code/yarn.lock index 7b3b1ceb2a00..388606f61c43 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -4790,15 +4790,11 @@ __metadata: "@storybook/blocks": "workspace:*" "@storybook/client-logger": "workspace:*" "@storybook/components": "workspace:*" - "@storybook/core-common": "workspace:*" "@storybook/manager-api": "workspace:*" "@storybook/node-logger": "workspace:*" "@storybook/preview-api": "workspace:*" "@storybook/theming": "workspace:*" "@storybook/types": "workspace:*" - cjs-module-lexer: "npm:^1.2.3" - es-module-lexer: "npm:^1.5.0" - globby: "npm:^14.0.1" lodash: "npm:^4.17.21" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" @@ -5601,9 +5597,11 @@ __metadata: better-opn: "npm:^3.0.2" boxen: "npm:^7.1.1" chalk: "npm:^4.1.0" + cjs-module-lexer: "npm:^1.2.3" cli-table3: "npm:^0.6.1" compression: "npm:^1.7.4" detect-port: "npm:^1.3.0" + es-module-lexer: "npm:^1.5.0" express: "npm:^4.17.3" fs-extra: "npm:^11.1.0" globby: "npm:^14.0.1" From e67928a4a2c9d2b346c5f68049537e0f5132daab Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 13:02:32 +0200 Subject: [PATCH 36/42] Adjust gitignore --- .../lib/core-server/src/utils/__search-files-tests__/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/core-server/src/utils/__search-files-tests__/.gitignore b/code/lib/core-server/src/utils/__search-files-tests__/.gitignore index 736e8ae58ad8..7e4e8f40e4f1 100644 --- a/code/lib/core-server/src/utils/__search-files-tests__/.gitignore +++ b/code/lib/core-server/src/utils/__search-files-tests__/.gitignore @@ -1 +1 @@ -!node_modules \ No newline at end of file +src/ignored.js \ No newline at end of file From 7f5b3b6c26682863c6900725c49ee8a3ba5ca4d8 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 13:19:38 +0200 Subject: [PATCH 37/42] Fix tests and finalize --- code/lib/core-events/src/index.ts | 2 +- .../lib/core-server/src/presets/common-preset.ts | 3 +++ .../server-channel/file-search-channel.test.ts | 5 +++-- .../src/utils/parser/generic-parser.test.ts | 2 +- .../core-server/src/utils/search-files.test.ts | 16 ++++++++-------- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/code/lib/core-events/src/index.ts b/code/lib/core-events/src/index.ts index 112a6f99ac23..82978a994d07 100644 --- a/code/lib/core-events/src/index.ts +++ b/code/lib/core-events/src/index.ts @@ -89,8 +89,8 @@ export const { CURRENT_STORY_WAS_SET, DOCS_PREPARED, DOCS_RENDERED, - FILE_COMPONENT_SEARCH_RESULT, FILE_COMPONENT_SEARCH, + FILE_COMPONENT_SEARCH_RESULT, FORCE_RE_RENDER, FORCE_REMOUNT, GLOBALS_UPDATED, diff --git a/code/lib/core-server/src/presets/common-preset.ts b/code/lib/core-server/src/presets/common-preset.ts index 6dcd6366eff0..fbc39465aad4 100644 --- a/code/lib/core-server/src/presets/common-preset.ts +++ b/code/lib/core-server/src/presets/common-preset.ts @@ -34,6 +34,7 @@ import invariant from 'tiny-invariant'; import { parseStaticDir } from '../utils/server-statics'; import { defaultStaticDirs } from '../utils/constants'; import { sendTelemetryError } from '../withTelemetry'; +import { initFileSearchChannel } from '../server-channel/file-search-channel'; const interpolate = (string: string, data: Record = {}) => Object.entries(data).reduce((acc, [k, v]) => acc.replace(new RegExp(`%${k}%`, 'g'), v), string); @@ -340,6 +341,8 @@ export const experimental_serverChannel = async ( } }); + initFileSearchChannel(channel, options); + return channel; }; diff --git a/code/lib/core-server/src/server-channel/file-search-channel.test.ts b/code/lib/core-server/src/server-channel/file-search-channel.test.ts index 33c2e234329b..e967910dd6c7 100644 --- a/code/lib/core-server/src/server-channel/file-search-channel.test.ts +++ b/code/lib/core-server/src/server-channel/file-search-channel.test.ts @@ -1,9 +1,10 @@ import type { ChannelTransport } from '@storybook/channels'; import { Channel } from '@storybook/channels'; import { FILE_COMPONENT_SEARCH, FILE_COMPONENT_SEARCH_RESULT } from '@storybook/core-events'; -import { initFileSearchChannel } from './file-search-channel'; import { beforeEach, describe, expect, vi, it } from 'vitest'; +import { initFileSearchChannel } from './file-search-channel'; + const mocks = vi.hoisted(() => { return { searchFiles: vi.fn(), @@ -24,7 +25,7 @@ vi.mock('@storybook/core-common', async (importOriginal) => { extractProperRendererNameFromFramework: vi.fn().mockResolvedValue('react'), getProjectRoot: vi .fn() - .mockReturnValue(require('path').join(__dirname, '..', 'utils', '__tests__')), + .mockReturnValue(require('path').join(__dirname, '..', 'utils', '__search-files-tests__')), }; }); diff --git a/code/lib/core-server/src/utils/parser/generic-parser.test.ts b/code/lib/core-server/src/utils/parser/generic-parser.test.ts index df450fd797df..6d3ff96e15b0 100644 --- a/code/lib/core-server/src/utils/parser/generic-parser.test.ts +++ b/code/lib/core-server/src/utils/parser/generic-parser.test.ts @@ -5,7 +5,7 @@ import fs from 'fs'; const genericParser = new GenericParser(); -const TEST_DIR = path.join(__dirname, '..', '__tests__'); +const TEST_DIR = path.join(__dirname, '..', '__search-files-tests__'); describe('generic-parser', () => { it('should correctly return exports from CommonJS files', async () => { diff --git a/code/lib/core-server/src/utils/search-files.test.ts b/code/lib/core-server/src/utils/search-files.test.ts index 54e32858a63e..6aaec136df74 100644 --- a/code/lib/core-server/src/utils/search-files.test.ts +++ b/code/lib/core-server/src/utils/search-files.test.ts @@ -6,7 +6,7 @@ describe('search-files', () => { it('should automatically convert static search to a dynamic glob search', async (t) => { const files = await searchFiles({ searchQuery: 'ommonjs', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }); expect(files).toEqual(['src/commonjs-module-default.js', 'src/commonjs-module.js']); @@ -15,7 +15,7 @@ describe('search-files', () => { it('should automatically convert static search to a dynamic glob search (with file extension)', async (t) => { const files = await searchFiles({ searchQuery: 'module.js', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }); expect(files).toEqual(['src/commonjs-module.js', 'src/es-module.js']); @@ -24,7 +24,7 @@ describe('search-files', () => { it('should return all files if the search query matches the parent folder', async (t) => { const files = await searchFiles({ searchQuery: 'file-extensions', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }); expect(files).toEqual([ @@ -42,7 +42,7 @@ describe('search-files', () => { it('should ignore files that do not have the allowed extensions', async (t) => { const files = await searchFiles({ searchQuery: 'asset', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }); expect(files).toEqual([]); @@ -51,7 +51,7 @@ describe('search-files', () => { it('should ignore test files (*.spec.*, *.test.*)', async (t) => { const files = await searchFiles({ searchQuery: 'tests', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }); expect(files).toEqual([]); @@ -60,7 +60,7 @@ describe('search-files', () => { it('should work with glob search patterns', async (t) => { const files = await searchFiles({ searchQuery: '**/commonjs-module.js', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }); expect(files).toEqual(['src/commonjs-module.js']); @@ -69,7 +69,7 @@ describe('search-files', () => { it('should ignore node_modules', async (t) => { const files = await searchFiles({ searchQuery: 'file-in-common.js', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }); expect(files).toEqual([]); @@ -79,7 +79,7 @@ describe('search-files', () => { await expect(() => searchFiles({ searchQuery: '../**/*', - cwd: path.join(__dirname, '__tests__'), + cwd: path.join(__dirname, '__search-files-tests__'), }) ).rejects.toThrowError(); }); From 314112af20d11a9fad82b38b486b5dc2890698b0 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 13:20:09 +0200 Subject: [PATCH 38/42] Adjust eslintignore --- code/.eslintignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/.eslintignore b/code/.eslintignore index bcc715b171a8..5ced53c96672 100644 --- a/code/.eslintignore +++ b/code/.eslintignore @@ -18,4 +18,4 @@ ember-output !.eslintrc-markdown.js !.storybook lib/core-common/templates/base-preview-head.html -addons/controls/src/utils/__tests__ \ No newline at end of file +lib/core-server/src/utils/__search-files-tests__ \ No newline at end of file From 81ce3d48bdf52bd31e8d403caf470078c22dd6bb Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 13:21:43 +0200 Subject: [PATCH 39/42] Update manager global exports --- code/ui/manager/src/globals/exports.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/ui/manager/src/globals/exports.ts b/code/ui/manager/src/globals/exports.ts index 73881b9b5919..794741a69e8b 100644 --- a/code/ui/manager/src/globals/exports.ts +++ b/code/ui/manager/src/globals/exports.ts @@ -136,6 +136,8 @@ export default { 'CURRENT_STORY_WAS_SET', 'DOCS_PREPARED', 'DOCS_RENDERED', + 'FILE_COMPONENT_SEARCH', + 'FILE_COMPONENT_SEARCH_RESULT', 'FORCE_REMOUNT', 'FORCE_RE_RENDER', 'GLOBALS_UPDATED', From 423d404bd4ed25900c8fe8c93d9cbd45427e7f5a Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 13:42:49 +0200 Subject: [PATCH 40/42] Remove leftovers --- code/addons/controls/package.json | 1 + code/addons/controls/src/constants.ts | 2 -- code/addons/essentials/package.json | 4 ---- code/ui/manager/src/globals/exports.ts | 2 ++ 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index d0ae7fea7e3f..d13ea6560843 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -58,6 +58,7 @@ "devDependencies": { "@storybook/client-logger": "workspace:*", "@storybook/components": "workspace:*", + "@storybook/core-common": "workspace:*", "@storybook/manager-api": "workspace:*", "@storybook/node-logger": "workspace:*", "@storybook/preview-api": "workspace:*", diff --git a/code/addons/controls/src/constants.ts b/code/addons/controls/src/constants.ts index fc0f91e21ec8..a2360dfff87c 100644 --- a/code/addons/controls/src/constants.ts +++ b/code/addons/controls/src/constants.ts @@ -1,4 +1,2 @@ export const ADDON_ID = 'addon-controls' as const; export const PARAM_KEY = 'controls' as const; -export const FILE_COMPONENT_SEARCH = 'file-component-search' as const; -export const FILE_COMPONENT_SEARCH_RESULT = 'file-component-search-result' as const; diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index e4056091d3bd..2d22b284ac3d 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -59,7 +59,6 @@ "require": "./dist/measure/preview.js" }, "./measure/manager": "./dist/measure/manager.js", - "./preset": "./dist/preset.js", "./outline/preview": { "types": "./dist/outline/preview.d.ts", "import": "./dist/outline/preview.mjs", @@ -99,12 +98,10 @@ "@storybook/addon-outline": "workspace:*", "@storybook/addon-toolbars": "workspace:*", "@storybook/addon-viewport": "workspace:*", - "@storybook/channels": "workspace:*", "@storybook/core-common": "workspace:*", "@storybook/manager-api": "workspace:*", "@storybook/node-logger": "workspace:*", "@storybook/preview-api": "workspace:*", - "@storybook/types": "workspace:*", "ts-dedent": "^2.0.0" }, "devDependencies": { @@ -116,7 +113,6 @@ "bundler": { "nodeEntries": [ "./src/index.ts", - "./src/preset.ts", "./src/docs/preset.ts", "./src/docs/mdx-react-shim.ts" ], diff --git a/code/ui/manager/src/globals/exports.ts b/code/ui/manager/src/globals/exports.ts index 794741a69e8b..d3da898e844c 100644 --- a/code/ui/manager/src/globals/exports.ts +++ b/code/ui/manager/src/globals/exports.ts @@ -133,6 +133,8 @@ export default { 'CHANNEL_CREATED', 'CHANNEL_WS_DISCONNECT', 'CONFIG_ERROR', + 'CREATE_NEW_STORYFILE', + 'CREATE_NEW_STORYFILE_RESULT', 'CURRENT_STORY_WAS_SET', 'DOCS_PREPARED', 'DOCS_RENDERED', From b2d3149d150f77e1a84660a73f38717f5d622ecc Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 13:50:11 +0200 Subject: [PATCH 41/42] Update lock file --- code/yarn.lock | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/yarn.lock b/code/yarn.lock index 388606f61c43..7be8a5f1fd96 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -4790,6 +4790,7 @@ __metadata: "@storybook/blocks": "workspace:*" "@storybook/client-logger": "workspace:*" "@storybook/components": "workspace:*" + "@storybook/core-common": "workspace:*" "@storybook/manager-api": "workspace:*" "@storybook/node-logger": "workspace:*" "@storybook/preview-api": "workspace:*" @@ -4870,12 +4871,10 @@ __metadata: "@storybook/addon-outline": "workspace:*" "@storybook/addon-toolbars": "workspace:*" "@storybook/addon-viewport": "workspace:*" - "@storybook/channels": "workspace:*" "@storybook/core-common": "workspace:*" "@storybook/manager-api": "workspace:*" "@storybook/node-logger": "workspace:*" "@storybook/preview-api": "workspace:*" - "@storybook/types": "workspace:*" ts-dedent: "npm:^2.0.0" typescript: "npm:^5.3.2" languageName: unknown From 4d055fb0230c2d09308079e8c15affc5af143c12 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 9 Apr 2024 14:22:09 +0200 Subject: [PATCH 42/42] Update exports --- code/ui/manager/src/globals/exports.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/ui/manager/src/globals/exports.ts b/code/ui/manager/src/globals/exports.ts index d3da898e844c..794741a69e8b 100644 --- a/code/ui/manager/src/globals/exports.ts +++ b/code/ui/manager/src/globals/exports.ts @@ -133,8 +133,6 @@ export default { 'CHANNEL_CREATED', 'CHANNEL_WS_DISCONNECT', 'CONFIG_ERROR', - 'CREATE_NEW_STORYFILE', - 'CREATE_NEW_STORYFILE_RESULT', 'CURRENT_STORY_WAS_SET', 'DOCS_PREPARED', 'DOCS_RENDERED',