import CJS_COMPAT_NODE_URL_bhpmtlmh4se from 'node:url';
import CJS_COMPAT_NODE_PATH_bhpmtlmh4se from 'node:path';
import CJS_COMPAT_NODE_MODULE_bhpmtlmh4se from "node:module";

var __filename = CJS_COMPAT_NODE_URL_bhpmtlmh4se.fileURLToPath(import.meta.url);
var __dirname = CJS_COMPAT_NODE_PATH_bhpmtlmh4se.dirname(__filename);
var require = CJS_COMPAT_NODE_MODULE_bhpmtlmh4se.createRequire(import.meta.url);

// ------------------------------------------------------------
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
// ------------------------------------------------------------
import {
  require_dist
} from "./chunk-F6PCHNVR.js";
import {
  __name,
  __toESM
} from "./chunk-7YMXN42S.js";

// src/csf-tools/CsfFile.ts
var import_ts_dedent = __toESM(require_dist(), 1);
import { readFile, writeFile } from "node:fs/promises";
import {
  BabelFileClass,
  babelParse,
  generate,
  recast,
  types as t2,
  traverse
} from "storybook/internal/babel";
import { isExportStory, storyNameFromExport, toId, toTestId } from "storybook/internal/csf";
import { logger } from "storybook/internal/node-logger";

// src/csf-tools/findVarInitialization.ts
import { types as t } from "storybook/internal/babel";
var findVarInitialization = /* @__PURE__ */ __name((identifier, program) => {
  let init = null;
  let declarations = null;
  program.body.find((node) => {
    if (t.isVariableDeclaration(node)) {
      declarations = node.declarations;
    } else if (t.isExportNamedDeclaration(node) && t.isVariableDeclaration(node.declaration)) {
      declarations = node.declaration.declarations;
    }
    return declarations && declarations.find((decl) => {
      if (t.isVariableDeclarator(decl) && t.isIdentifier(decl.id) && decl.id.name === identifier) {
        init = decl.init;
        return true;
      }
      return false;
    });
  });
  return init;
}, "findVarInitialization");

