"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// module.ts
var module_exports = {};
__export(module_exports, {
  default: () => RunEdgeExtension
});
module.exports = __toCommonJS(module_exports);

// steps/CreateWebSocketServer/index.ts
var import_path7 = __toESM(require("path"));

// steps/CreateWebSocketServer/webSocketServer/messageDispatcher.ts
var import_path = __toESM(require("path"));
var import_ws = __toESM(require("ws"));
var import_browser_extension_manifest_fields = __toESM(require("browser-extension-manifest-fields"));
function dispatchMessage(server, message) {
  server.clients.forEach((client) => {
    if (client.readyState === import_ws.default.OPEN) {
      client.send(JSON.stringify(message));
    }
  });
}
function messageDispatcher(server, options, updatedFile) {
  if (!updatedFile || !options.manifestPath)
    return;
  const manifestLocales = (0, import_browser_extension_manifest_fields.default)(options.manifestPath).locales;
  const manifestScripts = (0, import_browser_extension_manifest_fields.default)(options.manifestPath).scripts;
  const jsonScripts = (0, import_browser_extension_manifest_fields.default)(options.manifestPath).json;
  if (import_path.default.basename(updatedFile) === "manifest.json") {
    dispatchMessage(server, {
      changedFile: "manifest.json"
    });
  }
  manifestLocales?.forEach((path13) => {
    if (path13.includes(updatedFile)) {
      dispatchMessage(server, {
        changedFile: "_locales"
      });
    }
  });
  Object.entries(manifestScripts).forEach(([entryName, entryData]) => {
    const entryDataArr = Array.isArray(entryData) ? entryData : [entryData];
    const entryFiles = Object.values(entryDataArr).flatMap((arr) => arr);
    if (entryFiles.includes(updatedFile)) {
      if (entryName === "background/service_worker") {
        dispatchMessage(server, {
          changedFile: "service_worker"
        });
      }
    }
  });
  Object.entries(jsonScripts).forEach(([entryName, entryData]) => {
    if (entryData?.includes(updatedFile)) {
      if (entryName === "declarative_net_request") {
        dispatchMessage(server, {
          changedFile: "declarative_net_request"
        });
      }
    }
  });
}

// steps/CreateWebSocketServer/webSocketServer/startServer.ts
var import_ws2 = __toESM(require("ws"));

// helpers/messages.ts
var import_path3 = __toESM(require("path"));
var import_console = require("console");
var import_safe = require("@colors/colors/safe");
var import_prefers_yarn = __toESM(require("prefers-yarn"));

// steps/calculateDirSize.ts
var import_fs = __toESM(require("fs"));
var import_path2 = __toESM(require("path"));
function calculateDirectorySize(dirPath) {
  let totalSize = 0;
  const items = import_fs.default.readdirSync(dirPath);
  for (const item of items) {
    const fullPath = import_path2.default.join(dirPath, item);
    const stats = import_fs.default.statSync(fullPath);
    if (stats.isFile()) {
      totalSize += stats.size;
    } else if (stats.isDirectory()) {
      totalSize += calculateDirectorySize(fullPath);
    }
  }
  return totalSize;
}
function getDirectorySize(filepath) {
  const fileSizeInBytes = calculateDirectorySize(filepath);
  const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
  const sizeType = Math.floor(Math.log(fileSizeInBytes) / Math.log(1024));
  const size = (fileSizeInBytes / Math.pow(1024, sizeType)).toFixed(1);
  return `${size} ${sizes[sizeType]}`;
}

