import CJS_COMPAT_NODE_URL_vmjy0ls48qs from 'node:url';
import CJS_COMPAT_NODE_PATH_vmjy0ls48qs from 'node:path';
import CJS_COMPAT_NODE_MODULE_vmjy0ls48qs from "node:module";

var __filename = CJS_COMPAT_NODE_URL_vmjy0ls48qs.fileURLToPath(import.meta.url);
var __dirname = CJS_COMPAT_NODE_PATH_vmjy0ls48qs.dirname(__filename);
var require = CJS_COMPAT_NODE_MODULE_vmjy0ls48qs.createRequire(import.meta.url);

// ------------------------------------------------------------
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
// ------------------------------------------------------------
import {
  parseStaticDir,
  sendTelemetryError
} from "../../_node-chunks/chunk-COQO7QZN.js";
import "../../_node-chunks/chunk-GOJT6XFG.js";
import {
  invariant
} from "../../_node-chunks/chunk-DNVEE2BL.js";
import {
  resolvePackageDir
} from "../../_node-chunks/chunk-QCNZE2OD.js";
import {
  join
} from "../../_node-chunks/chunk-OSRDPJRA.js";
import "../../_node-chunks/chunk-FKOMCTUZ.js";
import {
  loadConfig
} from "../../_node-chunks/chunk-PN46VWCQ.js";
import {
  require_dist
} from "../../_node-chunks/chunk-CUPFOBQ2.js";
import {
  require_picocolors
} from "../../_node-chunks/chunk-QRRCZBDR.js";
import {
  __commonJS,
  __name,
  __require,
  __toESM
} from "../../_node-chunks/chunk-XAZ4DWTT.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 { isAbsolute, join as join5 } from "node:path";
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 telemetry6 } 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-ATF3L6MJ.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-PMXTMYIJ.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/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 telemetry4 } 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.traverse({
              ObjectProperty(p) {
                const key = p.get("key");
                if (key.isIdentifier() && key.node.name in args) {
                  p.get("value").replaceWith(args[key.node.name]);
                  delete args[key.node.name];
                }
              },
              noScope: true
            });
            const remainder = Object.entries(args);
            if (Object.keys(args).length) {
              remainder.forEach(([key, value]) => {
                a.pushContainer("properties", t4.objectProperty(t4.identifier(key), value));
              });
            }
          }
        }
      } else {
        path.unshiftContainer(
          "properties",
          t4.objectProperty(
            t4.identifier("args"),
            t4.objectExpression(
              Object.entries(args).map(([key, value]) => t4.objectProperty(t4.identifier(key), value))
            )
          )
        );
      }
    },
    noScope: true
  });
}, "updateArgsInCsfFile");

