diff --git a/node-src/tasks/upload.test.ts b/node-src/tasks/upload.test.ts index de2477fd5..17a955ecf 100644 --- a/node-src/tasks/upload.test.ts +++ b/node-src/tasks/upload.test.ts @@ -164,6 +164,27 @@ describe('traceChangedFiles', () => { expect(ctx.onlyStoryFiles).toStrictEqual(Object.keys(deps)); }); + it('escapes special characters on context', async () => { + const deps = { './example-(new).stories.js': ['./example-(new).stories.js'] }; + findChangedDependencies.mockResolvedValue([]); + findChangedPackageFiles.mockResolvedValue([]); + getDependentStoryFiles.mockResolvedValue(deps); + + const ctx = { + env, + log, + http, + options: {}, + sourceDir: '/static/', + fileInfo: { statsPath: '/static/preview-stats.json' }, + git: { changedFiles: ['./example.js'] }, + turboSnap: {}, + } as any; + await traceChangedFiles(ctx, {} as any); + + expect(ctx.onlyStoryFiles).toStrictEqual(["./example-\\(\\new\\)\\.stories.js"]); + }); + it('does not run package dependency analysis if there are no metadata changes', async () => { const deps = { 123: ['./example.stories.js'] }; getDependentStoryFiles.mockResolvedValue(deps); diff --git a/node-src/tasks/upload.ts b/node-src/tasks/upload.ts index f2ee52839..4bc4c5a7c 100644 --- a/node-src/tasks/upload.ts +++ b/node-src/tasks/upload.ts @@ -37,6 +37,9 @@ interface PathSpec { contentLength: number; } +const escapedSpecialChars = '`$^*+?()[]'; +const specialCharsRegex = new RegExp(`([${escapedSpecialChars.split('').join('\\')}])`); + // Get all paths in rootDir, starting at dirname. // We don't want the paths to include rootDir -- so if rootDir = storybook-static, // paths will be like iframe.html rather than storybook-static/iframe.html @@ -154,7 +157,9 @@ export const traceChangedFiles = async (ctx: Context, task: Task) => { changedDependencyNames || [] ); if (onlyStoryFiles) { - ctx.onlyStoryFiles = Object.keys(onlyStoryFiles); + // Escape special characters in the filename so it does not conflict with picomatch + ctx.onlyStoryFiles = Object.keys(onlyStoryFiles).map((key) => key.split(specialCharsRegex).join('\\')); + if (!ctx.options.interactive) { if (!ctx.options.traceChanged) { ctx.log.info(