// helpers/messages.ts
function manifestFieldError(feature, htmlFilePath) {
  const hintMessage = `Check the ${(0, import_safe.bold)(
    feature
  )} field in your manifest.json file and try again.`;
  const errorMessage = `[manifest.json] File path ${(0, import_safe.underline)(
    htmlFilePath
  )} not found. ${hintMessage}`;
  return errorMessage;
}
function manifestNotFound() {
  (0, import_console.log)(`
${(0, import_safe.bold)("Error! Can't find the project's manifest file.")}

Check your extension ${(0, import_safe.yellow)(
    "manifest.json"
  )} file and ensure its path points to
one of the options above, and try again.
`);
}
function extensionData(compiler, message, isFirstRun3) {
  if (!message.data) {
    (0, import_console.error)(`[\u26D4\uFE0F] ${(0, import_safe.bgCyan)((0, import_safe.white)((0, import_safe.bold)(` edge-browser `)))} ${(0, import_safe.red)(
      "\u2716\uFE0E\u2716\uFE0E\u2716\uFE0E"
    )} No data received from client.

Ensure your extension is enabled and that no hanging Edge instance is open then try again.`);
    process.exit(1);
  }
  const compilerOptions = compiler.options;
  const { id, management } = message.data;
  if (!management) {
    if (process.env.EXTENSION_ENV === "development") {
      (0, import_console.error)(
        `[\u26D4\uFE0F] ${(0, import_safe.bgCyan)((0, import_safe.white)((0, import_safe.bold)(` edge-browser `)))} ${(0, import_safe.green)(
          "\u25BA\u25BA\u25BA"
        )} No management API info received from client. Investigate.`
      );
    }
  }
  const { name, description, version, hostPermissions, permissions } = management;
  const manifestPath = import_path3.default.join(compilerOptions.context || "", "manifest.json");
  const manifestFromCompiler = require(manifestPath);
  const permissionsBefore = manifestFromCompiler.permissions || [];
  const permissionsAfter = permissions || [];
  const permissionsParsed = permissionsAfter.map((permission) => {
    if (permissionsBefore.includes(permission))
      return permission;
    return `${permission} (dev only)`;
  });
  const fixedId = manifestFromCompiler.id === id;
  const hasHost = hostPermissions && hostPermissions.length;
  (0, import_console.log)("");
  (0, import_console.log)(`${(0, import_safe.bold)(`\u2022 Name:`)} ${name}`);
  description && (0, import_console.log)(`${(0, import_safe.bold)(`\u2022 Description:`)} ${description}`);
  (0, import_console.log)(`${(0, import_safe.bold)(`\u2022 Version:`)} ${version}`);
  (0, import_console.log)(
    `${(0, import_safe.bold)(`\u2022 Size:`)} ${getDirectorySize(
      compilerOptions.output.path || "dist"
    )}`
  );
  (0, import_console.log)(`${(0, import_safe.bold)(`\u2022 ID:`)} ${id} (${fixedId ? "fixed" : "dynamic"})`);
  hasHost && (0, import_console.log)(`${(0, import_safe.bold)(`\u2022 Host Permissions`)}: ${hostPermissions.sort().join(", ")}`);
  (0, import_console.log)(`${(0, import_safe.bold)(`\u2022 Permissions:`)} ${permissionsParsed.sort().join(", ")}`);
  (0, import_console.log)(
    `${(0, import_safe.bold)(`\u2022 Settings URL`)}: ${(0, import_safe.underline)(
      (0, import_safe.blue)(`edge://extensions/?id=${id}`)
    )}
`
  );
}
function stdoutData(compiler, message) {
  const compilerOptions = compiler.options;
  const management = message.data?.management;
  const edgeRuntime = (0, import_safe.bgCyan)((0, import_safe.white)((0, import_safe.bold)(` edge-browser `)));
  (0, import_console.log)(
    `${edgeRuntime} ${(0, import_safe.green)("\u25BA\u25BA\u25BA")} Running Edge in ${compilerOptions.mode} mode. Browser ${management?.type} ${management?.enabled ? "enabled" : "disabled"}.`
  );
}
function isFirstRun() {
  (0, import_console.log)("");
  (0, import_console.log)("This is your first run using extension-create. Welcome! \u{1F389}");
  (0, import_console.log)(
    `To start developing your extension, terminate this process and run ${(0, import_safe.bold)(
      (0, import_safe.blue)((0, import_prefers_yarn.default)() ? `yarn dev` : `npm run dev`)
    )}.`
  );
  (0, import_console.log)(
    `
\u{1F9E9} Learn more at ${(0, import_safe.blue)((0, import_safe.underline)(`https://docs.extensioncreate.com`))}`
  );
}
function watchModeClosed(code, reason) {
  const message = reason.toString();
  (0, import_console.log)(
    `[\u{1F613}] ${(0, import_safe.bgCyan)((0, import_safe.white)((0, import_safe.bold)(` edge-browser `)))} ${(0, import_safe.red)(
      "\u2716\uFE0E\u2716\uFE0E\u2716\uFE0E"
    )} Watch mode closed (code ${code}). ${message && "\n\nReason!!! " + message + "\n"}Exiting...