// src/csf-tools/CsfFile.ts
var PREVIEW_FILE_REGEX = /\/preview(.(js|jsx|mjs|ts|tsx))?$/;
var isValidPreviewPath = /* @__PURE__ */ __name((filepath) => PREVIEW_FILE_REGEX.test(filepath), "isValidPreviewPath");
function parseIncludeExclude(prop) {
  if (t2.isArrayExpression(prop)) {
    return prop.elements.map((e) => {
      if (t2.isStringLiteral(e)) {
        return e.value;
      }
      throw new Error(`Expected string literal: ${e}`);
    });
  }
  if (t2.isStringLiteral(prop)) {
    return new RegExp(prop.value);
  }
  if (t2.isRegExpLiteral(prop)) {
    return new RegExp(prop.pattern, prop.flags);
  }
  throw new Error(`Unknown include/exclude: ${prop}`);
}
__name(parseIncludeExclude, "parseIncludeExclude");
function parseTags(prop) {
  if (!t2.isArrayExpression(prop)) {
    throw new Error("CSF: Expected tags array");
  }
  return prop.elements.map((e) => {
    if (t2.isStringLiteral(e)) {
      return e.value;
    }
    throw new Error(`CSF: Expected tag to be string literal`);
  });
}
__name(parseTags, "parseTags");
function parseTestTags(optionsNode, program) {
  if (!optionsNode) {
    return [];
  }
  let node = optionsNode;
  if (t2.isIdentifier(node)) {
    node = findVarInitialization(node.name, program);
  }
  if (t2.isObjectExpression(node)) {
    const tagsProp = node.properties.find(
      (property) => t2.isObjectProperty(property) && t2.isIdentifier(property.key) && property.key.name === "tags"
    );
    if (tagsProp) {
      let tagsNode = tagsProp.value;
      if (t2.isIdentifier(tagsNode)) {
        tagsNode = findVarInitialization(tagsNode.name, program);
      }
      return parseTags(tagsNode);
    }
  }
  return [];
}
__name(parseTestTags, "parseTestTags");
var formatLocation = /* @__PURE__ */ __name((node, fileName) => {
  let loc = "";
  if (node.loc) {
    const { line, column } = node.loc?.start || {};
    loc = `(line ${line}, col ${column})`;
  }
  return `${fileName || ""} ${loc}`.trim();
}, "formatLocation");
var isModuleMock = /* @__PURE__ */ __name((importPath) => MODULE_MOCK_REGEX.test(importPath), "isModuleMock");
var isArgsStory = /* @__PURE__ */ __name((init, parent, csf) => {
  let storyFn = init;
  if (t2.isCallExpression(init)) {
    const { callee, arguments: bindArguments } = init;
    if (t2.isProgram(parent) && t2.isMemberExpression(callee) && t2.isIdentifier(callee.object) && t2.isIdentifier(callee.property) && callee.property.name === "bind" && (bindArguments.length === 0 || bindArguments.length === 1 && t2.isObjectExpression(bindArguments[0]) && bindArguments[0].properties.length === 0)) {
      const boundIdentifier = callee.object.name;
      const template = findVarInitialization(boundIdentifier, parent);
      if (template) {
        csf._templates[boundIdentifier] = template;
        storyFn = template;
      }
    }
  }
  if (t2.isArrowFunctionExpression(storyFn)) {
    return storyFn.params.length > 0;
  }
  if (t2.isFunctionDeclaration(storyFn)) {
    return storyFn.params.length > 0;
  }
  return false;
}, "isArgsStory");
var parseExportsOrder = /* @__PURE__ */ __name((init) => {
  if (t2.isArrayExpression(init)) {
    return init.elements.map((item) => {
      if (t2.isStringLiteral(item)) {
        return item.value;
      }
      throw new Error(`Expected string literal named export: ${item}`);
    });
  }
  throw new Error(`Expected array of string literals: ${init}`);
}, "parseExportsOrder");
var sortExports = /* @__PURE__ */ __name((exportByName, order) => {
  return order.reduce(
    (acc, name) => {
      const namedExport = exportByName[name];
      if (namedExport) {
        acc[name] = namedExport;
      }
      return acc;
    },
    {}
  );
}, "sortExports");
var hasMount = /* @__PURE__ */ __name((play) => {
  if (t2.isArrowFunctionExpression(play) || t2.isFunctionDeclaration(play)) {
    const params = play.params;
    if (params.length >= 1) {
      const [arg] = params;
      if (t2.isObjectPattern(arg)) {
        return !!arg.properties.find((prop) => {
          if (t2.isObjectProperty(prop) && t2.isIdentifier(prop.key)) {
            return prop.key.name === "mount";
          }
        });
      }
    }
  }
  return false;
}, "hasMount");
var MODULE_MOCK_REGEX = /^[.\/#].*\.mock($|\.[^.]*$)/i;
var NoMetaError = class extends Error {
  static {
    __name(this, "NoMetaError");
  }
  constructor(message, ast, fileName) {
    const msg = message.trim();
    super(import_ts_dedent.dedent`
      CSF: ${msg} ${formatLocation(ast, fileName)}
      
      More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
    `);
    this.name = this.constructor.name;
  }
};
var MultipleMetaError = class extends Error {
  static {
    __name(this, "MultipleMetaError");
  }
  constructor(message, ast, fileName) {
    const msg = `${message} ${formatLocation(ast, fileName)}`.trim();
    super(import_ts_dedent.dedent`
      CSF: ${message} ${formatLocation(ast, fileName)}
      
      More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
    `);
    this.name = this.constructor.name;
  }
};
var MixedFactoryError = class extends Error {
  static {
    __name(this, "MixedFactoryError");
  }
  constructor(message, ast, fileName) {
    const msg = `${message} ${formatLocation(ast, fileName)}`.trim();
    super(import_ts_dedent.dedent`
      CSF: ${message} ${formatLocation(ast, fileName)}
      
      More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
    `);
    this.name = this.constructor.name;
  }
};
var BadMetaError = class extends Error {
  static {
    __name(this, "BadMetaError");
  }
  constructor(message, ast, fileName) {
    const msg = ``.trim();
    super(import_ts_dedent.dedent`
      CSF: ${message} ${formatLocation(ast, fileName)}
      
      More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
    `);
    this.name = this.constructor.name;
  }
};
var CsfFile = class {
  constructor(ast, options, file) {
    this._stories = {};
    this._metaAnnotations = {};
    this._storyExports = {};
    this._storyPaths = {};
    this._storyStatements = {};
    this._storyAnnotations = {};
    this._templates = {};
    this._tests = [];
    this._ast = ast;
    this._file = file;
    this._options = options;
    this.imports = [];
  }
  static {
    __name(this, "CsfFile");
  }
  _parseTitle(value) {
    const node = t2.isIdentifier(value) ? findVarInitialization(value.name, this._ast.program) : value;
    if (t2.isStringLiteral(node)) {
      return node.value;
    }
    if (t2.isTSSatisfiesExpression(node) && t2.isStringLiteral(node.expression)) {
      return node.expression.value;
    }
    throw new Error(import_ts_dedent.dedent`
      CSF: unexpected dynamic title ${formatLocation(node, this._options.fileName)}

      More info: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#string-literal-titles
    `);
  }
  _parseMeta(declaration, program) {
    if (this._metaNode) {
      throw new MultipleMetaError("multiple meta objects", declaration, this._options.fileName);
    }
    this._metaNode = declaration;
    const meta = {};
    declaration.properties.forEach((p) => {
      if (t2.isIdentifier(p.key)) {
        this._metaAnnotations[p.key.name] = p.value;
        if (p.key.name === "title") {
          meta.title = this._parseTitle(p.value);
        } else if (["includeStories", "excludeStories"].includes(p.key.name)) {
          meta[p.key.name] = parseIncludeExclude(p.value);
        } else if (p.key.name === "component") {
          const n = p.value;
          if (t2.isIdentifier(n)) {
            const id = n.name;
            const importStmt = program.body.find(
              (stmt) => t2.isImportDeclaration(stmt) && stmt.specifiers.find((spec) => spec.local.name === id)
            );
            if (importStmt) {
              const { source } = importStmt;
              if (t2.isStringLiteral(source)) {
                this._rawComponentPath = source.value;
              }
            }
          }
          const { code } = recast.print(p.value, {});
          meta.component = code;
        } else if (p.key.name === "tags") {
          let node = p.value;
          if (t2.isIdentifier(node)) {
            node = findVarInitialization(node.name, this._ast.program);
          }
          meta.tags = parseTags(node);
        } else if (p.key.name === "id") {
          if (t2.isStringLiteral(p.value)) {
            meta.id = p.value.value;
          } else {
            throw new Error(`Unexpected component id: ${p.value}`);
          }
        }
      }
    });
    this._meta = meta;
  }
  getStoryExport(key) {
    let node = this._storyExports[key];
    node = t2.isVariableDeclarator(node) ? node.init : node;
    if (t2.isCallExpression(node)) {
      const { callee, arguments: bindArguments } = node;
      if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.object) && t2.isIdentifier(callee.property) && callee.property.name === "bind" && (bindArguments.length === 0 || bindArguments.length === 1 && t2.isObjectExpression(bindArguments[0]) && bindArguments[0].properties.length === 0)) {
        const { name } = callee.object;
        node = this._templates[name];
      }
    }
    return node;
  }
  parse() {
    const self = this;
    traverse(this._ast, {
      ExportDefaultDeclaration: {
        enter(path) {
          const { node, parent } = path;
          const isVariableReference = t2.isIdentifier(node.declaration) && t2.isProgram(parent);
          if (self._options.transformInlineMeta && !isVariableReference && t2.isExpression(node.declaration)) {
            const metaId = path.scope.generateUidIdentifier("meta");
            self._metaVariableName = metaId.name;
            const nodes = [
              t2.variableDeclaration("const", [t2.variableDeclarator(metaId, node.declaration)]),
              t2.exportDefaultDeclaration(metaId)
            ];
            nodes.forEach((_node) => _node.loc = path.node.loc);
            path.replaceWithMultiple(nodes);
            return;
          }
          let metaNode;
          let decl;
          if (isVariableReference) {
            const variableName = node.declaration.name;
            self._metaVariableName = variableName;
            const isVariableDeclarator = /* @__PURE__ */ __name((declaration) => t2.isIdentifier(declaration.id) && declaration.id.name === variableName, "isVariableDeclarator");
            self._metaStatement = self._ast.program.body.find(
              (topLevelNode) => t2.isVariableDeclaration(topLevelNode) && topLevelNode.declarations.find(isVariableDeclarator)
            );
            decl = (self?._metaStatement?.declarations || []).find(
              isVariableDeclarator
            )?.init;
          } else {
            self._metaStatement = node;
            decl = node.declaration;
          }
          if (t2.isObjectExpression(decl)) {
            metaNode = decl;
          } else if (
            // export default { ... } as Meta<...>
            // export default { ... } satisfies Meta<...>
            (t2.isTSAsExpression(decl) || t2.isTSSatisfiesExpression(decl)) && t2.isObjectExpression(decl.expression)
          ) {
            metaNode = decl.expression;
          } else if (
            // export default { ... } satisfies Meta as Meta<...>
            t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression)
          ) {
            metaNode = decl.expression.expression;
          }
          if (metaNode && t2.isProgram(parent)) {
            self._parseMeta(metaNode, parent);
          }
          if (self._metaStatement && !self._metaNode) {
            throw new NoMetaError(
              "default export must be an object",
              self._metaStatement,
              self._options.fileName
            );
          }
          self._metaPath = path;
        }
      },
      ExportNamedDeclaration: {
        enter(path) {
          const { node, parent } = path;
          let declarations;
          if (t2.isVariableDeclaration(node.declaration)) {
            declarations = node.declaration.declarations.filter((d) => t2.isVariableDeclarator(d));
          } else if (t2.isFunctionDeclaration(node.declaration)) {
            declarations = [node.declaration];
          }
          if (declarations) {
            declarations.forEach((decl) => {
              if (t2.isIdentifier(decl.id)) {
                let storyIsFactory = false;
                const { name: exportName } = decl.id;
                if (exportName === "__namedExportsOrder" && t2.isVariableDeclarator(decl)) {
                  self._namedExportsOrder = parseExportsOrder(decl.init);
                  return;
                }
                self._storyExports[exportName] = decl;
                self._storyPaths[exportName] = path;
                self._storyStatements[exportName] = node;
                let name = storyNameFromExport(exportName);
                if (self._storyAnnotations[exportName]) {
                  logger.warn(
                    `Unexpected annotations for "${exportName}" before story declaration`
                  );
                } else {
                  self._storyAnnotations[exportName] = {};
                }
                let storyNode;
                if (t2.isVariableDeclarator(decl)) {
                  if (t2.isTSAsExpression(decl.init) && t2.isTSSatisfiesExpression(decl.init.expression)) {
                    storyNode = decl.init.expression.expression;
                  } else if (t2.isTSAsExpression(decl.init) || t2.isTSSatisfiesExpression(decl.init)) {
                    storyNode = decl.init.expression;
                  } else {
                    storyNode = decl.init;
                  }
                } else {
                  storyNode = decl;
                }
                if (t2.isCallExpression(storyNode) && t2.isMemberExpression(storyNode.callee) && t2.isIdentifier(storyNode.callee.property) && (storyNode.callee.property.name === "story" || storyNode.callee.property.name === "extend")) {
                  storyIsFactory = true;
                  storyNode = storyNode.arguments[0];
                }
                if (self._metaIsFactory && !storyIsFactory) {
                  throw new MixedFactoryError(
                    "expected factory story",
                    storyNode,
                    self._options.fileName
                  );
                } else if (!self._metaIsFactory && storyIsFactory) {
                  if (self._metaNode) {
                    throw new MixedFactoryError(
                      "expected non-factory story",
                      storyNode,
                      self._options.fileName
                    );
                  } else {
                    throw new BadMetaError(
                      "meta() factory must be imported from .storybook/preview configuration",
                      storyNode,
                      self._options.fileName
                    );
                  }
                }
                const parameters = {};
                if (t2.isObjectExpression(storyNode)) {
                  parameters.__isArgsStory = true;
                  storyNode.properties.forEach((p) => {
                    if (t2.isIdentifier(p.key)) {
                      if (p.key.name === "render") {
                        parameters.__isArgsStory = isArgsStory(
                          p.value,
                          parent,
                          self
                        );
                      } else if (p.key.name === "name" && t2.isStringLiteral(p.value)) {
                        name = p.value.value;
                      } else if (p.key.name === "storyName" && t2.isStringLiteral(p.value)) {
                        logger.warn(
                          `Unexpected usage of "storyName" in "${exportName}". Please use "name" instead.`
                        );
                      } else if (p.key.name === "parameters" && t2.isObjectExpression(p.value)) {
                        const idProperty = p.value.properties.find(
                          (property) => t2.isObjectProperty(property) && t2.isIdentifier(property.key) && property.key.name === "__id"
                        );
                        if (idProperty) {
                          parameters.__id = idProperty.value.value;
                        }
                      }
                      self._storyAnnotations[exportName][p.key.name] = p.value;
                    }
                  });
                } else {
                  parameters.__isArgsStory = isArgsStory(storyNode, parent, self);
                }
                self._stories[exportName] = {
                  id: "FIXME",
                  name,
                  parameters,
                  __stats: {
                    factory: storyIsFactory
                  }
                };
              }
            });
          } else if (node.specifiers.length > 0) {
            node.specifiers.forEach((specifier) => {
              if (t2.isExportSpecifier(specifier) && t2.isIdentifier(specifier.exported)) {
                const { name: exportName } = specifier.exported;
                const { name: localName } = specifier.local;
                const decl = t2.isProgram(parent) ? findVarInitialization(localName, parent) : specifier.local;
                if (exportName === "default") {
                  let metaNode;
                  if (t2.isObjectExpression(decl)) {
                    metaNode = decl;
                  } else if (
                    // export default { ... } as Meta<...>
                    // export default { ... } satisfies Meta<...>
                    (t2.isTSAsExpression(decl) || t2.isTSSatisfiesExpression(decl)) && t2.isObjectExpression(decl.expression)
                  ) {
                    metaNode = decl.expression;
                  } else if (
                    // export default { ... } satisfies Meta as Meta<...>
                    t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression)
                  ) {
                    metaNode = decl.expression.expression;
                  }
                  if (metaNode && t2.isProgram(parent)) {
                    self._parseMeta(metaNode, parent);
                  }
                } else {
                  const annotations = {};
                  const storyNode = decl;
                  if (t2.isObjectExpression(storyNode)) {
                    storyNode.properties.forEach((p) => {
                      if (t2.isIdentifier(p.key)) {
                        annotations[p.key.name] = p.value;
                      }
                    });
                  }
                  self._storyAnnotations[exportName] = annotations;
                  self._storyStatements[exportName] = decl;
                  self._storyPaths[exportName] = path;
                  self._stories[exportName] = {
                    id: "FIXME",
                    name: exportName,
                    localName,
                    parameters: {},
                    __stats: {}
                  };
                }
              }
            });
          }
        }
      },
      ExpressionStatement: {
        enter({ node, parent }) {
          const { expression } = node;
          if (t2.isProgram(parent) && t2.isAssignmentExpression(expression) && t2.isMemberExpression(expression.left) && t2.isIdentifier(expression.left.object) && t2.isIdentifier(expression.left.property)) {
            const exportName = expression.left.object.name;
            const annotationKey = expression.left.property.name;
            const annotationValue = expression.right;
            if (self._storyAnnotations[exportName]) {
              if (annotationKey === "story" && t2.isObjectExpression(annotationValue)) {
                annotationValue.properties.forEach((prop) => {
                  if (t2.isIdentifier(prop.key)) {
                    self._storyAnnotations[exportName][prop.key.name] = prop.value;
                  }
                });
              } else {
                self._storyAnnotations[exportName][annotationKey] = annotationValue;
              }
            }
            if (annotationKey === "storyName" && t2.isStringLiteral(annotationValue)) {
              const storyName = annotationValue.value;
              const story = self._stories[exportName];
              if (!story) {
                return;
              }
              story.name = storyName;
            }
          }
          if (t2.isCallExpression(expression) && t2.isMemberExpression(expression.callee) && t2.isIdentifier(expression.callee.object) && t2.isIdentifier(expression.callee.property) && expression.callee.property.name === "test" && expression.arguments.length >= 2 && t2.isStringLiteral(expression.arguments[0])) {
            const exportName = expression.callee.object.name;
            const testName = expression.arguments[0].value;
            const testFunction = expression.arguments.length === 2 ? expression.arguments[1] : expression.arguments[2];
            const testArguments = expression.arguments.length === 2 ? null : expression.arguments[1];
            const tags = parseTestTags(testArguments, self._ast.program);
            self._tests.push({
              function: testFunction,
              name: testName,
              node: expression,
              // can't set id because meta title isn't available yet
              // so it's set later on
              id: "FIXME",
              tags,
              parent: { node: self._storyStatements[exportName] }
            });
            self._stories[exportName].__stats.tests = true;
          }
        }
      },
      CallExpression: {
        enter(path) {
          const { node } = path;
          const { callee } = node;
          if (t2.isIdentifier(callee) && callee.name === "storiesOf") {
            throw new Error(import_ts_dedent.dedent`
              Unexpected \`storiesOf\` usage: ${formatLocation(node, self._options.fileName)}.

              SB8 does not support \`storiesOf\`.
            `);
          }
          if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.property) && callee.property.name === "meta" && t2.isIdentifier(callee.object) && node.arguments.length > 0) {
            const configCandidate = path.scope.getBinding(callee.object.name);
            const configParent = configCandidate?.path?.parentPath?.node;
            if (t2.isImportDeclaration(configParent)) {
              if (isValidPreviewPath(configParent.source.value)) {
                self._metaIsFactory = true;
                const metaDeclarator = path.findParent(
                  (p) => p.isVariableDeclarator()
                );
                self._metaVariableName = t2.isIdentifier(metaDeclarator.node.id) ? metaDeclarator.node.id.name : callee.property.name;
                const metaNode = node.arguments[0];
                self._parseMeta(metaNode, self._ast.program);
              } else {
                throw new BadMetaError(
                  "meta() factory must be imported from .storybook/preview configuration",
                  configParent,
                  self._options.fileName
                );
              }
            }
          }
        }
      },
      ImportDeclaration: {
        enter({ node }) {
          const { source } = node;
          if (t2.isStringLiteral(source)) {
            self.imports.push(source.value);
          } else {
            throw new Error("CSF: unexpected import source");
          }
        }
      }
    });
    if (!self._meta) {
      throw new NoMetaError("missing default export", self._ast, self._options.fileName);
    }
    const entries = Object.entries(self._stories);
    self._meta.title = this._options.makeTitle(self._meta?.title);
    if (self._metaAnnotations.play) {
      self._meta.tags = [...self._meta.tags || [], "play-fn"];
    }
    self._stories = entries.reduce(
      (acc, [key, story]) => {
        if (!isExportStory(key, self._meta)) {
          return acc;
        }
        const id = story.parameters?.__id ?? toId(self._meta?.id || self._meta?.title, storyNameFromExport(key));
        const parameters = { ...story.parameters, __id: id };
        const { includeStories } = self._meta || {};
        if (key === "__page" && (entries.length === 1 || Array.isArray(includeStories) && includeStories.length === 1)) {
          parameters.docsOnly = true;
        }
        acc[key] = { ...story, id, parameters };
        const storyAnnotations = self._storyAnnotations[key];
        const { tags, play } = storyAnnotations;
        if (tags) {
          const node = t2.isIdentifier(tags) ? findVarInitialization(tags.name, this._ast.program) : tags;
          acc[key].tags = parseTags(node);
        }
        if (play) {
          acc[key].tags = [...acc[key].tags || [], "play-fn"];
        }
        const stats = acc[key].__stats;
        ["play", "render", "loaders", "beforeEach", "globals", "tags"].forEach((annotation) => {
          stats[annotation] = !!storyAnnotations[annotation] || !!self._metaAnnotations[annotation];
        });
        const storyExport = self.getStoryExport(key);
        stats.storyFn = !!(t2.isArrowFunctionExpression(storyExport) || t2.isFunctionDeclaration(storyExport));
        stats.mount = hasMount(storyAnnotations.play ?? self._metaAnnotations.play);
        stats.moduleMock = !!self.imports.find((fname) => isModuleMock(fname));
        const storyNode = self._storyStatements[key];
        const storyTests = self._tests.filter((t7) => t7.parent.node === storyNode);
        if (storyTests.length > 0) {
          stats.tests = true;
          storyTests.forEach((test) => {
            test.id = toTestId(id, test.name);
          });
        }
        return acc;
      },
      {}
    );
    Object.keys(self._storyExports).forEach((key) => {
      if (!isExportStory(key, self._meta)) {
        delete self._storyExports[key];
        delete self._storyAnnotations[key];
        delete self._storyStatements[key];
      }
    });
    if (self._namedExportsOrder) {
      const unsortedExports = Object.keys(self._storyExports);
      self._storyExports = sortExports(self._storyExports, self._namedExportsOrder);
      self._stories = sortExports(self._stories, self._namedExportsOrder);
      const sortedExports = Object.keys(self._storyExports);
      if (unsortedExports.length !== sortedExports.length) {
        throw new Error(
          `Missing exports after sort: ${unsortedExports.filter(
            (key) => !sortedExports.includes(key)
          )}`
        );
      }
    }
    return self;
  }
  get meta() {
    return this._meta;
  }
  get stories() {
    return Object.values(this._stories);
  }
  getStoryTests(story) {
    const storyNode = typeof story === "string" ? this._storyStatements[story] : story;
    if (!storyNode) {
      return [];
    }
    return this._tests.filter((t7) => t7.parent.node === storyNode);
  }
  get indexInputs() {
    const { fileName } = this._options;
    if (!fileName) {
      throw new Error(
        import_ts_dedent.dedent`Cannot automatically create index inputs with CsfFile.indexInputs because the CsfFile instance was created without a the fileName option.
        Either add the fileName option when creating the CsfFile instance, or create the index inputs manually.`
      );
    }
    const index = [];
    Object.entries(this._stories).map(([exportName, story]) => {
      const tags = [...this._meta?.tags ?? [], ...story.tags ?? []];
      const storyInput = {
        importPath: fileName,
        rawComponentPath: this._rawComponentPath,
        exportName,
        title: this.meta?.title,
        metaId: this.meta?.id,
        tags,
        __id: story.id,
        __stats: story.__stats
      };
      const tests = this.getStoryTests(exportName);
      const hasTests = tests.length > 0;
      index.push({
        ...storyInput,
        type: "story",
        subtype: "story",
        name: story.name
      });
      if (hasTests) {
        tests.forEach((test) => {
          index.push({
            ...storyInput,
            // TODO implementent proper title => path behavior in `transformStoryIndexToStoriesHash`
            // title: `${storyInput.title}/${story.name}`,
            type: "story",
            subtype: "test",
            name: test.name,
            parent: story.id,
            parentName: story.name,
            tags: [
              ...storyInput.tags,
              // this tag comes before test tags so users can invert if they like
              "!autodocs",
              ...test.tags,
              // this tag comes after test tags so users can't change it
              "test-fn"
            ],
            __id: test.id
          });
        });
      }
    });
    return index;
  }
};
var babelParseFile = /* @__PURE__ */ __name(({
  code,
  filename = "",
  ast
}) => {
  return new BabelFileClass({ filename }, { code, ast: ast ?? babelParse(code) });
}, "babelParseFile");
var loadCsf = /* @__PURE__ */ __name((code, options) => {
  const ast = babelParse(code);
  const file = babelParseFile({ code, filename: options.fileName, ast });
  return new CsfFile(ast, options, file);
}, "loadCsf");
var formatCsf = /* @__PURE__ */ __name((csf, options = { sourceMaps: false }, code) => {
  const result = generate(csf._ast, options, code);
  if (options.sourceMaps) {
    return result;
  }
  return result.code;
}, "formatCsf");
var printCsf = /* @__PURE__ */ __name((csf, options = {}) => {
  return recast.print(csf._ast, options);
}, "printCsf");
var readCsf = /* @__PURE__ */ __name(async (fileName, options) => {
  const code = (await readFile(fileName, "utf-8")).toString();
  return loadCsf(code, { ...options, fileName });
}, "readCsf");
var writeCsf = /* @__PURE__ */ __name(async (csf, fileName) => {
  const fname = fileName || csf._options.fileName;
  if (!fname) {
    throw new Error("Please specify a fileName for writeCsf");
  }
  await writeFile(fileName, printCsf(csf).code);
}, "writeCsf");

