@storybook/core-server 7.0.0-beta.21 → 7.0.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __create=Object.create;var __defProp=Object.defineProperty;var __getOwnPropD
|
|
|
7
7
|
`);let statics=staticDirs?staticDirs.map(dir=>typeof dir=="string"?dir:`${dir.from}:${dir.to}`):options.staticDir;statics&&statics.length>0&&await Promise.all(statics.map(async dir=>{try{let relativeDir=staticDirs?(0,import_core_common.getDirectoryFromWorkingDir)({configDir:options.configDir,workingDir:process.cwd(),directory:dir}):dir,{staticDir,staticPath,targetEndpoint}=await parseStaticDir(relativeDir);if(import_node_logger2.logger.info(import_chalk2.default`=> Serving static files from {cyan ${staticDir}} at {cyan ${targetEndpoint}}`),router2.use(targetEndpoint,import_express.default.static(staticPath,{index:!1})),!hasCustomFavicon&&targetEndpoint==="/"){let faviconPath=import_path2.default.join(staticPath,"favicon.svg");await(0,import_fs_extra2.pathExists)(faviconPath)&&(hasCustomFavicon=!0,router2.use((0,import_serve_favicon.default)(faviconPath)))}}catch(e){import_node_logger2.logger.warn(e.message)}})),hasCustomFavicon||router2.use((0,import_serve_favicon.default)(defaultFavIcon))}var parseStaticDir=async arg=>{let lastColonIndex=arg.lastIndexOf(":"),isWindowsRawDirOnly=import_path2.default.win32.isAbsolute(arg)&&lastColonIndex===1,splitIndex=lastColonIndex!==-1&&!isWindowsRawDirOnly?lastColonIndex:arg.length,target=(arg.substring(splitIndex+1)||"/").split(import_path2.default.sep).join(import_path2.default.posix.sep),rawDir=arg.substring(0,splitIndex),staticDir=import_path2.default.isAbsolute(rawDir)?rawDir:`./${rawDir}`,staticPath=import_path2.default.resolve(staticDir),targetDir=target.replace(/^\/?/,"./"),targetEndpoint=targetDir.substring(1);if(!await(0,import_fs_extra2.pathExists)(staticPath))throw new Error((0,import_ts_dedent.dedent)(import_chalk2.default`
|
|
8
8
|
Failed to load static files, no such directory: {cyan ${staticPath}}
|
|
9
9
|
Make sure this directory exists, or omit the {bold -s (--static-dir)} option.
|
|
10
|
-
`));return{staticDir,staticPath,targetDir,targetEndpoint}};async function copyAllStaticFiles(staticDirs,outputDir){staticDirs&&staticDirs.length>0&&await Promise.all(staticDirs.map(async dir=>{try{let{staticDir,staticPath,targetDir}=await parseStaticDir(dir),targetPath=import_path3.default.join(outputDir,targetDir);import_node_logger3.logger.info(import_chalk3.default`=> Copying static files: {cyan ${staticDir}} => {cyan ${targetDir}}`);let skipPaths=["index.html","iframe.html"].map(f=>import_path3.default.join(targetPath,f));await import_fs_extra3.default.copy(staticPath,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})}catch(e){import_node_logger3.logger.error(e.message),process.exit(-1)}}))}async function copyAllStaticFilesRelativeToMain(staticDirs,outputDir,configDir){let workingDir=process.cwd();return staticDirs.reduce(async(acc,dir)=>{await acc;let staticDirAndTarget=typeof dir=="string"?dir:`${dir.from}:${dir.to}`,{staticPath:from,targetEndpoint:to}=await parseStaticDir((0,import_core_common2.getDirectoryFromWorkingDir)({configDir,workingDir,directory:staticDirAndTarget})),targetPath=import_path3.default.join(outputDir,to),skipPaths=["index.html","iframe.html"].map(f=>import_path3.default.join(targetPath,f));import_node_logger3.logger.info(import_chalk3.default`=> Copying static files: {cyan ${from}} at {cyan ${targetPath}}`),await import_fs_extra3.default.copy(from,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})},Promise.resolve())}var import_node_url=require("url");async function getManagerBuilder(){return import("@storybook/builder-manager")}async function getPreviewBuilder(builderName,configDir){let builderPackage;if(builderName)builderPackage=require.resolve(["webpack5"].includes(builderName)?`@storybook/builder-${builderName}`:builderName,{paths:[configDir]});else throw new Error("no builder configured!");return await import((0,import_node_url.pathToFileURL)(builderPackage).href)}async function getBuilders({presets,configDir}){var _a;let core=await presets.apply("core",void 0),builderName=typeof(core==null?void 0:core.builder)=="string"?core.builder:(_a=core==null?void 0:core.builder)==null?void 0:_a.name;return Promise.all([getPreviewBuilder(builderName,configDir),getManagerBuilder()])}var import_fs_extra4=require("fs-extra"),import_debounce=__toESM(require("lodash/debounce.js")),import_core_events=require("@storybook/core-events");var import_watchpack=__toESM(require("watchpack")),import_slash=__toESM(require("slash")),import_fs=__toESM(require("fs")),import_path4=__toESM(require("path")),import_globby=__toESM(require("globby")),import_uniq=__toESM(require("lodash/uniq.js")),isDirectory=directory=>{try{return import_fs.default.lstatSync(directory).isDirectory()}catch{return!1}};function toImportPath(relativePath){return relativePath.startsWith(".")?relativePath:`./${relativePath}`}function watchStorySpecifiers(specifiers,options,onInvalidate){let wp=new import_watchpack.default({followSymlinks:!1,ignored:["**/.git","node_modules"]});wp.watch({directories:(0,import_uniq.default)(specifiers.map(ns=>ns.directory))});async function onChangeOrRemove(watchpackPath,removed){let importPath=(0,import_slash.default)(watchpackPath.startsWith(".")?watchpackPath:`./${watchpackPath}`),matchingSpecifier=specifiers.find(ns=>ns.importPathMatcher.exec(importPath));if(matchingSpecifier){onInvalidate(matchingSpecifier,importPath,removed);return}let absolutePath=import_path4.default.join(options.workingDir,importPath);!removed&&isDirectory(absolutePath)&&await Promise.all(specifiers.filter(specifier=>importPath.startsWith(specifier.directory)).map(async specifier=>{let dirGlob=import_path4.default.join(options.workingDir,importPath,"**",import_path4.default.basename(specifier.files));(await(0,import_globby.default)(dirGlob.replace(/\\/g,"/"))).forEach(filePath=>{let fileImportPath=toImportPath(import_path4.default.relative(options.workingDir,filePath).replace(/\\/g,"/"));specifier.importPathMatcher.exec(fileImportPath)&&onInvalidate(specifier,fileImportPath,removed)})}))}return wp.on("change",async(filePath,mtime,explanation)=>{await onChangeOrRemove(filePath,!mtime)}),wp.on("remove",async(filePath,explanation)=>{await onChangeOrRemove(filePath,!0)}),()=>wp.close()}var DEBOUNCE=100;async function extractStoriesJson(outputFile,initializedStoryIndexGenerator,transform){let storyIndex=await(await initializedStoryIndexGenerator).getIndex();await(0,import_fs_extra4.writeJSON)(outputFile,transform?transform(storyIndex):storyIndex)}function useStoriesJson({router:router2,initializedStoryIndexGenerator,workingDir=process.cwd(),serverChannel,normalizedStories}){let maybeInvalidate=(0,import_debounce.default)(()=>serverChannel.emit(import_core_events.STORY_INDEX_INVALIDATED),DEBOUNCE,{leading:!0});watchStorySpecifiers(normalizedStories,{workingDir},async(specifier,path7,removed)=>{(await initializedStoryIndexGenerator).invalidate(specifier,path7,removed),maybeInvalidate()}),router2.use("/index.json",async(req,res)=>{try{let index=await(await initializedStoryIndexGenerator).getIndex();res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}}),router2.use("/stories.json",async(req,res)=>{try{let generator=await initializedStoryIndexGenerator,index=convertToIndexV3(await generator.getIndex());res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}})}var convertToIndexV3=index=>{let{entries}=index;return{v:3,stories:Object.entries(entries).reduce((acc,[id,entry])=>{let{type,...rest}=entry;return acc[id]={...rest,kind:rest.title,story:rest.name,parameters:{__id:rest.id,docsOnly:type==="docs",fileName:rest.importPath}},acc},{})}};var import_fs_extra5=require("fs-extra"),import_telemetry=require("@storybook/telemetry");async function extractStorybookMetadata(outputFile,configDir){let storybookMetadata=await(0,import_telemetry.getStorybookMetadata)(configDir);await(0,import_fs_extra5.writeJSON)(outputFile,storybookMetadata)}function useStorybookMetadata(router2,configDir){router2.use("/project.json",async(req,res)=>{let storybookMetadata=await(0,import_telemetry.getStorybookMetadata)(configDir);res.header("Content-Type","application/json"),res.send(JSON.stringify(storybookMetadata))})}var import_path5=__toESM(require("path")),import_fs_extra6=__toESM(require("fs-extra")),import_globby2=__toESM(require("globby")),import_slash2=__toESM(require("slash")),import_preview_api=require("@storybook/preview-api"),import_core_common3=require("@storybook/core-common"),import_node_logger4=require("@storybook/node-logger"),import_csf_tools=require("@storybook/csf-tools"),import_csf=require("@storybook/csf"),import_docs_mdx=require("@storybook/docs-mdx"),AUTODOCS_TAG="autodocs",STORIES_MDX_TAG="stories-mdx";function isMdxEntry({tags}){return!(tags!=null&&tags.includes(AUTODOCS_TAG))&&!(tags!=null&&tags.includes(STORIES_MDX_TAG))}var DuplicateEntriesError=class extends Error{constructor(message,entries){super();this.message=message,this.entries=entries}},makeAbsolute=(otherImport,normalizedPath,workingDir)=>otherImport.startsWith(".")?(0,import_slash2.default)(import_path5.default.resolve(workingDir,(0,import_core_common3.normalizeStoryPath)(import_path5.default.join(import_path5.default.dirname(normalizedPath),otherImport)))):otherImport,StoryIndexGenerator=class{constructor(specifiers,options){this.specifiers=specifiers;this.options=options;this.specifierToCache=new Map}async initialize(){await Promise.all(this.specifiers.map(async specifier=>{let pathToSubIndex={},fullGlob=(0,import_slash2.default)(import_path5.default.join(this.options.workingDir,specifier.directory,specifier.files));(await(0,import_globby2.default)(fullGlob)).sort().forEach(absolutePath=>{let ext=import_path5.default.extname(absolutePath);if(ext===".storyshot"){let relativePath=import_path5.default.relative(this.options.workingDir,absolutePath);import_node_logger4.logger.info(`Skipping ${ext} file ${relativePath}`);return}pathToSubIndex[absolutePath]=!1}),this.specifierToCache.set(specifier,pathToSubIndex)})),await this.ensureExtracted()}async updateExtracted(updater,overwrite=!1){await Promise.all(this.specifiers.map(async specifier=>{let entry=this.specifierToCache.get(specifier);return Promise.all(Object.keys(entry).map(async absolutePath=>{entry[absolutePath]&&!overwrite||(entry[absolutePath]=await updater(specifier,absolutePath,entry[absolutePath]))}))}))}isDocsMdx(absolutePath){return/(?<!\.stories)\.mdx$/i.test(absolutePath)}async ensureExtracted(){return await this.updateExtracted(async(specifier,absolutePath)=>this.isDocsMdx(absolutePath)?!1:this.extractStories(specifier,absolutePath)),this.options.docs.disable||await this.updateExtracted(async(specifier,absolutePath)=>this.extractDocs(specifier,absolutePath)),this.specifiers.flatMap(specifier=>{let cache4=this.specifierToCache.get(specifier);return Object.values(cache4).flatMap(entry=>entry?entry.type==="docs"?[entry]:entry.entries:[])})}findDependencies(absoluteImports){let dependencies=[],foundImports=new Set;return this.specifierToCache.forEach(cache4=>{Object.keys(cache4).filter(fileName=>{let foundImport=absoluteImports.find(storyImport=>fileName.startsWith(storyImport));return foundImport&&foundImports.add(foundImport),!!foundImport}).forEach(fileName=>{let cacheEntry=cache4[fileName];if(cacheEntry&&cacheEntry.type==="stories")dependencies.push(cacheEntry);else throw new Error(`Unexpected dependency: ${cacheEntry}`)})}),dependencies}async extractStories(specifier,absolutePath){let relativePath=import_path5.default.relative(this.options.workingDir,absolutePath),entries=[];try{let importPath=(0,import_slash2.default)((0,import_core_common3.normalizeStoryPath)(relativePath)),makeTitle=userTitle=>(0,import_preview_api.userOrAutoTitleFromSpecifier)(importPath,specifier,userTitle),storyIndexer=this.options.storyIndexers.find(indexer=>indexer.test.exec(absolutePath));if(!storyIndexer)throw new Error(`No matching story indexer found for ${absolutePath}`);let csf=await storyIndexer.indexer(absolutePath,{makeTitle}),componentTags=csf.meta.tags||[];if(csf.stories.forEach(({id,name,tags:storyTags,parameters})=>{if(!(parameters!=null&¶meters.docsOnly)){let tags=[...storyTags||componentTags,"story"];entries.push({id,title:csf.meta.title,name,importPath,tags,type:"story"})}}),!this.options.docs.disable&&csf.stories.length){let{autodocs}=this.options.docs,componentAutodocs=componentTags.includes(AUTODOCS_TAG),autodocsOptedIn=autodocs===!0||autodocs==="tag"&&componentAutodocs;if(componentTags.includes(STORIES_MDX_TAG)||autodocsOptedIn){let name=this.options.docs.defaultName,id=(0,import_csf.toId)(csf.meta.title,name);entries.unshift({id,title:csf.meta.title,name,importPath,type:"docs",tags:[...componentTags,"docs",...autodocsOptedIn&&!componentAutodocs?[AUTODOCS_TAG]:[]],storiesImports:[]})}}}catch(err){if(err instanceof import_csf_tools.NoMetaError)import_node_logger4.logger.info(`\u{1F4A1} Skipping ${relativePath}: ${err}`);else throw import_node_logger4.logger.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}return{entries,type:"stories",dependents:[]}}async extractDocs(specifier,absolutePath){let relativePath=import_path5.default.relative(this.options.workingDir,absolutePath);try{if(!this.options.storyStoreV7)throw new Error("You cannot use `.mdx` files without using `storyStoreV7`.");let normalizedPath=(0,import_core_common3.normalizeStoryPath)(relativePath),importPath=(0,import_slash2.default)(normalizedPath),content=await import_fs_extra6.default.readFile(absolutePath,"utf8"),result=(0,import_docs_mdx.analyze)(content);if(result.isTemplate)return!1;let absoluteImports=result.imports.map(p=>makeAbsolute(p,normalizedPath,this.options.workingDir)),dependencies=this.findDependencies(absoluteImports),ofTitle;if(result.of){let absoluteOf=makeAbsolute(result.of,normalizedPath,this.options.workingDir);if(dependencies.forEach(dep=>{if(dep.entries.length>0){let first=dep.entries[0];import_path5.default.normalize(import_path5.default.resolve(this.options.workingDir,first.importPath)).startsWith(import_path5.default.normalize(absoluteOf))&&(ofTitle=first.title)}}),!ofTitle)throw new Error(`Could not find "${result.of}" for docs file "${relativePath}".`)}dependencies.forEach(dep=>{dep.dependents.push(absolutePath)});let title=ofTitle||(0,import_preview_api.userOrAutoTitleFromSpecifier)(importPath,specifier,result.title),name=result.name||this.options.docs.defaultName;return{id:(0,import_csf.toId)(title,name),title,name,importPath,storiesImports:dependencies.map(dep=>dep.entries[0].importPath),type:"docs",tags:[...result.tags||[],"docs"]}}catch(err){throw import_node_logger4.logger.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}}chooseDuplicate(firstEntry,secondEntry){var _a;let firstIsBetter=!0;(secondEntry.type==="story"||isMdxEntry(secondEntry)&&firstEntry.type==="docs"&&!isMdxEntry(firstEntry))&&(firstIsBetter=!1);let betterEntry=firstIsBetter?firstEntry:secondEntry,worseEntry=firstIsBetter?secondEntry:firstEntry,changeDocsName='Use `<Meta of={} name="Other Name">` to distinguish them.';if(worseEntry.type==="story")throw new DuplicateEntriesError(`Duplicate stories with id: ${firstEntry.id}`,[firstEntry,secondEntry]);if(betterEntry.type==="story"){let worseDescriptor=isMdxEntry(worseEntry)?"component docs page":"automatically generated docs page";betterEntry.name===this.options.docs.defaultName?import_node_logger4.logger.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your default docs entry name (${betterEntry.name}), so the docs page is being dropped. Consider changing the story name.`):import_node_logger4.logger.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your ${worseDescriptor} (${worseEntry.name}), so the docs page is being dropped. ${changeDocsName}`)}else if(isMdxEntry(betterEntry)){if(isMdxEntry(worseEntry)&&import_node_logger4.logger.warn(`\u{1F6A8} You have two component docs pages with the same name ${betterEntry.title}:${betterEntry.name}. ${changeDocsName}`),(_a=worseEntry.tags)!=null&&_a.includes(AUTODOCS_TAG)&&this.options.docs.autodocs!==!0)throw new Error(`You created a component docs page for ${worseEntry.title} (${betterEntry.importPath}), but also tagged the CSF file (${worseEntry.importPath}) with '${AUTODOCS_TAG}'. This is probably a mistake.`)}else return{...betterEntry,storiesImports:[...betterEntry.storiesImports,worseEntry.importPath,...worseEntry.storiesImports]};return betterEntry}async sortStories(storiesList){let entries={};storiesList.forEach(entry=>{let existing=entries[entry.id];existing?entries[entry.id]=this.chooseDuplicate(existing,entry):entries[entry.id]=entry});let sortableStories=Object.values(entries);if(this.options.storyStoreV7){let storySortParameter=await this.getStorySortParameter(),fileNameOrder=this.storyFileNames();(0,import_preview_api.sortStoriesV7)(sortableStories,storySortParameter,fileNameOrder)}return sortableStories.reduce((acc,item)=>(acc[item.id]=item,acc),{})}async getIndex(){if(this.lastIndex)return this.lastIndex;let storiesList=await this.ensureExtracted(),sorted=await this.sortStories(storiesList),compat=sorted;if(this.options.storiesV2Compatibility){let titleToStoryCount=Object.values(sorted).reduce((acc,story)=>(acc[story.title]=(acc[story.title]||0)+1,acc),{});compat=Object.entries(sorted).reduce((acc,entry)=>{let[id,story]=entry;return story.type==="docs"||(acc[id]={...story,kind:story.title,story:story.name,parameters:{__id:story.id,docsOnly:titleToStoryCount[story.title]===1&&story.name==="Page",fileName:story.importPath}}),acc},{})}return this.lastIndex={v:4,entries:compat},this.lastIndex}invalidate(specifier,importPath,removed){let absolutePath=(0,import_slash2.default)(import_path5.default.resolve(this.options.workingDir,importPath)),cache4=this.specifierToCache.get(specifier),cacheEntry=cache4[absolutePath];if(cacheEntry&&cacheEntry.type==="stories"){let{dependents}=cacheEntry,invalidated=new Set;this.specifierToCache.forEach(otherCache=>{dependents.forEach(dep=>{otherCache[dep]&&(invalidated.add(dep),otherCache[dep]=!1)})})}if(removed){if(cacheEntry&&cacheEntry.type==="docs"){let absoluteImports=cacheEntry.storiesImports.map(p=>import_path5.default.resolve(this.options.workingDir,p));this.findDependencies(absoluteImports).forEach(dep=>dep.dependents.splice(dep.dependents.indexOf(absolutePath),1))}delete cache4[absolutePath]}else cache4[absolutePath]=!1;this.lastIndex=null}async getStorySortParameter(){let previewFile=["js","jsx","ts","tsx"].map(ext=>import_path5.default.join(this.options.configDir,`preview.${ext}`)).find(fname=>import_fs_extra6.default.existsSync(fname)),storySortParameter;if(previewFile){let previewCode=(await import_fs_extra6.default.readFile(previewFile,"utf-8")).toString();storySortParameter=await(0,import_csf_tools.getStorySortParameter)(previewCode)}return storySortParameter}storyFileNames(){return Array.from(this.specifierToCache.values()).flatMap(r=>Object.keys(r))}};function summarizeIndex(storyIndex){let storyCount=0,autodocsCount=0,storiesMdxCount=0,mdxCount=0;return Object.values(storyIndex.entries).forEach(entry=>{entry.type==="story"?storyCount+=1:entry.type==="docs"&&(isMdxEntry(entry)?mdxCount+=1:entry.tags.includes(STORIES_MDX_TAG)?storiesMdxCount+=1:entry.tags.includes(AUTODOCS_TAG)&&(autodocsCount+=1))}),{storyCount,autodocsCount,storiesMdxCount,mdxCount,version:storyIndex.v}}async function buildStaticStandalone(options){var _a;if(options.configType="PRODUCTION",options.outputDir==="")throw new Error("Won't remove current directory. Check your outputDir!");if((_a=options.staticDir)!=null&&_a.includes("/"))throw new Error("Won't copy root directory. Check your staticDirs!");if(options.outputDir=(0,import_path6.isAbsolute)(options.outputDir)?options.outputDir:(0,import_path6.join)(process.cwd(),options.outputDir),options.configDir=(0,import_path6.resolve)(options.configDir),import_node_logger5.logger.info(import_chalk4.default`=> Cleaning outputDir: {cyan ${options.outputDir.replace(process.cwd(),"")}}`),options.outputDir==="/")throw new Error("Won't remove directory '/'. Check your outputDir!");await(0,import_fs_extra7.emptyDir)(options.outputDir),await(0,import_fs_extra7.ensureDir)(options.outputDir);let{framework}=(0,import_core_common4.loadMainConfig)(options),corePresets=[],frameworkName=typeof framework=="string"?framework:framework==null?void 0:framework.name;frameworkName?corePresets.push((0,import_path6.join)(frameworkName,"preset")):import_node_logger5.logger.warn(`you have not specified a framework in your ${options.configDir}/main.js`),import_node_logger5.logger.info("=> Loading presets");let presets=await(0,import_core_common4.loadAllPresets)({corePresets:[require.resolve("@storybook/core-server/dist/presets/common-preset"),...corePresets],overridePresets:[],...options}),[previewBuilder,managerBuilder]=await getBuilders({...options,presets}),{renderer}=await presets.apply("core",void 0);presets=await(0,import_core_common4.loadAllPresets)({corePresets:[require.resolve("@storybook/core-server/dist/presets/common-preset"),...managerBuilder.corePresets||[],...previewBuilder.corePresets||[],...renderer?[(0,import_core_common4.resolveAddonName)(options.configDir,renderer,options)]:[],...corePresets,require.resolve("@storybook/core-server/dist/presets/babel-cache-preset")],overridePresets:previewBuilder.overridePresets||[],...options});let[features,core,staticDirs,storyIndexers,stories,docsOptions]=await Promise.all([presets.apply("features"),presets.apply("core"),presets.apply("staticDirs"),presets.apply("storyIndexers",[]),presets.apply("stories"),presets.apply("docs",{})]),fullOptions={...options,presets,features};if(staticDirs&&options.staticDir)throw new Error(import_ts_dedent2.dedent`
|
|
10
|
+
`));return{staticDir,staticPath,targetDir,targetEndpoint}};async function copyAllStaticFiles(staticDirs,outputDir){staticDirs&&staticDirs.length>0&&await Promise.all(staticDirs.map(async dir=>{try{let{staticDir,staticPath,targetDir}=await parseStaticDir(dir),targetPath=import_path3.default.join(outputDir,targetDir);import_node_logger3.logger.info(import_chalk3.default`=> Copying static files: {cyan ${staticDir}} => {cyan ${targetDir}}`);let skipPaths=["index.html","iframe.html"].map(f=>import_path3.default.join(targetPath,f));await import_fs_extra3.default.copy(staticPath,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})}catch(e){import_node_logger3.logger.error(e.message),process.exit(-1)}}))}async function copyAllStaticFilesRelativeToMain(staticDirs,outputDir,configDir){let workingDir=process.cwd();return staticDirs.reduce(async(acc,dir)=>{await acc;let staticDirAndTarget=typeof dir=="string"?dir:`${dir.from}:${dir.to}`,{staticPath:from,targetEndpoint:to}=await parseStaticDir((0,import_core_common2.getDirectoryFromWorkingDir)({configDir,workingDir,directory:staticDirAndTarget})),targetPath=import_path3.default.join(outputDir,to),skipPaths=["index.html","iframe.html"].map(f=>import_path3.default.join(targetPath,f));import_node_logger3.logger.info(import_chalk3.default`=> Copying static files: {cyan ${from}} at {cyan ${targetPath}}`),await import_fs_extra3.default.copy(from,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})},Promise.resolve())}var import_node_url=require("url");async function getManagerBuilder(){return import("@storybook/builder-manager")}async function getPreviewBuilder(builderName,configDir){let builderPackage;if(builderName)builderPackage=require.resolve(["webpack5"].includes(builderName)?`@storybook/builder-${builderName}`:builderName,{paths:[configDir]});else throw new Error("no builder configured!");return await import((0,import_node_url.pathToFileURL)(builderPackage).href)}async function getBuilders({presets,configDir}){var _a;let core=await presets.apply("core",void 0),builderName=typeof(core==null?void 0:core.builder)=="string"?core.builder:(_a=core==null?void 0:core.builder)==null?void 0:_a.name;return Promise.all([getPreviewBuilder(builderName,configDir),getManagerBuilder()])}var import_fs_extra4=require("fs-extra"),import_debounce=__toESM(require("lodash/debounce.js")),import_core_events=require("@storybook/core-events");var import_watchpack=__toESM(require("watchpack")),import_slash=__toESM(require("slash")),import_fs=__toESM(require("fs")),import_path4=__toESM(require("path")),import_globby=__toESM(require("globby")),import_uniq=__toESM(require("lodash/uniq.js")),isDirectory=directory=>{try{return import_fs.default.lstatSync(directory).isDirectory()}catch{return!1}};function toImportPath(relativePath){return relativePath.startsWith(".")?relativePath:`./${relativePath}`}function watchStorySpecifiers(specifiers,options,onInvalidate){let wp=new import_watchpack.default({followSymlinks:!1,ignored:["**/.git","node_modules"]});wp.watch({directories:(0,import_uniq.default)(specifiers.map(ns=>ns.directory))});async function onChangeOrRemove(watchpackPath,removed){let importPath=(0,import_slash.default)(watchpackPath.startsWith(".")?watchpackPath:`./${watchpackPath}`),matchingSpecifier=specifiers.find(ns=>ns.importPathMatcher.exec(importPath));if(matchingSpecifier){onInvalidate(matchingSpecifier,importPath,removed);return}let absolutePath=import_path4.default.join(options.workingDir,importPath);!removed&&isDirectory(absolutePath)&&await Promise.all(specifiers.filter(specifier=>importPath.startsWith(specifier.directory)).map(async specifier=>{let dirGlob=import_path4.default.join(options.workingDir,importPath,"**",import_path4.default.basename(specifier.files));(await(0,import_globby.default)(dirGlob.replace(/\\/g,"/"))).forEach(filePath=>{let fileImportPath=toImportPath(import_path4.default.relative(options.workingDir,filePath).replace(/\\/g,"/"));specifier.importPathMatcher.exec(fileImportPath)&&onInvalidate(specifier,fileImportPath,removed)})}))}return wp.on("change",async(filePath,mtime,explanation)=>{await onChangeOrRemove(filePath,!mtime)}),wp.on("remove",async(filePath,explanation)=>{await onChangeOrRemove(filePath,!0)}),()=>wp.close()}var DEBOUNCE=100;async function extractStoriesJson(outputFile,initializedStoryIndexGenerator,transform){let storyIndex=await(await initializedStoryIndexGenerator).getIndex();await(0,import_fs_extra4.writeJSON)(outputFile,transform?transform(storyIndex):storyIndex)}function useStoriesJson({router:router2,initializedStoryIndexGenerator,workingDir=process.cwd(),serverChannel,normalizedStories}){let maybeInvalidate=(0,import_debounce.default)(()=>serverChannel.emit(import_core_events.STORY_INDEX_INVALIDATED),DEBOUNCE,{leading:!0});watchStorySpecifiers(normalizedStories,{workingDir},async(specifier,path7,removed)=>{(await initializedStoryIndexGenerator).invalidate(specifier,path7,removed),maybeInvalidate()}),router2.use("/index.json",async(req,res)=>{try{let index=await(await initializedStoryIndexGenerator).getIndex();res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}}),router2.use("/stories.json",async(req,res)=>{try{let generator=await initializedStoryIndexGenerator,index=convertToIndexV3(await generator.getIndex());res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}})}var convertToIndexV3=index=>{let{entries}=index;return{v:3,stories:Object.entries(entries).reduce((acc,[id,entry])=>{let{type,...rest}=entry;return acc[id]={...rest,kind:rest.title,story:rest.name,parameters:{__id:rest.id,docsOnly:type==="docs",fileName:rest.importPath}},acc},{})}};var import_fs_extra5=require("fs-extra"),import_telemetry=require("@storybook/telemetry");async function extractStorybookMetadata(outputFile,configDir){let storybookMetadata=await(0,import_telemetry.getStorybookMetadata)(configDir);await(0,import_fs_extra5.writeJSON)(outputFile,storybookMetadata)}function useStorybookMetadata(router2,configDir){router2.use("/project.json",async(req,res)=>{let storybookMetadata=await(0,import_telemetry.getStorybookMetadata)(configDir);res.header("Content-Type","application/json"),res.send(JSON.stringify(storybookMetadata))})}var import_path5=__toESM(require("path")),import_fs_extra6=__toESM(require("fs-extra")),import_globby2=__toESM(require("globby")),import_slash2=__toESM(require("slash")),import_preview_api=require("@storybook/preview-api"),import_core_common3=require("@storybook/core-common"),import_node_logger4=require("@storybook/node-logger"),import_csf_tools=require("@storybook/csf-tools"),import_csf=require("@storybook/csf"),import_docs_mdx=require("@storybook/docs-mdx"),AUTODOCS_TAG="autodocs",STORIES_MDX_TAG="stories-mdx",PLAY_FN_TAG="play-fn";function isMdxEntry({tags}){return!(tags!=null&&tags.includes(AUTODOCS_TAG))&&!(tags!=null&&tags.includes(STORIES_MDX_TAG))}var DuplicateEntriesError=class extends Error{constructor(message,entries){super();this.message=message,this.entries=entries}},makeAbsolute=(otherImport,normalizedPath,workingDir)=>otherImport.startsWith(".")?(0,import_slash2.default)(import_path5.default.resolve(workingDir,(0,import_core_common3.normalizeStoryPath)(import_path5.default.join(import_path5.default.dirname(normalizedPath),otherImport)))):otherImport,StoryIndexGenerator=class{constructor(specifiers,options){this.specifiers=specifiers;this.options=options;this.specifierToCache=new Map}async initialize(){await Promise.all(this.specifiers.map(async specifier=>{let pathToSubIndex={},fullGlob=(0,import_slash2.default)(import_path5.default.join(this.options.workingDir,specifier.directory,specifier.files));(await(0,import_globby2.default)(fullGlob)).sort().forEach(absolutePath=>{let ext=import_path5.default.extname(absolutePath);if(ext===".storyshot"){let relativePath=import_path5.default.relative(this.options.workingDir,absolutePath);import_node_logger4.logger.info(`Skipping ${ext} file ${relativePath}`);return}pathToSubIndex[absolutePath]=!1}),this.specifierToCache.set(specifier,pathToSubIndex)})),await this.ensureExtracted()}async updateExtracted(updater,overwrite=!1){await Promise.all(this.specifiers.map(async specifier=>{let entry=this.specifierToCache.get(specifier);return Promise.all(Object.keys(entry).map(async absolutePath=>{entry[absolutePath]&&!overwrite||(entry[absolutePath]=await updater(specifier,absolutePath,entry[absolutePath]))}))}))}isDocsMdx(absolutePath){return/(?<!\.stories)\.mdx$/i.test(absolutePath)}async ensureExtracted(){return await this.updateExtracted(async(specifier,absolutePath)=>this.isDocsMdx(absolutePath)?!1:this.extractStories(specifier,absolutePath)),this.options.docs.disable||await this.updateExtracted(async(specifier,absolutePath)=>this.extractDocs(specifier,absolutePath)),this.specifiers.flatMap(specifier=>{let cache4=this.specifierToCache.get(specifier);return Object.values(cache4).flatMap(entry=>entry?entry.type==="docs"?[entry]:entry.entries:[])})}findDependencies(absoluteImports){let dependencies=[],foundImports=new Set;return this.specifierToCache.forEach(cache4=>{Object.keys(cache4).filter(fileName=>{let foundImport=absoluteImports.find(storyImport=>fileName.startsWith(storyImport));return foundImport&&foundImports.add(foundImport),!!foundImport}).forEach(fileName=>{let cacheEntry=cache4[fileName];if(cacheEntry&&cacheEntry.type==="stories")dependencies.push(cacheEntry);else throw new Error(`Unexpected dependency: ${cacheEntry}`)})}),dependencies}async extractStories(specifier,absolutePath){let relativePath=import_path5.default.relative(this.options.workingDir,absolutePath),entries=[];try{let importPath=(0,import_slash2.default)((0,import_core_common3.normalizeStoryPath)(relativePath)),makeTitle=userTitle=>(0,import_preview_api.userOrAutoTitleFromSpecifier)(importPath,specifier,userTitle),storyIndexer=this.options.storyIndexers.find(indexer=>indexer.test.exec(absolutePath));if(!storyIndexer)throw new Error(`No matching story indexer found for ${absolutePath}`);let csf=await storyIndexer.indexer(absolutePath,{makeTitle}),componentTags=csf.meta.tags||[];if(csf.stories.forEach(({id,name,tags:storyTags,parameters})=>{if(!(parameters!=null&¶meters.docsOnly)){let tags=[...storyTags||componentTags,"story"];entries.push({id,title:csf.meta.title,name,importPath,tags,type:"story"})}}),!this.options.docs.disable&&csf.stories.length){let{autodocs}=this.options.docs,componentAutodocs=componentTags.includes(AUTODOCS_TAG),autodocsOptedIn=autodocs===!0||autodocs==="tag"&&componentAutodocs;if(componentTags.includes(STORIES_MDX_TAG)||autodocsOptedIn){let name=this.options.docs.defaultName,id=(0,import_csf.toId)(csf.meta.title,name);entries.unshift({id,title:csf.meta.title,name,importPath,type:"docs",tags:[...componentTags,"docs",...autodocsOptedIn&&!componentAutodocs?[AUTODOCS_TAG]:[]],storiesImports:[]})}}}catch(err){if(err instanceof import_csf_tools.NoMetaError)import_node_logger4.logger.info(`\u{1F4A1} Skipping ${relativePath}: ${err}`);else throw import_node_logger4.logger.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}return{entries,type:"stories",dependents:[]}}async extractDocs(specifier,absolutePath){let relativePath=import_path5.default.relative(this.options.workingDir,absolutePath);try{if(!this.options.storyStoreV7)throw new Error("You cannot use `.mdx` files without using `storyStoreV7`.");let normalizedPath=(0,import_core_common3.normalizeStoryPath)(relativePath),importPath=(0,import_slash2.default)(normalizedPath),content=await import_fs_extra6.default.readFile(absolutePath,"utf8"),result=(0,import_docs_mdx.analyze)(content);if(result.isTemplate)return!1;let absoluteImports=result.imports.map(p=>makeAbsolute(p,normalizedPath,this.options.workingDir)),dependencies=this.findDependencies(absoluteImports),ofTitle;if(result.of){let absoluteOf=makeAbsolute(result.of,normalizedPath,this.options.workingDir);if(dependencies.forEach(dep=>{if(dep.entries.length>0){let first=dep.entries[0];import_path5.default.normalize(import_path5.default.resolve(this.options.workingDir,first.importPath)).startsWith(import_path5.default.normalize(absoluteOf))&&(ofTitle=first.title)}}),!ofTitle)throw new Error(`Could not find "${result.of}" for docs file "${relativePath}".`)}dependencies.forEach(dep=>{dep.dependents.push(absolutePath)});let title=ofTitle||(0,import_preview_api.userOrAutoTitleFromSpecifier)(importPath,specifier,result.title),name=result.name||this.options.docs.defaultName;return{id:(0,import_csf.toId)(title,name),title,name,importPath,storiesImports:dependencies.map(dep=>dep.entries[0].importPath),type:"docs",tags:[...result.tags||[],"docs"]}}catch(err){throw import_node_logger4.logger.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}}chooseDuplicate(firstEntry,secondEntry){var _a;let firstIsBetter=!0;(secondEntry.type==="story"||isMdxEntry(secondEntry)&&firstEntry.type==="docs"&&!isMdxEntry(firstEntry))&&(firstIsBetter=!1);let betterEntry=firstIsBetter?firstEntry:secondEntry,worseEntry=firstIsBetter?secondEntry:firstEntry,changeDocsName='Use `<Meta of={} name="Other Name">` to distinguish them.';if(worseEntry.type==="story")throw new DuplicateEntriesError(`Duplicate stories with id: ${firstEntry.id}`,[firstEntry,secondEntry]);if(betterEntry.type==="story"){let worseDescriptor=isMdxEntry(worseEntry)?"component docs page":"automatically generated docs page";betterEntry.name===this.options.docs.defaultName?import_node_logger4.logger.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your default docs entry name (${betterEntry.name}), so the docs page is being dropped. Consider changing the story name.`):import_node_logger4.logger.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your ${worseDescriptor} (${worseEntry.name}), so the docs page is being dropped. ${changeDocsName}`)}else if(isMdxEntry(betterEntry)){if(isMdxEntry(worseEntry)&&import_node_logger4.logger.warn(`\u{1F6A8} You have two component docs pages with the same name ${betterEntry.title}:${betterEntry.name}. ${changeDocsName}`),(_a=worseEntry.tags)!=null&&_a.includes(AUTODOCS_TAG)&&this.options.docs.autodocs!==!0)throw new Error(`You created a component docs page for ${worseEntry.title} (${betterEntry.importPath}), but also tagged the CSF file (${worseEntry.importPath}) with '${AUTODOCS_TAG}'. This is probably a mistake.`)}else return{...betterEntry,storiesImports:[...betterEntry.storiesImports,worseEntry.importPath,...worseEntry.storiesImports]};return betterEntry}async sortStories(storiesList){let entries={};storiesList.forEach(entry=>{let existing=entries[entry.id];existing?entries[entry.id]=this.chooseDuplicate(existing,entry):entries[entry.id]=entry});let sortableStories=Object.values(entries);if(this.options.storyStoreV7){let storySortParameter=await this.getStorySortParameter(),fileNameOrder=this.storyFileNames();(0,import_preview_api.sortStoriesV7)(sortableStories,storySortParameter,fileNameOrder)}return sortableStories.reduce((acc,item)=>(acc[item.id]=item,acc),{})}async getIndex(){if(this.lastIndex)return this.lastIndex;let storiesList=await this.ensureExtracted(),sorted=await this.sortStories(storiesList),compat=sorted;if(this.options.storiesV2Compatibility){let titleToStoryCount=Object.values(sorted).reduce((acc,story)=>(acc[story.title]=(acc[story.title]||0)+1,acc),{});compat=Object.entries(sorted).reduce((acc,entry)=>{let[id,story]=entry;return story.type==="docs"||(acc[id]={...story,kind:story.title,story:story.name,parameters:{__id:story.id,docsOnly:titleToStoryCount[story.title]===1&&story.name==="Page",fileName:story.importPath}}),acc},{})}return this.lastIndex={v:4,entries:compat},this.lastIndex}invalidate(specifier,importPath,removed){let absolutePath=(0,import_slash2.default)(import_path5.default.resolve(this.options.workingDir,importPath)),cache4=this.specifierToCache.get(specifier),cacheEntry=cache4[absolutePath];if(cacheEntry&&cacheEntry.type==="stories"){let{dependents}=cacheEntry,invalidated=new Set;this.specifierToCache.forEach(otherCache=>{dependents.forEach(dep=>{otherCache[dep]&&(invalidated.add(dep),otherCache[dep]=!1)})})}if(removed){if(cacheEntry&&cacheEntry.type==="docs"){let absoluteImports=cacheEntry.storiesImports.map(p=>import_path5.default.resolve(this.options.workingDir,p));this.findDependencies(absoluteImports).forEach(dep=>dep.dependents.splice(dep.dependents.indexOf(absolutePath),1))}delete cache4[absolutePath]}else cache4[absolutePath]=!1;this.lastIndex=null}async getStorySortParameter(){let previewFile=["js","jsx","ts","tsx"].map(ext=>import_path5.default.join(this.options.configDir,`preview.${ext}`)).find(fname=>import_fs_extra6.default.existsSync(fname)),storySortParameter;if(previewFile){let previewCode=(await import_fs_extra6.default.readFile(previewFile,"utf-8")).toString();storySortParameter=await(0,import_csf_tools.getStorySortParameter)(previewCode)}return storySortParameter}storyFileNames(){return Array.from(this.specifierToCache.values()).flatMap(r=>Object.keys(r))}};var PAGE_REGEX=/(page|screen)/i,isPageStory=storyId=>PAGE_REGEX.test(storyId),isExampleEntry=entry=>["example-introduction--docs","example-button--docs","example-button--primary","example-button--secondary","example-button--large","example-button--small","example-header--docs","example-header--logged-in","example-header--logged-out","example-page--logged-in","example-page--logged-out"].includes(entry.id);function summarizeIndex(storyIndex){let storyCount=0,exampleStoryCount=0,exampleDocsCount=0,pageStoryCount=0,playStoryCount=0,autodocsCount=0,storiesMdxCount=0,mdxCount=0;return Object.values(storyIndex.entries).forEach(entry=>{var _a,_b,_c;isExampleEntry(entry)?(entry.type==="story"&&(exampleStoryCount+=1),entry.type==="docs"&&(exampleDocsCount+=1)):entry.type==="story"?(storyCount+=1,isPageStory(entry.title)&&(pageStoryCount+=1),(_a=entry.tags)!=null&&_a.includes(PLAY_FN_TAG)&&(playStoryCount+=1)):entry.type==="docs"&&(isMdxEntry(entry)?mdxCount+=1:(_b=entry.tags)!=null&&_b.includes(STORIES_MDX_TAG)?storiesMdxCount+=1:(_c=entry.tags)!=null&&_c.includes(AUTODOCS_TAG)&&(autodocsCount+=1))}),{storyCount,pageStoryCount,playStoryCount,autodocsCount,storiesMdxCount,mdxCount,exampleStoryCount,exampleDocsCount,version:storyIndex.v}}async function buildStaticStandalone(options){var _a;if(options.configType="PRODUCTION",options.outputDir==="")throw new Error("Won't remove current directory. Check your outputDir!");if((_a=options.staticDir)!=null&&_a.includes("/"))throw new Error("Won't copy root directory. Check your staticDirs!");if(options.outputDir=(0,import_path6.isAbsolute)(options.outputDir)?options.outputDir:(0,import_path6.join)(process.cwd(),options.outputDir),options.configDir=(0,import_path6.resolve)(options.configDir),import_node_logger5.logger.info(import_chalk4.default`=> Cleaning outputDir: {cyan ${options.outputDir.replace(process.cwd(),"")}}`),options.outputDir==="/")throw new Error("Won't remove directory '/'. Check your outputDir!");await(0,import_fs_extra7.emptyDir)(options.outputDir),await(0,import_fs_extra7.ensureDir)(options.outputDir);let{framework}=(0,import_core_common4.loadMainConfig)(options),corePresets=[],frameworkName=typeof framework=="string"?framework:framework==null?void 0:framework.name;frameworkName?corePresets.push((0,import_path6.join)(frameworkName,"preset")):import_node_logger5.logger.warn(`you have not specified a framework in your ${options.configDir}/main.js`),import_node_logger5.logger.info("=> Loading presets");let presets=await(0,import_core_common4.loadAllPresets)({corePresets:[require.resolve("@storybook/core-server/dist/presets/common-preset"),...corePresets],overridePresets:[],...options}),[previewBuilder,managerBuilder]=await getBuilders({...options,presets}),{renderer}=await presets.apply("core",void 0);presets=await(0,import_core_common4.loadAllPresets)({corePresets:[require.resolve("@storybook/core-server/dist/presets/common-preset"),...managerBuilder.corePresets||[],...previewBuilder.corePresets||[],...renderer?[(0,import_core_common4.resolveAddonName)(options.configDir,renderer,options)]:[],...corePresets,require.resolve("@storybook/core-server/dist/presets/babel-cache-preset")],overridePresets:previewBuilder.overridePresets||[],...options});let[features,core,staticDirs,storyIndexers,stories,docsOptions]=await Promise.all([presets.apply("features"),presets.apply("core"),presets.apply("staticDirs"),presets.apply("storyIndexers",[]),presets.apply("stories"),presets.apply("docs",{})]),fullOptions={...options,presets,features};if(staticDirs&&options.staticDir)throw new Error(import_ts_dedent2.dedent`
|
|
11
11
|
Conflict when trying to read staticDirs:
|
|
12
12
|
* Storybook's configuration option: 'staticDirs'
|
|
13
13
|
* Storybook's CLI flag: '--staticDir' or '-s'
|
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import{__require}from"./chunk-R4NKYYJA.mjs";import{getPreviewHeadTemplate,getPre
|
|
|
7
7
|
`);let statics=staticDirs?staticDirs.map(dir=>typeof dir=="string"?dir:`${dir.from}:${dir.to}`):options.staticDir;statics&&statics.length>0&&await Promise.all(statics.map(async dir=>{try{let relativeDir=staticDirs?getDirectoryFromWorkingDir({configDir:options.configDir,workingDir:process.cwd(),directory:dir}):dir,{staticDir,staticPath,targetEndpoint}=await parseStaticDir(relativeDir);if(logger2.info(chalk2`=> Serving static files from {cyan ${staticDir}} at {cyan ${targetEndpoint}}`),router2.use(targetEndpoint,express.static(staticPath,{index:!1})),!hasCustomFavicon&&targetEndpoint==="/"){let faviconPath=path2.join(staticPath,"favicon.svg");await pathExists(faviconPath)&&(hasCustomFavicon=!0,router2.use(favicon(faviconPath)))}}catch(e){logger2.warn(e.message)}})),hasCustomFavicon||router2.use(favicon(defaultFavIcon))}var parseStaticDir=async arg=>{let lastColonIndex=arg.lastIndexOf(":"),isWindowsRawDirOnly=path2.win32.isAbsolute(arg)&&lastColonIndex===1,splitIndex=lastColonIndex!==-1&&!isWindowsRawDirOnly?lastColonIndex:arg.length,target=(arg.substring(splitIndex+1)||"/").split(path2.sep).join(path2.posix.sep),rawDir=arg.substring(0,splitIndex),staticDir=path2.isAbsolute(rawDir)?rawDir:`./${rawDir}`,staticPath=path2.resolve(staticDir),targetDir=target.replace(/^\/?/,"./"),targetEndpoint=targetDir.substring(1);if(!await pathExists(staticPath))throw new Error(dedent(chalk2`
|
|
8
8
|
Failed to load static files, no such directory: {cyan ${staticPath}}
|
|
9
9
|
Make sure this directory exists, or omit the {bold -s (--static-dir)} option.
|
|
10
|
-
`));return{staticDir,staticPath,targetDir,targetEndpoint}};async function copyAllStaticFiles(staticDirs,outputDir){staticDirs&&staticDirs.length>0&&await Promise.all(staticDirs.map(async dir=>{try{let{staticDir,staticPath,targetDir}=await parseStaticDir(dir),targetPath=path3.join(outputDir,targetDir);logger3.info(chalk3`=> Copying static files: {cyan ${staticDir}} => {cyan ${targetDir}}`);let skipPaths=["index.html","iframe.html"].map(f=>path3.join(targetPath,f));await fs2.copy(staticPath,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})}catch(e){logger3.error(e.message),process.exit(-1)}}))}async function copyAllStaticFilesRelativeToMain(staticDirs,outputDir,configDir){let workingDir=process.cwd();return staticDirs.reduce(async(acc,dir)=>{await acc;let staticDirAndTarget=typeof dir=="string"?dir:`${dir.from}:${dir.to}`,{staticPath:from,targetEndpoint:to}=await parseStaticDir(getDirectoryFromWorkingDir2({configDir,workingDir,directory:staticDirAndTarget})),targetPath=path3.join(outputDir,to),skipPaths=["index.html","iframe.html"].map(f=>path3.join(targetPath,f));logger3.info(chalk3`=> Copying static files: {cyan ${from}} at {cyan ${targetPath}}`),await fs2.copy(from,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})},Promise.resolve())}import{pathToFileURL}from"url";async function getManagerBuilder(){return import("@storybook/builder-manager")}async function getPreviewBuilder(builderName,configDir){let builderPackage;if(builderName)builderPackage=__require.resolve(["webpack5"].includes(builderName)?`@storybook/builder-${builderName}`:builderName,{paths:[configDir]});else throw new Error("no builder configured!");return await import(pathToFileURL(builderPackage).href)}async function getBuilders({presets,configDir}){let core=await presets.apply("core",void 0),builderName=typeof core?.builder=="string"?core.builder:core?.builder?.name;return Promise.all([getPreviewBuilder(builderName,configDir),getManagerBuilder()])}import{writeJSON}from"fs-extra";import debounce from"lodash/debounce.js";import{STORY_INDEX_INVALIDATED}from"@storybook/core-events";import Watchpack from"watchpack";import slash from"slash";import fs3 from"fs";import path4 from"path";import glob from"globby";import uniq from"lodash/uniq.js";var isDirectory=directory=>{try{return fs3.lstatSync(directory).isDirectory()}catch{return!1}};function toImportPath(relativePath){return relativePath.startsWith(".")?relativePath:`./${relativePath}`}function watchStorySpecifiers(specifiers,options,onInvalidate){let wp=new Watchpack({followSymlinks:!1,ignored:["**/.git","node_modules"]});wp.watch({directories:uniq(specifiers.map(ns=>ns.directory))});async function onChangeOrRemove(watchpackPath,removed){let importPath=slash(watchpackPath.startsWith(".")?watchpackPath:`./${watchpackPath}`),matchingSpecifier=specifiers.find(ns=>ns.importPathMatcher.exec(importPath));if(matchingSpecifier){onInvalidate(matchingSpecifier,importPath,removed);return}let absolutePath=path4.join(options.workingDir,importPath);!removed&&isDirectory(absolutePath)&&await Promise.all(specifiers.filter(specifier=>importPath.startsWith(specifier.directory)).map(async specifier=>{let dirGlob=path4.join(options.workingDir,importPath,"**",path4.basename(specifier.files));(await glob(dirGlob.replace(/\\/g,"/"))).forEach(filePath=>{let fileImportPath=toImportPath(path4.relative(options.workingDir,filePath).replace(/\\/g,"/"));specifier.importPathMatcher.exec(fileImportPath)&&onInvalidate(specifier,fileImportPath,removed)})}))}return wp.on("change",async(filePath,mtime,explanation)=>{await onChangeOrRemove(filePath,!mtime)}),wp.on("remove",async(filePath,explanation)=>{await onChangeOrRemove(filePath,!0)}),()=>wp.close()}var DEBOUNCE=100;async function extractStoriesJson(outputFile,initializedStoryIndexGenerator,transform){let storyIndex=await(await initializedStoryIndexGenerator).getIndex();await writeJSON(outputFile,transform?transform(storyIndex):storyIndex)}function useStoriesJson({router:router2,initializedStoryIndexGenerator,workingDir=process.cwd(),serverChannel,normalizedStories}){let maybeInvalidate=debounce(()=>serverChannel.emit(STORY_INDEX_INVALIDATED),DEBOUNCE,{leading:!0});watchStorySpecifiers(normalizedStories,{workingDir},async(specifier,path7,removed)=>{(await initializedStoryIndexGenerator).invalidate(specifier,path7,removed),maybeInvalidate()}),router2.use("/index.json",async(req,res)=>{try{let index=await(await initializedStoryIndexGenerator).getIndex();res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}}),router2.use("/stories.json",async(req,res)=>{try{let generator=await initializedStoryIndexGenerator,index=convertToIndexV3(await generator.getIndex());res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}})}var convertToIndexV3=index=>{let{entries}=index;return{v:3,stories:Object.entries(entries).reduce((acc,[id,entry])=>{let{type,...rest}=entry;return acc[id]={...rest,kind:rest.title,story:rest.name,parameters:{__id:rest.id,docsOnly:type==="docs",fileName:rest.importPath}},acc},{})}};import{writeJSON as writeJSON2}from"fs-extra";import{getStorybookMetadata}from"@storybook/telemetry";async function extractStorybookMetadata(outputFile,configDir){let storybookMetadata=await getStorybookMetadata(configDir);await writeJSON2(outputFile,storybookMetadata)}function useStorybookMetadata(router2,configDir){router2.use("/project.json",async(req,res)=>{let storybookMetadata=await getStorybookMetadata(configDir);res.header("Content-Type","application/json"),res.send(JSON.stringify(storybookMetadata))})}import path5 from"path";import fs4 from"fs-extra";import glob2 from"globby";import slash2 from"slash";import{userOrAutoTitleFromSpecifier,sortStoriesV7}from"@storybook/preview-api";import{normalizeStoryPath}from"@storybook/core-common";import{logger as logger4}from"@storybook/node-logger";import{getStorySortParameter,NoMetaError}from"@storybook/csf-tools";import{toId}from"@storybook/csf";import{analyze}from"@storybook/docs-mdx";var AUTODOCS_TAG="autodocs",STORIES_MDX_TAG="stories-mdx";function isMdxEntry({tags}){return!tags?.includes(AUTODOCS_TAG)&&!tags?.includes(STORIES_MDX_TAG)}var DuplicateEntriesError=class extends Error{constructor(message,entries){super();this.message=message,this.entries=entries}},makeAbsolute=(otherImport,normalizedPath,workingDir)=>otherImport.startsWith(".")?slash2(path5.resolve(workingDir,normalizeStoryPath(path5.join(path5.dirname(normalizedPath),otherImport)))):otherImport,StoryIndexGenerator=class{constructor(specifiers,options){this.specifiers=specifiers;this.options=options;this.specifierToCache=new Map}async initialize(){await Promise.all(this.specifiers.map(async specifier=>{let pathToSubIndex={},fullGlob=slash2(path5.join(this.options.workingDir,specifier.directory,specifier.files));(await glob2(fullGlob)).sort().forEach(absolutePath=>{let ext=path5.extname(absolutePath);if(ext===".storyshot"){let relativePath=path5.relative(this.options.workingDir,absolutePath);logger4.info(`Skipping ${ext} file ${relativePath}`);return}pathToSubIndex[absolutePath]=!1}),this.specifierToCache.set(specifier,pathToSubIndex)})),await this.ensureExtracted()}async updateExtracted(updater,overwrite=!1){await Promise.all(this.specifiers.map(async specifier=>{let entry=this.specifierToCache.get(specifier);return Promise.all(Object.keys(entry).map(async absolutePath=>{entry[absolutePath]&&!overwrite||(entry[absolutePath]=await updater(specifier,absolutePath,entry[absolutePath]))}))}))}isDocsMdx(absolutePath){return/(?<!\.stories)\.mdx$/i.test(absolutePath)}async ensureExtracted(){return await this.updateExtracted(async(specifier,absolutePath)=>this.isDocsMdx(absolutePath)?!1:this.extractStories(specifier,absolutePath)),this.options.docs.disable||await this.updateExtracted(async(specifier,absolutePath)=>this.extractDocs(specifier,absolutePath)),this.specifiers.flatMap(specifier=>{let cache4=this.specifierToCache.get(specifier);return Object.values(cache4).flatMap(entry=>entry?entry.type==="docs"?[entry]:entry.entries:[])})}findDependencies(absoluteImports){let dependencies=[],foundImports=new Set;return this.specifierToCache.forEach(cache4=>{Object.keys(cache4).filter(fileName=>{let foundImport=absoluteImports.find(storyImport=>fileName.startsWith(storyImport));return foundImport&&foundImports.add(foundImport),!!foundImport}).forEach(fileName=>{let cacheEntry=cache4[fileName];if(cacheEntry&&cacheEntry.type==="stories")dependencies.push(cacheEntry);else throw new Error(`Unexpected dependency: ${cacheEntry}`)})}),dependencies}async extractStories(specifier,absolutePath){let relativePath=path5.relative(this.options.workingDir,absolutePath),entries=[];try{let importPath=slash2(normalizeStoryPath(relativePath)),makeTitle=userTitle=>userOrAutoTitleFromSpecifier(importPath,specifier,userTitle),storyIndexer=this.options.storyIndexers.find(indexer=>indexer.test.exec(absolutePath));if(!storyIndexer)throw new Error(`No matching story indexer found for ${absolutePath}`);let csf=await storyIndexer.indexer(absolutePath,{makeTitle}),componentTags=csf.meta.tags||[];if(csf.stories.forEach(({id,name,tags:storyTags,parameters})=>{if(!parameters?.docsOnly){let tags=[...storyTags||componentTags,"story"];entries.push({id,title:csf.meta.title,name,importPath,tags,type:"story"})}}),!this.options.docs.disable&&csf.stories.length){let{autodocs}=this.options.docs,componentAutodocs=componentTags.includes(AUTODOCS_TAG),autodocsOptedIn=autodocs===!0||autodocs==="tag"&&componentAutodocs;if(componentTags.includes(STORIES_MDX_TAG)||autodocsOptedIn){let name=this.options.docs.defaultName,id=toId(csf.meta.title,name);entries.unshift({id,title:csf.meta.title,name,importPath,type:"docs",tags:[...componentTags,"docs",...autodocsOptedIn&&!componentAutodocs?[AUTODOCS_TAG]:[]],storiesImports:[]})}}}catch(err){if(err instanceof NoMetaError)logger4.info(`\u{1F4A1} Skipping ${relativePath}: ${err}`);else throw logger4.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}return{entries,type:"stories",dependents:[]}}async extractDocs(specifier,absolutePath){let relativePath=path5.relative(this.options.workingDir,absolutePath);try{if(!this.options.storyStoreV7)throw new Error("You cannot use `.mdx` files without using `storyStoreV7`.");let normalizedPath=normalizeStoryPath(relativePath),importPath=slash2(normalizedPath),content=await fs4.readFile(absolutePath,"utf8"),result=analyze(content);if(result.isTemplate)return!1;let absoluteImports=result.imports.map(p=>makeAbsolute(p,normalizedPath,this.options.workingDir)),dependencies=this.findDependencies(absoluteImports),ofTitle;if(result.of){let absoluteOf=makeAbsolute(result.of,normalizedPath,this.options.workingDir);if(dependencies.forEach(dep=>{if(dep.entries.length>0){let first=dep.entries[0];path5.normalize(path5.resolve(this.options.workingDir,first.importPath)).startsWith(path5.normalize(absoluteOf))&&(ofTitle=first.title)}}),!ofTitle)throw new Error(`Could not find "${result.of}" for docs file "${relativePath}".`)}dependencies.forEach(dep=>{dep.dependents.push(absolutePath)});let title=ofTitle||userOrAutoTitleFromSpecifier(importPath,specifier,result.title),name=result.name||this.options.docs.defaultName;return{id:toId(title,name),title,name,importPath,storiesImports:dependencies.map(dep=>dep.entries[0].importPath),type:"docs",tags:[...result.tags||[],"docs"]}}catch(err){throw logger4.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}}chooseDuplicate(firstEntry,secondEntry){let firstIsBetter=!0;(secondEntry.type==="story"||isMdxEntry(secondEntry)&&firstEntry.type==="docs"&&!isMdxEntry(firstEntry))&&(firstIsBetter=!1);let betterEntry=firstIsBetter?firstEntry:secondEntry,worseEntry=firstIsBetter?secondEntry:firstEntry,changeDocsName='Use `<Meta of={} name="Other Name">` to distinguish them.';if(worseEntry.type==="story")throw new DuplicateEntriesError(`Duplicate stories with id: ${firstEntry.id}`,[firstEntry,secondEntry]);if(betterEntry.type==="story"){let worseDescriptor=isMdxEntry(worseEntry)?"component docs page":"automatically generated docs page";betterEntry.name===this.options.docs.defaultName?logger4.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your default docs entry name (${betterEntry.name}), so the docs page is being dropped. Consider changing the story name.`):logger4.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your ${worseDescriptor} (${worseEntry.name}), so the docs page is being dropped. ${changeDocsName}`)}else if(isMdxEntry(betterEntry)){if(isMdxEntry(worseEntry)&&logger4.warn(`\u{1F6A8} You have two component docs pages with the same name ${betterEntry.title}:${betterEntry.name}. ${changeDocsName}`),worseEntry.tags?.includes(AUTODOCS_TAG)&&this.options.docs.autodocs!==!0)throw new Error(`You created a component docs page for ${worseEntry.title} (${betterEntry.importPath}), but also tagged the CSF file (${worseEntry.importPath}) with '${AUTODOCS_TAG}'. This is probably a mistake.`)}else return{...betterEntry,storiesImports:[...betterEntry.storiesImports,worseEntry.importPath,...worseEntry.storiesImports]};return betterEntry}async sortStories(storiesList){let entries={};storiesList.forEach(entry=>{let existing=entries[entry.id];existing?entries[entry.id]=this.chooseDuplicate(existing,entry):entries[entry.id]=entry});let sortableStories=Object.values(entries);if(this.options.storyStoreV7){let storySortParameter=await this.getStorySortParameter(),fileNameOrder=this.storyFileNames();sortStoriesV7(sortableStories,storySortParameter,fileNameOrder)}return sortableStories.reduce((acc,item)=>(acc[item.id]=item,acc),{})}async getIndex(){if(this.lastIndex)return this.lastIndex;let storiesList=await this.ensureExtracted(),sorted=await this.sortStories(storiesList),compat=sorted;if(this.options.storiesV2Compatibility){let titleToStoryCount=Object.values(sorted).reduce((acc,story)=>(acc[story.title]=(acc[story.title]||0)+1,acc),{});compat=Object.entries(sorted).reduce((acc,entry)=>{let[id,story]=entry;return story.type==="docs"||(acc[id]={...story,kind:story.title,story:story.name,parameters:{__id:story.id,docsOnly:titleToStoryCount[story.title]===1&&story.name==="Page",fileName:story.importPath}}),acc},{})}return this.lastIndex={v:4,entries:compat},this.lastIndex}invalidate(specifier,importPath,removed){let absolutePath=slash2(path5.resolve(this.options.workingDir,importPath)),cache4=this.specifierToCache.get(specifier),cacheEntry=cache4[absolutePath];if(cacheEntry&&cacheEntry.type==="stories"){let{dependents}=cacheEntry,invalidated=new Set;this.specifierToCache.forEach(otherCache=>{dependents.forEach(dep=>{otherCache[dep]&&(invalidated.add(dep),otherCache[dep]=!1)})})}if(removed){if(cacheEntry&&cacheEntry.type==="docs"){let absoluteImports=cacheEntry.storiesImports.map(p=>path5.resolve(this.options.workingDir,p));this.findDependencies(absoluteImports).forEach(dep=>dep.dependents.splice(dep.dependents.indexOf(absolutePath),1))}delete cache4[absolutePath]}else cache4[absolutePath]=!1;this.lastIndex=null}async getStorySortParameter(){let previewFile=["js","jsx","ts","tsx"].map(ext=>path5.join(this.options.configDir,`preview.${ext}`)).find(fname=>fs4.existsSync(fname)),storySortParameter;if(previewFile){let previewCode=(await fs4.readFile(previewFile,"utf-8")).toString();storySortParameter=await getStorySortParameter(previewCode)}return storySortParameter}storyFileNames(){return Array.from(this.specifierToCache.values()).flatMap(r=>Object.keys(r))}};function summarizeIndex(storyIndex){let storyCount=0,autodocsCount=0,storiesMdxCount=0,mdxCount=0;return Object.values(storyIndex.entries).forEach(entry=>{entry.type==="story"?storyCount+=1:entry.type==="docs"&&(isMdxEntry(entry)?mdxCount+=1:entry.tags.includes(STORIES_MDX_TAG)?storiesMdxCount+=1:entry.tags.includes(AUTODOCS_TAG)&&(autodocsCount+=1))}),{storyCount,autodocsCount,storiesMdxCount,mdxCount,version:storyIndex.v}}async function buildStaticStandalone(options){if(options.configType="PRODUCTION",options.outputDir==="")throw new Error("Won't remove current directory. Check your outputDir!");if(options.staticDir?.includes("/"))throw new Error("Won't copy root directory. Check your staticDirs!");if(options.outputDir=isAbsolute(options.outputDir)?options.outputDir:join(process.cwd(),options.outputDir),options.configDir=resolve(options.configDir),logger5.info(chalk4`=> Cleaning outputDir: {cyan ${options.outputDir.replace(process.cwd(),"")}}`),options.outputDir==="/")throw new Error("Won't remove directory '/'. Check your outputDir!");await emptyDir(options.outputDir),await ensureDir(options.outputDir);let{framework}=loadMainConfig(options),corePresets=[],frameworkName=typeof framework=="string"?framework:framework?.name;frameworkName?corePresets.push(join(frameworkName,"preset")):logger5.warn(`you have not specified a framework in your ${options.configDir}/main.js`),logger5.info("=> Loading presets");let presets=await loadAllPresets({corePresets:[__require.resolve("@storybook/core-server/dist/presets/common-preset"),...corePresets],overridePresets:[],...options}),[previewBuilder,managerBuilder]=await getBuilders({...options,presets}),{renderer}=await presets.apply("core",void 0);presets=await loadAllPresets({corePresets:[__require.resolve("@storybook/core-server/dist/presets/common-preset"),...managerBuilder.corePresets||[],...previewBuilder.corePresets||[],...renderer?[resolveAddonName(options.configDir,renderer,options)]:[],...corePresets,__require.resolve("@storybook/core-server/dist/presets/babel-cache-preset")],overridePresets:previewBuilder.overridePresets||[],...options});let[features,core,staticDirs,storyIndexers,stories,docsOptions]=await Promise.all([presets.apply("features"),presets.apply("core"),presets.apply("staticDirs"),presets.apply("storyIndexers",[]),presets.apply("stories"),presets.apply("docs",{})]),fullOptions={...options,presets,features};if(staticDirs&&options.staticDir)throw new Error(dedent2`
|
|
10
|
+
`));return{staticDir,staticPath,targetDir,targetEndpoint}};async function copyAllStaticFiles(staticDirs,outputDir){staticDirs&&staticDirs.length>0&&await Promise.all(staticDirs.map(async dir=>{try{let{staticDir,staticPath,targetDir}=await parseStaticDir(dir),targetPath=path3.join(outputDir,targetDir);logger3.info(chalk3`=> Copying static files: {cyan ${staticDir}} => {cyan ${targetDir}}`);let skipPaths=["index.html","iframe.html"].map(f=>path3.join(targetPath,f));await fs2.copy(staticPath,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})}catch(e){logger3.error(e.message),process.exit(-1)}}))}async function copyAllStaticFilesRelativeToMain(staticDirs,outputDir,configDir){let workingDir=process.cwd();return staticDirs.reduce(async(acc,dir)=>{await acc;let staticDirAndTarget=typeof dir=="string"?dir:`${dir.from}:${dir.to}`,{staticPath:from,targetEndpoint:to}=await parseStaticDir(getDirectoryFromWorkingDir2({configDir,workingDir,directory:staticDirAndTarget})),targetPath=path3.join(outputDir,to),skipPaths=["index.html","iframe.html"].map(f=>path3.join(targetPath,f));logger3.info(chalk3`=> Copying static files: {cyan ${from}} at {cyan ${targetPath}}`),await fs2.copy(from,targetPath,{dereference:!0,preserveTimestamps:!0,filter:(_,dest)=>!skipPaths.includes(dest)})},Promise.resolve())}import{pathToFileURL}from"url";async function getManagerBuilder(){return import("@storybook/builder-manager")}async function getPreviewBuilder(builderName,configDir){let builderPackage;if(builderName)builderPackage=__require.resolve(["webpack5"].includes(builderName)?`@storybook/builder-${builderName}`:builderName,{paths:[configDir]});else throw new Error("no builder configured!");return await import(pathToFileURL(builderPackage).href)}async function getBuilders({presets,configDir}){let core=await presets.apply("core",void 0),builderName=typeof core?.builder=="string"?core.builder:core?.builder?.name;return Promise.all([getPreviewBuilder(builderName,configDir),getManagerBuilder()])}import{writeJSON}from"fs-extra";import debounce from"lodash/debounce.js";import{STORY_INDEX_INVALIDATED}from"@storybook/core-events";import Watchpack from"watchpack";import slash from"slash";import fs3 from"fs";import path4 from"path";import glob from"globby";import uniq from"lodash/uniq.js";var isDirectory=directory=>{try{return fs3.lstatSync(directory).isDirectory()}catch{return!1}};function toImportPath(relativePath){return relativePath.startsWith(".")?relativePath:`./${relativePath}`}function watchStorySpecifiers(specifiers,options,onInvalidate){let wp=new Watchpack({followSymlinks:!1,ignored:["**/.git","node_modules"]});wp.watch({directories:uniq(specifiers.map(ns=>ns.directory))});async function onChangeOrRemove(watchpackPath,removed){let importPath=slash(watchpackPath.startsWith(".")?watchpackPath:`./${watchpackPath}`),matchingSpecifier=specifiers.find(ns=>ns.importPathMatcher.exec(importPath));if(matchingSpecifier){onInvalidate(matchingSpecifier,importPath,removed);return}let absolutePath=path4.join(options.workingDir,importPath);!removed&&isDirectory(absolutePath)&&await Promise.all(specifiers.filter(specifier=>importPath.startsWith(specifier.directory)).map(async specifier=>{let dirGlob=path4.join(options.workingDir,importPath,"**",path4.basename(specifier.files));(await glob(dirGlob.replace(/\\/g,"/"))).forEach(filePath=>{let fileImportPath=toImportPath(path4.relative(options.workingDir,filePath).replace(/\\/g,"/"));specifier.importPathMatcher.exec(fileImportPath)&&onInvalidate(specifier,fileImportPath,removed)})}))}return wp.on("change",async(filePath,mtime,explanation)=>{await onChangeOrRemove(filePath,!mtime)}),wp.on("remove",async(filePath,explanation)=>{await onChangeOrRemove(filePath,!0)}),()=>wp.close()}var DEBOUNCE=100;async function extractStoriesJson(outputFile,initializedStoryIndexGenerator,transform){let storyIndex=await(await initializedStoryIndexGenerator).getIndex();await writeJSON(outputFile,transform?transform(storyIndex):storyIndex)}function useStoriesJson({router:router2,initializedStoryIndexGenerator,workingDir=process.cwd(),serverChannel,normalizedStories}){let maybeInvalidate=debounce(()=>serverChannel.emit(STORY_INDEX_INVALIDATED),DEBOUNCE,{leading:!0});watchStorySpecifiers(normalizedStories,{workingDir},async(specifier,path7,removed)=>{(await initializedStoryIndexGenerator).invalidate(specifier,path7,removed),maybeInvalidate()}),router2.use("/index.json",async(req,res)=>{try{let index=await(await initializedStoryIndexGenerator).getIndex();res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}}),router2.use("/stories.json",async(req,res)=>{try{let generator=await initializedStoryIndexGenerator,index=convertToIndexV3(await generator.getIndex());res.header("Content-Type","application/json"),res.send(JSON.stringify(index))}catch(err){res.status(500),res.send(err.message)}})}var convertToIndexV3=index=>{let{entries}=index;return{v:3,stories:Object.entries(entries).reduce((acc,[id,entry])=>{let{type,...rest}=entry;return acc[id]={...rest,kind:rest.title,story:rest.name,parameters:{__id:rest.id,docsOnly:type==="docs",fileName:rest.importPath}},acc},{})}};import{writeJSON as writeJSON2}from"fs-extra";import{getStorybookMetadata}from"@storybook/telemetry";async function extractStorybookMetadata(outputFile,configDir){let storybookMetadata=await getStorybookMetadata(configDir);await writeJSON2(outputFile,storybookMetadata)}function useStorybookMetadata(router2,configDir){router2.use("/project.json",async(req,res)=>{let storybookMetadata=await getStorybookMetadata(configDir);res.header("Content-Type","application/json"),res.send(JSON.stringify(storybookMetadata))})}import path5 from"path";import fs4 from"fs-extra";import glob2 from"globby";import slash2 from"slash";import{userOrAutoTitleFromSpecifier,sortStoriesV7}from"@storybook/preview-api";import{normalizeStoryPath}from"@storybook/core-common";import{logger as logger4}from"@storybook/node-logger";import{getStorySortParameter,NoMetaError}from"@storybook/csf-tools";import{toId}from"@storybook/csf";import{analyze}from"@storybook/docs-mdx";var AUTODOCS_TAG="autodocs",STORIES_MDX_TAG="stories-mdx",PLAY_FN_TAG="play-fn";function isMdxEntry({tags}){return!tags?.includes(AUTODOCS_TAG)&&!tags?.includes(STORIES_MDX_TAG)}var DuplicateEntriesError=class extends Error{constructor(message,entries){super();this.message=message,this.entries=entries}},makeAbsolute=(otherImport,normalizedPath,workingDir)=>otherImport.startsWith(".")?slash2(path5.resolve(workingDir,normalizeStoryPath(path5.join(path5.dirname(normalizedPath),otherImport)))):otherImport,StoryIndexGenerator=class{constructor(specifiers,options){this.specifiers=specifiers;this.options=options;this.specifierToCache=new Map}async initialize(){await Promise.all(this.specifiers.map(async specifier=>{let pathToSubIndex={},fullGlob=slash2(path5.join(this.options.workingDir,specifier.directory,specifier.files));(await glob2(fullGlob)).sort().forEach(absolutePath=>{let ext=path5.extname(absolutePath);if(ext===".storyshot"){let relativePath=path5.relative(this.options.workingDir,absolutePath);logger4.info(`Skipping ${ext} file ${relativePath}`);return}pathToSubIndex[absolutePath]=!1}),this.specifierToCache.set(specifier,pathToSubIndex)})),await this.ensureExtracted()}async updateExtracted(updater,overwrite=!1){await Promise.all(this.specifiers.map(async specifier=>{let entry=this.specifierToCache.get(specifier);return Promise.all(Object.keys(entry).map(async absolutePath=>{entry[absolutePath]&&!overwrite||(entry[absolutePath]=await updater(specifier,absolutePath,entry[absolutePath]))}))}))}isDocsMdx(absolutePath){return/(?<!\.stories)\.mdx$/i.test(absolutePath)}async ensureExtracted(){return await this.updateExtracted(async(specifier,absolutePath)=>this.isDocsMdx(absolutePath)?!1:this.extractStories(specifier,absolutePath)),this.options.docs.disable||await this.updateExtracted(async(specifier,absolutePath)=>this.extractDocs(specifier,absolutePath)),this.specifiers.flatMap(specifier=>{let cache4=this.specifierToCache.get(specifier);return Object.values(cache4).flatMap(entry=>entry?entry.type==="docs"?[entry]:entry.entries:[])})}findDependencies(absoluteImports){let dependencies=[],foundImports=new Set;return this.specifierToCache.forEach(cache4=>{Object.keys(cache4).filter(fileName=>{let foundImport=absoluteImports.find(storyImport=>fileName.startsWith(storyImport));return foundImport&&foundImports.add(foundImport),!!foundImport}).forEach(fileName=>{let cacheEntry=cache4[fileName];if(cacheEntry&&cacheEntry.type==="stories")dependencies.push(cacheEntry);else throw new Error(`Unexpected dependency: ${cacheEntry}`)})}),dependencies}async extractStories(specifier,absolutePath){let relativePath=path5.relative(this.options.workingDir,absolutePath),entries=[];try{let importPath=slash2(normalizeStoryPath(relativePath)),makeTitle=userTitle=>userOrAutoTitleFromSpecifier(importPath,specifier,userTitle),storyIndexer=this.options.storyIndexers.find(indexer=>indexer.test.exec(absolutePath));if(!storyIndexer)throw new Error(`No matching story indexer found for ${absolutePath}`);let csf=await storyIndexer.indexer(absolutePath,{makeTitle}),componentTags=csf.meta.tags||[];if(csf.stories.forEach(({id,name,tags:storyTags,parameters})=>{if(!parameters?.docsOnly){let tags=[...storyTags||componentTags,"story"];entries.push({id,title:csf.meta.title,name,importPath,tags,type:"story"})}}),!this.options.docs.disable&&csf.stories.length){let{autodocs}=this.options.docs,componentAutodocs=componentTags.includes(AUTODOCS_TAG),autodocsOptedIn=autodocs===!0||autodocs==="tag"&&componentAutodocs;if(componentTags.includes(STORIES_MDX_TAG)||autodocsOptedIn){let name=this.options.docs.defaultName,id=toId(csf.meta.title,name);entries.unshift({id,title:csf.meta.title,name,importPath,type:"docs",tags:[...componentTags,"docs",...autodocsOptedIn&&!componentAutodocs?[AUTODOCS_TAG]:[]],storiesImports:[]})}}}catch(err){if(err instanceof NoMetaError)logger4.info(`\u{1F4A1} Skipping ${relativePath}: ${err}`);else throw logger4.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}return{entries,type:"stories",dependents:[]}}async extractDocs(specifier,absolutePath){let relativePath=path5.relative(this.options.workingDir,absolutePath);try{if(!this.options.storyStoreV7)throw new Error("You cannot use `.mdx` files without using `storyStoreV7`.");let normalizedPath=normalizeStoryPath(relativePath),importPath=slash2(normalizedPath),content=await fs4.readFile(absolutePath,"utf8"),result=analyze(content);if(result.isTemplate)return!1;let absoluteImports=result.imports.map(p=>makeAbsolute(p,normalizedPath,this.options.workingDir)),dependencies=this.findDependencies(absoluteImports),ofTitle;if(result.of){let absoluteOf=makeAbsolute(result.of,normalizedPath,this.options.workingDir);if(dependencies.forEach(dep=>{if(dep.entries.length>0){let first=dep.entries[0];path5.normalize(path5.resolve(this.options.workingDir,first.importPath)).startsWith(path5.normalize(absoluteOf))&&(ofTitle=first.title)}}),!ofTitle)throw new Error(`Could not find "${result.of}" for docs file "${relativePath}".`)}dependencies.forEach(dep=>{dep.dependents.push(absolutePath)});let title=ofTitle||userOrAutoTitleFromSpecifier(importPath,specifier,result.title),name=result.name||this.options.docs.defaultName;return{id:toId(title,name),title,name,importPath,storiesImports:dependencies.map(dep=>dep.entries[0].importPath),type:"docs",tags:[...result.tags||[],"docs"]}}catch(err){throw logger4.warn(`\u{1F6A8} Extraction error on ${relativePath}: ${err}`),err}}chooseDuplicate(firstEntry,secondEntry){let firstIsBetter=!0;(secondEntry.type==="story"||isMdxEntry(secondEntry)&&firstEntry.type==="docs"&&!isMdxEntry(firstEntry))&&(firstIsBetter=!1);let betterEntry=firstIsBetter?firstEntry:secondEntry,worseEntry=firstIsBetter?secondEntry:firstEntry,changeDocsName='Use `<Meta of={} name="Other Name">` to distinguish them.';if(worseEntry.type==="story")throw new DuplicateEntriesError(`Duplicate stories with id: ${firstEntry.id}`,[firstEntry,secondEntry]);if(betterEntry.type==="story"){let worseDescriptor=isMdxEntry(worseEntry)?"component docs page":"automatically generated docs page";betterEntry.name===this.options.docs.defaultName?logger4.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your default docs entry name (${betterEntry.name}), so the docs page is being dropped. Consider changing the story name.`):logger4.warn(`\u{1F6A8} You have a story for ${betterEntry.title} with the same name as your ${worseDescriptor} (${worseEntry.name}), so the docs page is being dropped. ${changeDocsName}`)}else if(isMdxEntry(betterEntry)){if(isMdxEntry(worseEntry)&&logger4.warn(`\u{1F6A8} You have two component docs pages with the same name ${betterEntry.title}:${betterEntry.name}. ${changeDocsName}`),worseEntry.tags?.includes(AUTODOCS_TAG)&&this.options.docs.autodocs!==!0)throw new Error(`You created a component docs page for ${worseEntry.title} (${betterEntry.importPath}), but also tagged the CSF file (${worseEntry.importPath}) with '${AUTODOCS_TAG}'. This is probably a mistake.`)}else return{...betterEntry,storiesImports:[...betterEntry.storiesImports,worseEntry.importPath,...worseEntry.storiesImports]};return betterEntry}async sortStories(storiesList){let entries={};storiesList.forEach(entry=>{let existing=entries[entry.id];existing?entries[entry.id]=this.chooseDuplicate(existing,entry):entries[entry.id]=entry});let sortableStories=Object.values(entries);if(this.options.storyStoreV7){let storySortParameter=await this.getStorySortParameter(),fileNameOrder=this.storyFileNames();sortStoriesV7(sortableStories,storySortParameter,fileNameOrder)}return sortableStories.reduce((acc,item)=>(acc[item.id]=item,acc),{})}async getIndex(){if(this.lastIndex)return this.lastIndex;let storiesList=await this.ensureExtracted(),sorted=await this.sortStories(storiesList),compat=sorted;if(this.options.storiesV2Compatibility){let titleToStoryCount=Object.values(sorted).reduce((acc,story)=>(acc[story.title]=(acc[story.title]||0)+1,acc),{});compat=Object.entries(sorted).reduce((acc,entry)=>{let[id,story]=entry;return story.type==="docs"||(acc[id]={...story,kind:story.title,story:story.name,parameters:{__id:story.id,docsOnly:titleToStoryCount[story.title]===1&&story.name==="Page",fileName:story.importPath}}),acc},{})}return this.lastIndex={v:4,entries:compat},this.lastIndex}invalidate(specifier,importPath,removed){let absolutePath=slash2(path5.resolve(this.options.workingDir,importPath)),cache4=this.specifierToCache.get(specifier),cacheEntry=cache4[absolutePath];if(cacheEntry&&cacheEntry.type==="stories"){let{dependents}=cacheEntry,invalidated=new Set;this.specifierToCache.forEach(otherCache=>{dependents.forEach(dep=>{otherCache[dep]&&(invalidated.add(dep),otherCache[dep]=!1)})})}if(removed){if(cacheEntry&&cacheEntry.type==="docs"){let absoluteImports=cacheEntry.storiesImports.map(p=>path5.resolve(this.options.workingDir,p));this.findDependencies(absoluteImports).forEach(dep=>dep.dependents.splice(dep.dependents.indexOf(absolutePath),1))}delete cache4[absolutePath]}else cache4[absolutePath]=!1;this.lastIndex=null}async getStorySortParameter(){let previewFile=["js","jsx","ts","tsx"].map(ext=>path5.join(this.options.configDir,`preview.${ext}`)).find(fname=>fs4.existsSync(fname)),storySortParameter;if(previewFile){let previewCode=(await fs4.readFile(previewFile,"utf-8")).toString();storySortParameter=await getStorySortParameter(previewCode)}return storySortParameter}storyFileNames(){return Array.from(this.specifierToCache.values()).flatMap(r=>Object.keys(r))}};var PAGE_REGEX=/(page|screen)/i,isPageStory=storyId=>PAGE_REGEX.test(storyId),isExampleEntry=entry=>["example-introduction--docs","example-button--docs","example-button--primary","example-button--secondary","example-button--large","example-button--small","example-header--docs","example-header--logged-in","example-header--logged-out","example-page--logged-in","example-page--logged-out"].includes(entry.id);function summarizeIndex(storyIndex){let storyCount=0,exampleStoryCount=0,exampleDocsCount=0,pageStoryCount=0,playStoryCount=0,autodocsCount=0,storiesMdxCount=0,mdxCount=0;return Object.values(storyIndex.entries).forEach(entry=>{isExampleEntry(entry)?(entry.type==="story"&&(exampleStoryCount+=1),entry.type==="docs"&&(exampleDocsCount+=1)):entry.type==="story"?(storyCount+=1,isPageStory(entry.title)&&(pageStoryCount+=1),entry.tags?.includes(PLAY_FN_TAG)&&(playStoryCount+=1)):entry.type==="docs"&&(isMdxEntry(entry)?mdxCount+=1:entry.tags?.includes(STORIES_MDX_TAG)?storiesMdxCount+=1:entry.tags?.includes(AUTODOCS_TAG)&&(autodocsCount+=1))}),{storyCount,pageStoryCount,playStoryCount,autodocsCount,storiesMdxCount,mdxCount,exampleStoryCount,exampleDocsCount,version:storyIndex.v}}async function buildStaticStandalone(options){if(options.configType="PRODUCTION",options.outputDir==="")throw new Error("Won't remove current directory. Check your outputDir!");if(options.staticDir?.includes("/"))throw new Error("Won't copy root directory. Check your staticDirs!");if(options.outputDir=isAbsolute(options.outputDir)?options.outputDir:join(process.cwd(),options.outputDir),options.configDir=resolve(options.configDir),logger5.info(chalk4`=> Cleaning outputDir: {cyan ${options.outputDir.replace(process.cwd(),"")}}`),options.outputDir==="/")throw new Error("Won't remove directory '/'. Check your outputDir!");await emptyDir(options.outputDir),await ensureDir(options.outputDir);let{framework}=loadMainConfig(options),corePresets=[],frameworkName=typeof framework=="string"?framework:framework?.name;frameworkName?corePresets.push(join(frameworkName,"preset")):logger5.warn(`you have not specified a framework in your ${options.configDir}/main.js`),logger5.info("=> Loading presets");let presets=await loadAllPresets({corePresets:[__require.resolve("@storybook/core-server/dist/presets/common-preset"),...corePresets],overridePresets:[],...options}),[previewBuilder,managerBuilder]=await getBuilders({...options,presets}),{renderer}=await presets.apply("core",void 0);presets=await loadAllPresets({corePresets:[__require.resolve("@storybook/core-server/dist/presets/common-preset"),...managerBuilder.corePresets||[],...previewBuilder.corePresets||[],...renderer?[resolveAddonName(options.configDir,renderer,options)]:[],...corePresets,__require.resolve("@storybook/core-server/dist/presets/babel-cache-preset")],overridePresets:previewBuilder.overridePresets||[],...options});let[features,core,staticDirs,storyIndexers,stories,docsOptions]=await Promise.all([presets.apply("features"),presets.apply("core"),presets.apply("staticDirs"),presets.apply("storyIndexers",[]),presets.apply("stories"),presets.apply("docs",{})]),fullOptions={...options,presets,features};if(staticDirs&&options.staticDir)throw new Error(dedent2`
|
|
11
11
|
Conflict when trying to read staticDirs:
|
|
12
12
|
* Storybook's configuration option: 'staticDirs'
|
|
13
13
|
* Storybook's CLI flag: '--staticDir' or '-s'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/core-server",
|
|
3
|
-
"version": "7.0.0-beta.
|
|
3
|
+
"version": "7.0.0-beta.23",
|
|
4
4
|
"description": "Storybook framework-agnostic API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook"
|
|
@@ -58,17 +58,17 @@
|
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@aw-web-design/x-default-browser": "1.4.88",
|
|
60
60
|
"@discoveryjs/json-ext": "^0.5.3",
|
|
61
|
-
"@storybook/builder-manager": "7.0.0-beta.
|
|
62
|
-
"@storybook/core-common": "7.0.0-beta.
|
|
63
|
-
"@storybook/core-events": "7.0.0-beta.
|
|
61
|
+
"@storybook/builder-manager": "7.0.0-beta.23",
|
|
62
|
+
"@storybook/core-common": "7.0.0-beta.23",
|
|
63
|
+
"@storybook/core-events": "7.0.0-beta.23",
|
|
64
64
|
"@storybook/csf": "next",
|
|
65
|
-
"@storybook/csf-tools": "7.0.0-beta.
|
|
65
|
+
"@storybook/csf-tools": "7.0.0-beta.23",
|
|
66
66
|
"@storybook/docs-mdx": "next",
|
|
67
67
|
"@storybook/global": "^5.0.0",
|
|
68
|
-
"@storybook/node-logger": "7.0.0-beta.
|
|
69
|
-
"@storybook/preview-api": "7.0.0-beta.
|
|
70
|
-
"@storybook/telemetry": "7.0.0-beta.
|
|
71
|
-
"@storybook/types": "7.0.0-beta.
|
|
68
|
+
"@storybook/node-logger": "7.0.0-beta.23",
|
|
69
|
+
"@storybook/preview-api": "7.0.0-beta.23",
|
|
70
|
+
"@storybook/telemetry": "7.0.0-beta.23",
|
|
71
|
+
"@storybook/types": "7.0.0-beta.23",
|
|
72
72
|
"@types/detect-port": "^1.3.0",
|
|
73
73
|
"@types/node": "^16.0.0",
|
|
74
74
|
"@types/node-fetch": "^2.5.7",
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
],
|
|
120
120
|
"platform": "node"
|
|
121
121
|
},
|
|
122
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "540859f1e7daeb25a03b2095e4223effc7f590b8"
|
|
123
123
|
}
|