// src/core-server/utils/save-story/save-story.ts
var parseArgs = /* @__PURE__ */ __name((args) => JSON.parse(args, (_, value) => {
  if (value === "__sb_empty_function_arg__") {
    return () => {
    };
  }
  return value;
}), "parseArgs");
var removeExtraNewlines = /* @__PURE__ */ __name((code, name) => {
  const anything = "([\\s\\S])";
  const newline = "(\\r\\n|\\r|\\n)";
  const closing = newline + "};" + newline;
  const regex = new RegExp(
    // Looks for an export by the given name, considers the first closing brace on its own line
    // to be the end of the story definition.
    `^(?<before>${anything}*)(?<story>export const ${name} =${anything}+?${closing})(?<after>${anything}*)$`
  );
  const { before, story, after } = code.match(regex)?.groups || {};
  return story ? before + story.replaceAll(/(\r\n|\r|\n)(\r\n|\r|\n)([ \t]*[a-z0-9_]+): /gi, "$2$3:") + after : code;
}, "removeExtraNewlines");
function initializeSaveStory(channel, options, coreConfig) {
  channel.on(SAVE_STORY_REQUEST, async ({ id, payload }) => {
    const { csfId, importPath, args, name } = payload;
    let newStoryId;
    let newStoryName;
    let sourceFileName;
    let sourceFilePath;
    let sourceStoryName;
    try {
      sourceFileName = basename2(importPath);
      sourceFilePath = join4(process.cwd(), importPath);
      const csf = await readCsf(sourceFilePath, {
        makeTitle: /* @__PURE__ */ __name((userTitle) => userTitle || "myTitle", "makeTitle")
      });
      const parsed = csf.parse();
      const stories = Object.entries(parsed._stories);
      const [componentId, storyId] = csfId.split("--");
      newStoryName = name && storyNameFromExport(name);
      newStoryId = newStoryName && toId(componentId, newStoryName);
      const [storyName] = stories.find(([key, value]) => value.id.endsWith(`--${storyId}`)) || [];
      if (!storyName) {
        throw new SaveStoryError(`Source story not found.`);
      }
      if (name && csf.getStoryExport(name)) {
        throw new SaveStoryError(`Story already exists.`);
      }
      sourceStoryName = storyNameFromExport(storyName);
      await updateArgsInCsfFile(
        name ? duplicateStoryWithNewName(parsed, storyName, name) : csf.getStoryExport(storyName),
        args ? parseArgs(args) : {}
      );
      const code = await formatFileContent(
        sourceFilePath,
        removeExtraNewlines(printCsf(csf).code, name || storyName)
      );
      await Promise.all([
        new Promise((resolve) => {
          channel.on(STORY_RENDERED, resolve);
          setTimeout(() => resolve(channel.off(STORY_RENDERED, resolve)), 3e3);
        }),
        writeFile2(sourceFilePath, code)
      ]);
      channel.emit(SAVE_STORY_RESPONSE, {
        id,
        success: true,
        payload: {
          csfId,
          newStoryId,
          newStoryName,
          newStoryExportName: name,
          sourceFileContent: code,
          sourceFileName,
          sourceStoryName,
          sourceStoryExportName: storyName
        },
        error: null
      });
      const isCLIExample = isExampleStoryId(newStoryId ?? csfId);
      if (!coreConfig.disableTelemetry && !isCLIExample) {
        await telemetry4("save-story", {
          action: name ? "createStory" : "updateStory",
          success: true
        });
      }
    } catch (error) {
      channel.emit(SAVE_STORY_RESPONSE, {
        id,
        success: false,
        error: error instanceof SaveStoryError ? error.message : "Unknown error"
      });
      logger.error(
        `Error writing to ${sourceFilePath}:
${error.stack || error.message || error.toString()}`
      );
      if (!coreConfig.disableTelemetry && !(error instanceof SaveStoryError)) {
        await telemetry4("save-story", {
          action: name ? "createStory" : "updateStory",
          success: false,
          error
        });
      }
    }
  });
}
__name(initializeSaveStory, "initializeSaveStory");

