UNPKG

storybook

Version:

Storybook: Develop, document, and test UI components in isolation

1,422 lines (1,375 loc) • 67.6 kB
import CJS_COMPAT_NODE_URL_q99y7iqlbzn from 'node:url'; import CJS_COMPAT_NODE_PATH_q99y7iqlbzn from 'node:path'; import CJS_COMPAT_NODE_MODULE_q99y7iqlbzn from "node:module"; var __filename = CJS_COMPAT_NODE_URL_q99y7iqlbzn.fileURLToPath(import.meta.url); var __dirname = CJS_COMPAT_NODE_PATH_q99y7iqlbzn.dirname(__filename); var require = CJS_COMPAT_NODE_MODULE_q99y7iqlbzn.createRequire(import.meta.url); // ------------------------------------------------------------ // end of CJS compatibility banner, injected by Storybook's esbuild configuration // ------------------------------------------------------------ import { parseStaticDir, sendTelemetryError } from "../../_node-chunks/chunk-GJU3UNCG.js"; import "../../_node-chunks/chunk-UXQJJRYH.js"; import { getLastEvents, getSessionId } from "../../_node-chunks/chunk-ZHQALUV5.js"; import { invariant } from "../../_node-chunks/chunk-35SLFIQV.js"; import { resolvePackageDir } from "../../_node-chunks/chunk-7N53RHGS.js"; import { isAbsolute, join } from "../../_node-chunks/chunk-LMQEOO5W.js"; import "../../_node-chunks/chunk-KCF2Q4OQ.js"; import { loadConfig } from "../../_node-chunks/chunk-DF53JQZU.js"; import { require_dist } from "../../_node-chunks/chunk-IMHUIAVE.js"; import { require_picocolors } from "../../_node-chunks/chunk-KABHBSS3.js"; import { __commonJS, __name, __require, __toESM } from "../../_node-chunks/chunk-MB5KTO7X.js"; // ../node_modules/shell-quote/quote.js var require_quote = __commonJS({ "../node_modules/shell-quote/quote.js"(exports, module) { "use strict"; module.exports = /* @__PURE__ */ __name(function quote(xs) { return xs.map(function(s) { if (s === "") { return "''"; } if (s && typeof s === "object") { return s.op.replace(/(.)/g, "\\$1"); } if (/["\s\\]/.test(s) && !/'/.test(s)) { return "'" + s.replace(/(['])/g, "\\$1") + "'"; } if (/["'\s]/.test(s)) { return '"' + s.replace(/(["\\$`!])/g, "\\$1") + '"'; } return String(s).replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, "$1\\$2"); }).join(" "); }, "quote"); } }); // ../node_modules/shell-quote/parse.js var require_parse = __commonJS({ "../node_modules/shell-quote/parse.js"(exports, module) { "use strict"; var CONTROL = "(?:" + [ "\\|\\|", "\\&\\&", ";;", "\\|\\&", "\\<\\(", "\\<\\<\\<", ">>", ">\\&", "<\\&", "[&;()|<>]" ].join("|") + ")"; var controlRE = new RegExp("^" + CONTROL + "$"); var META = "|&;()<> \\t"; var SINGLE_QUOTE = '"((\\\\"|[^"])*?)"'; var DOUBLE_QUOTE = "'((\\\\'|[^'])*?)'"; var hash = /^#$/; var SQ = "'"; var DQ = '"'; var DS = "$"; var TOKEN = ""; var mult = 4294967296; for (i = 0; i < 4; i++) { TOKEN += (mult * Math.random()).toString(16); } var i; var startsWithToken = new RegExp("^" + TOKEN); function matchAll(s, r) { var origIndex = r.lastIndex; var matches = []; var matchObj; while (matchObj = r.exec(s)) { matches.push(matchObj); if (r.lastIndex === matchObj.index) { r.lastIndex += 1; } } r.lastIndex = origIndex; return matches; } __name(matchAll, "matchAll"); function getVar(env2, pre, key) { var r = typeof env2 === "function" ? env2(key) : env2[key]; if (typeof r === "undefined" && key != "") { r = ""; } else if (typeof r === "undefined") { r = "$"; } if (typeof r === "object") { return pre + TOKEN + JSON.stringify(r) + TOKEN; } return pre + r; } __name(getVar, "getVar"); function parseInternal(string, env2, opts) { if (!opts) { opts = {}; } var BS = opts.escape || "\\"; var BAREWORD = "(\\" + BS + `['"` + META + `]|[^\\s'"` + META + "])+"; var chunker = new RegExp([ "(" + CONTROL + ")", // control chars "(" + BAREWORD + "|" + SINGLE_QUOTE + "|" + DOUBLE_QUOTE + ")+" ].join("|"), "g"); var matches = matchAll(string, chunker); if (matches.length === 0) { return []; } if (!env2) { env2 = {}; } var commented = false; return matches.map(function(match) { var s = match[0]; if (!s || commented) { return void 0; } if (controlRE.test(s)) { return { op: s }; } var quote = false; var esc = false; var out = ""; var isGlob = false; var i2; function parseEnvVar() { i2 += 1; var varend; var varname; var char = s.charAt(i2); if (char === "{") { i2 += 1; if (s.charAt(i2) === "}") { throw new Error("Bad substitution: " + s.slice(i2 - 2, i2 + 1)); } varend = s.indexOf("}", i2); if (varend < 0) { throw new Error("Bad substitution: " + s.slice(i2)); } varname = s.slice(i2, varend); i2 = varend; } else if (/[*@#?$!_-]/.test(char)) { varname = char; i2 += 1; } else { var slicedFromI = s.slice(i2); varend = slicedFromI.match(/[^\w\d_]/); if (!varend) { varname = slicedFromI; i2 = s.length; } else { varname = slicedFromI.slice(0, varend.index); i2 += varend.index - 1; } } return getVar(env2, "", varname); } __name(parseEnvVar, "parseEnvVar"); for (i2 = 0; i2 < s.length; i2++) { var c = s.charAt(i2); isGlob = isGlob || !quote && (c === "*" || c === "?"); if (esc) { out += c; esc = false; } else if (quote) { if (c === quote) { quote = false; } else if (quote == SQ) { out += c; } else { if (c === BS) { i2 += 1; c = s.charAt(i2); if (c === DQ || c === BS || c === DS) { out += c; } else { out += BS + c; } } else if (c === DS) { out += parseEnvVar(); } else { out += c; } } } else if (c === DQ || c === SQ) { quote = c; } else if (controlRE.test(c)) { return { op: s }; } else if (hash.test(c)) { commented = true; var commentObj = { comment: string.slice(match.index + i2 + 1) }; if (out.length) { return [out, commentObj]; } return [commentObj]; } else if (c === BS) { esc = true; } else if (c === DS) { out += parseEnvVar(); } else { out += c; } } if (isGlob) { return { op: "glob", pattern: out }; } return out; }).reduce(function(prev, arg) { return typeof arg === "undefined" ? prev : prev.concat(arg); }, []); } __name(parseInternal, "parseInternal"); module.exports = /* @__PURE__ */ __name(function parse(s, env2, opts) { var mapped = parseInternal(s, env2, opts); if (typeof env2 !== "function") { return mapped; } return mapped.reduce(function(acc, s2) { if (typeof s2 === "object") { return acc.concat(s2); } var xs = s2.split(RegExp("(" + TOKEN + ".*?" + TOKEN + ")", "g")); if (xs.length === 1) { return acc.concat(xs[0]); } return acc.concat(xs.filter(Boolean).map(function(x) { if (startsWithToken.test(x)) { return JSON.parse(x.split(TOKEN)[1]); } return x; })); }, []); }, "parse"); } }); // ../node_modules/shell-quote/index.js var require_shell_quote = __commonJS({ "../node_modules/shell-quote/index.js"(exports) { "use strict"; exports.quote = require_quote(); exports.parse = require_parse(); } }); // ../node_modules/launch-editor/editor-info/macos.js var require_macos = __commonJS({ "../node_modules/launch-editor/editor-info/macos.js"(exports, module) { module.exports = { "/Applications/Atom.app/Contents/MacOS/Atom": "atom", "/Applications/Atom Beta.app/Contents/MacOS/Atom Beta": "/Applications/Atom Beta.app/Contents/MacOS/Atom Beta", "/Applications/Brackets.app/Contents/MacOS/Brackets": "brackets", "/Applications/Sublime Text.app/Contents/MacOS/Sublime Text": "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl", "/Applications/Sublime Text.app/Contents/MacOS/sublime_text": "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl", "/Applications/Sublime Text 2.app/Contents/MacOS/Sublime Text 2": "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl", "/Applications/Sublime Text Dev.app/Contents/MacOS/Sublime Text": "/Applications/Sublime Text Dev.app/Contents/SharedSupport/bin/subl", "/Applications/Visual Studio Code.app/Contents/MacOS/Electron": "code", "/Applications/Visual Studio Code - Insiders.app/Contents/MacOS/Electron": "code-insiders", "/Applications/VSCodium.app/Contents/MacOS/Electron": "codium", "/Applications/Cursor.app/Contents/MacOS/Cursor": "cursor", "/Applications/Trae.app/Contents/MacOS/Electron": "trae", "/Applications/AppCode.app/Contents/MacOS/appcode": "/Applications/AppCode.app/Contents/MacOS/appcode", "/Applications/CLion.app/Contents/MacOS/clion": "/Applications/CLion.app/Contents/MacOS/clion", "/Applications/IntelliJ IDEA.app/Contents/MacOS/idea": "/Applications/IntelliJ IDEA.app/Contents/MacOS/idea", "/Applications/IntelliJ IDEA Ultimate.app/Contents/MacOS/idea": "/Applications/IntelliJ IDEA Ultimate.app/Contents/MacOS/idea", "/Applications/IntelliJ IDEA Community Edition.app/Contents/MacOS/idea": "/Applications/IntelliJ IDEA Community Edition.app/Contents/MacOS/idea", "/Applications/PhpStorm.app/Contents/MacOS/phpstorm": "/Applications/PhpStorm.app/Contents/MacOS/phpstorm", "/Applications/PyCharm.app/Contents/MacOS/pycharm": "/Applications/PyCharm.app/Contents/MacOS/pycharm", "/Applications/PyCharm CE.app/Contents/MacOS/pycharm": "/Applications/PyCharm CE.app/Contents/MacOS/pycharm", "/Applications/RubyMine.app/Contents/MacOS/rubymine": "/Applications/RubyMine.app/Contents/MacOS/rubymine", "/Applications/WebStorm.app/Contents/MacOS/webstorm": "/Applications/WebStorm.app/Contents/MacOS/webstorm", "/Applications/MacVim.app/Contents/MacOS/MacVim": "mvim", "/Applications/GoLand.app/Contents/MacOS/goland": "/Applications/GoLand.app/Contents/MacOS/goland", "/Applications/Rider.app/Contents/MacOS/rider": "/Applications/Rider.app/Contents/MacOS/rider", "/Applications/Zed.app/Contents/MacOS/zed": "zed" }; } }); // ../node_modules/launch-editor/editor-info/linux.js var require_linux = __commonJS({ "../node_modules/launch-editor/editor-info/linux.js"(exports, module) { module.exports = { atom: "atom", Brackets: "brackets", "code-insiders": "code-insiders", code: "code", vscodium: "vscodium", codium: "codium", trae: "trae", emacs: "emacs", gvim: "gvim", idea: "idea", "idea.sh": "idea", phpstorm: "phpstorm", "phpstorm.sh": "phpstorm", pycharm: "pycharm", "pycharm.sh": "pycharm", rubymine: "rubymine", "rubymine.sh": "rubymine", sublime_text: "subl", vim: "vim", webstorm: "webstorm", "webstorm.sh": "webstorm", goland: "goland", "goland.sh": "goland", rider: "rider", "rider.sh": "rider", zed: "zed" }; } }); // ../node_modules/launch-editor/editor-info/windows.js var require_windows = __commonJS({ "../node_modules/launch-editor/editor-info/windows.js"(exports, module) { module.exports = [ "Brackets.exe", "Code.exe", "Code - Insiders.exe", "VSCodium.exe", "Cursor.exe", "atom.exe", "sublime_text.exe", "notepad++.exe", "clion.exe", "clion64.exe", "idea.exe", "idea64.exe", "phpstorm.exe", "phpstorm64.exe", "pycharm.exe", "pycharm64.exe", "rubymine.exe", "rubymine64.exe", "webstorm.exe", "webstorm64.exe", "goland.exe", "goland64.exe", "rider.exe", "rider64.exe", "trae.exe" ]; } }); // ../node_modules/launch-editor/guess.js var require_guess = __commonJS({ "../node_modules/launch-editor/guess.js"(exports, module) { var path = __require("path"); var shellQuote = require_shell_quote(); var childProcess = __require("child_process"); var COMMON_EDITORS_MACOS = require_macos(); var COMMON_EDITORS_LINUX = require_linux(); var COMMON_EDITORS_WIN = require_windows(); module.exports = /* @__PURE__ */ __name(function guessEditor(specifiedEditor) { if (specifiedEditor) { return shellQuote.parse(specifiedEditor); } if (process.env.LAUNCH_EDITOR) { return [process.env.LAUNCH_EDITOR]; } if (process.versions.webcontainer) { return [process.env.EDITOR || "code"]; } try { if (process.platform === "darwin") { const output = childProcess.execSync("ps x -o comm=", { stdio: ["pipe", "pipe", "ignore"] }).toString(); const processNames = Object.keys(COMMON_EDITORS_MACOS); const processList = output.split("\n"); for (let i = 0; i < processNames.length; i++) { const processName = processNames[i]; if (processList.includes(processName)) { return [COMMON_EDITORS_MACOS[processName]]; } const processNameWithoutApplications = processName.replace("/Applications", ""); if (output.indexOf(processNameWithoutApplications) !== -1) { if (processName !== COMMON_EDITORS_MACOS[processName]) { return [COMMON_EDITORS_MACOS[processName]]; } const runningProcess = processList.find((procName) => procName.endsWith(processNameWithoutApplications)); if (runningProcess !== void 0) { return [runningProcess]; } } } } else if (process.platform === "win32") { const output = childProcess.execSync( 'powershell -NoProfile -Command "[Console]::OutputEncoding=[Text.Encoding]::UTF8;Get-CimInstance -Query \\"select executablepath from win32_process where executablepath is not null\\" | % { $_.ExecutablePath }"', { stdio: ["pipe", "pipe", "ignore"] } ).toString(); const runningProcesses = output.split("\r\n"); for (let i = 0; i < runningProcesses.length; i++) { const fullProcessPath = runningProcesses[i].trim(); const shortProcessName = path.basename(fullProcessPath); if (COMMON_EDITORS_WIN.indexOf(shortProcessName) !== -1) { return [fullProcessPath]; } } } else if (process.platform === "linux") { const output = childProcess.execSync("ps x --no-heading -o comm --sort=comm", { stdio: ["pipe", "pipe", "ignore"] }).toString(); const processNames = Object.keys(COMMON_EDITORS_LINUX); for (let i = 0; i < processNames.length; i++) { const processName = processNames[i]; if (output.indexOf(processName) !== -1) { return [COMMON_EDITORS_LINUX[processName]]; } } } } catch (ignoreError) { } if (process.env.VISUAL) { return [process.env.VISUAL]; } else if (process.env.EDITOR) { return [process.env.EDITOR]; } return [null]; }, "guessEditor"); } }); // ../node_modules/launch-editor/get-args.js var require_get_args = __commonJS({ "../node_modules/launch-editor/get-args.js"(exports, module) { var path = __require("path"); module.exports = /* @__PURE__ */ __name(function getArgumentsForPosition(editor, fileName, lineNumber, columnNumber = 1) { const editorBasename = path.basename(editor).replace(/\.(exe|cmd|bat)$/i, ""); switch (editorBasename) { case "atom": case "Atom": case "Atom Beta": case "subl": case "sublime": case "sublime_text": case "wstorm": case "charm": case "zed": return [`${fileName}:${lineNumber}:${columnNumber}`]; case "notepad++": return ["-n" + lineNumber, "-c" + columnNumber, fileName]; case "vim": case "mvim": return [`+call cursor(${lineNumber}, ${columnNumber})`, fileName]; case "joe": case "gvim": return [`+${lineNumber}`, fileName]; case "emacs": case "emacsclient": return [`+${lineNumber}:${columnNumber}`, fileName]; case "rmate": case "mate": case "mine": return ["--line", lineNumber, fileName]; case "code": case "Code": case "code-insiders": case "Code - Insiders": case "codium": case "trae": case "cursor": case "vscodium": case "VSCodium": return ["-r", "-g", `${fileName}:${lineNumber}:${columnNumber}`]; case "appcode": case "clion": case "clion64": case "idea": case "idea64": case "phpstorm": case "phpstorm64": case "pycharm": case "pycharm64": case "rubymine": case "rubymine64": case "webstorm": case "webstorm64": case "goland": case "goland64": case "rider": case "rider64": return ["--line", lineNumber, "--column", columnNumber, fileName]; } if (process.env.LAUNCH_EDITOR) { return [fileName, lineNumber, columnNumber]; } return [fileName]; }, "getArgumentsForPosition"); } }); // ../node_modules/launch-editor/index.js var require_launch_editor = __commonJS({ "../node_modules/launch-editor/index.js"(exports, module) { var fs = __require("fs"); var os = __require("os"); var path = __require("path"); var colors = require_picocolors(); var childProcess = __require("child_process"); var guessEditor = require_guess(); var getArgumentsForPosition = require_get_args(); function wrapErrorCallback(cb) { return (fileName, errorMessage) => { console.log(); console.log( colors.red("Could not open " + path.basename(fileName) + " in the editor.") ); if (errorMessage) { if (errorMessage[errorMessage.length - 1] !== ".") { errorMessage += "."; } console.log( colors.red("The editor process exited with an error: " + errorMessage) ); } console.log(); if (cb) cb(fileName, errorMessage); }; } __name(wrapErrorCallback, "wrapErrorCallback"); function isTerminalEditor(editor) { switch (editor) { case "vim": case "emacs": case "nano": return true; } return false; } __name(isTerminalEditor, "isTerminalEditor"); var positionRE = /:(\d+)(:(\d+))?$/; function parseFile(file) { if (file.startsWith("file://")) { file = __require("url").fileURLToPath(file); } const fileName = file.replace(positionRE, ""); const match = file.match(positionRE); const lineNumber = match && match[1]; const columnNumber = match && match[3]; return { fileName, lineNumber, columnNumber }; } __name(parseFile, "parseFile"); var _childProcess = null; function launchEditor(file, specifiedEditor, onErrorCallback) { const parsed = parseFile(file); let { fileName } = parsed; const { lineNumber, columnNumber } = parsed; if (!fs.existsSync(fileName)) { return; } if (typeof specifiedEditor === "function") { onErrorCallback = specifiedEditor; specifiedEditor = void 0; } onErrorCallback = wrapErrorCallback(onErrorCallback); const [editor, ...args] = guessEditor(specifiedEditor); if (!editor) { onErrorCallback(fileName, null); return; } if (process.platform === "linux" && fileName.startsWith("/mnt/") && /Microsoft/i.test(os.release())) { fileName = path.relative("", fileName); } if (lineNumber) { const extraArgs = getArgumentsForPosition(editor, fileName, lineNumber, columnNumber); args.push.apply(args, extraArgs); } else { args.push(fileName); } if (_childProcess && isTerminalEditor(editor)) { _childProcess.kill("SIGKILL"); } if (process.platform === "win32") { let escapeCmdArgs2 = function(cmdArgs) { return cmdArgs.replace(/([&|<>,;=^])/g, "^$1"); }, doubleQuoteIfNeeded2 = function(str) { if (str.includes("^")) { return `^"${str}^"`; } else if (str.includes(" ")) { return `"${str}"`; } return str; }; var escapeCmdArgs = escapeCmdArgs2, doubleQuoteIfNeeded = doubleQuoteIfNeeded2; __name(escapeCmdArgs2, "escapeCmdArgs"); __name(doubleQuoteIfNeeded2, "doubleQuoteIfNeeded"); const launchCommand = [editor, ...args.map(escapeCmdArgs2)].map(doubleQuoteIfNeeded2).join(" "); _childProcess = childProcess.exec(launchCommand, { stdio: "inherit", shell: true }); } else { _childProcess = childProcess.spawn(editor, args, { stdio: "inherit" }); } _childProcess.on("exit", function(errorCode) { _childProcess = null; if (errorCode) { onErrorCallback(fileName, "(code " + errorCode + ")"); } }); _childProcess.on("error", function(error) { let { code, message } = error; if ("ENOENT" === code) { message = `${message} ('${editor}' command does not exist in 'PATH')`; } onErrorCallback(fileName, message); }); } __name(launchEditor, "launchEditor"); module.exports = launchEditor; } }); // src/core-server/presets/common-preset.ts import { existsSync as existsSync3 } from "node:fs"; import { readFile as readFile3 } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import { optionalEnvToBoolean } from "storybook/internal/common"; import { JsPackageManagerFactory, findConfigFile as findConfigFile3, getDirectoryFromWorkingDir, getPreviewBodyTemplate, getPreviewHeadTemplate, loadEnvs, removeAddon as removeAddonBase } from "storybook/internal/common"; import { readCsf as readCsf2 } from "storybook/internal/csf-tools"; import { logger as logger3 } from "storybook/internal/node-logger"; import { telemetry as telemetry7 } from "storybook/internal/telemetry"; var import_ts_dedent4 = __toESM(require_dist(), 1); // src/core-server/server-channel/create-new-story-channel.ts import { existsSync as existsSync2 } from "node:fs"; import { writeFile } from "node:fs/promises"; import { relative } from "node:path"; import { getStoryId } from "storybook/internal/common"; import { CREATE_NEW_STORYFILE_REQUEST, CREATE_NEW_STORYFILE_RESPONSE } from "storybook/internal/core-events"; import { telemetry } from "storybook/internal/telemetry"; // src/core-server/utils/get-new-story-file.ts import { existsSync } from "node:fs"; import { readFile } from "node:fs/promises"; import { basename, dirname, extname, join as join2 } from "node:path"; import { extractProperFrameworkName, findConfigFile, getFrameworkName, getProjectRoot } from "storybook/internal/common"; import { isCsfFactoryPreview } from "storybook/internal/csf-tools"; // src/core-server/utils/new-story-templates/csf-factory-template.ts var import_ts_dedent = __toESM(require_dist(), 1); // src/core-server/utils/get-component-variable-name.ts var getComponentVariableName = /* @__PURE__ */ __name(async (name) => { const camelCase = await import("../../_node-chunks/camelcase-K7FL3FGB.js"); const camelCased = camelCase.default(name.replace(/^[^a-zA-Z_$]*/, ""), { pascalCase: true }); const sanitized = camelCased.replace(/[^a-zA-Z_$]+/, ""); return sanitized; }, "getComponentVariableName"); // src/core-server/utils/new-story-templates/csf-factory-template.ts async function getCsfFactoryTemplateForNewStoryFile(data) { const importName = data.componentIsDefaultExport ? await getComponentVariableName(data.basenameWithoutExtension) : data.componentExportName; const importStatement = data.componentIsDefaultExport ? `import ${importName} from './${data.basenameWithoutExtension}';` : `import { ${importName} } from './${data.basenameWithoutExtension}';`; const previewImport = `import preview from '#.storybook/preview';`; return import_ts_dedent.dedent` ${previewImport} ${importStatement} const meta = preview.meta({ component: ${importName}, }); export const ${data.exportedStoryName} = meta.story({}); `; } __name(getCsfFactoryTemplateForNewStoryFile, "getCsfFactoryTemplateForNewStoryFile"); // src/core-server/utils/new-story-templates/javascript.ts var import_ts_dedent2 = __toESM(require_dist(), 1); async function getJavaScriptTemplateForNewStoryFile(data) { const importName = data.componentIsDefaultExport ? await getComponentVariableName(data.basenameWithoutExtension) : data.componentExportName; const importStatement = data.componentIsDefaultExport ? `import ${importName} from './${data.basenameWithoutExtension}';` : `import { ${importName} } from './${data.basenameWithoutExtension}';`; return import_ts_dedent2.dedent` ${importStatement} const meta = { component: ${importName}, }; export default meta; export const ${data.exportedStoryName} = {}; `; } __name(getJavaScriptTemplateForNewStoryFile, "getJavaScriptTemplateForNewStoryFile"); // src/core-server/utils/new-story-templates/typescript.ts var import_ts_dedent3 = __toESM(require_dist(), 1); async function getTypeScriptTemplateForNewStoryFile(data) { const importName = data.componentIsDefaultExport ? await getComponentVariableName(data.basenameWithoutExtension) : data.componentExportName; const importStatement = data.componentIsDefaultExport ? `import ${importName} from './${data.basenameWithoutExtension}'` : `import { ${importName} } from './${data.basenameWithoutExtension}'`; return import_ts_dedent3.dedent` import type { Meta, StoryObj } from '${data.frameworkPackage}'; ${importStatement}; const meta = { component: ${importName}, } satisfies Meta<typeof ${importName}>; export default meta; type Story = StoryObj<typeof meta>; export const ${data.exportedStoryName}: Story = {}; `; } __name(getTypeScriptTemplateForNewStoryFile, "getTypeScriptTemplateForNewStoryFile"); // src/core-server/utils/get-new-story-file.ts async function getNewStoryFile({ componentFilePath, componentExportName, componentIsDefaultExport, componentExportCount }, options) { const frameworkPackageName = await getFrameworkName(options); const sanitizedFrameworkPackageName = extractProperFrameworkName(frameworkPackageName); const base = basename(componentFilePath); const extension = extname(componentFilePath); const basenameWithoutExtension = base.replace(extension, ""); const dir = dirname(componentFilePath); const { storyFileName, isTypescript, storyFileExtension } = getStoryMetadata(componentFilePath); const storyFileNameWithExtension = `${storyFileName}.${storyFileExtension}`; const alternativeStoryFileNameWithExtension = `${basenameWithoutExtension}.${componentExportName}.stories.${storyFileExtension}`; const exportedStoryName = "Default"; let useCsfFactory = false; try { const previewConfig = findConfigFile("preview", options.configDir); if (previewConfig) { const previewContent = await readFile(previewConfig, "utf-8"); useCsfFactory = isCsfFactoryPreview(loadConfig(previewContent)); } } catch (err) { } let storyFileContent = ""; if (useCsfFactory) { storyFileContent = await getCsfFactoryTemplateForNewStoryFile({ basenameWithoutExtension, componentExportName, componentIsDefaultExport, exportedStoryName }); } else { storyFileContent = isTypescript && frameworkPackageName ? await getTypeScriptTemplateForNewStoryFile({ basenameWithoutExtension, componentExportName, componentIsDefaultExport, frameworkPackage: sanitizedFrameworkPackageName, exportedStoryName }) : await getJavaScriptTemplateForNewStoryFile({ basenameWithoutExtension, componentExportName, componentIsDefaultExport, exportedStoryName }); } const storyFilePath = doesStoryFileExist(join2(getProjectRoot(), dir), storyFileName) && componentExportCount > 1 ? join2(getProjectRoot(), dir, alternativeStoryFileNameWithExtension) : join2(getProjectRoot(), dir, storyFileNameWithExtension); return { storyFilePath, exportedStoryName, storyFileContent, dirname }; } __name(getNewStoryFile, "getNewStoryFile"); var getStoryMetadata = /* @__PURE__ */ __name((componentFilePath) => { const isTypescript = /\.(ts|tsx|mts|cts)$/.test(componentFilePath); const base = basename(componentFilePath); const extension = extname(componentFilePath); const basenameWithoutExtension = base.replace(extension, ""); const storyFileExtension = isTypescript ? "tsx" : "jsx"; return { storyFileName: `${basenameWithoutExtension}.stories`, storyFileExtension, isTypescript }; }, "getStoryMetadata"); var doesStoryFileExist = /* @__PURE__ */ __name((parentFolder, storyFileName) => { return existsSync(join2(parentFolder, `${storyFileName}.ts`)) || existsSync(join2(parentFolder, `${storyFileName}.tsx`)) || existsSync(join2(parentFolder, `${storyFileName}.js`)) || existsSync(join2(parentFolder, `${storyFileName}.jsx`)); }, "doesStoryFileExist"); // src/core-server/server-channel/create-new-story-channel.ts function initCreateNewStoryChannel(channel, options, coreOptions) { channel.on( CREATE_NEW_STORYFILE_REQUEST, async (data) => { try { const { storyFilePath, exportedStoryName, storyFileContent } = await getNewStoryFile( data.payload, options ); const relativeStoryFilePath = relative(process.cwd(), storyFilePath); const { storyId, kind } = await getStoryId({ storyFilePath, exportedStoryName }, options); if (existsSync2(storyFilePath)) { channel.emit(CREATE_NEW_STORYFILE_RESPONSE, { success: false, id: data.id, payload: { type: "STORY_FILE_EXISTS", kind }, error: `A story file already exists at ${relativeStoryFilePath}` }); if (!coreOptions.disableTelemetry) { telemetry("create-new-story-file", { success: false, error: "STORY_FILE_EXISTS" }); } return; } await writeFile(storyFilePath, storyFileContent, "utf-8"); channel.emit(CREATE_NEW_STORYFILE_RESPONSE, { success: true, id: data.id, payload: { storyId, storyFilePath: relative(process.cwd(), storyFilePath), exportedStoryName }, error: null }); if (!coreOptions.disableTelemetry) { telemetry("create-new-story-file", { success: true }); } } catch (e) { channel.emit(CREATE_NEW_STORYFILE_RESPONSE, { success: false, id: data.id, error: e?.message }); if (!coreOptions.disableTelemetry) { await telemetry("create-new-story-file", { success: false, error: e }); } } } ); return channel; } __name(initCreateNewStoryChannel, "initCreateNewStoryChannel"); // src/core-server/server-channel/file-search-channel.ts import { readFile as readFile2 } from "node:fs/promises"; import { dirname as dirname2, join as join3 } from "node:path"; import { extractProperRendererNameFromFramework, getFrameworkName as getFrameworkName2, getProjectRoot as getProjectRoot2 } from "storybook/internal/common"; import { FILE_COMPONENT_SEARCH_REQUEST, FILE_COMPONENT_SEARCH_RESPONSE } from "storybook/internal/core-events"; import { telemetry as telemetry2 } from "storybook/internal/telemetry"; // src/core-server/utils/parser/generic-parser.ts import { parser, types as t } from "storybook/internal/babel"; var GenericParser = class { static { __name(this, "GenericParser"); } /** * Parse the content of a file and return the exports * * @param content The content of the file * @returns The exports of the file */ async parse(content) { const ast = parser.parse(content, { allowImportExportEverywhere: true, allowAwaitOutsideFunction: true, allowNewTargetOutsideFunction: true, allowReturnOutsideFunction: true, allowUndeclaredExports: true, plugins: [ // Language features "typescript", "jsx", // Latest ECMAScript features "asyncGenerators", "bigInt", "classProperties", "classPrivateProperties", "classPrivateMethods", "classStaticBlock", "dynamicImport", "exportNamespaceFrom", "logicalAssignment", "moduleStringNames", "nullishCoalescingOperator", "numericSeparator", "objectRestSpread", "optionalCatchBinding", "optionalChaining", "privateIn", "regexpUnicodeSets", "topLevelAwait", // ECMAScript proposals "asyncDoExpressions", "decimal", "decorators", "decoratorAutoAccessors", "deferredImportEvaluation", "destructuringPrivate", "doExpressions", "explicitResourceManagement", "exportDefaultFrom", "functionBind", "functionSent", "importAttributes", "importReflection", "moduleBlocks", "partialApplication", "recordAndTuple", "sourcePhaseImports", "throwExpressions" ] }); const exports = []; ast.program.body.forEach(/* @__PURE__ */ __name(function traverse3(node) { if (t.isExportNamedDeclaration(node)) { if (t.isFunctionDeclaration(node.declaration) && t.isIdentifier(node.declaration.id)) { exports.push({ name: node.declaration.id.name, default: false }); } if (t.isClassDeclaration(node.declaration) && t.isIdentifier(node.declaration.id)) { exports.push({ name: node.declaration.id.name, default: false }); } if (node.declaration === null && node.specifiers.length > 0) { node.specifiers.forEach((specifier) => { if (t.isExportSpecifier(specifier) && t.isIdentifier(specifier.exported)) { exports.push({ name: specifier.exported.name, default: false }); } }); } if (t.isVariableDeclaration(node.declaration)) { node.declaration.declarations.forEach((declaration) => { if (t.isVariableDeclarator(declaration) && t.isIdentifier(declaration.id)) { exports.push({ name: declaration.id.name, default: false }); } }); } } else if (t.isExportDefaultDeclaration(node)) { exports.push({ name: "default", default: true }); } }, "traverse")); return { exports }; } }; // src/core-server/utils/parser/index.ts function getParser(renderer) { switch (renderer) { default: return new GenericParser(); } } __name(getParser, "getParser"); // src/core-server/utils/search-files.ts var FILE_EXTENSIONS = ["js", "mjs", "cjs", "jsx", "mts", "ts", "tsx", "cts"]; var IGNORED_FILES = [ "**/node_modules/**", "**/*.spec.*", "**/*.test.*", "**/*.stories.*", "**/storybook-static/**" ]; async function searchFiles({ searchQuery, cwd, ignoredFiles = IGNORED_FILES, fileExtensions = FILE_EXTENSIONS }) { const { globby, isDynamicPattern } = await import("../../_node-chunks/globby-RBUNLUI2.js"); const hasSearchSpecialGlobChars = isDynamicPattern(searchQuery, { cwd }); const hasFileExtensionRegex = /(\.[a-z]+)$/i; const searchQueryHasExtension = hasFileExtensionRegex.test(searchQuery); const fileExtensionsPattern = `{${fileExtensions.join(",")}}`; const globbedSearchQuery = hasSearchSpecialGlobChars ? searchQuery : searchQueryHasExtension ? [`**/*${searchQuery}*`, `**/*${searchQuery}*/**`] : [ `**/*${searchQuery}*.${fileExtensionsPattern}`, `**/*${searchQuery}*/**/*.${fileExtensionsPattern}` ]; const entries = await globby(globbedSearchQuery, { ignore: ignoredFiles, gitignore: true, caseSensitiveMatch: false, cwd, objectMode: true }); return entries.map((entry) => entry.path).filter((entry) => fileExtensions.some((ext) => entry.endsWith(`.${ext}`))); } __name(searchFiles, "searchFiles"); // src/core-server/server-channel/file-search-channel.ts async function initFileSearchChannel(channel, options, coreOptions) { channel.on( FILE_COMPONENT_SEARCH_REQUEST, async (data) => { const searchQuery = data.id; try { if (!searchQuery) { return; } const frameworkName = await getFrameworkName2(options); const rendererName = await extractProperRendererNameFromFramework( frameworkName ); const files = await searchFiles({ searchQuery, cwd: getProjectRoot2() }); const entries = files.map(async (file) => { const parser3 = getParser(rendererName); try { const content = await readFile2(join3(getProjectRoot2(), file), "utf-8"); const { storyFileName } = getStoryMetadata(join3(getProjectRoot2(), file)); const dir = dirname2(file); const storyFileExists = doesStoryFileExist(join3(getProjectRoot2(), dir), storyFileName); const info = await parser3.parse(content); return { filepath: file, exportedComponents: info.exports, storyFileExists }; } catch (e) { if (!coreOptions.disableTelemetry) { telemetry2("create-new-story-file-search", { success: false, error: `Could not parse file: ${e}` }); } return { filepath: file, storyFileExists: false, exportedComponents: null }; } }); if (!coreOptions.disableTelemetry) { telemetry2("create-new-story-file-search", { success: true, payload: { fileCount: entries.length } }); } channel.emit(FILE_COMPONENT_SEARCH_RESPONSE, { success: true, id: searchQuery, payload: { files: await Promise.all(entries) }, error: null }); } catch (e) { channel.emit(FILE_COMPONENT_SEARCH_RESPONSE, { success: false, id: searchQuery ?? "", error: `An error occurred while searching for components in the project. ${e?.message}` }); if (!coreOptions.disableTelemetry) { telemetry2("create-new-story-file-search", { success: false, error: `An error occured while searching for components: ${e}` }); } } } ); return channel; } __name(initFileSearchChannel, "initFileSearchChannel"); // src/core-server/server-channel/open-in-editor-channel.ts var import_launch_editor = __toESM(require_launch_editor(), 1); import { OPEN_IN_EDITOR_REQUEST, OPEN_IN_EDITOR_RESPONSE } from "storybook/internal/core-events"; import { telemetry as telemetry3 } from "storybook/internal/telemetry"; async function initOpenInEditorChannel(channel, _options, coreOptions) { channel.on(OPEN_IN_EDITOR_REQUEST, async (payload) => { const sendTelemetry = /* @__PURE__ */ __name((data) => { if (!coreOptions.disableTelemetry) { telemetry3("open-in-editor", data); } }, "sendTelemetry"); try { const { file: targetFile, line, column } = payload; if (!targetFile) { throw new Error("No file was provided to open"); } const location = typeof line === "number" ? `${targetFile}:${line}${typeof column === "number" ? `:${column}` : ""}` : targetFile; await new Promise((resolve, reject) => { (0, import_launch_editor.default)(location, void 0, (_fileName, errorMessage) => { if (errorMessage) { reject(new Error(errorMessage)); } else { resolve(); } }); }); channel.emit(OPEN_IN_EDITOR_RESPONSE, { file: targetFile, line, column, error: null }); sendTelemetry({ success: true }); } catch (e) { const error = e?.message || "Failed to open in editor"; channel.emit(OPEN_IN_EDITOR_RESPONSE, { error, ...payload }); sendTelemetry({ success: false, error }); } }); return channel; } __name(initOpenInEditorChannel, "initOpenInEditorChannel"); // src/core-server/server-channel/preview-initialized-channel.ts import { PREVIEW_INITIALIZED } from "storybook/internal/core-events"; import { telemetry as telemetry4 } from "storybook/internal/telemetry"; var makePayload = /* @__PURE__ */ __name((userAgent, lastInit, sessionId) => { let timeSinceInit; const payload = { userAgent, isNewUser: false, timeSinceInit }; if (sessionId && lastInit?.body?.sessionId === sessionId) { payload.timeSinceInit = Date.now() - lastInit.timestamp; payload.isNewUser = !!lastInit.body.payload.newUser; } return payload; }, "makePayload"); function initPreviewInitializedChannel(channel, options, _coreConfig) { channel.on(PREVIEW_INITIALIZED, async ({ userAgent }) => { if (!options.disableTelemetry) { try { const sessionId = await getSessionId(); const lastEvents = await getLastEvents(); const lastInit = lastEvents.init; const lastPreviewFirstLoad = lastEvents["preview-first-load"]; if (!lastPreviewFirstLoad) { const payload = makePayload(userAgent, lastInit, sessionId); telemetry4("preview-first-load", payload); } } catch (e) { } } }); } __name(initPreviewInitializedChannel, "initPreviewInitializedChannel"); // src/core-server/utils/constants.ts var defaultStaticDirs = [ { from: join(resolvePackageDir("storybook"), "assets/browser"), to: "/sb-common-assets" } ]; var defaultFavicon = join(resolvePackageDir("storybook"), "assets/browser/favicon.svg"); // src/core-server/utils/save-story/save-story.ts import { writeFile as writeFile2 } from "node:fs/promises"; import { basename as basename2, join as join4 } from "node:path"; import { formatFileContent } from "storybook/internal/common"; import { SAVE_STORY_REQUEST, SAVE_STORY_RESPONSE, STORY_RENDERED } from "storybook/internal/core-events"; import { storyNameFromExport, toId } from "storybook/internal/csf"; import { printCsf, readCsf } from "storybook/internal/csf-tools"; import { logger } from "storybook/internal/node-logger"; import { isExampleStoryId, telemetry as telemetry5 } from "storybook/internal/telemetry"; // src/core-server/utils/save-story/duplicate-story-with-new-name.ts import { types as t2, traverse } from "storybook/internal/babel"; // src/core-server/utils/save-story/utils.ts var SaveStoryError = class extends Error { static { __name(this, "SaveStoryError"); } }; // src/core-server/utils/save-story/duplicate-story-with-new-name.ts var duplicateStoryWithNewName = /* @__PURE__ */ __name((csfFile, storyName, newStoryName) => { const node = csfFile._storyExports[storyName]; const cloned = t2.cloneNode(node); if (!cloned) { throw new SaveStoryError(`cannot clone Node`); } let found = false; traverse(cloned, { Identifier(path) { if (found) { return; } if (path.node.name === storyName) { found = true; path.node.name = newStoryName; } }, ObjectProperty(path) { const key = path.get("key"); if (key.isIdentifier() && key.node.name === "args") { path.remove(); } }, noScope: true }); const isCsf4Story = t2.isCallExpression(cloned.init) && t2.isMemberExpression(cloned.init.callee) && t2.isIdentifier(cloned.init.callee.property) && cloned.init.callee.property.name === "story"; if (!isCsf4Story && (t2.isArrowFunctionExpression(cloned.init) || t2.isCallExpression(cloned.init))) { throw new SaveStoryError(`Creating a new story based on a CSF2 story is not supported`); } traverse(csfFile._ast, { Program(path) { path.pushContainer( "body", t2.exportNamedDeclaration(t2.variableDeclaration("const", [cloned])) ); } }); return cloned; }, "duplicateStoryWithNewName"); // src/core-server/utils/save-story/update-args-in-csf-file.ts import { types as t4, traverse as traverse2 } from "storybook/internal/babel"; // src/core-server/utils/save-story/valueToAST.ts import { parser as parser2, types as t3 } from "storybook/internal/babel"; function valueToAST(literal) { if (literal === null) { return t3.nullLiteral(); } switch (typeof literal) { case "function": const ast = parser2.parse(literal.toString(), { allowReturnOutsideFunction: true, allowSuperOutsideMethod: true }); return ast.program.body[0]?.expression; case "number": return t3.numericLiteral(literal); case "string": return t3.stringLiteral(literal); case "boolean": return t3.booleanLiteral(literal); case "undefined": return t3.identifier("undefined"); default: if (Array.isArray(literal)) { return t3.arrayExpression(literal.map(valueToAST)); } return t3.objectExpression( Object.keys(literal).filter((k) => { const value = literal[k]; return typeof value !== "undefined"; }).map((k) => { const value = literal[k]; return t3.objectProperty(t3.stringLiteral(k), valueToAST(value)); }) ); } } __name(valueToAST, "valueToAST"); // src/core-server/utils/save-story/update-args-in-csf-file.ts var updateArgsInCsfFile = /* @__PURE__ */ __name(async (node, input) => { let found = false; const args = Object.fromEntries( Object.entries(input).map(([k, v]) => { return [k, valueToAST(v)]; }) ); const isCsf4Story = t4.isCallExpression(node) && t4.isMemberExpression(node.callee) && t4.isIdentifier(node.callee.property) && node.callee.property.name === "story"; if (!isCsf4Story && (t4.isArrowFunctionExpression(node) || t4.isCallExpression(node))) { throw new SaveStoryError(`Updating a CSF2 story is not supported`); } if (t4.isObjectExpression(node)) { const properties = node.properties; const argsProperty = properties.find((property) => { if (t4.isObjectProperty(property)) { const key = property.key; return t4.isIdentifier(key) && key.name === "args"; } return false; }); if (argsProperty) { if (t4.isObjectProperty(argsProperty)) { const a = argsProperty.value; if (t4.isObjectExpression(a)) { a.properties.forEach((p) => { if (t4.isObjectProperty(p)) { const key = p.key; if (t4.isIdentifier(key) && key.name in args) { p.value = args[key.name]; delete args[key.name]; } } }); const remainder = Object.entries(args); if (Object.keys(args).length) { remainder.forEach(([key, value]) => { a.properties.push(t4.objectProperty(t4.identifier(key), value)); }); } } } } else { properties.unshift( t4.objectProperty( t4.identifier("args"), t4.objectExpression( Object.entries(args).map(([key, value]) => t4.objectProperty(t4.identifier(key), value)) ) ) ); } return; } traverse2(node, { ObjectExpression(path) { if (found) { return; } found = true; const properties = path.get("properties"); const argsProperty = properties.find((property) => { if (property.isObjectProperty()) { const key = property.get("key"); return key.isIdentifier() && key.node.name === "args"; } return false; }); if (argsProperty) { if (argsProperty.isObjectProperty()) { const a = argsProperty.get("value"); if (a.isObjectExpression()) { a.traver