'use strict';

var chunkKBVOYAAL_cjs = require('./chunk-KBVOYAAL.cjs');
var chunk5TILMGJA_cjs = require('./chunk-5TILMGJA.cjs');
var chunkAQL6MQFJ_cjs = require('./chunk-AQL6MQFJ.cjs');
var chunkYW7AIVNG_cjs = require('./chunk-YW7AIVNG.cjs');
var chunkQJGW77MV_cjs = require('./chunk-QJGW77MV.cjs');
var chunk3T7FP546_cjs = require('./chunk-3T7FP546.cjs');
var child_process = require('child_process');
var fs = require('fs');
var promises = require('fs/promises');
var path = require('path');
var bundler = require('@mastra/core/bundler');
var error = require('@mastra/core/error');
var virtual = require('@rollup/plugin-virtual');
var pkg = require('empathic/package');
var fsExtra = require('fs-extra/esm');
var tinyglobby = require('tinyglobby');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n.default = e;
  return Object.freeze(n);
}

var virtual__default = /*#__PURE__*/_interopDefault(virtual);
var pkg__namespace = /*#__PURE__*/_interopNamespace(pkg);
var fsExtra__default = /*#__PURE__*/_interopDefault(fsExtra);

var IS_DEFAULT = /* @__PURE__ */ Symbol("IS_DEFAULT");
var Bundler = class extends bundler.MastraBundler {
  analyzeOutputDir = ".build";
  outputDir = "output";
  platform = "node";
  constructor(name, component = "BUNDLER") {
    super({ name, component });
  }
  async prepare(outputDirectory) {
    await fsExtra.emptyDir(outputDirectory);
    await fsExtra.ensureDir(path.join(outputDirectory, this.analyzeOutputDir));
    await fsExtra.ensureDir(path.join(outputDirectory, this.outputDir));
  }
  async writePackageJson(outputDirectory, dependencies, resolutions) {
    this.logger.debug("Writing project's package.json");
    await fsExtra.ensureDir(outputDirectory);
    const pkgPath = path.join(outputDirectory, "package.json");
    const dependenciesMap = /* @__PURE__ */ new Map();
    for (const [key, value] of dependencies.entries()) {
      if (key.startsWith("@")) {
        const pkgChunks = key.split("/");
        dependenciesMap.set(`${pkgChunks[0]}/${pkgChunks[1]}`, value);
      } else {
        const pkgName = key.split("/")[0] || key;
        dependenciesMap.set(pkgName, value);
      }
    }
    await promises.writeFile(
      pkgPath,
      JSON.stringify(
        {
          name: "server",
          version: "1.0.0",
          description: "",
          type: "module",
          main: "index.mjs",
          scripts: {
            start: "node ./index.mjs"
          },
          author: "Mastra",
          license: "ISC",
          dependencies: Object.fromEntries(dependenciesMap.entries()),
          ...Object.keys(resolutions ?? {}).length > 0 && { resolutions },
          pnpm: {
            neverBuiltDependencies: []
          }
        },
        null,
        2
      )
    );
  }
  createBundler(inputOptions, outputOptions) {
    return chunkAQL6MQFJ_cjs.createBundler(inputOptions, outputOptions);
  }
  async getUserBundlerOptions(mastraEntryFile, outputDirectory) {
    const defaultBundlerOptions = {
      externals: [],
      sourcemap: false,
      transpilePackages: [],
      [IS_DEFAULT]: true
    };
    try {
      const bundlerOptions = await chunkKBVOYAAL_cjs.getBundlerOptions(mastraEntryFile, outputDirectory);
      return bundlerOptions ?? defaultBundlerOptions;
    } catch (error) {
      this.logger.debug("Failed to get bundler options, sourcemap will be disabled", { error });
    }
    return defaultBundlerOptions;
  }
  async analyze(entry, mastraFile, outputDirectory) {
    return await chunk5TILMGJA_cjs.analyzeBundle(
      [].concat(entry),
      mastraFile,
      {
        outputDir: path.join(outputDirectory, this.analyzeOutputDir),
        projectRoot: outputDirectory,
        platform: this.platform
      },
      this.logger
    );
  }
  async installDependencies(outputDirectory, rootDir = process.cwd()) {
    const deps = new chunkQJGW77MV_cjs.DepsService(rootDir);
    deps.__setLogger(this.logger);
    await deps.install({ dir: path.join(outputDirectory, this.outputDir) });
  }
  /**
   * Generate a package-lock.json for the output directory so that deploy targets
   * can use `npm ci` instead of `npm install`, skipping version resolution entirely.
   * This is a lockfile-only operation — no packages are downloaded.
   *
   * Temporarily moves node_modules out of the way because pnpm's symlink-based
   * layout confuses npm's arborist, then restores it afterwards so that
   * `mastra start` (or wrangler) can still resolve dependencies at runtime.
   */
  async generateNpmLockfile(outputDir) {
    const nodeModules = path.join(outputDir, "node_modules");
    const nodeModulesTmp = path.join(outputDir, "node_modules.__tmp");
    let movedNodeModules = false;
    try {
      if (await fsExtra__default.default.pathExists(nodeModules)) {
        await fsExtra__default.default.move(nodeModules, nodeModulesTmp, { overwrite: true });
        movedNodeModules = true;
      }
      child_process.execSync("npm install --package-lock-only --force", {
        cwd: outputDir,
        stdio: "pipe",
        timeout: 6e4
      });
    } catch {
      this.logger.warn("Failed to generate package-lock.json \u2014 deploy will fall back to npm install");
    } finally {
      if (movedNodeModules) {
        await promises.rm(nodeModules, { recursive: true, force: true });
        await fsExtra__default.default.move(nodeModulesTmp, nodeModules, { overwrite: true });
      }
    }
  }
  async copyPublic(mastraDir, outputDirectory) {
    const publicDir = path.join(mastraDir, "public");
    try {
      await promises.stat(publicDir);
    } catch {
      return;
    }
    await fsExtra.copy(publicDir, path.join(outputDirectory, this.outputDir));
  }
  async copyDOTNPMRC({
    rootDir = process.cwd(),
    outputDirectory
  }) {
    const sourceDotNpmRcPath = path.join(rootDir, ".npmrc");
    const targetDotNpmRcPath = path.join(outputDirectory, this.outputDir, ".npmrc");
    try {
      await promises.stat(sourceDotNpmRcPath);
      await fsExtra.copy(sourceDotNpmRcPath, targetDotNpmRcPath);
    } catch {
      return;
    }
  }
  async getBundlerOptions(serverFile, mastraEntryFile, analyzedBundleInfo, toolsPaths, { enableSourcemap, enableEsmShim, externals }) {
    const { workspaceRoot } = await chunk5TILMGJA_cjs.getWorkspaceInformation({ mastraEntryFile });
    const closestPkgJson = pkg__namespace.up({ cwd: path.dirname(mastraEntryFile) });
    const projectRoot = closestPkgJson ? path.dirname(closestPkgJson) : process.cwd();
    const inputOptions = await chunkAQL6MQFJ_cjs.getInputOptions(
      mastraEntryFile,
      analyzedBundleInfo,
      this.platform,
      {
        "process.env.NODE_ENV": JSON.stringify("production")
      },
      { sourcemap: enableSourcemap, workspaceRoot, projectRoot, enableEsmShim, externalsPreset: externals === true }
    );
    const isVirtual = serverFile.includes("\n") || !fs.existsSync(serverFile);
    const toolsInputOptions = await this.listToolsInputOptions(toolsPaths);
    if (isVirtual) {
      inputOptions.input = { index: "#entry", ...toolsInputOptions };
      if (Array.isArray(inputOptions.plugins)) {
        inputOptions.plugins.unshift(virtual__default.default({ "#entry": serverFile }));
      } else {
        inputOptions.plugins = [virtual__default.default({ "#entry": serverFile })];
      }
    } else {
      inputOptions.input = { index: serverFile, ...toolsInputOptions };
    }
    return inputOptions;
  }
  getAllToolPaths(mastraDir, toolsPaths = []) {
    const normalizedMastraDir = chunk3T7FP546_cjs.slash(mastraDir);
    const defaultToolsPath = path.posix.join(normalizedMastraDir, "tools/**/*.{js,ts}");
    const defaultToolsIgnorePaths = [
      `!${path.posix.join(normalizedMastraDir, "tools/**/*.{test,spec}.{js,ts}")}`,
      `!${path.posix.join(normalizedMastraDir, "tools/**/__tests__/**")}`
    ];
    const defaultPaths = [defaultToolsPath, ...defaultToolsIgnorePaths];
    if (toolsPaths.length === 0) {
      return [defaultPaths];
    }
    return [...toolsPaths, defaultPaths];
  }
  async listToolsInputOptions(toolsPaths) {
    const inputs = {};
    for (const toolPath of toolsPaths) {
      const expandedPaths = await tinyglobby.glob(toolPath, {
        absolute: true,
        expandDirectories: false
      });
      for (const path$1 of expandedPaths) {
        if (await fsExtra__default.default.pathExists(path$1)) {
          const fileService = new chunkQJGW77MV_cjs.FileService();
          const entryFile = fileService.getFirstExistingFile([
            path.join(path$1, "index.ts"),
            path.join(path$1, "index.js"),
            path$1
            // if path itself is a file
          ]);
          if (!entryFile || (await promises.stat(entryFile)).isDirectory()) {
            this.logger.warn("No entry file found, skipping", { path: path$1 });
            continue;
          }
          const uniqueToolID = crypto.randomUUID();
          const normalizedEntryFile = entryFile.replaceAll("\\", "/");
          inputs[`tools/${uniqueToolID}`] = normalizedEntryFile;
        } else {
          this.logger.warn("Tool path does not exist, skipping", { path: path$1 });
        }
      }
    }
    return inputs;
  }
  async _bundle(serverFile, mastraEntryFile, {
    projectRoot,
    outputDirectory,
    enableEsmShim = true
  }, toolsPaths = [], bundleLocation = path.join(outputDirectory, this.outputDir)) {
    const analyzeDir = path.join(outputDirectory, this.analyzeOutputDir);
    const bundlerOptions = await this.getUserBundlerOptions(mastraEntryFile, outputDirectory);
    const internalBundlerOptions = {
      enableSourcemap: !!bundlerOptions.sourcemap,
      externals: bundlerOptions.externals ?? [],
      enableEsmShim,
      dynamicPackages: bundlerOptions.dynamicPackages
    };
    let analyzedBundleInfo;
    try {
      const resolvedToolsPaths = await this.listToolsInputOptions(toolsPaths);
      analyzedBundleInfo = await chunk5TILMGJA_cjs.analyzeBundle(
        [serverFile, ...Object.values(resolvedToolsPaths)],
        mastraEntryFile,
        {
          outputDir: analyzeDir,
          projectRoot,
          platform: this.platform,
          bundlerOptions: internalBundlerOptions
        },
        this.logger
      );
    } catch (error$1) {
      const message = error$1 instanceof Error ? error$1.message : String(error$1);
      if (error$1 instanceof error.MastraError) {
        throw error$1;
      }
      throw new error.MastraError(
        {
          id: "DEPLOYER_BUNDLER_ANALYZE_FAILED",
          text: `Failed to analyze Mastra application: ${message}`,
          domain: error.ErrorDomain.DEPLOYER,
          category: error.ErrorCategory.SYSTEM
        },
        error$1
      );
    }
    const dependenciesToInstall = /* @__PURE__ */ new Map();
    for (const [dep, depInfo] of analyzedBundleInfo.externalDependencies) {
      if (analyzedBundleInfo.workspaceMap.has(dep) || !chunk3T7FP546_cjs.isBareModuleSpecifier(dep)) {
        continue;
      }
      let version = depInfo.version;
      let actualPackageName;
      try {
        let rootPath = await chunkYW7AIVNG_cjs.getPackageRootPath(dep, projectRoot);
        if (!rootPath) {
          rootPath = await chunkYW7AIVNG_cjs.getPackageRootPath(dep, undefined);
        }
        if (rootPath) {
          const pkg2 = await fsExtra.readJSON(`${rootPath}/package.json`);
          actualPackageName = pkg2.name;
          if (!version) {
            version = pkg2.version;
          }
        }
      } catch {
      }
      version = version || "latest";
      const isAlias = actualPackageName && dep !== actualPackageName;
      if (isAlias) {
        dependenciesToInstall.set(dep, `npm:${actualPackageName}@${version}`);
      } else {
        dependenciesToInstall.set(dep, version);
      }
    }
    try {
      await this.writePackageJson(path.join(outputDirectory, this.outputDir), dependenciesToInstall);
      this.logger.info("Bundling Mastra application");
      const inputOptions = await this.getBundlerOptions(
        serverFile,
        mastraEntryFile,
        analyzedBundleInfo,
        toolsPaths,
        internalBundlerOptions
      );
      const bundler = await this.createBundler(
        {
          ...inputOptions,
          logLevel: inputOptions.logLevel === "silent" ? "warn" : inputOptions.logLevel,
          onwarn: (warning) => {
            if (warning.code === "CIRCULAR_DEPENDENCY") {
              if (warning.ids?.[0]?.includes("node_modules")) {
                return;
              }
              this.logger.warn("Circular dependency found", {
                dependency: warning.message.replace("Circular dependency: ", "")
              });
            }
          }
        },
        {
          dir: bundleLocation,
          manualChunks: {
            mastra: ["#mastra"]
          },
          sourcemap: internalBundlerOptions.enableSourcemap
        }
      );
      await bundler.write();
      const toolImports = [];
      const toolsExports = [];
      Array.from(Object.keys(inputOptions.input || {})).filter((key) => key.startsWith("tools/")).forEach((key, index) => {
        const toolExport = `tool${index}`;
        toolImports.push(`import * as ${toolExport} from './${key}.mjs';`);
        toolsExports.push(toolExport);
      });
      await promises.writeFile(
        path.join(bundleLocation, "tools.mjs"),
        `${toolImports.join("\n")}

export const tools = [${toolsExports.join(", ")}]`
      );
      this.logger.info("Bundling Mastra done");
      this.logger.info("Copying public files");
      await this.copyPublic(path.dirname(mastraEntryFile), outputDirectory);
      this.logger.info("Done copying public files");
      this.logger.info("Copying .npmrc file");
      await this.copyDOTNPMRC({ outputDirectory, rootDir: projectRoot });
      this.logger.info("Done copying .npmrc file");
      this.logger.info("Installing dependencies");
      await this.installDependencies(outputDirectory, projectRoot);
      this.logger.info("Done installing dependencies");
      this.logger.info("Generating package-lock.json for deploy");
      await this.generateNpmLockfile(path.join(outputDirectory, this.outputDir));
      this.logger.info("Done generating package-lock.json");
    } catch (error$1) {
      const message = error$1 instanceof Error ? error$1.message : String(error$1);
      throw new error.MastraError(
        {
          id: "DEPLOYER_BUNDLER_BUNDLE_STAGE_FAILED",
          text: `Failed during bundler bundle stage: ${message}`,
          domain: error.ErrorDomain.DEPLOYER,
          category: error.ErrorCategory.SYSTEM
        },
        error$1
      );
    }
  }
  async lint(_entryFile, _outputDirectory, toolsPaths) {
    const toolsInputOptions = await this.listToolsInputOptions(toolsPaths);
    const toolsLength = Object.keys(toolsInputOptions).length;
    if (toolsLength > 0) {
      this.logger.info("Found tools", { count: toolsLength });
    }
  }
};

exports.Bundler = Bundler;
exports.IS_DEFAULT = IS_DEFAULT;
//# sourceMappingURL=chunk-RJXYP6DA.cjs.map
//# sourceMappingURL=chunk-RJXYP6DA.cjs.map