`
  );
}
function browserNotFound(edgePath) {
  (0, import_console.error)(
    `${(0, import_safe.bgCyan)((0, import_safe.white)((0, import_safe.bold)(` edge-browser `)))} ${(0, import_safe.red)(
      "\u2716\uFE0E\u2716\uFE0E\u2716\uFE0E"
    )} Edge not found at ${edgePath}`
  );
}
function webSocketError(error2) {
  error2(
    `[\u26D4\uFE0F] ${(0, import_safe.bgCyan)((0, import_safe.white)((0, import_safe.bold)(` edge-browser `)))} ${(0, import_safe.red)(
      "\u2716\uFE0E\u2716\uFE0E\u2716\uFE0E"
    )} WebSocket error`,
    error2
  );
}
function parseFileError(error2, filepath) {
  error2(
    `[\u26D4\uFE0F] ${(0, import_safe.bgCyan)((0, import_safe.white)((0, import_safe.bold)(` edge-browser `)))} ${(0, import_safe.red)(
      "\u2716\uFE0E\u2716\uFE0E\u2716\uFE0E"
    )} Error parsing file: ${filepath}. Reason: ${error2.message}`
  );
}
var messages_default = {
  manifestFieldError,
  manifestNotFound,
  extensionData,
  stdoutData,
  isFirstRun,
  watchModeClosed,
  browserNotFound,
  webSocketError,
  parseFileError
};

// steps/RunEdgePlugin/edge/isFirstRun.ts
var import_path4 = __toESM(require("path"));
var import_fs2 = __toESM(require("fs"));
function isFirstRun2() {
  return !import_fs2.default.existsSync(import_path4.default.resolve(__dirname, "run-edge-data-dir"));
}

// steps/CreateWebSocketServer/webSocketServer/startServer.ts
function startServer_default(compiler, statsConfig, port) {
  const webSocketServer = new import_ws2.default.Server({
    host: "localhost",
    port
  });
  const isUserFirstRun = isFirstRun2();
  webSocketServer.on("connection", (ws) => {
    ws.send(JSON.stringify({ status: "serverReady" }));
    ws.on("error", (error2) => {
      messages_default.webSocketError(error2);
      webSocketServer.close();
    });
    ws.on("close", (code, reason) => {
      if (!isUserFirstRun) {
        messages_default.watchModeClosed(code, reason);
      }
      webSocketServer.close();
    });
    ws.on("message", (msg) => {
      const message = JSON.parse(msg.toString());
      if (message.status === "clientReady") {
        if (statsConfig === true) {
          messages_default.extensionData(compiler, message, isUserFirstRun);
        }
        messages_default.stdoutData(compiler, message);
        if (statsConfig === true) {
          if (isUserFirstRun) {
            setTimeout(() => {
              messages_default.isFirstRun();
            }, 2500);
          }
        }
      }
    });
  });
  return webSocketServer;
}

// steps/CreateWebSocketServer/rewriteReloadPort.ts
var import_path5 = __toESM(require("path"));
var import_fs3 = __toESM(require("fs"));
function replacePortInFile(port) {
  const filePath = import_path5.default.resolve(
    __dirname,
    "./extensions/manager-extension/tools/reloadService.js"
  );
  import_fs3.default.readFile(filePath, "utf8", (err, data) => {
    if (err) {
      console.error(`Error reading file: ${err.message}`);
      return;
    }
    const updatedData = data.replace(/__RELOAD_PORT__/g, port.toString());
    import_fs3.default.writeFile(filePath, updatedData, "utf8", (err2) => {
      if (err2) {
        console.error(`Error writing to file: ${err2.message}`);
      }
    });
  });
}

// steps/CreateWebSocketServer/rewriteFirstRunVariable.ts
var import_path6 = __toESM(require("path"));
var import_fs4 = __toESM(require("fs"));
function rewriteFirstRunVariable() {
  const firstRun = isFirstRun2();
  const filePath = import_path6.default.resolve(
    __dirname,
    "./extensions/manager-extension/tools/initialTab.js"
  );
  import_fs4.default.readFile(filePath, "utf8", (err, data) => {
    if (err) {
      console.error(`Error reading file: ${err.message}`);
      return;
    }
    const updatedData = data.replace(
      /__IS_FIRST_RUN__ = false/g,
      `__IS_FIRST_RUN__ = ${firstRun}`.toString()
    );
    import_fs4.default.writeFile(filePath, updatedData, "utf8", (err2) => {
      if (err2) {
        console.error(`Error writing to file: ${err2.message}`);
      }
    });
  });
}

// steps/CreateWebSocketServer/index.ts
var CreateWebSocketServer = class {
  options;
  constructor(options) {
    this.options = options;
  }
  apply(compiler) {
    if (!this.options.manifestPath)
      return;
    replacePortInFile(this.options.port || 8001);
    rewriteFirstRunVariable();
    const statConfig = this.options.stats;
    const wss = startServer_default(compiler, statConfig, this.options.port);
    compiler.hooks.watchRun.tapAsync(
      "RunEdgeExtensionPlugin (CreateWebSocketServer)",
      (compiler2, done) => {
        const files = compiler2.modifiedFiles || /* @__PURE__ */ new Set();
        const changedFile = files.values().next().value;
        if (!changedFile) {
          done();
          return;
        }
        const relativePath = import_path7.default.relative(
          import_path7.default.dirname(this.options.manifestPath || ""),
          changedFile
        );
        const context = import_path7.default.relative(process.cwd(), import_path7.default.dirname(changedFile));
        if (process.env.EXTENSION_ENV === "development") {
          console.info(
            `\u25BA\u25BA Updated file \`${relativePath}\` (relative to ${context})`
          );
        }
        if (this.options.manifestPath) {
          messageDispatcher(wss, this.options, changedFile);
        }
        done();
      }
    );
  }
};

