storybook
Version:
Storybook: Develop, document, and test UI components in isolation
1,422 lines (1,375 loc) • 67.6 kB
JavaScript
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