// src/csf-tools/ConfigFile.ts
var import_ts_dedent2 = __toESM(require_dist(), 1);
import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
import {
  babelParse as babelParse2,
  generate as generate2,
  recast as recast2,
  types as t3,
  traverse as traverse2
} from "storybook/internal/babel";
import { logger as logger2 } from "storybook/internal/node-logger";
var getCsfParsingErrorMessage = /* @__PURE__ */ __name(({
  expectedType,
  foundType,
  node
}) => {
  return import_ts_dedent2.dedent`
      CSF Parsing error: Expected '${expectedType}' but found '${foundType}' instead in '${node?.type}'.
    `;
}, "getCsfParsingErrorMessage");
var propKey = /* @__PURE__ */ __name((p) => {
  if (t3.isIdentifier(p.key)) {
    return p.key.name;
  }
  if (t3.isStringLiteral(p.key)) {
    return p.key.value;
  }
  return null;
}, "propKey");
var unwrap = /* @__PURE__ */ __name((node) => {
  if (t3.isTSAsExpression(node) || t3.isTSSatisfiesExpression(node)) {
    return unwrap(node.expression);
  }
  return node;
}, "unwrap");
var _getPath = /* @__PURE__ */ __name((path, node) => {
  if (path.length === 0) {
    return node;
  }
  if (t3.isObjectExpression(node)) {
    const [first, ...rest] = path;
    const field = node.properties.find((p) => propKey(p) === first);
    if (field) {
      return _getPath(rest, field.value);
    }
  }
  return void 0;
}, "_getPath");
var _getPathProperties = /* @__PURE__ */ __name((path, node) => {
  if (path.length === 0) {
    if (t3.isObjectExpression(node)) {
      return node.properties;
    }
    throw new Error("Expected object expression");
  }
  if (t3.isObjectExpression(node)) {
    const [first, ...rest] = path;
    const field = node.properties.find((p) => propKey(p) === first);
    if (field) {
      if (rest.length === 0) {
        return node.properties;
      }
      return _getPathProperties(rest, field.value);
    }
  }
  return void 0;
}, "_getPathProperties");
var _findVarDeclarator = /* @__PURE__ */ __name((identifier, program) => {
  let declarator = null;
  let declarations = null;
  program.body.find((node) => {
    if (t3.isVariableDeclaration(node)) {
      declarations = node.declarations;
    } else if (t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration)) {
      declarations = node.declaration.declarations;
    }
    return declarations && declarations.find((decl) => {
      if (t3.isVariableDeclarator(decl) && t3.isIdentifier(decl.id) && decl.id.name === identifier) {
        declarator = decl;
        return true;
      }
      return false;
    });
  });
  return declarator;
}, "_findVarDeclarator");
var _findVarInitialization = /* @__PURE__ */ __name((identifier, program) => {
  const declarator = _findVarDeclarator(identifier, program);
  return declarator?.init;
}, "_findVarInitialization");
var _makeObjectExpression = /* @__PURE__ */ __name((path, value) => {
  if (path.length === 0) {
    return value;
  }
  const [first, ...rest] = path;
  const innerExpression = _makeObjectExpression(rest, value);
  return t3.objectExpression([t3.objectProperty(t3.identifier(first), innerExpression)]);
}, "_makeObjectExpression");
var _updateExportNode = /* @__PURE__ */ __name((path, expr, existing) => {
  const [first, ...rest] = path;
  const existingField = existing.properties.find(
    (p) => propKey(p) === first
  );
  if (!existingField) {
    existing.properties.push(
      t3.objectProperty(t3.identifier(first), _makeObjectExpression(rest, expr))
    );
  } else if (t3.isObjectExpression(existingField.value) && rest.length > 0) {
    _updateExportNode(rest, expr, existingField.value);
  } else {
    existingField.value = _makeObjectExpression(rest, expr);
  }
}, "_updateExportNode");
var ConfigFile = class {
  constructor(ast, code, fileName) {
    this._exports = {};
    // FIXME: this is a hack. this is only used in the case where the user is
    // modifying a named export that's a scalar. The _exports map is not suitable
    // for that. But rather than refactor the whole thing, we just use this as a stopgap.
    this._exportDecls = {};
    this.hasDefaultExport = false;
    this._ast = ast;
    this._code = code;
    this.fileName = fileName;
  }
  static {
    __name(this, "ConfigFile");
  }
  _parseExportsObject(exportsObject) {
    this._exportsObject = exportsObject;
    exportsObject.properties.forEach((p) => {
      const exportName = propKey(p);
      if (exportName) {
        let exportVal = p.value;
        if (t3.isIdentifier(exportVal)) {
          exportVal = _findVarInitialization(exportVal.name, this._ast.program);
        }
        this._exports[exportName] = exportVal;
      }
    });
  }
  parse() {
    const self = this;
    traverse2(this._ast, {
      ExportDefaultDeclaration: {
        enter({ node, parent }) {
          self.hasDefaultExport = true;
          let decl = t3.isIdentifier(node.declaration) && t3.isProgram(parent) ? _findVarInitialization(node.declaration.name, parent) : node.declaration;
          decl = unwrap(decl);
          if (t3.isCallExpression(decl) && t3.isObjectExpression(decl.arguments[0])) {
            decl = decl.arguments[0];
          }
          if (t3.isObjectExpression(decl)) {
            self._parseExportsObject(decl);
          } else {
            logger2.warn(
              getCsfParsingErrorMessage({
                expectedType: "ObjectExpression",
                foundType: decl?.type,
                node: decl || node.declaration
              })
            );
          }
        }
      },
      ExportNamedDeclaration: {
        enter({ node, parent }) {
          if (t3.isVariableDeclaration(node.declaration)) {
            node.declaration.declarations.forEach((decl) => {
              if (t3.isVariableDeclarator(decl) && t3.isIdentifier(decl.id)) {
                const { name: exportName } = decl.id;
                let exportVal = decl.init;
                if (t3.isIdentifier(exportVal)) {
                  exportVal = _findVarInitialization(exportVal.name, parent);
                }
                self._exports[exportName] = exportVal;
                self._exportDecls[exportName] = decl;
              }
            });
          } else if (t3.isFunctionDeclaration(node.declaration)) {
            const decl = node.declaration;
            if (t3.isIdentifier(decl.id)) {
              const { name: exportName } = decl.id;
              self._exportDecls[exportName] = decl;
            }
          } else if (node.specifiers) {
            node.specifiers.forEach((spec) => {
              if (t3.isExportSpecifier(spec) && t3.isIdentifier(spec.local) && t3.isIdentifier(spec.exported)) {
                const { name: localName } = spec.local;
                const { name: exportName } = spec.exported;
                const decl = _findVarDeclarator(localName, parent);
                if (decl) {
                  self._exports[exportName] = decl.init;
                  self._exportDecls[exportName] = decl;
                }
              }
            });
          } else {
            logger2.warn(
              getCsfParsingErrorMessage({
                expectedType: "VariableDeclaration",
                foundType: node.declaration?.type,
                node: node.declaration
              })
            );
          }
        }
      },
      ExpressionStatement: {
        enter({ node, parent }) {
          if (t3.isAssignmentExpression(node.expression) && node.expression.operator === "=") {
            const { left, right } = node.expression;
            if (t3.isMemberExpression(left) && t3.isIdentifier(left.object) && left.object.name === "module" && t3.isIdentifier(left.property) && left.property.name === "exports") {
              let exportObject = right;
              if (t3.isIdentifier(right)) {
                exportObject = _findVarInitialization(right.name, parent);
              }
              exportObject = unwrap(exportObject);
              if (t3.isObjectExpression(exportObject)) {
                self._exportsObject = exportObject;
                exportObject.properties.forEach((p) => {
                  const exportName = propKey(p);
                  if (exportName) {
                    let exportVal = p.value;
                    if (t3.isIdentifier(exportVal)) {
                      exportVal = _findVarInitialization(
                        exportVal.name,
                        parent
                      );
                    }
                    self._exports[exportName] = exportVal;
                  }
                });
              } else {
                logger2.warn(
                  getCsfParsingErrorMessage({
                    expectedType: "ObjectExpression",
                    foundType: exportObject?.type,
                    node: exportObject
                  })
                );
              }
            }
          }
        }
      },
      CallExpression: {
        enter: /* @__PURE__ */ __name(({ node }) => {
          if (t3.isIdentifier(node.callee) && node.callee.name === "definePreview" && node.arguments.length === 1 && t3.isObjectExpression(node.arguments[0])) {
            self._parseExportsObject(node.arguments[0]);
          }
        }, "enter")
      }
    });
    return self;
  }
  getFieldNode(path) {
    const [root, ...rest] = path;
    const exported = this._exports[root];
    if (!exported) {
      return void 0;
    }
    return _getPath(rest, exported);
  }
  getFieldProperties(path) {
    const [root, ...rest] = path;
    const exported = this._exports[root];
    if (!exported) {
      return void 0;
    }
    return _getPathProperties(rest, exported);
  }
  getFieldValue(path) {
    const node = this.getFieldNode(path);
    if (node) {
      const { code } = generate2(node, {});
      const value = (0, eval)(`(() => (${code}))()`);
      return value;
    }
    return void 0;
  }
  getSafeFieldValue(path) {
    try {
      return this.getFieldValue(path);
    } catch (e) {
    }
    return void 0;
  }
  setFieldNode(path, expr) {
    const [first, ...rest] = path;
    const exportNode = this._exports[first];
    if (this._exportsObject) {
      const properties = this._exportsObject.properties;
      const existingProp = properties.find((p) => propKey(p) === first);
      if (existingProp && t3.isIdentifier(existingProp.value)) {
        const varDecl2 = _findVarDeclarator(existingProp.value.name, this._ast.program);
        if (varDecl2 && t3.isObjectExpression(varDecl2.init)) {
          _updateExportNode(rest, expr, varDecl2.init);
          return;
        }
      }
      _updateExportNode(path, expr, this._exportsObject);
      this._exports[path[0]] = expr;
      return;
    }
    if (exportNode && t3.isObjectExpression(exportNode) && rest.length > 0) {
      _updateExportNode(rest, expr, exportNode);
      return;
    }
    const varDecl = _findVarDeclarator(first, this._ast.program);
    if (varDecl && t3.isObjectExpression(varDecl.init)) {
      _updateExportNode(rest, expr, varDecl.init);
      return;
    }
    if (exportNode && rest.length === 0 && this._exportDecls[path[0]]) {
      const decl = this._exportDecls[path[0]];
      if (t3.isVariableDeclarator(decl)) {
        decl.init = _makeObjectExpression([], expr);
      }
    } else if (this.hasDefaultExport) {
      throw new Error(
        `Could not set the "${path.join(
          "."
        )}" field as the default export is not an object in this file.`
      );
    } else {
      const exportObj = _makeObjectExpression(rest, expr);
      const newExport = t3.exportNamedDeclaration(
        t3.variableDeclaration("const", [t3.variableDeclarator(t3.identifier(first), exportObj)])
      );
      this._exports[first] = exportObj;
      this._ast.program.body.push(newExport);
    }
  }
  /**
   * @example
   *
   * ```ts
   * // 1. { framework: 'framework-name' }
   * // 2. { framework: { name: 'framework-name', options: {} }
   * getNameFromPath(['framework']); // => 'framework-name'
   * ```
   *
   * @returns The name of a node in a given path, supporting the following formats:
   */
  getNameFromPath(path) {
    const node = this.getFieldNode(path);
    if (!node) {
      return void 0;
    }
    return this._getPresetValue(node, "name");
  }
  /**
   * Returns an array of names of a node in a given path, supporting the following formats:
   *
   * @example
   *
   * ```ts
   * const config = {
   *   addons: ['first-addon', { name: 'second-addon', options: {} }],
   * };
   * // => ['first-addon', 'second-addon']
   * getNamesFromPath(['addons']);
   * ```
   */
  getNamesFromPath(path) {
    const node = this.getFieldNode(path);
    if (!node) {
      return void 0;
    }
    const pathNames = [];
    if (t3.isArrayExpression(node)) {
      node.elements.forEach((element) => {
        pathNames.push(this._getPresetValue(element, "name"));
      });
    }
    return pathNames;
  }
  _getPnpWrappedValue(node) {
    if (t3.isCallExpression(node)) {
      const arg = node.arguments[0];
      if (t3.isStringLiteral(arg)) {
        return arg.value;
      }
    }
    return void 0;
  }
  /**
   * Given a node and a fallback property, returns a **non-evaluated** string value of the node.
   *
   * 1. `{ node: 'value' }`
   * 2. `{ node: { fallbackProperty: 'value' } }`
   */
  _getPresetValue(node, fallbackProperty) {
    let value;
    if (t3.isStringLiteral(node)) {
      value = node.value;
    } else if (t3.isObjectExpression(node)) {
      node.properties.forEach((prop) => {
        if (t3.isObjectProperty(prop) && t3.isIdentifier(prop.key) && prop.key.name === fallbackProperty) {
          if (t3.isStringLiteral(prop.value)) {
            value = prop.value.value;
          } else {
            value = this._getPnpWrappedValue(prop.value);
          }
        }
        if (t3.isObjectProperty(prop) && t3.isStringLiteral(prop.key) && prop.key.value === "name" && t3.isStringLiteral(prop.value)) {
          value = prop.value.value;
        }
      });
    } else if (t3.isCallExpression(node)) {
      value = this._getPnpWrappedValue(node);
    }
    if (!value) {
      throw new Error(
        `The given node must be a string literal or an object expression with a "${fallbackProperty}" property that is a string literal.`
      );
    }
    return value;
  }
  removeField(path) {
    const removeProperty = /* @__PURE__ */ __name((properties2, prop) => {
      const index = properties2.findIndex(
        (p) => t3.isIdentifier(p.key) && p.key.name === prop || t3.isStringLiteral(p.key) && p.key.value === prop
      );
      if (index >= 0) {
        properties2.splice(index, 1);
      }
    }, "removeProperty");
    if (path.length === 1) {
      let removedRootProperty = false;
      this._ast.program.body.forEach((node) => {
        if (t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration)) {
          const decl = node.declaration.declarations[0];
          if (t3.isIdentifier(decl.id) && decl.id.name === path[0]) {
            this._ast.program.body.splice(this._ast.program.body.indexOf(node), 1);
            removedRootProperty = true;
          }
        }
        if (t3.isExportDefaultDeclaration(node)) {
          let decl = node.declaration;
          if (t3.isIdentifier(decl)) {
            decl = _findVarInitialization(decl.name, this._ast.program);
          }
          decl = unwrap(decl);
          if (t3.isObjectExpression(decl)) {
            const properties2 = decl.properties;
            removeProperty(properties2, path[0]);
            removedRootProperty = true;
          }
        }
        if (t3.isExpressionStatement(node) && t3.isAssignmentExpression(node.expression) && t3.isMemberExpression(node.expression.left) && t3.isIdentifier(node.expression.left.object) && node.expression.left.object.name === "module" && t3.isIdentifier(node.expression.left.property) && node.expression.left.property.name === "exports" && t3.isObjectExpression(node.expression.right)) {
          const properties2 = node.expression.right.properties;
          removeProperty(properties2, path[0]);
          removedRootProperty = true;
        }
      });
      if (removedRootProperty) {
        return;
      }
    }
    const properties = this.getFieldProperties(path);
    if (properties) {
      const lastPath = path.at(-1);
      removeProperty(properties, lastPath);
    }
  }
  appendValueToArray(path, value) {
    const node = this.valueToNode(value);
    if (node) {
      this.appendNodeToArray(path, node);
    }
  }
  appendNodeToArray(path, node) {
    const current = this.getFieldNode(path);
    if (!current) {
      this.setFieldNode(path, t3.arrayExpression([node]));
    } else if (t3.isArrayExpression(current)) {
      current.elements.push(node);
    } else {
      throw new Error(`Expected array at '${path.join(".")}', got '${current.type}'`);
    }
  }
  /**
   * Specialized helper to remove addons or other array entries that can either be strings or
   * objects with a name property.
   */
  removeEntryFromArray(path, value) {
    const current = this.getFieldNode(path);
    if (!current) {
      return;
    }
    if (t3.isArrayExpression(current)) {
      const index = current.elements.findIndex((element) => {
        if (t3.isStringLiteral(element)) {
          return element.value === value;
        }
        if (t3.isObjectExpression(element)) {
          const name = this._getPresetValue(element, "name");
          return name === value;
        }
        return this._getPnpWrappedValue(element) === value;
      });
      if (index >= 0) {
        current.elements.splice(index, 1);
      } else {
        throw new Error(`Could not find '${value}' in array at '${path.join(".")}'`);
      }
    } else {
      throw new Error(`Expected array at '${path.join(".")}', got '${current.type}'`);
    }
  }
  _inferQuotes() {
    if (!this._quotes) {
      const occurrences = (this._ast.tokens || []).slice(0, 500).reduce(
        (acc, token) => {
          if (token.type.label === "string") {
            acc[this._code[token.start]] += 1;
          }
          return acc;
        },
        { "'": 0, '"': 0 }
      );
      this._quotes = occurrences["'"] > occurrences['"'] ? "single" : "double";
    }
    return this._quotes;
  }
  valueToNode(value) {
    const quotes = this._inferQuotes();
    let valueNode;
    if (quotes === "single") {
      const { code } = generate2(t3.valueToNode(value), { jsescOption: { quotes } });
      const program = babelParse2(`const __x = ${code}`);
      traverse2(program, {
        VariableDeclaration: {
          enter({ node }) {
            if (node.declarations.length === 1 && t3.isVariableDeclarator(node.declarations[0]) && t3.isIdentifier(node.declarations[0].id) && node.declarations[0].id.name === "__x") {
              valueNode = node.declarations[0].init;
            }
          }
        }
      });
    } else {
      valueNode = t3.valueToNode(value);
    }
    return valueNode;
  }
  setFieldValue(path, value) {
    const valueNode = this.valueToNode(value);
    if (!valueNode) {
      throw new Error(`Unexpected value ${JSON.stringify(value)}`);
    }
    this.setFieldNode(path, valueNode);
  }
  getBodyDeclarations() {
    return this._ast.program.body;
  }
  setBodyDeclaration(declaration) {
    this._ast.program.body.push(declaration);
  }
  /**
   * Import specifiers for a specific require import
   *
   * @example
   *
   * ```ts
   * // const { foo } = require('bar');
   * setRequireImport(['foo'], 'bar');
   *
   * // const foo = require('bar');
   * setRequireImport('foo', 'bar');
   * ```
   *
   * @param importSpecifiers - The import specifiers to set. If a string is passed in, a default
   *   import will be set. Otherwise, an array of named imports will be set
   * @param fromImport - The module to import from
   */
  setRequireImport(importSpecifier, fromImport) {
    const requireDeclaration = this._ast.program.body.find((node) => {
      const hasDeclaration = t3.isVariableDeclaration(node) && node.declarations.length === 1 && t3.isVariableDeclarator(node.declarations[0]) && t3.isCallExpression(node.declarations[0].init) && t3.isIdentifier(node.declarations[0].init.callee) && node.declarations[0].init.callee.name === "require" && t3.isStringLiteral(node.declarations[0].init.arguments[0]) && (node.declarations[0].init.arguments[0].value === fromImport || node.declarations[0].init.arguments[0].value === fromImport.split("node:")[1]);
      if (hasDeclaration) {
        fromImport = node.declarations[0].init.arguments[0].value;
      }
      return hasDeclaration;
    });
    const hasRequireSpecifier = /* @__PURE__ */ __name((name) => t3.isObjectPattern(requireDeclaration?.declarations[0].id) && requireDeclaration?.declarations[0].id.properties.find(
      (specifier) => t3.isObjectProperty(specifier) && t3.isIdentifier(specifier.key) && specifier.key.name === name
    ), "hasRequireSpecifier");
    const hasDefaultRequireSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.declarations.length === 1 && t3.isVariableDeclarator(declaration.declarations[0]) && t3.isIdentifier(declaration.declarations[0].id) && declaration.declarations[0].id.name === name, "hasDefaultRequireSpecifier");
    if (typeof importSpecifier === "string") {
      const addDefaultRequireSpecifier = /* @__PURE__ */ __name(() => {
        this._ast.program.body.unshift(
          t3.variableDeclaration("const", [
            t3.variableDeclarator(
              t3.identifier(importSpecifier),
              t3.callExpression(t3.identifier("require"), [t3.stringLiteral(fromImport)])
            )
          ])
        );
      }, "addDefaultRequireSpecifier");
      if (requireDeclaration) {
        if (!hasDefaultRequireSpecifier(requireDeclaration, importSpecifier)) {
          addDefaultRequireSpecifier();
        }
      } else {
        addDefaultRequireSpecifier();
      }
    } else if (requireDeclaration) {
      importSpecifier.forEach((specifier) => {
        if (!hasRequireSpecifier(specifier)) {
          requireDeclaration.declarations[0].id.properties.push(
            t3.objectProperty(t3.identifier(specifier), t3.identifier(specifier), void 0, true)
          );
        }
      });
    } else {
      this._ast.program.body.unshift(
        t3.variableDeclaration("const", [
          t3.variableDeclarator(
            t3.objectPattern(
              importSpecifier.map(
                (specifier) => t3.objectProperty(t3.identifier(specifier), t3.identifier(specifier), void 0, true)
              )
            ),
            t3.callExpression(t3.identifier("require"), [t3.stringLiteral(fromImport)])
          )
        ])
      );
    }
  }
  /**
   * Set import specifiers for a given import statement.
   *
   * Does not support setting type imports (yet)
   *
   * @example
   *
   * ```ts
   * // import { foo } from 'bar';
   * setImport(['foo'], 'bar');
   *
   * // import foo from 'bar';
   * setImport('foo', 'bar');
   *
   * // import * as foo from 'bar';
   * setImport({ namespace: 'foo' }, 'bar');
   *
   * // import 'bar';
   * setImport(null, 'bar');
   * ```
   *
   * @param importSpecifiers - The import specifiers to set. If a string is passed in, a default
   *   import will be set. Otherwise, an array of named imports will be set
   * @param fromImport - The module to import from
   */
  setImport(importSpecifier, fromImport) {
    const importDeclaration = this._ast.program.body.find((node) => {
      const hasDeclaration = t3.isImportDeclaration(node) && (node.source.value === fromImport || node.source.value === fromImport.split("node:")[1]);
      if (hasDeclaration) {
        fromImport = node.source.value;
      }
      return hasDeclaration;
    });
    const getNewImportSpecifier = /* @__PURE__ */ __name((specifier) => t3.importSpecifier(t3.identifier(specifier), t3.identifier(specifier)), "getNewImportSpecifier");
    const hasImportSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.specifiers.find(
      (specifier) => t3.isImportSpecifier(specifier) && t3.isIdentifier(specifier.imported) && specifier.imported.name === name
    ), "hasImportSpecifier");
    const hasNamespaceImportSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.specifiers.find(
      (specifier) => t3.isImportNamespaceSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === name
    ), "hasNamespaceImportSpecifier");
    const hasDefaultImportSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.specifiers.find(
      (specifier) => t3.isImportDefaultSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === name
    ), "hasDefaultImportSpecifier");
    if (importSpecifier === null) {
      if (!importDeclaration) {
        this._ast.program.body.unshift(t3.importDeclaration([], t3.stringLiteral(fromImport)));
      }
    } else if (typeof importSpecifier === "string") {
      if (importDeclaration) {
        if (!hasDefaultImportSpecifier(importDeclaration, importSpecifier)) {
          importDeclaration.specifiers.push(
            t3.importDefaultSpecifier(t3.identifier(importSpecifier))
          );
        }
      } else {
        this._ast.program.body.unshift(
          t3.importDeclaration(
            [t3.importDefaultSpecifier(t3.identifier(importSpecifier))],
            t3.stringLiteral(fromImport)
          )
        );
      }
    } else if (Array.isArray(importSpecifier)) {
      if (importDeclaration) {
        importSpecifier.forEach((specifier) => {
          if (!hasImportSpecifier(importDeclaration, specifier)) {
            importDeclaration.specifiers.push(getNewImportSpecifier(specifier));
          }
        });
      } else {
        this._ast.program.body.unshift(
          t3.importDeclaration(
            importSpecifier.map(getNewImportSpecifier),
            t3.stringLiteral(fromImport)
          )
        );
      }
    } else if (importSpecifier.namespace) {
      if (importDeclaration) {
        if (!hasNamespaceImportSpecifier(importDeclaration, importSpecifier.namespace)) {
          importDeclaration.specifiers.push(
            t3.importNamespaceSpecifier(t3.identifier(importSpecifier.namespace))
          );
        }
      } else {
        this._ast.program.body.unshift(
          t3.importDeclaration(
            [t3.importNamespaceSpecifier(t3.identifier(importSpecifier.namespace))],
            t3.stringLiteral(fromImport)
          )
        );
      }
    }
  }
  _removeRequireImport(importSpecifier, fromImport) {
    const requireDeclarationIndex = this._ast.program.body.findIndex((node) => {
      const hasDeclaration = t3.isVariableDeclaration(node) && node.declarations.length === 1 && t3.isVariableDeclarator(node.declarations[0]) && t3.isCallExpression(node.declarations[0].init) && t3.isIdentifier(node.declarations[0].init.callee) && node.declarations[0].init.callee.name === "require" && t3.isStringLiteral(node.declarations[0].init.arguments[0]) && (node.declarations[0].init.arguments[0].value === fromImport || node.declarations[0].init.arguments[0].value === fromImport.split("node:")[1]);
      return hasDeclaration;
    });
    if (requireDeclarationIndex === -1) {
      return;
    }
    const requireDeclaration = this._ast.program.body[requireDeclarationIndex];
    const declarator = requireDeclaration.declarations[0];
    if (importSpecifier === null) {
      return;
    }
    if (typeof importSpecifier === "string") {
      if (t3.isIdentifier(declarator.id) && declarator.id.name === importSpecifier) {
        this._ast.program.body.splice(requireDeclarationIndex, 1);
      }
      return;
    }
    if (typeof importSpecifier === "object" && "namespace" in importSpecifier) {
      return;
    }
    if (Array.isArray(importSpecifier) && t3.isObjectPattern(declarator.id)) {
      const objectPattern = declarator.id;
      importSpecifier.forEach((specifier) => {
        const index = objectPattern.properties.findIndex(
          (prop) => t3.isObjectProperty(prop) && t3.isIdentifier(prop.key) && prop.key.name === specifier
        );
        if (index !== -1) {
          objectPattern.properties.splice(index, 1);
        }
      });
      if (objectPattern.properties.length === 0) {
        this._ast.program.body.splice(requireDeclarationIndex, 1);
      }
    }
  }
  _removeImport(importSpecifier, fromImport) {
    const importDeclarationIndex = this._ast.program.body.findIndex(
      (node) => t3.isImportDeclaration(node) && (node.source.value === fromImport || node.source.value === fromImport.split("node:")[1])
    );
    if (importDeclarationIndex === -1) {
      return;
    }
    const importDeclaration = this._ast.program.body[importDeclarationIndex];
    if (importSpecifier === null) {
      if (importDeclaration.specifiers.length === 0) {
        this._ast.program.body.splice(importDeclarationIndex, 1);
      }
      return;
    }
    if (typeof importSpecifier === "object" && "namespace" in importSpecifier) {
      const index = importDeclaration.specifiers.findIndex(
        (specifier) => t3.isImportNamespaceSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === importSpecifier.namespace
      );
      if (index !== -1) {
        importDeclaration.specifiers.splice(index, 1);
      }
    }
    if (typeof importSpecifier === "string") {
      const index = importDeclaration.specifiers.findIndex(
        (specifier) => t3.isImportDefaultSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === importSpecifier
      );
      if (index !== -1) {
        importDeclaration.specifiers.splice(index, 1);
      }
    }
    if (Array.isArray(importSpecifier)) {
      importSpecifier.forEach((specifier) => {
        const index = importDeclaration.specifiers.findIndex(
          (current) => t3.isImportSpecifier(current) && t3.isIdentifier(current.imported) && current.imported.name === specifier
        );
        if (index !== -1) {
          importDeclaration.specifiers.splice(index, 1);
        }
      });
    }
    if (importDeclaration.specifiers.length === 0) {
      this._ast.program.body.splice(importDeclarationIndex, 1);
    }
  }
  /**
   * Remove import specifiers for a given import statement.
   *
   * Does not support removing type imports (yet)
   *
   * @example
   *
   * ```ts
   * // import { foo } from 'bar';
   * setImport(['foo'], 'bar');
   *
   * // import foo from 'bar';
   * setImport('foo', 'bar');
   *
   * // import * as foo from 'bar';
   * setImport({ namespace: 'foo' }, 'bar');
   *
   * // import 'bar';
   * setImport(null, 'bar');
   * ```
   *
   * @param importSpecifiers - The import specifiers to remove. If a string is passed in, will only
   *   remove the default import. Otherwise, named imports matching the array will be removed.
   * @param fromImport - The module to import from
   */
  removeImport(importSpecifier, fromImport) {
    this._removeRequireImport(importSpecifier, fromImport);
    this._removeImport(importSpecifier, fromImport);
  }
};
var loadConfig = /* @__PURE__ */ __name((code, fileName) => {
  const ast = babelParse2(code);
  return new ConfigFile(ast, code, fileName);
}, "loadConfig");
var formatConfig = /* @__PURE__ */ __name((config) => {
  return printConfig(config).code;
}, "formatConfig");
var printConfig = /* @__PURE__ */ __name((config, options = {}) => {
  return recast2.print(config._ast, options);
}, "printConfig");
var readConfig = /* @__PURE__ */ __name(async (fileName) => {
  const code = (await readFile2(fileName, "utf-8")).toString();
  return loadConfig(code, fileName).parse();
}, "readConfig");
var writeConfig = /* @__PURE__ */ __name(async (config, fileName) => {
  const fname = fileName || config.fileName;
  if (!fname) {
    throw new Error("Please specify a fileName for writeConfig");
  }
  await writeFile2(fname, formatConfig(config));
}, "writeConfig");
var isCsfFactoryPreview = /* @__PURE__ */ __name((previewConfig) => {
  const program = previewConfig._ast.program;
  return !!program.body.find((node) => {
    return t3.isImportDeclaration(node) && node.source.value.includes("@storybook") && node.specifiers.some((specifier) => {
      return t3.isImportSpecifier(specifier) && t3.isIdentifier(specifier.imported) && specifier.imported.name === "definePreview";
    });
  });
}, "isCsfFactoryPreview");