// steps/SetupReloadStrategy/ApplyManifestDevDefaults/index.ts
var import_webpack = require("webpack");

// steps/SetupReloadStrategy/ApplyManifestDevDefaults/patchCSP.ts
var import_content_security_policy_parser = __toESM(require("content-security-policy-parser"));
function patchV2CSP(manifest) {
  let policy = manifest.content_security_policy;
  if (!policy) {
    return "script-src 'self' 'unsafe-eval' blob: filesystem:; object-src 'self' blob: filesystem:; ";
  }
  const csp = (0, import_content_security_policy_parser.default)(policy);
  policy = "";
  if (!csp["script-src"]) {
    csp["script-src"] = ["'self' 'unsafe-eval' blob: filesystem:"];
  }
  if (!csp["script-src"].includes("'unsafe-eval'")) {
    csp["script-src"].push("'unsafe-eval'");
  }
  for (const k in csp) {
    policy += `${k} ${csp[k].join(" ")};`;
  }
  return policy;
}
function patchV3CSP(manifest) {
  const policy = manifest.content_security_policy;
  if (!policy) {
    return {
      extension_pages: "script-src 'self'; object-src 'self'; "
    };
  }
  const csp = (0, import_content_security_policy_parser.default)(policy.extension_pages);
  let extensionPagesPolicy = "";
  for (const directive in csp) {
    extensionPagesPolicy += `${directive} ${csp[directive].join(" ")}; `;
  }
  return {
    extension_pages: extensionPagesPolicy.trim()
  };
}

// steps/SetupReloadStrategy/ApplyManifestDevDefaults/patchWebResources.ts
function patchWebResourcesV2(manifest) {
  const defaultResources = ["/*.json", "/*.js", "/*.css"];
  const resources = manifest.web_accessible_resources;
  if (!resources || resources.length === 0) {
    return defaultResources;
  }
  const webResources = new Set(resources);
  for (const resource of defaultResources) {
    webResources.add(resource);
  }
  return Array.from(webResources);
}
function patchWebResourcesV3(manifest) {
  const defaultResources = ["/*.json", "/*.js", "/*.css"];
  const resources = manifest.web_accessible_resources;
  if (!resources || resources.length === 0) {
    return [
      {
        resources: defaultResources,
        matches: ["<all_urls>"]
      }
    ];
  }
  const updatedResources = resources.map((entry) => {
    const resourceSet = new Set(entry.resources);
    defaultResources.forEach((resource) => {
      if (entry && entry.resources) {
        if (!entry.resources.includes(resource)) {
          resourceSet.add(resource);
        }
      }
    });
    return { ...entry, resources: Array.from(resourceSet) };
  });
  return updatedResources;
}

// steps/SetupReloadStrategy/ApplyManifestDevDefaults/patchBackground.ts
function patchBackground(manifest) {
  if (!manifest.background) {
    if (manifest.manifest_version === 2) {
      return {
        background: {
          ...manifest.background,
          scripts: ["background/script.js"]
        }
      };
    }
    return {
      background: {
        ...manifest.background,
        service_worker: "background/service_worker.js"
      }
    };
  }
  return {
    background: {
      ...manifest.background
    }
  };
}

// steps/SetupReloadStrategy/ApplyManifestDevDefaults/patchExternallyConnectable.ts
function patchExternallyConnectable(manifest) {
  if (manifest.externally_connectable && !manifest.externally_connectable.ids) {
    return {
      externally_connectable: {
        ...manifest.externally_connectable,
        ids: [
          ...new Set(manifest.externally_connectable.ids || []),
          "*"
        ]
      }
    };
  }
  if (manifest.externally_connectable && !manifest.externally_connectable.ids) {
    return {
      externally_connectable: {
        ...manifest.externally_connectable,
        ids: ["*"]
      }
    };
  }
  return {};
}

// helpers/utils.ts
function getManifestContent(compilation, manifestPath) {
  if (compilation.getAsset("manifest.json") || compilation.assets["manifest.json"]) {
    const manifest = compilation.assets["manifest.json"].source().toString();
    return JSON.parse(manifest || "{}");
  }
  return require(manifestPath);
}