// src/core-server/utils/whats-new.ts
import { writeFile as writeFile3 } from "node:fs/promises";
import { findConfigFile as findConfigFile2, loadMainConfig } from "storybook/internal/common";
import {
  REQUEST_WHATS_NEW_DATA,
  RESULT_WHATS_NEW_DATA,
  SET_WHATS_NEW_CACHE,
  TELEMETRY_ERROR,
  TOGGLE_WHATS_NEW_NOTIFICATIONS
} from "storybook/internal/core-events";
import { printConfig, readConfig } from "storybook/internal/csf-tools";
import { logger as logger2 } from "storybook/internal/node-logger";
import { telemetry as telemetry5 } from "storybook/internal/telemetry";
var WHATS_NEW_CACHE = "whats-new-cache";
var WHATS_NEW_URL = "https://storybook.js.org/whats-new/v1";
function initializeWhatsNew(channel, options, coreOptions) {
  channel.on(SET_WHATS_NEW_CACHE, async (data) => {
    const cache = await options.cache.get(WHATS_NEW_CACHE).catch((e) => {
      logger2.verbose(e);
      return {};
    });
    await options.cache.set(WHATS_NEW_CACHE, { ...cache, ...data });
  });
  channel.on(REQUEST_WHATS_NEW_DATA, async () => {
    try {
      const post = await fetch(WHATS_NEW_URL).then(async (response) => {
        if (response.ok) {
          return response.json();
        }
        throw response;
      });
      const main = await loadMainConfig({ configDir: options.configDir });
      const disableWhatsNewNotifications = main.core?.disableWhatsNewNotifications === true;
      const cache = await options.cache.get(WHATS_NEW_CACHE) ?? {};
      const data = {
        ...post,
        status: "SUCCESS",
        postIsRead: post.url === cache.lastReadPost,
        showNotification: post.url !== cache.lastDismissedPost && post.url !== cache.lastReadPost,
        disableWhatsNewNotifications
      };
      channel.emit(RESULT_WHATS_NEW_DATA, { data });
    } catch (e) {
      logger2.verbose(e instanceof Error ? e.message : String(e));
      channel.emit(RESULT_WHATS_NEW_DATA, {
        data: { status: "ERROR" }
      });
    }
  });
  channel.on(
    TOGGLE_WHATS_NEW_NOTIFICATIONS,
    async ({ disableWhatsNewNotifications }) => {
      const isTelemetryEnabled = coreOptions.disableTelemetry !== true;
      try {
        const mainPath = findConfigFile2("main", options.configDir);
        invariant(mainPath, `unable to find Storybook main file in ${options.configDir}`);
        const main = await readConfig(mainPath);
        if (!main._exportsObject) {
          throw new Error(
            `Unable to parse Storybook main file while trying to read 'core' property`
          );
        }
        main.setFieldValue(["core", "disableWhatsNewNotifications"], disableWhatsNewNotifications);
        await writeFile3(mainPath, printConfig(main).code);
        if (isTelemetryEnabled) {
          await telemetry5("core-config", { disableWhatsNewNotifications });
        }
      } catch (error) {
        invariant(error instanceof Error);
        if (isTelemetryEnabled) {
          await sendTelemetryError(error, "core-config", {
            cliOptions: options,
            presetOptions: { ...options, corePresets: [], overridePresets: [] },
            skipPrompt: true
          });
        }
      }
    }
  );
  channel.on(TELEMETRY_ERROR, async (error) => {
    const isTelemetryEnabled = coreOptions.disableTelemetry !== true;
    if (isTelemetryEnabled) {
      await sendTelemetryError(error, "browser", {
        cliOptions: options,
        presetOptions: { ...options, corePresets: [], overridePresets: [] },
        skipPrompt: true
      });
    }
  });
}
__name(initializeWhatsNew, "initializeWhatsNew");