// src/csf-tools/getStorySortParameter.ts
var import_ts_dedent3 = __toESM(require_dist(), 1);
import { babelParse as babelParse3, generate as generate3, types as t4, traverse as traverse3 } from "storybook/internal/babel";
import { logger as logger3 } from "storybook/internal/node-logger";
var getValue = /* @__PURE__ */ __name((obj, key) => {
  let value;
  obj.properties.forEach((p) => {
    if (t4.isIdentifier(p.key) && p.key.name === key) {
      value = p.value;
    }
  });
  return value;
}, "getValue");
var parseValue = /* @__PURE__ */ __name((value) => {
  const expr = stripTSModifiers(value);
  if (t4.isArrayExpression(expr)) {
    return expr.elements.map((o) => {
      return parseValue(o);
    });
  }
  if (t4.isObjectExpression(expr)) {
    return expr.properties.reduce((acc, p) => {
      if (t4.isIdentifier(p.key)) {
        acc[p.key.name] = parseValue(p.value);
      }
      return acc;
    }, {});
  }
  if (t4.isLiteral(expr)) {
    return expr.value;
  }
  if (t4.isIdentifier(expr)) {
    return unsupported(expr.name, true);
  }
  throw new Error(`Unknown node type ${expr.type}`);
}, "parseValue");
var unsupported = /* @__PURE__ */ __name((unexpectedVar, isError) => {
  const message = import_ts_dedent3.dedent`
    Unexpected '${unexpectedVar}'. Parameter 'options.storySort' should be defined inline e.g.:

    export default {
      parameters: {
        options: {
          storySort: <array | object | function>
        },
      },
    };
  `;
  if (isError) {
    throw new Error(message);
  } else {
    logger3.log(message);
  }
}, "unsupported");
var stripTSModifiers = /* @__PURE__ */ __name((expr) => t4.isTSAsExpression(expr) || t4.isTSSatisfiesExpression(expr) ? expr.expression : expr, "stripTSModifiers");
var parseParameters = /* @__PURE__ */ __name((params) => {
  const paramsObject = stripTSModifiers(params);
  if (t4.isObjectExpression(paramsObject)) {
    const options = getValue(paramsObject, "options");
    if (options) {
      if (t4.isObjectExpression(options)) {
        return getValue(options, "storySort");
      }
      unsupported("options", true);
    }
  }
  return void 0;
}, "parseParameters");
var parseDefault = /* @__PURE__ */ __name((defaultExpr, program) => {
  const defaultObj = stripTSModifiers(defaultExpr);
  if (t4.isObjectExpression(defaultObj)) {
    let params = getValue(defaultObj, "parameters");
    if (t4.isIdentifier(params)) {
      params = findVarInitialization(params.name, program);
    }
    if (params) {
      return parseParameters(params);
    }
  } else {
    unsupported("default", true);
  }
  return void 0;
}, "parseDefault");
var getStorySortParameter = /* @__PURE__ */ __name((previewCode) => {
  if (!previewCode.includes("storySort")) {
    return void 0;
  }
  let storySort;
  const ast = babelParse3(previewCode);
  traverse3(ast, {
    ExportNamedDeclaration: {
      enter({ node }) {
        if (t4.isVariableDeclaration(node.declaration)) {
          node.declaration.declarations.forEach((decl) => {
            if (t4.isVariableDeclarator(decl) && t4.isIdentifier(decl.id)) {
              const { name: exportName } = decl.id;
              if (exportName === "parameters" && decl.init) {
                const paramsObject = stripTSModifiers(decl.init);
                storySort = parseParameters(paramsObject);
              }
            }
          });
        } else {
          node.specifiers.forEach((spec) => {
            if (t4.isIdentifier(spec.exported) && spec.exported.name === "parameters") {
              unsupported("parameters", false);
            }
          });
        }
      }
    },
    ExportDefaultDeclaration: {
      enter({ node }) {
        let defaultObj = node.declaration;
        if (t4.isIdentifier(defaultObj)) {
          defaultObj = findVarInitialization(defaultObj.name, ast.program);
        }
        defaultObj = stripTSModifiers(defaultObj);
        if (t4.isCallExpression(defaultObj) && t4.isObjectExpression(defaultObj.arguments?.[0])) {
          storySort = parseDefault(defaultObj.arguments[0], ast.program);
        } else if (t4.isObjectExpression(defaultObj)) {
          storySort = parseDefault(defaultObj, ast.program);
        } else {
          unsupported("default", false);
        }
      }
    }
  });
  if (!storySort) {
    return void 0;
  }
  if (t4.isArrowFunctionExpression(storySort)) {
    const { code: sortCode } = generate3(storySort, {});
    return (0, eval)(sortCode);
  }
  if (t4.isFunctionExpression(storySort)) {
    const { code: sortCode } = generate3(storySort, {});
    const functionName = storySort.id?.name;
    const wrapper = `(a, b) => {
      ${sortCode};
      return ${functionName}(a, b)
    }`;
    return (0, eval)(wrapper);
  }
  if (t4.isLiteral(storySort) || t4.isArrayExpression(storySort) || t4.isObjectExpression(storySort)) {
    return parseValue(storySort);
  }
  return unsupported("storySort", true);
}, "getStorySortParameter");