// steps/SetupReloadStrategy/ApplyManifestDevDefaults/index.ts
var ApplyManifestDevDefaultsPlugin = class {
  manifestPath;
  constructor(options) {
    this.manifestPath = options.manifestPath;
  }
  generateManifestPatches(compilation) {
    const manifest = getManifestContent(compilation, this.manifestPath);
    const patchedManifest = {
      // Preserve all other user entries
      ...manifest,
      // Allow usig source map based on eval, using Manifest V2.
      // script-src 'self' 'unsafe-eval';
      // See https://github.com/awesome-webextension/webpack-target-webextension#source-map.
      // For V3, see https://developer.chrome.com/docs/extensions/migrating/improve-security/#update-csp
      content_security_policy: manifest.manifest_version === 3 ? patchV3CSP(manifest) : patchV2CSP(manifest),
      // Set permission scripting as it's required for reload to work
      // with content scripts in v3. See:
      // https://github.com/awesome-webextension/webpack-target-webextension#content-script
      ...manifest.manifest_version === 3 ? manifest.permissions ? { permissions: [.../* @__PURE__ */ new Set(["scripting", ...manifest.permissions])] } : { permissions: ["scripting"] } : (
        // : {permissions: []}
        {}
      ),
      // Use the background script to inject the reload handler.
      ...patchBackground(manifest),
      // A misuse of external_connectable can break communication
      // across extension reloads, so we ensure that the extension
      // is externally connectable to all other extensions.
      ...patchExternallyConnectable(manifest),
      // We need to allow /*.json', '/*.js', '/*.css to be able to load
      // the reload script and the reload handler assets.
      web_accessible_resources: manifest.manifest_version === 3 ? patchWebResourcesV3(manifest) : patchWebResourcesV2(manifest)
    };
    const source = JSON.stringify(patchedManifest, null, 2);
    const rawSource = new import_webpack.sources.RawSource(source);
    if (compilation.getAsset("manifest.json")) {
      compilation.updateAsset("manifest.json", rawSource);
    }
  }
  apply(compiler) {
    compiler.hooks.thisCompilation.tap(
      "RunChromeExtension (ApplyManifestDevDefaults)",
      (compilation) => {
        const Error2 = compiler.webpack.WebpackError;
        compilation.hooks.processAssets.tap(
          {
            name: "RunChromeExtension (ApplyManifestDevDefaults)",
            // Summarize the list of existing assets.
            stage: import_webpack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
          },
          (_assets) => {
            if (!this.manifestPath) {
              const errorMessage = "No manifest.json found in your extension bundle. Unable to patch manifest.json.";
              if (!!compilation && !!Error2) {
                compilation.errors.push(
                  new Error2(
                    `[RunChromeExtension (ApplyManifestDevDefaults)]: ${errorMessage}`
                  )
                );
              }
              return;
            }
            this.generateManifestPatches(compilation);
          }
        );
      }
    );
  }
};
var ApplyManifestDevDefaults_default = ApplyManifestDevDefaultsPlugin;

// steps/SetupReloadStrategy/TargetWebExtensionPlugin/index.ts
var import_fs5 = __toESM(require("fs"));
var import_path8 = __toESM(require("path"));
var import_webpack_target_webextension = __toESM(require("webpack-target-webextension"));
var import_safe2 = require("@colors/colors/safe");
var TargetWebExtensionPlugin = class {
  manifestPath;
  constructor(options) {
    this.manifestPath = options.manifestPath;
  }
  handleMissingBackground(manifest) {
    if (manifest.manifest_version === 3) {
      if (manifest.background.service_worker) {
        const serviceWorker = manifest.background.service_worker;
        const serviceWorkerPath = import_path8.default.join(
          import_path8.default.dirname(this.manifestPath),
          serviceWorker
        );
        if (!import_fs5.default.existsSync(serviceWorkerPath)) {
          const fieldError = messages_default.manifestFieldError(
            "background.service_worker",
            serviceWorkerPath
          );
          console.error((0, import_safe2.red)((0, import_safe2.bold)(fieldError)));
          process.exit(1);
        }
      }
    }
    if (manifest.background.scripts) {
      const backgroundScripts = manifest.background.scripts;
      const backgroundPath = import_path8.default.join(
        import_path8.default.dirname(this.manifestPath),
        backgroundScripts[0]
      );
      if (!import_fs5.default.existsSync(backgroundPath)) {
        const fieldError = messages_default.manifestFieldError(
          "background.scripts",
          backgroundPath
        );
        throw Error(fieldError);
      }
    }
  }
  getEntryName(manifestPath) {
    const manifest = require(manifestPath);
    if (manifest.background) {
      if (manifest.manifest_version === 3) {
        return { serviceWorkerEntry: "background/service_worker" };
      }
      if (manifest.manifest_version === 2) {
        return { pageEntry: "background/script" };
      }
    }
    return { pageEntry: "background" };
  }
  apply(compiler) {
    if (!this.manifestPath || !import_fs5.default.lstatSync(this.manifestPath).isFile()) {
      return;
    }
    const manifest = require(this.manifestPath);
    if (manifest.background) {
      this.handleMissingBackground(manifest);
    }
    new import_webpack_target_webextension.default({
      background: this.getEntryName(this.manifestPath),
      weakRuntimeCheck: true
    }).apply(compiler);
  }
};
var TargetWebExtensionPlugin_default = TargetWebExtensionPlugin;