// src/core-server/presets/common-preset.ts
var interpolate = /* @__PURE__ */ __name((string, data = {}) => Object.entries(data).reduce((acc, [k, v]) => acc.replace(new RegExp(`%${k}%`, "g"), v), string), "interpolate");
var staticDirs = /* @__PURE__ */ __name(async (values = []) => [
  ...defaultStaticDirs,
  ...values
], "staticDirs");
var favicon = /* @__PURE__ */ __name(async (value, options) => {
  if (value) {
    return value;
  }
  const staticDirsValue = await options.presets.apply("staticDirs");
  const statics = staticDirsValue ? staticDirsValue.map((dir) => typeof dir === "string" ? dir : `${dir.from}:${dir.to}`) : [];
  const faviconPaths = statics.map((dir) => {
    const results = [];
    const normalizedDir = staticDirsValue && !isAbsolute(dir) ? getDirectoryFromWorkingDir({
      configDir: options.configDir,
      workingDir: process.cwd(),
      directory: dir
    }) : dir;
    const { staticPath, targetEndpoint } = parseStaticDir(normalizedDir);
    if (["/favicon.svg", "/favicon.ico"].includes(targetEndpoint)) {
      results.push(staticPath);
    }
    if (targetEndpoint === "/") {
      results.push(join5(staticPath, "favicon.svg"));
      results.push(join5(staticPath, "favicon.ico"));
    }
    return results.filter((path) => existsSync3(path));
  }).reduce((l1, l2) => l1.concat(l2), []);
  if (faviconPaths.length > 1) {
    logger3.warn(import_ts_dedent4.dedent`
      Looks like multiple favicons were detected. Using the first one.

      ${faviconPaths.join(", ")}
    `);
  }
  return faviconPaths[0] || defaultFavicon;
}, "favicon");
var babel = /* @__PURE__ */ __name(async (_, options) => {
  const { presets } = options;
  const babelDefault = await presets.apply("babelDefault", {}, options) ?? {};
  return {
    ...babelDefault,
    // This override makes sure that we will never transpile babel further down then the browsers that storybook supports.
    // This is needed to support the mount property of the context described here:
    // https://storybook.js.org/docs/writing-tests/interaction-testing#run-code-before-each-test
    overrides: [
      ...babelDefault?.overrides ?? [],
      {
        include: /\.(story|stories)\.[cm]?[jt]sx?$/,
        presets: [
          [
            "@babel/preset-env",
            {
              bugfixes: true,
              targets: {
                // This is the same browser supports that we use to bundle our manager and preview code.
                chrome: 100,
                safari: 15,
                firefox: 91
              }
            }
          ]
        ]
      }
    ]
  };
}, "babel");
var title = /* @__PURE__ */ __name((previous, options) => previous || options.packageJson?.name || false, "title");
var logLevel = /* @__PURE__ */ __name((previous, options) => previous || options.loglevel || "info", "logLevel");
var previewHead = /* @__PURE__ */ __name(async (base, { configDir, presets }) => {
  const interpolations = await presets.apply("env");
  return getPreviewHeadTemplate(configDir, interpolations);
}, "previewHead");
var env = /* @__PURE__ */ __name(async () => {
  const { raw } = await loadEnvs({ production: true });
  return raw;
}, "env");
var previewBody = /* @__PURE__ */ __name(async (base, { configDir, presets }) => {
  const interpolations = await presets.apply("env");
  return getPreviewBodyTemplate(configDir, interpolations);
}, "previewBody");
var typescript = /* @__PURE__ */ __name(() => ({
  check: false,
  // 'react-docgen' faster than `react-docgen-typescript` but produces lower quality results
  reactDocgen: "react-docgen",
  reactDocgenTypescriptOptions: {
    shouldExtractLiteralValuesFromEnum: true,
    shouldRemoveUndefinedFromOptional: true,
    propFilter: /* @__PURE__ */ __name((prop) => prop.parent ? !/node_modules/.test(prop.parent.fileName) : true, "propFilter"),
    // NOTE: this default cannot be changed
    savePropValueAsString: true
  }
}), "typescript");
var experimental_serverAPI = /* @__PURE__ */ __name((extension, options) => {
  let removeAddon = removeAddonBase;
  const packageManager = JsPackageManagerFactory.getPackageManager({
    configDir: options.configDir
  });
  if (!options.disableTelemetry) {
    removeAddon = /* @__PURE__ */ __name(async (id, opts) => {
      await telemetry6("remove", { addon: id, source: "api" });
      return removeAddonBase(id, { ...opts, packageManager });
    }, "removeAddon");
  }
  return { ...extension, removeAddon };
}, "experimental_serverAPI");
var core = /* @__PURE__ */ __name(async (existing, options) => ({
  ...existing,
  disableTelemetry: options.disableTelemetry === true,
  enableCrashReports: options.enableCrashReports || optionalEnvToBoolean(process.env.STORYBOOK_ENABLE_CRASH_REPORTS)
}), "core");
var features = /* @__PURE__ */ __name(async (existing) => ({
  ...existing,
  argTypeTargetsV7: true,
  legacyDecoratorFileOrder: false,
  disallowImplicitActionsInRenderV8: true,
  viewport: true,
  highlight: true,
  controls: true,
  interactions: true,
  actions: true,
  backgrounds: true,
  outline: true,
  measure: true
}), "features");
var csfIndexer = {
  test: /(stories|story)\.(m?js|ts)x?$/,
  createIndex: /* @__PURE__ */ __name(async (fileName, options) => (await readCsf2(fileName, options)).parse().indexInputs, "createIndex")
};
var experimental_indexers = /* @__PURE__ */ __name((existingIndexers) => [csfIndexer].concat(existingIndexers || []), "experimental_indexers");
var frameworkOptions = /* @__PURE__ */ __name(async (_, options) => {
  const config = await options.presets.apply("framework");
  if (typeof config === "string") {
    return {};
  }
  if (typeof config === "undefined") {
    return null;
  }
  return config.options;
}, "frameworkOptions");
var managerHead = /* @__PURE__ */ __name(async (_, options) => {
  const location = join5(options.configDir, "manager-head.html");
  if (existsSync3(location)) {
    const contents = readFile3(location, { encoding: "utf8" });
    const interpolations = options.presets.apply("env");
    return interpolate(await contents, await interpolations);
  }
  return "";
}, "managerHead");
var experimental_serverChannel = /* @__PURE__ */ __name(async (channel, options) => {
  const coreOptions = await options.presets.apply("core");
  initializeWhatsNew(channel, options, coreOptions);
  initializeSaveStory(channel, options, coreOptions);
  initFileSearchChannel(channel, options, coreOptions);
  initCreateNewStoryChannel(channel, options, coreOptions);
  initOpenInEditorChannel(channel, options, coreOptions);
  return channel;
}, "experimental_serverChannel");
var resolvedReact = /* @__PURE__ */ __name(async (existing) => {
  try {
    return {
      ...existing,
      react: resolvePackageDir("react"),
      reactDom: resolvePackageDir("react-dom")
    };
  } catch (e) {
    return existing;
  }
}, "resolvedReact");
var managerEntries = /* @__PURE__ */ __name(async (existing) => {
  return [
    join(resolvePackageDir("storybook"), "dist/core-server/presets/common-manager.js"),
    ...existing || []
  ];
}, "managerEntries");
var viteFinal = /* @__PURE__ */ __name(async (existing, options) => {
  const previewConfigPath = findConfigFile3("preview", options.configDir);
  if (!previewConfigPath) {
    return existing;
  }
  const { viteInjectMockerRuntime } = await import("../../_node-chunks/plugin-DYA7WIIB.js");
  const { viteMockPlugin } = await import("../../_node-chunks/plugin-JAIR74H6.js");
  const coreOptions = await options.presets.apply("core");
  return {
    ...existing,
    plugins: [
      ...existing.plugins ?? [],
      ...previewConfigPath ? [
        viteInjectMockerRuntime({ previewConfigPath }),
        viteMockPlugin({ previewConfigPath, coreOptions, configDir: options.configDir })
      ] : []
    ]
  };
}, "viteFinal");
var webpackFinal = /* @__PURE__ */ __name(async (config, options) => {
  const previewConfigPath = findConfigFile3("preview", options.configDir);
  if (!previewConfigPath) {
    return config;
  }
  const { WebpackMockPlugin } = await import("../../_node-chunks/webpack-mock-plugin-43DGG7E2.js");
  const { WebpackInjectMockerRuntimePlugin } = await import("../../_node-chunks/webpack-inject-mocker-runtime-plugin-4VAI3YRE.js");
  config.plugins = config.plugins || [];
  config.module.rules.push({
    test: /preview\.(t|j)sx?$/,
    use: [
      {
        loader: fileURLToPath(
          import.meta.resolve("storybook/webpack/loaders/storybook-mock-transform-loader")
        )
      }
    ]
  });
  config.plugins.push(new WebpackMockPlugin({ previewConfigPath }));
  config.plugins.push(new WebpackInjectMockerRuntimePlugin());
  return config;
}, "webpackFinal");
export {
  babel,
  core,
  csfIndexer,
  env,
  experimental_indexers,
  experimental_serverAPI,
  experimental_serverChannel,
  favicon,
  features,
  frameworkOptions,
  logLevel,
  managerEntries,
  managerHead,
  previewBody,
  previewHead,
  resolvedReact,
  staticDirs,
  title,
  typescript,
  viteFinal,
  webpackFinal
};