// src/csf-tools/enrichCsf.ts
import { generate as generate4, types as t5 } from "storybook/internal/babel";
var enrichCsfStory = /* @__PURE__ */ __name((csf, csfSource, key, options) => {
  const storyExport = csfSource.getStoryExport(key);
  const isCsfFactory = t5.isCallExpression(storyExport) && t5.isMemberExpression(storyExport.callee) && t5.isIdentifier(storyExport.callee.object) && storyExport.callee.object.name === "meta";
  const source = !options?.disableSource && extractSource(storyExport);
  const description = !options?.disableDescription && extractDescription(csfSource._storyStatements[key]);
  const parameters = [];
  const baseStoryObject = isCsfFactory ? t5.memberExpression(t5.identifier(key), t5.identifier("input")) : t5.identifier(key);
  const originalParameters = t5.memberExpression(baseStoryObject, t5.identifier("parameters"));
  parameters.push(t5.spreadElement(originalParameters));
  const optionalDocs = t5.optionalMemberExpression(
    originalParameters,
    t5.identifier("docs"),
    false,
    true
  );
  const extraDocsParameters = [];
  if (source) {
    const optionalSource = t5.optionalMemberExpression(
      optionalDocs,
      t5.identifier("source"),
      false,
      true
    );
    extraDocsParameters.push(
      t5.objectProperty(
        t5.identifier("source"),
        t5.objectExpression([
          t5.objectProperty(t5.identifier("originalSource"), t5.stringLiteral(source)),
          t5.spreadElement(optionalSource)
        ])
      )
    );
  }
  if (description) {
    const optionalDescription = t5.optionalMemberExpression(
      optionalDocs,
      t5.identifier("description"),
      false,
      true
    );
    extraDocsParameters.push(
      t5.objectProperty(
        t5.identifier("description"),
        t5.objectExpression([
          t5.objectProperty(t5.identifier("story"), t5.stringLiteral(description)),
          t5.spreadElement(optionalDescription)
        ])
      )
    );
  }
  if (extraDocsParameters.length > 0) {
    parameters.push(
      t5.objectProperty(
        t5.identifier("docs"),
        t5.objectExpression([t5.spreadElement(optionalDocs), ...extraDocsParameters])
      )
    );
    const addParameter = t5.expressionStatement(
      t5.assignmentExpression("=", originalParameters, t5.objectExpression(parameters))
    );
    csf._ast.program.body.push(addParameter);
  }
}, "enrichCsfStory");
var addComponentDescription = /* @__PURE__ */ __name((node, path, value) => {
  if (!path.length) {
    const hasExistingComponent = node.properties.find(
      (p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === "component"
    );
    if (!hasExistingComponent) {
      node.properties.unshift(value);
    }
    return;
  }
  const [first, ...rest] = path;
  const existing = node.properties.find(
    (p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === first && t5.isObjectExpression(p.value)
  );
  let subNode;
  if (existing) {
    subNode = existing.value;
  } else {
    subNode = t5.objectExpression([]);
    node.properties.push(t5.objectProperty(t5.identifier(first), subNode));
  }
  addComponentDescription(subNode, rest, value);
}, "addComponentDescription");
var enrichCsfMeta = /* @__PURE__ */ __name((csf, csfSource, options) => {
  const description = !options?.disableDescription && extractDescription(csfSource._metaStatement);
  if (description) {
    const metaNode = csf._metaNode;
    if (metaNode && t5.isObjectExpression(metaNode)) {
      addComponentDescription(
        metaNode,
        ["parameters", "docs", "description"],
        t5.objectProperty(t5.identifier("component"), t5.stringLiteral(description))
      );
    }
  }
}, "enrichCsfMeta");
var enrichCsf = /* @__PURE__ */ __name((csf, csfSource, options) => {
  enrichCsfMeta(csf, csfSource, options);
  Object.keys(csf._storyExports).forEach((key) => {
    enrichCsfStory(csf, csfSource, key, options);
  });
}, "enrichCsf");
var extractSource = /* @__PURE__ */ __name((node) => {
  const src = t5.isVariableDeclarator(node) ? node.init : node;
  const { code } = generate4(src, {});
  return code;
}, "extractSource");
var extractDescription = /* @__PURE__ */ __name((node) => {
  if (!node?.leadingComments) {
    return "";
  }
  const comments = node.leadingComments.map((comment) => {
    if (comment.type === "CommentLine" || !comment.value.startsWith("*")) {
      return null;
    }
    return comment.value.split("\n").map((line) => line.replace(/^(\s+)?(\*+)?(\s)?/, "")).join("\n").trim();
  }).filter(Boolean);
  return comments.join("\n");
}, "extractDescription");

// src/csf-tools/index.ts
import { babelParse as babelParse4 } from "storybook/internal/babel";

// src/csf-tools/vitest-plugin/transformer.ts
var import_ts_dedent4 = __toESM(require_dist(), 1);
import { types as t6 } from "storybook/internal/babel";
import { getStoryTitle } from "storybook/internal/common";
import { combineTags } from "storybook/internal/csf";
import { logger as logger4 } from "storybook/internal/node-logger";
var isValidTest = /* @__PURE__ */ __name((storyTags, tagsFilter) => {
  if (tagsFilter.include.length && !tagsFilter.include.some((tag) => storyTags?.includes(tag))) {
    return false;
  }
  if (tagsFilter.exclude.some((tag) => storyTags?.includes(tag))) {
    return false;
  }
  return true;
}, "isValidTest");
var DOUBLE_SPACES = "  ";
var getLiteralWithZeroWidthSpace = /* @__PURE__ */ __name((testTitle) => t6.stringLiteral(`${testTitle}${DOUBLE_SPACES}`), "getLiteralWithZeroWidthSpace");
async function vitestTransform({
  code,
  fileName,
  configDir,
  stories,
  tagsFilter,
  previewLevelTags = []
}) {
  const parsed = loadCsf(code, {
    fileName,
    transformInlineMeta: true,
    makeTitle: /* @__PURE__ */ __name((title) => {
      const result = getStoryTitle({
        storyFilePath: fileName,
        configDir,
        stories,
        userTitle: title
      }) || "unknown";
      if (result === "unknown") {
        logger4.warn(
          import_ts_dedent4.dedent`
            [Storybook]: Could not calculate story title for "${fileName}".
            Please make sure that this file matches the globs included in the "stories" field in your Storybook configuration at "${configDir}".
          `
        );
      }
      return result;
    }, "makeTitle")
  }).parse();
  const ast = parsed._ast;
  const metaExportName = parsed._metaVariableName;
  const metaNode = parsed._metaNode;
  const metaTitleProperty = metaNode.properties.find(
    (prop) => t6.isObjectProperty(prop) && t6.isIdentifier(prop.key) && prop.key.name === "title"
  );
  const metaTitle = t6.stringLiteral(parsed._meta?.title || "unknown");
  if (!metaTitleProperty) {
    metaNode.properties.push(t6.objectProperty(t6.identifier("title"), metaTitle));
  } else if (t6.isObjectProperty(metaTitleProperty)) {
    metaTitleProperty.value = metaTitle;
  }
  if (!metaNode || !parsed._meta) {
    throw new Error(
      "The Storybook vitest plugin could not detect the meta (default export) object in the story file. \n\nPlease make sure you have a default export with the meta object. If you are using a different export format that is not supported, please file an issue with details about your use case."
    );
  }
  const validStories = {};
  Object.keys(parsed._stories).forEach((key) => {
    const finalTags = combineTags(
      "test",
      "dev",
      ...previewLevelTags,
      ...parsed.meta?.tags || [],
      ...parsed._stories[key].tags || []
    );
    if (isValidTest(finalTags, tagsFilter)) {
      validStories[key] = parsed._storyStatements[key];
    }
  });
  const vitestTestId = parsed._file.path.scope.generateUidIdentifier("test");
  const vitestDescribeId = parsed._file.path.scope.generateUidIdentifier("describe");
  if (Object.keys(validStories).length === 0) {
    const describeSkipBlock = t6.expressionStatement(
      t6.callExpression(t6.memberExpression(vitestDescribeId, t6.identifier("skip")), [
        t6.stringLiteral("No valid tests found")
      ])
    );
    ast.program.body.push(describeSkipBlock);
    const imports2 = [
      t6.importDeclaration(
        [
          t6.importSpecifier(vitestTestId, t6.identifier("test")),
          t6.importSpecifier(vitestDescribeId, t6.identifier("describe"))
        ],
        t6.stringLiteral("vitest")
      )
    ];
    ast.program.body.unshift(...imports2);
    return formatCsf(parsed, { sourceMaps: true, sourceFileName: fileName }, code);
  }
  const vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect");
  const testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory");
  const skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip));
  function getTestGuardDeclaration() {
    const isRunningFromThisFileId2 = parsed._file.path.scope.generateUidIdentifier("isRunningFromThisFile");
    const testPathProperty = t6.memberExpression(
      t6.callExpression(t6.memberExpression(vitestExpectId, t6.identifier("getState")), []),
      t6.identifier("testPath")
    );
    const filePathProperty = t6.memberExpression(
      t6.memberExpression(t6.identifier("globalThis"), t6.identifier("__vitest_worker__")),
      t6.identifier("filepath")
    );
    const nullishCoalescingExpression = t6.logicalExpression(
      "??",
      // TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
      // https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
      filePathProperty,
      testPathProperty
    );
    const includesCall = t6.callExpression(
      t6.memberExpression(
        t6.callExpression(t6.identifier("convertToFilePath"), [
          t6.memberExpression(
            t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
            t6.identifier("url")
          )
        ]),
        t6.identifier("includes")
      ),
      [nullishCoalescingExpression]
    );
    const isRunningFromThisFileDeclaration2 = t6.variableDeclaration("const", [
      t6.variableDeclarator(isRunningFromThisFileId2, includesCall)
    ]);
    return { isRunningFromThisFileDeclaration: isRunningFromThisFileDeclaration2, isRunningFromThisFileId: isRunningFromThisFileId2 };
  }
  __name(getTestGuardDeclaration, "getTestGuardDeclaration");
  const { isRunningFromThisFileDeclaration, isRunningFromThisFileId } = getTestGuardDeclaration();
  ast.program.body.push(isRunningFromThisFileDeclaration);
  const getTestStatementForStory = /* @__PURE__ */ __name(({
    localName,
    exportName,
    testTitle,
    node,
    overrideSourcemap = true,
    storyId
  }) => {
    const testStoryCall = t6.expressionStatement(
      t6.callExpression(vitestTestId, [
        t6.stringLiteral(testTitle),
        t6.callExpression(testStoryId, [
          t6.stringLiteral(exportName),
          t6.identifier(localName),
          t6.identifier(metaExportName),
          skipTagsId,
          t6.stringLiteral(storyId)
        ])
      ])
    );
    if (overrideSourcemap) {
      testStoryCall.loc = node.loc;
    }
    return testStoryCall;
  }, "getTestStatementForStory");
  const getDescribeStatementForStory = /* @__PURE__ */ __name((options) => {
    const { localName, describeTitle, exportName, tests, node, parentStoryId } = options;
    const describeBlock = t6.callExpression(vitestDescribeId, [
      getLiteralWithZeroWidthSpace(describeTitle),
      t6.arrowFunctionExpression(
        [],
        t6.blockStatement([
          getTestStatementForStory({
            ...options,
            testTitle: "base story",
            overrideSourcemap: false,
            storyId: parentStoryId
          }),
          ...tests.map(({ name: testName, node: testNode, id: storyId }) => {
            const testStatement = t6.expressionStatement(
              t6.callExpression(vitestTestId, [
                t6.stringLiteral(testName),
                t6.callExpression(testStoryId, [
                  t6.stringLiteral(exportName),
                  t6.identifier(localName),
                  t6.identifier(metaExportName),
                  t6.arrayExpression([]),
                  t6.stringLiteral(storyId),
                  t6.stringLiteral(testName)
                ])
              ])
            );
            testStatement.loc = testNode.loc;
            return testStatement;
          })
        ])
      )
    ]);
    describeBlock.loc = node.loc;
    return t6.expressionStatement(describeBlock);
  }, "getDescribeStatementForStory");
  const storyTestStatements = Object.entries(validStories).map(([exportName, node]) => {
    if (node === null) {
      logger4.warn(
        import_ts_dedent4.dedent`
            [Storybook]: Could not transform "${exportName}" story into test at "${fileName}".
            Please make sure to define stories in the same file and not re-export stories coming from other files".
          `
      );
      return;
    }
    const localName = parsed._stories[exportName].localName ?? exportName;
    const testTitle = parsed._stories[exportName].name ?? exportName;
    const storyId = parsed._stories[exportName].id;
    const tests = parsed.getStoryTests(exportName);
    if (tests?.length > 0) {
      return getDescribeStatementForStory({
        localName,
        describeTitle: testTitle,
        exportName,
        tests,
        node,
        parentStoryId: storyId
      });
    }
    return getTestStatementForStory({
      testTitle,
      localName,
      exportName,
      node,
      storyId
    });
  }).filter((st) => !!st);
  const testBlock = t6.ifStatement(isRunningFromThisFileId, t6.blockStatement(storyTestStatements));
  ast.program.body.push(testBlock);
  const hasTests = Object.keys(validStories).some(
    (exportName) => parsed.getStoryTests(exportName).length > 0
  );
  const imports = [
    t6.importDeclaration(
      [
        t6.importSpecifier(vitestTestId, t6.identifier("test")),
        t6.importSpecifier(vitestExpectId, t6.identifier("expect")),
        ...hasTests ? [t6.importSpecifier(vitestDescribeId, t6.identifier("describe"))] : []
      ],
      t6.stringLiteral("vitest")
    ),
    t6.importDeclaration(
      [
        t6.importSpecifier(testStoryId, t6.identifier("testStory")),
        t6.importSpecifier(t6.identifier("convertToFilePath"), t6.identifier("convertToFilePath"))
      ],
      t6.stringLiteral("@storybook/addon-vitest/internal/test-utils")
    )
  ];
  ast.program.body.unshift(...imports);
  return formatCsf(parsed, { sourceMaps: true, sourceFileName: fileName }, code);
}
__name(vitestTransform, "vitestTransform");

export {
  isValidPreviewPath,
  isModuleMock,
  NoMetaError,
  MultipleMetaError,
  MixedFactoryError,
  BadMetaError,
  CsfFile,
  babelParseFile,
  loadCsf,
  formatCsf,
  printCsf,
  readCsf,
  writeCsf,
  ConfigFile,
  loadConfig,
  formatConfig,
  printConfig,
  readConfig,
  writeConfig,
  isCsfFactoryPreview,
  getStorySortParameter,
  enrichCsfStory,
  enrichCsfMeta,
  enrichCsf,
  extractSource,
  extractDescription,
  vitestTransform,
  babelParse4 as babelParse
};