// steps/SetupReloadStrategy/AddRuntimeListener.ts
var import_path9 = __toESM(require("path"));
function AddRuntimeListener(compiler, manifestPath) {
  compiler.options.module.rules.push({
    test: /\.(t|j)sx?$/,
    use: [
      {
        loader: import_path9.default.resolve(
          __dirname,
          "./loaders/InjectBackgroundRuntimeLoader"
        ),
        options: {
          manifestPath
        }
      }
    ]
  });
}

// steps/SetupReloadStrategy/index.ts
var SetupReloadStrategy = class {
  manifestPath;
  constructor(options) {
    this.manifestPath = options.manifestPath;
  }
  apply(compiler) {
    AddRuntimeListener(compiler, this.manifestPath);
    new ApplyManifestDevDefaults_default({
      manifestPath: this.manifestPath
    }).apply(compiler);
    new TargetWebExtensionPlugin_default({
      manifestPath: this.manifestPath
    }).apply(compiler);
  }
};
var SetupReloadStrategy_default = SetupReloadStrategy;

// steps/RunEdgePlugin/index.ts
var import_fs7 = __toESM(require("fs"));
var import_path12 = __toESM(require("path"));
var import_child_process = require("child_process");
var import_safe4 = require("@colors/colors/safe");
var import_edge_location = __toESM(require("edge-location"));

// steps/RunEdgePlugin/edge/browser.config.ts
var import_path11 = __toESM(require("path"));

// steps/RunEdgePlugin/edge/createUserDataDir.ts
var import_path10 = __toESM(require("path"));
var import_fs6 = __toESM(require("fs"));
var import_safe3 = require("@colors/colors/safe");

// helpers/addProgressBar.ts
var import_progress = __toESM(require("progress"));
function addProgressBar(text, completionCallback) {
  const contentLength = 128 * 1024;
  const bar = new import_progress.default(`${text} [:bar] :percent :etas`, {
    complete: "=",
    incomplete: " ",
    width: 50,
    total: contentLength
  });
  const timer = setInterval(() => {
    const chunk = Math.random() * 10 * 1024;
    bar.tick(chunk);
    if (bar.complete) {
      clearInterval(timer);
      completionCallback();
    }
  }, 50);
}

