From fc38e731eb4b99f138d869675842199c977aa6ec Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 6 Oct 2022 11:38:41 +0200 Subject: [PATCH 1/7] flatten the files esbuild outputs, to make loading addons in the manager more robust --- code/lib/builder-manager/src/utils/files.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/code/lib/builder-manager/src/utils/files.ts b/code/lib/builder-manager/src/utils/files.ts index 56c6204ead56..d98f82f13c84 100644 --- a/code/lib/builder-manager/src/utils/files.ts +++ b/code/lib/builder-manager/src/utils/files.ts @@ -1,11 +1,20 @@ import { writeFile, ensureFile } from 'fs-extra'; +import { join } from 'path'; import { compilation } from '../index'; export async function readOrderedFiles(addonsDir: string) { const files = await Promise.all( compilation?.outputFiles?.map(async (file) => { - await ensureFile(file.path).then(() => writeFile(file.path, file.contents)); - return file.path.replace(addonsDir, './sb-addons'); + // convert deeply nested paths to a single level, also remove special characters + const filePath = file.path + .replace(addonsDir, '') + .replace(/[^a-z0-9\-.]+/g, '-') + .replace(/^-/, '/'); + const location = join(addonsDir, filePath); + const url = `./sb-addons${filePath}`; + + await ensureFile(location).then(() => writeFile(location, file.contents)); + return url; }) || [] ); From d01e3628e134e61736711c5b135a4bcc8dbe1535 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 6 Oct 2022 12:50:11 +0200 Subject: [PATCH 2/7] add a test for the path conversion code --- code/lib/builder-manager/src/index.ts | 5 ++-- .../builder-manager/src/utils/files.test.ts | 19 +++++++++++++++ code/lib/builder-manager/src/utils/files.ts | 24 ++++++++++++------- 3 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 code/lib/builder-manager/src/utils/files.test.ts diff --git a/code/lib/builder-manager/src/index.ts b/code/lib/builder-manager/src/index.ts index fb36d1e42638..eb99070b8877 100644 --- a/code/lib/builder-manager/src/index.ts +++ b/code/lib/builder-manager/src/index.ts @@ -23,8 +23,7 @@ import { getData } from './utils/data'; import { safeResolve } from './utils/safeResolve'; import { readOrderedFiles } from './utils/files'; -// eslint-disable-next-line import/no-mutable-exports -export let compilation: Compilation; +let compilation: Compilation; let asyncIterator: ReturnType | ReturnType; export const getConfig: ManagerBuilder['getConfig'] = async (options) => { @@ -128,7 +127,7 @@ const starter: StarterFunction = async function* starterGeneratorFn({ router.use(`/sb-addons`, express.static(addonsDir)); router.use(`/sb-manager`, express.static(coreDirOrigin)); - const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir); + const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation); yield; diff --git a/code/lib/builder-manager/src/utils/files.test.ts b/code/lib/builder-manager/src/utils/files.test.ts new file mode 100644 index 000000000000..807154ec679a --- /dev/null +++ b/code/lib/builder-manager/src/utils/files.test.ts @@ -0,0 +1,19 @@ +import { sanatizePath } from './files'; + +test('sanatizePath', () => { + const addonsDir = '/Users/username/Projects/projectname/storybook'; + const text = 'demo text'; + const file = { + path: '/Users/username/Projects/projectname/storybook/node_modules/@storybook/addon-x/dist/manager.mjs', + contents: Uint8Array.from(Array.from(text).map((letter) => letter.charCodeAt(0))), + text, + }; + const { location, url } = sanatizePath(file, addonsDir); + + expect(location).toMatchInlineSnapshot( + `"/Users/username/Projects/projectname/storybook/node-modules-storybook-addon-x-dist-manager.mjs"` + ); + expect(url).toMatchInlineSnapshot( + `"./sb-addons/node-modules-storybook-addon-x-dist-manager.mjs"` + ); +}); diff --git a/code/lib/builder-manager/src/utils/files.ts b/code/lib/builder-manager/src/utils/files.ts index d98f82f13c84..4b96722fa4e0 100644 --- a/code/lib/builder-manager/src/utils/files.ts +++ b/code/lib/builder-manager/src/utils/files.ts @@ -1,17 +1,13 @@ +import { OutputFile } from 'esbuild'; import { writeFile, ensureFile } from 'fs-extra'; import { join } from 'path'; -import { compilation } from '../index'; +import { Compilation } from '../types'; -export async function readOrderedFiles(addonsDir: string) { +export async function readOrderedFiles(addonsDir: string, outputFiles: Compilation['outputFiles']) { const files = await Promise.all( - compilation?.outputFiles?.map(async (file) => { + outputFiles?.map(async (file) => { // convert deeply nested paths to a single level, also remove special characters - const filePath = file.path - .replace(addonsDir, '') - .replace(/[^a-z0-9\-.]+/g, '-') - .replace(/^-/, '/'); - const location = join(addonsDir, filePath); - const url = `./sb-addons${filePath}`; + const { location, url } = sanatizePath(file, addonsDir); await ensureFile(location).then(() => writeFile(location, file.contents)); return url; @@ -22,3 +18,13 @@ export async function readOrderedFiles(addonsDir: string) { const cssFiles = files.filter((file) => file.endsWith('.css')); return { cssFiles, jsFiles }; } + +export function sanatizePath(file: OutputFile, addonsDir: string) { + const filePath = file.path + .replace(addonsDir, '') + .replace(/[^a-z0-9\-.]+/g, '-') + .replace(/^-/, '/'); + const location = join(addonsDir, filePath); + const url = `./sb-addons${filePath}`; + return { location, url }; +} From fc1c4cc18d2164e43f1c0576911a1c44ffd1c522 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 6 Oct 2022 12:56:00 +0200 Subject: [PATCH 3/7] fix --- code/lib/builder-manager/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/builder-manager/src/index.ts b/code/lib/builder-manager/src/index.ts index eb99070b8877..94210335b458 100644 --- a/code/lib/builder-manager/src/index.ts +++ b/code/lib/builder-manager/src/index.ts @@ -127,7 +127,7 @@ const starter: StarterFunction = async function* starterGeneratorFn({ router.use(`/sb-addons`, express.static(addonsDir)); router.use(`/sb-manager`, express.static(coreDirOrigin)); - const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation); + const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation.outputFiles); yield; From 640301f56343fd0db75d950a6ab483d9ec3bad13 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 6 Oct 2022 13:00:34 +0200 Subject: [PATCH 4/7] fix --- code/lib/builder-manager/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/builder-manager/src/index.ts b/code/lib/builder-manager/src/index.ts index 94210335b458..083e64d442d1 100644 --- a/code/lib/builder-manager/src/index.ts +++ b/code/lib/builder-manager/src/index.ts @@ -192,7 +192,7 @@ const builder: BuilderFunction = async function* builderGeneratorFn({ startTime, yield; const managerFiles = copy(coreDirOrigin, coreDirTarget); - const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir); + const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation.outputFiles); yield; From ca7dd1dc326450b61523e223de75b556e5340341 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 6 Oct 2022 13:21:57 +0200 Subject: [PATCH 5/7] fix --- code/lib/builder-manager/src/index.ts | 4 ++-- code/lib/builder-manager/src/utils/files.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/lib/builder-manager/src/index.ts b/code/lib/builder-manager/src/index.ts index 083e64d442d1..10f4e5c5e209 100644 --- a/code/lib/builder-manager/src/index.ts +++ b/code/lib/builder-manager/src/index.ts @@ -127,7 +127,7 @@ const starter: StarterFunction = async function* starterGeneratorFn({ router.use(`/sb-addons`, express.static(addonsDir)); router.use(`/sb-manager`, express.static(coreDirOrigin)); - const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation.outputFiles); + const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation?.outputFiles); yield; @@ -192,7 +192,7 @@ const builder: BuilderFunction = async function* builderGeneratorFn({ startTime, yield; const managerFiles = copy(coreDirOrigin, coreDirTarget); - const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation.outputFiles); + const { cssFiles, jsFiles } = await readOrderedFiles(addonsDir, compilation?.outputFiles); yield; diff --git a/code/lib/builder-manager/src/utils/files.ts b/code/lib/builder-manager/src/utils/files.ts index 4b96722fa4e0..3d8eaab3eb3d 100644 --- a/code/lib/builder-manager/src/utils/files.ts +++ b/code/lib/builder-manager/src/utils/files.ts @@ -3,7 +3,7 @@ import { writeFile, ensureFile } from 'fs-extra'; import { join } from 'path'; import { Compilation } from '../types'; -export async function readOrderedFiles(addonsDir: string, outputFiles: Compilation['outputFiles']) { +export async function readOrderedFiles(addonsDir: string, outputFiles: Compilation['outputFiles'] | undefined) { const files = await Promise.all( outputFiles?.map(async (file) => { // convert deeply nested paths to a single level, also remove special characters From 662e2510da18d46381995b6073559d5852ca992e Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 7 Oct 2022 13:33:01 +0200 Subject: [PATCH 6/7] escape the url of the addon file for the browser --- code/lib/builder-manager/src/utils/files.test.ts | 6 +++--- code/lib/builder-manager/src/utils/files.ts | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/lib/builder-manager/src/utils/files.test.ts b/code/lib/builder-manager/src/utils/files.test.ts index 807154ec679a..5d8501dfbce2 100644 --- a/code/lib/builder-manager/src/utils/files.test.ts +++ b/code/lib/builder-manager/src/utils/files.test.ts @@ -4,16 +4,16 @@ test('sanatizePath', () => { const addonsDir = '/Users/username/Projects/projectname/storybook'; const text = 'demo text'; const file = { - path: '/Users/username/Projects/projectname/storybook/node_modules/@storybook/addon-x/dist/manager.mjs', + path: '/Users/username/Projects/projectname/storybook/node_modules/@storybook/addon-x+y/dist/manager.mjs', contents: Uint8Array.from(Array.from(text).map((letter) => letter.charCodeAt(0))), text, }; const { location, url } = sanatizePath(file, addonsDir); expect(location).toMatchInlineSnapshot( - `"/Users/username/Projects/projectname/storybook/node-modules-storybook-addon-x-dist-manager.mjs"` + `"/Users/username/Projects/projectname/storybook/node_modules/@storybook/addon-x+y/dist/manager.mjs"` ); expect(url).toMatchInlineSnapshot( - `"./sb-addons/node-modules-storybook-addon-x-dist-manager.mjs"` + `"./sb-addons/node_modules/%40storybook/addon-x%2By/dist/manager.mjs"` ); }); diff --git a/code/lib/builder-manager/src/utils/files.ts b/code/lib/builder-manager/src/utils/files.ts index 3d8eaab3eb3d..1361f758fffa 100644 --- a/code/lib/builder-manager/src/utils/files.ts +++ b/code/lib/builder-manager/src/utils/files.ts @@ -3,7 +3,10 @@ import { writeFile, ensureFile } from 'fs-extra'; import { join } from 'path'; import { Compilation } from '../types'; -export async function readOrderedFiles(addonsDir: string, outputFiles: Compilation['outputFiles'] | undefined) { +export async function readOrderedFiles( + addonsDir: string, + outputFiles: Compilation['outputFiles'] | undefined +) { const files = await Promise.all( outputFiles?.map(async (file) => { // convert deeply nested paths to a single level, also remove special characters @@ -20,11 +23,8 @@ export async function readOrderedFiles(addonsDir: string, outputFiles: Compilati } export function sanatizePath(file: OutputFile, addonsDir: string) { - const filePath = file.path - .replace(addonsDir, '') - .replace(/[^a-z0-9\-.]+/g, '-') - .replace(/^-/, '/'); + const filePath = file.path.replace(addonsDir, ''); const location = join(addonsDir, filePath); - const url = `./sb-addons${filePath}`; + const url = `./sb-addons${filePath.split('/').map(encodeURIComponent).join('/')}`; return { location, url }; } From 1eea30cb796d46950427f43d7a86ae6e7f976d93 Mon Sep 17 00:00:00 2001 From: Michael Shilman Date: Sat, 8 Oct 2022 10:40:12 +0800 Subject: [PATCH 7/7] Fix typo --- code/lib/builder-manager/src/utils/files.test.ts | 6 +++--- code/lib/builder-manager/src/utils/files.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/lib/builder-manager/src/utils/files.test.ts b/code/lib/builder-manager/src/utils/files.test.ts index 5d8501dfbce2..41d62ec82693 100644 --- a/code/lib/builder-manager/src/utils/files.test.ts +++ b/code/lib/builder-manager/src/utils/files.test.ts @@ -1,6 +1,6 @@ -import { sanatizePath } from './files'; +import { sanitizePath } from './files'; -test('sanatizePath', () => { +test('sanitizePath', () => { const addonsDir = '/Users/username/Projects/projectname/storybook'; const text = 'demo text'; const file = { @@ -8,7 +8,7 @@ test('sanatizePath', () => { contents: Uint8Array.from(Array.from(text).map((letter) => letter.charCodeAt(0))), text, }; - const { location, url } = sanatizePath(file, addonsDir); + const { location, url } = sanitizePath(file, addonsDir); expect(location).toMatchInlineSnapshot( `"/Users/username/Projects/projectname/storybook/node_modules/@storybook/addon-x+y/dist/manager.mjs"` diff --git a/code/lib/builder-manager/src/utils/files.ts b/code/lib/builder-manager/src/utils/files.ts index 1361f758fffa..0b7fd8fedba0 100644 --- a/code/lib/builder-manager/src/utils/files.ts +++ b/code/lib/builder-manager/src/utils/files.ts @@ -10,7 +10,7 @@ export async function readOrderedFiles( const files = await Promise.all( outputFiles?.map(async (file) => { // convert deeply nested paths to a single level, also remove special characters - const { location, url } = sanatizePath(file, addonsDir); + const { location, url } = sanitizePath(file, addonsDir); await ensureFile(location).then(() => writeFile(location, file.contents)); return url; @@ -22,7 +22,7 @@ export async function readOrderedFiles( return { cssFiles, jsFiles }; } -export function sanatizePath(file: OutputFile, addonsDir: string) { +export function sanitizePath(file: OutputFile, addonsDir: string) { const filePath = file.path.replace(addonsDir, ''); const location = join(addonsDir, filePath); const url = `./sb-addons${filePath.split('/').map(encodeURIComponent).join('/')}`;