// steps/RunEdgePlugin/edge/masterPreferences.ts
var masterPreferences = {
  alternate_error_pages: {
    enabled: false
  },
  autofill: {
    enabled: false
  },
  browser: {
    // Boolean that indicates whether we should check if we are the default browser
    // on start-up.
    check_default_browser: false,
    // Policy setting whether default browser check should be disabled and default
    // browser registration should take place.
    default_browser_setting_enabled: false
  },
  // A string property indicating whether default apps should be installed
  // in this profile.  Use the value "install" to enable defaults apps, or
  // "noinstall" to disable them.  This property is usually set in the
  // master_preferences and copied into the profile preferences on first run.
  // Defaults apps are installed only when creating a new profile.
  default_apps: "install",
  distribution: {
    // Boolean. Use alternate text for the shortcut. Cmd line override present.
    alternate_shortcut_text: false,
    // Boolean. Whether to instruct the installer to auto-launch edge on computer
    // startup. The default (if not provided) is |false|.
    auto_launch_chrome: false,
    // Boolean pref that disables all logging.
    //  disable_logging: true,
    // Boolean pref that triggers silent import of the default browser bookmarks.
    import_bookmarks: false,
    // Boolean pref that triggers silent import of the default browser history.
    import_history: false,
    // Boolean pref that triggers silent import of the default browser homepage.
    import_home_page: false,
    // Boolean pref that triggers silent import of the default search engine.
    import_search_engine: false,
    // Boolean. Do not show first run bubble, even if it would otherwise be shown.
    suppress_first_run_bubble: true,
    // Boolean. Do not launch Edge after first install. Cmd line override present.
    // "do_not_launch_chrome": true,
    // Boolean. Do not register with Google Update to have Edge launched after
    // install. Cmd line override present.
    do_not_register_for_update_launch: true,
    // Boolean. Register Edge as default browser. Cmd line override present.
    make_chrome_default: false,
    // Boolean. Register Edge as default browser for the current user.
    make_chrome_default_for_user: false,
    // Boolean. Expect to be run by an MSI installer. Cmd line override present.
    //  msi: true,
    // Boolean. Show EULA dialog before install.
    require_eula: false,
    // Boolean. Indicates that the first-run 'set-as-default' dialog should not be
    // shown. Relevant in Windows 8+ context only. If this is true, the standard
    // 'set default browser' prompt on the butter-bar will appear during the first
    // run.
    suppress_first_run_default_browser_prompt: true
  },
  dns_prefetching: {
    enabled: false
  },
  download: {
    // The default directory to save downloaded files to. This is only used if
    // the user does not select a directory for a download. It is recommended
    // that you use this in conjunction with "prompt_for_download" to ensure
    // that users are always prompted for a download location.
    default_directory: "/tmp/",
    // Whether to prompt for download location for each file download.
    directory_upgrade: true,
    // Whether downloaded PDFs should be opened in Adobe Acrobat Reader.
    open_pdf_in_adobe_reader: false,
    // Whether to prompt for download location for each file download.
    prompt_for_download: true
  },
  enable_do_not_track: true,
  extensions: {
    theme: {
      use_system: false
    },
    toolbarsize: -1,
    ui: {
      developer_mode: true
    }
  },
  plugins: {
    plugins_list: [
      {
        enabled: false,
        name: "Java(TM)"
      }
    ],
    show_details: true
  },
  profile: {
    password_manager_enabled: false
  },
  safebrowsing: {
    // Boolean that is true when SafeBrowsing is enabled.
    enabled: false,
    // Boolean that tell us whether malicious download feedback is enabled.
    safebrowsingextended_reporting_enabled: false
  },
  savefile: {
    default_directory: "/tmp",
    // Whether to prompt for download location for each file download.
    type: 0
  },
  search: {
    // Boolean that is true when Suggest support is enabled.
    suggest_enabled: false
  },
  session: {
    // An integer pref. Holds one of several values:
    // 0: (deprecated) open the homepage on startup.
    // 1: restore the last session.
    // 2: this was used to indicate a specific session should be restored. It is
    //    no longer used, but saved to avoid conflict with old preferences.
    // 3: unused, previously indicated the user wants to restore a saved session.
    // 4: restore the URLs defined in kURLsToRestoreOnStartup.
    // 5: open the New Tab Page on startup.
    restore_on_startup: 1
  },
  sync: {
    suppress_start: true
  },
  sync_promo: {
    // Boolean that specifies if the sign in promo is allowed to show on first run.
    // This preference is specified in the master preference file to suppress the
    // sign in promo for some installations.
    show_on_first_run_allowed: false,
    // Boolean that specifies if we should show a bubble in the new tab page.
    // The bubble is used to confirm that the user is signed into sync.
    show_ntp_bubble: false
  },
  translate: {
    enabled: false
  }
};
var masterPreferences_default = masterPreferences;

// steps/RunEdgePlugin/edge/createUserDataDir.ts
function createUserDataDir(dataDirPath, silent) {
  if (dataDirPath || import_fs6.default.existsSync(import_path10.default.resolve(__dirname, "run-edge-data-dir"))) {
    return dataDirPath || import_path10.default.resolve(__dirname, "run-edge-data-dir");
  }
  const userProfile = JSON.stringify(masterPreferences_default);
  if (!silent) {
    addProgressBar(`\u{1F464} Creating ${(0, import_safe3.bold)("Edge")} user data directory...`, () => {
      const outputPath = import_path10.default.resolve(__dirname, "run-edge-data-dir");
      const preferences = import_path10.default.join(outputPath, "Default");
      import_fs6.default.mkdirSync(preferences, { recursive: true });
      const preferencesPath = import_path10.default.join(preferences, "Preferences");
      import_fs6.default.writeFileSync(preferencesPath, userProfile, "utf8");
    });
  }
  return import_path10.default.resolve(__dirname, "run-edge-data-dir");
}

// steps/RunEdgePlugin/edge/browser.config.ts
var managerExtension = import_path11.default.resolve(
  __dirname,
  "extensions",
  "manager-extension"
);
var reloadExtension = import_path11.default.resolve(
  __dirname,
  "extensions",
  "reload-extension"
);
function browserConfig(configOptions) {
  const userBrowserExtension = configOptions.extensionPath?.replace(
    "manifest.json",
    ""
  );
  const extensionsToLoad = [`"${userBrowserExtension}"`, managerExtension];
  if (configOptions.autoReload) {
    extensionsToLoad.push(reloadExtension);
  }
  return [
    `--load-extension=${extensionsToLoad.join()}`,
    `--user-data-dir=${createUserDataDir(configOptions.userDataDir)}`,
    // Disable Edge's native first run experience.
    "--no-first-run",
    // Flags to pass to Edge
    // Any of http://peter.sh/experiments/chromium-command-line-switches/
    ...configOptions.browserFlags || []
  ].join(" ");
}

// steps/RunEdgePlugin/index.ts
process.on("SIGINT", () => {
  process.exit();
});
process.on("SIGTERM", () => {
  process.exit();
});
var EdgeExtensionLauncherPlugin = class {
  options;
  constructor(options) {
    this.options = options;
  }
  launchEdge() {
    const msEdge = (0, import_edge_location.default)();
    const edgeLaunchPath = this.options.startingUrl ? `"${msEdge}" "${this.options.startingUrl}"` : `"${msEdge}"`;
    if (!import_fs7.default.existsSync(import_path12.default.resolve(msEdge))) {
      console.error(
        `${(0, import_safe4.bgCyan)((0, import_safe4.white)((0, import_safe4.bold)(` edge-browser `)))} ${(0, import_safe4.red)(
          `\u2716\uFE0E\u2716\uFE0E\u2716\uFE0E`
        )} Edge not found at ${msEdge}`
      );
      process.exit();
    }
    if (!import_fs7.default.existsSync(msEdge) || "") {
      console.error(
        `${(0, import_safe4.bgCyan)((0, import_safe4.white)((0, import_safe4.bold)(` edge-browser `)))} ${(0, import_safe4.red)(`\u2716\uFE0E\u2716\uFE0E\u2716\uFE0E`)} Chrome browser ${typeof chrome === "undefined" ? "is not installed." : `is not found at ${msEdge}`}. Either install Edge or choose a different browser via ${(0, import_safe4.blue)("--browser")}.`
      );
      process.exit();
    }
    const edgeConfig = browserConfig(this.options);
    const cmd = `${edgeLaunchPath} ${edgeConfig}`;
    const child = (0, import_child_process.exec)(cmd, (error2, _stdout, stderr) => {
      if (error2 != null)
        throw error2;
      if (stderr.includes("Unable to move the cache")) {
        console.log(
          `${(0, import_safe4.bgCyan)((0, import_safe4.white)((0, import_safe4.bold)(` edge-browser `)))} ${(0, import_safe4.green)(
            `\u25BA\u25BA\u25BA`
          )} Edge instance already running.`
        );
      } else {
        console.log(
          `${(0, import_safe4.bgCyan)((0, import_safe4.white)((0, import_safe4.bold)(` edge-browser `)))} ${(0, import_safe4.green)(
            `\u25BA\u25BA\u25BA`
          )} Edge instance exited.`
        );
        process.exit();
      }
    });
    if (process.env.EXTENSION_ENV === "development") {
      child.stdout?.pipe(process.stdout);
      child.stderr?.pipe(process.stderr);
    }
  }
  apply(compiler) {
    let edgeDidLaunch = false;
    compiler.hooks.afterEmit.tapAsync(
      "RunEdgeExtensionPlugin (EdgeExtensionLauncher)",
      (compilation, done) => {
        if (compilation.errors.length > 0) {
          done();
          return;
        }
        if (edgeDidLaunch) {
          done();
          return;
        }
        this.launchEdge();
        edgeDidLaunch = true;
        done();
      }
    );
  }
};

// module.ts
var RunEdgeExtension = class {
  options;
  constructor(options) {
    this.options = {
      manifestPath: options.manifestPath,
      extensionPath: options.extensionPath,
      port: options.port || 8001,
      browserFlags: options.browserFlags || [],
      userDataDir: options.userDataDir,
      startingUrl: options.startingUrl,
      autoReload: options.autoReload != null ? options.autoReload : true,
      stats: options.stats != null ? options.stats : true
    };
  }
  /**
   * RunEdgeExtension works by creating a WebSockets server
   * that listens to changes triggered by the user extension
   * via webpack. When a change is detected, the server sends
   * a message to an extension called reload-extension, which
   * is injected into the browser. This extension is responsible
   * for sending messages to the user extension. We do that by
   * injecting a script into the background page that listens
   * to messages from the reload-extension. The HMR part is
   * done by webpack-target-webextension, which patches the
   * manifest file and modifies the background script to accept
   * both extension runtime updates (service_worker, manifest.json)
   * and HMR updates (background, content scripts).
   *
   * Features supported:
   * - HTML from the manifest file (action, options_ui, etc) - HMR enabled
   * - CSS/JS from the HTML file - HMR enabled
   * - Changes in assets from an HTML file - HMR enabled
   * - Background script - HMR enabled
   * - Content scripts (js) - HMR enabled
   * - Content scripts (css) - HMR enabled
   * - Context Menu (API) - Full extension reload (chrome.runtime.reload)
   * - declarative_net_request (API) - Full extension reload (chrome.runtime.reload)
   * - _locales - Full extension reload (chrome.runtime.reload)
   * - Service worker - Full extension reload (chrome.runtime.reload)
   * - manifest.json - Full extension reload (chrome.runtime.reload)
   */
  apply(compiler) {
    new CreateWebSocketServer(this.options).apply(compiler);
    new SetupReloadStrategy_default(this.options).apply(compiler);
    new EdgeExtensionLauncherPlugin(this.options).apply(compiler);
  }
};
