import {
  consumeTypes,
  generateTypesInChildProcess,
  rpc_exports
} from "./chunk-LHN7ASHT.js";
import {
  cloneDeepOptions,
  generateTypes,
  isTSProject,
  retrieveTypesAssetsInfo,
  validateOptions
} from "./chunk-ZU4UW7EP.js";
import {
  getIPV4,
  logger
} from "./chunk-KCWHOFI6.js";
import {
  WEB_CLIENT_OPTIONS_IDENTIFIER,
  __async,
  __name,
  __publicField,
  __spreadProps,
  __spreadValues
} from "./chunk-4CSLH7II.js";

// packages/dts-plugin/src/plugins/DevPlugin.ts
import fs from "fs-extra";
import path4 from "path";

// packages/dts-plugin/src/dev-worker/createDevWorker.ts
import * as path2 from "path";
import * as fse from "fs-extra";

// packages/dts-plugin/src/dev-worker/DevWorker.ts
import path from "path";
var _DevWorker = class _DevWorker {
  constructor(options) {
    __publicField(this, "_rpcWorker");
    __publicField(this, "_options");
    __publicField(this, "_res");
    this._options = cloneDeepOptions(options);
    this.removeUnSerializationOptions();
    this._rpcWorker = rpc_exports.createRpcWorker(path.resolve(__dirname, "./fork-dev-worker.js"), {}, void 0, false);
    this._res = this._rpcWorker.connect(this._options);
  }
  // moduleFederationConfig.manifest may have un serialization options
  removeUnSerializationOptions() {
    var _a, _b, _c, _d;
    (_b = (_a = this._options.host) == null ? void 0 : _a.moduleFederationConfig) == null ? true : delete _b.manifest;
    (_d = (_c = this._options.remote) == null ? void 0 : _c.moduleFederationConfig) == null ? true : delete _d.manifest;
  }
  get controlledPromise() {
    return this._res;
  }
  update() {
    var _a, _b;
    (_b = (_a = this._rpcWorker.process) == null ? void 0 : _a.send) == null ? void 0 : _b.call(_a, {
      type: rpc_exports.RpcGMCallTypes.CALL,
      id: this._rpcWorker.id,
      args: [
        void 0,
        "update"
      ]
    });
  }
  exit() {
    var _a;
    (_a = this._rpcWorker) == null ? void 0 : _a.terminate();
  }
};
__name(_DevWorker, "DevWorker");
var DevWorker = _DevWorker;

// packages/dts-plugin/src/dev-worker/createDevWorker.ts
function removeLogFile() {
  return __async(this, null, function* () {
    try {
      const logDir = path2.resolve(process.cwd(), ".mf/typesGenerate.log");
      yield fse.remove(logDir);
    } catch (err) {
      console.error("removeLogFile error", "forkDevWorker", err);
    }
  });
}
__name(removeLogFile, "removeLogFile");
function createDevWorker(options) {
  removeLogFile();
  return new DevWorker(__spreadValues({}, options));
}
__name(createDevWorker, "createDevWorker");

// packages/dts-plugin/src/plugins/DevPlugin.ts
import { normalizeOptions, TEMP_DIR as BasicTempDir } from "@module-federation/sdk";

// packages/dts-plugin/src/plugins/utils.ts
import path3 from "path";
function isDev() {
  return process.env["NODE_ENV"] === "development";
}
__name(isDev, "isDev");
function isPrd() {
  return process.env["NODE_ENV"] === "production";
}
__name(isPrd, "isPrd");
function getCompilerOutputDir(compiler) {
  try {
    return path3.relative(compiler.context, compiler.outputPath || compiler.options.output.path);
  } catch (err) {
    return "";
  }
}
__name(getCompilerOutputDir, "getCompilerOutputDir");

// packages/dts-plugin/src/plugins/DevPlugin.ts
var PROCESS_EXIT_CODE;
(function(PROCESS_EXIT_CODE2) {
  PROCESS_EXIT_CODE2[PROCESS_EXIT_CODE2["SUCCESS"] = 0] = "SUCCESS";
  PROCESS_EXIT_CODE2[PROCESS_EXIT_CODE2["FAILURE"] = 1] = "FAILURE";
})(PROCESS_EXIT_CODE || (PROCESS_EXIT_CODE = {}));
function ensureTempDir(filePath) {
  try {
    const dir = path4.dirname(filePath);
    fs.ensureDirSync(dir);
  } catch (_err) {
  }
}
__name(ensureTempDir, "ensureTempDir");
var _DevPlugin = class _DevPlugin {
  constructor(options, dtsOptions, generateTypesPromise, fetchRemoteTypeUrlsPromise) {
    __publicField(this, "name", "MFDevPlugin");
    __publicField(this, "_options");
    __publicField(this, "_devWorker");
    __publicField(this, "dtsOptions");
    __publicField(this, "generateTypesPromise");
    __publicField(this, "fetchRemoteTypeUrlsPromise");
    this._options = options;
    this.generateTypesPromise = generateTypesPromise;
    this.dtsOptions = dtsOptions;
    this.fetchRemoteTypeUrlsPromise = fetchRemoteTypeUrlsPromise;
  }
  static ensureLiveReloadEntry(options, filePath) {
    ensureTempDir(filePath);
    const liveReloadEntry = fs.readFileSync(path4.join(__dirname, "./iife/launch-web-client.js")).toString("utf-8");
    const liveReloadEntryWithOptions = liveReloadEntry.replace(WEB_CLIENT_OPTIONS_IDENTIFIER, JSON.stringify(options));
    fs.writeFileSync(filePath, liveReloadEntryWithOptions);
  }
  _stopWhenSIGTERMOrSIGINT() {
    process.on("SIGTERM", () => {
      logger.info(`${this._options.name} Process(${process.pid}) SIGTERM, mf server will exit...`);
      this._exit(0);
    });
    process.on("SIGINT", () => {
      logger.info(`${this._options.name} Process(${process.pid}) SIGINT, mf server will exit...`);
      this._exit(0);
    });
  }
  _handleUnexpectedExit() {
    process.on("unhandledRejection", (error) => {
      logger.error(error);
      logger.error(`Process(${process.pid}) unhandledRejection, mf server will exit...`);
      this._exit(1);
    });
    process.on("uncaughtException", (error) => {
      logger.error(error);
      logger.error(`Process(${process.pid}) uncaughtException, mf server will exit...`);
      this._exit(1);
    });
  }
  _exit(exitCode = 0) {
    var _a;
    (_a = this._devWorker) == null ? void 0 : _a.exit();
    process.exit(exitCode);
  }
  _afterEmit() {
    var _a;
    (_a = this._devWorker) == null ? void 0 : _a.update();
  }
  apply(compiler) {
    var _a;
    const { _options: { name, dev, dts } } = this;
    new compiler.webpack.DefinePlugin({
      FEDERATION_IPV4: JSON.stringify(getIPV4())
    }).apply(compiler);
    const normalizedDev = normalizeOptions(true, {
      disableLiveReload: true,
      disableHotTypesReload: false,
      disableDynamicRemoteTypeHints: false
    }, "mfOptions.dev")(dev);
    if (!isDev() || normalizedDev === false) {
      return;
    }
    if (normalizedDev.disableHotTypesReload && normalizedDev.disableLiveReload && normalizedDev.disableDynamicRemoteTypeHints) {
      return;
    }
    if (!name) {
      throw new Error("name is required if you want to enable dev server!");
    }
    if (!normalizedDev.disableDynamicRemoteTypeHints) {
      if (!this._options.runtimePlugins) {
        this._options.runtimePlugins = [];
      }
      this._options.runtimePlugins.push(path4.resolve(__dirname, "dynamic-remote-type-hints-plugin.js"));
    }
    if (!normalizedDev.disableLiveReload) {
      const TEMP_DIR = path4.join(`${process.cwd()}/node_modules`, BasicTempDir);
      const filepath = path4.join(TEMP_DIR, `live-reload.js`);
      if (typeof compiler.options.entry === "object") {
        _DevPlugin.ensureLiveReloadEntry({
          name
        }, filepath);
        Object.keys(compiler.options.entry).forEach((entry) => {
          const normalizedEntry = compiler.options.entry[entry];
          if (typeof normalizedEntry === "object" && Array.isArray(normalizedEntry.import)) {
            normalizedEntry.import.unshift(filepath);
          }
        });
      }
    }
    const defaultGenerateTypes = {
      compileInChildProcess: true
    };
    const defaultConsumeTypes = {
      consumeAPITypes: true
    };
    const normalizedDtsOptions = normalizeOptions(isTSProject(dts, compiler.context), {
      //  remote types dist(.dev-server) not be used currently, so no need to set extractThirdParty etc
      generateTypes: defaultGenerateTypes,
      consumeTypes: defaultConsumeTypes,
      extraOptions: {},
      displayErrorInTerminal: (_a = this.dtsOptions) == null ? void 0 : _a.displayErrorInTerminal
    }, "mfOptions.dts")(dts);
    const normalizedGenerateTypes = normalizeOptions(Boolean(normalizedDtsOptions), defaultGenerateTypes, "mfOptions.dts.generateTypes")(normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.generateTypes);
    const remote = normalizedGenerateTypes === false ? void 0 : __spreadProps(__spreadValues({
      implementation: normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.implementation,
      context: compiler.context,
      outputDir: getCompilerOutputDir(compiler),
      moduleFederationConfig: __spreadValues({}, this._options),
      hostRemoteTypesFolder: normalizedGenerateTypes.typesFolder || "@mf-types"
    }, normalizedGenerateTypes), {
      typesFolder: `.dev-server`
    });
    const normalizedConsumeTypes = normalizeOptions(Boolean(normalizedDtsOptions), defaultConsumeTypes, "mfOptions.dts.consumeTypes")(normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.consumeTypes);
    const host = normalizedConsumeTypes === false ? void 0 : __spreadValues({
      implementation: normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.implementation,
      context: compiler.context,
      moduleFederationConfig: this._options,
      typesFolder: normalizedConsumeTypes.typesFolder || "@mf-types",
      abortOnError: false
    }, normalizedConsumeTypes);
    const extraOptions = normalizedDtsOptions ? normalizedDtsOptions.extraOptions || {} : {};
    if (!remote && !host && normalizedDev.disableLiveReload) {
      return;
    }
    if (remote && !(remote == null ? void 0 : remote.tsConfigPath) && typeof normalizedDtsOptions === "object" && normalizedDtsOptions.tsConfigPath) {
      remote.tsConfigPath = normalizedDtsOptions.tsConfigPath;
    }
    Promise.all([
      this.generateTypesPromise,
      this.fetchRemoteTypeUrlsPromise
    ]).then(([_, remoteTypeUrls]) => {
      this._devWorker = createDevWorker({
        name,
        remote,
        host: __spreadProps(__spreadValues({}, host), {
          remoteTypeUrls
        }),
        extraOptions,
        disableLiveReload: normalizedDev.disableHotTypesReload,
        disableHotTypesReload: normalizedDev.disableHotTypesReload
      });
    });
    this._stopWhenSIGTERMOrSIGINT();
    this._handleUnexpectedExit();
    compiler.hooks.afterEmit.tap(this.name, this._afterEmit.bind(this));
  }
};
__name(_DevPlugin, "DevPlugin");
var DevPlugin = _DevPlugin;

// packages/dts-plugin/src/plugins/DtsPlugin.ts
import { normalizeOptions as normalizeOptions4 } from "@module-federation/sdk";

// packages/dts-plugin/src/plugins/ConsumeTypesPlugin.ts
import { normalizeOptions as normalizeOptions2 } from "@module-federation/sdk";
var _ConsumeTypesPlugin = class _ConsumeTypesPlugin {
  constructor(pluginOptions, dtsOptions, defaultOptions, fetchRemoteTypeUrlsResolve) {
    __publicField(this, "pluginOptions");
    __publicField(this, "dtsOptions");
    __publicField(this, "defaultOptions");
    __publicField(this, "callback");
    __publicField(this, "fetchRemoteTypeUrlsResolve");
    this.pluginOptions = pluginOptions;
    this.dtsOptions = dtsOptions;
    this.defaultOptions = defaultOptions;
    this.fetchRemoteTypeUrlsResolve = fetchRemoteTypeUrlsResolve;
  }
  apply(compiler) {
    const { dtsOptions, defaultOptions, pluginOptions, fetchRemoteTypeUrlsResolve } = this;
    if (isPrd()) {
      fetchRemoteTypeUrlsResolve(void 0);
      return;
    }
    const normalizedConsumeTypes = normalizeOptions2(true, defaultOptions, "mfOptions.dts.consumeTypes")(dtsOptions.consumeTypes);
    if (!normalizedConsumeTypes) {
      fetchRemoteTypeUrlsResolve(void 0);
      return;
    }
    const finalOptions = {
      host: __spreadValues({
        implementation: dtsOptions.implementation,
        context: compiler.context,
        moduleFederationConfig: pluginOptions
      }, normalizedConsumeTypes),
      extraOptions: dtsOptions.extraOptions || {},
      displayErrorInTerminal: dtsOptions.displayErrorInTerminal
    };
    validateOptions(finalOptions.host);
    const fetchRemoteTypeUrlsPromise = typeof normalizedConsumeTypes.remoteTypeUrls === "function" ? normalizedConsumeTypes.remoteTypeUrls() : Promise.resolve(normalizedConsumeTypes.remoteTypeUrls);
    const promise = fetchRemoteTypeUrlsPromise.then((remoteTypeUrls) => {
      consumeTypes(__spreadProps(__spreadValues({}, finalOptions), {
        host: __spreadProps(__spreadValues({}, finalOptions.host), {
          remoteTypeUrls
        })
      })).then(() => {
        fetchRemoteTypeUrlsResolve(remoteTypeUrls);
      }).catch(() => {
        fetchRemoteTypeUrlsResolve(remoteTypeUrls);
      });
    });
    compiler.hooks.thisCompilation.tap("mf:generateTypes", (compilation) => {
      compilation.hooks.processAssets.tapPromise({
        name: "mf:generateTypes",
        stage: (
          // @ts-expect-error use runtime variable in case peer dep not installed , it should execute before generate types
          compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER - 1
        )
      }, () => __async(this, null, function* () {
        yield promise;
      }));
    });
  }
};
__name(_ConsumeTypesPlugin, "ConsumeTypesPlugin");
var ConsumeTypesPlugin = _ConsumeTypesPlugin;

// packages/dts-plugin/src/plugins/GenerateTypesPlugin.ts
import fs2 from "fs";
import path5 from "path";
import { normalizeOptions as normalizeOptions3 } from "@module-federation/sdk";
var _GenerateTypesPlugin = class _GenerateTypesPlugin {
  constructor(pluginOptions, dtsOptions, defaultOptions, fetchRemoteTypeUrlsPromise, callback) {
    __publicField(this, "pluginOptions");
    __publicField(this, "dtsOptions");
    __publicField(this, "defaultOptions");
    __publicField(this, "fetchRemoteTypeUrlsPromise");
    __publicField(this, "callback");
    this.pluginOptions = pluginOptions;
    this.dtsOptions = dtsOptions;
    this.defaultOptions = defaultOptions;
    this.fetchRemoteTypeUrlsPromise = fetchRemoteTypeUrlsPromise;
    this.callback = callback;
  }
  apply(compiler) {
    const { dtsOptions, defaultOptions, pluginOptions, fetchRemoteTypeUrlsPromise, callback } = this;
    const normalizedGenerateTypes = normalizeOptions3(true, defaultOptions, "mfOptions.dts.generateTypes")(dtsOptions.generateTypes);
    if (!normalizedGenerateTypes) {
      callback();
      return;
    }
    const normalizedConsumeTypes = normalizeOptions3(true, defaultOptions, "mfOptions.dts.consumeTypes")(dtsOptions.consumeTypes);
    const finalOptions = {
      remote: __spreadValues({
        implementation: dtsOptions.implementation,
        context: compiler.context,
        outputDir: getCompilerOutputDir(compiler),
        moduleFederationConfig: pluginOptions
      }, normalizedGenerateTypes),
      host: normalizedConsumeTypes === false ? void 0 : __spreadValues({
        context: compiler.context,
        moduleFederationConfig: pluginOptions
      }, normalizedGenerateTypes),
      extraOptions: dtsOptions.extraOptions || {},
      displayErrorInTerminal: dtsOptions.displayErrorInTerminal
    };
    if (dtsOptions.tsConfigPath && !finalOptions.remote.tsConfigPath) {
      finalOptions.remote.tsConfigPath = dtsOptions.tsConfigPath;
    }
    validateOptions(finalOptions.remote);
    const isProd = !isDev();
    const getGenerateTypesFn = /* @__PURE__ */ __name(() => {
      let fn = generateTypes;
      let res;
      if (finalOptions.remote.compileInChildProcess) {
        fn = generateTypesInChildProcess;
      }
      if (isProd) {
        res = fn(finalOptions);
        return () => res;
      }
      return fn;
    }, "getGenerateTypesFn");
    const generateTypesFn = getGenerateTypesFn();
    const emitTypesFiles = /* @__PURE__ */ __name((compilation) => __async(this, null, function* () {
      try {
        const { zipTypesPath, apiTypesPath, zipName, apiFileName } = retrieveTypesAssetsInfo(finalOptions.remote);
        if (isProd && zipName && compilation.getAsset(zipName)) {
          callback();
          return;
        }
        yield generateTypesFn(finalOptions);
        const config = finalOptions.remote.moduleFederationConfig;
        let zipPrefix = "";
        if (typeof config.manifest === "object" && config.manifest.filePath) {
          zipPrefix = config.manifest.filePath;
        } else if (typeof config.manifest === "object" && config.manifest.fileName) {
          zipPrefix = path5.dirname(config.manifest.fileName);
        } else if (config.filename) {
          zipPrefix = path5.dirname(config.filename);
        }
        if (isProd) {
          const zipAssetName = path5.join(zipPrefix, zipName);
          const apiAssetName = path5.join(zipPrefix, apiFileName);
          if (zipTypesPath && !compilation.getAsset(zipAssetName)) {
            compilation.emitAsset(zipAssetName, new compiler.webpack.sources.RawSource(fs2.readFileSync(zipTypesPath), false));
          }
          if (apiTypesPath && !compilation.getAsset(apiAssetName)) {
            compilation.emitAsset(apiAssetName, new compiler.webpack.sources.RawSource(fs2.readFileSync(apiTypesPath), false));
          }
          callback();
        } else {
          const isEEXIST = /* @__PURE__ */ __name((err) => {
            return err.code == "EEXIST";
          }, "isEEXIST");
          if (zipTypesPath) {
            const zipContent = fs2.readFileSync(zipTypesPath);
            const zipOutputPath = path5.join(compiler.outputPath, zipPrefix, zipName);
            yield new Promise((resolve2, reject) => {
              compiler.outputFileSystem.mkdir(path5.dirname(zipOutputPath), (err) => {
                if (err && !isEEXIST(err)) {
                  reject(err);
                } else {
                  compiler.outputFileSystem.writeFile(zipOutputPath, zipContent, (writeErr) => {
                    if (writeErr && !isEEXIST(writeErr)) {
                      reject(writeErr);
                    } else {
                      resolve2();
                    }
                  });
                }
              });
            });
          }
          if (apiTypesPath) {
            const apiContent = fs2.readFileSync(apiTypesPath);
            const apiOutputPath = path5.join(compiler.outputPath, zipPrefix, apiFileName);
            yield new Promise((resolve2, reject) => {
              compiler.outputFileSystem.mkdir(path5.dirname(apiOutputPath), (err) => {
                if (err && !isEEXIST(err)) {
                  reject(err);
                } else {
                  compiler.outputFileSystem.writeFile(apiOutputPath, apiContent, (writeErr) => {
                    if (writeErr && !isEEXIST(writeErr)) {
                      reject(writeErr);
                    } else {
                      resolve2();
                    }
                  });
                }
              });
            });
          }
          callback();
        }
      } catch (err) {
        callback();
        if (finalOptions.displayErrorInTerminal) {
          console.error("Error in mf:generateTypes processAssets hook:", err);
        }
      }
    }), "emitTypesFiles");
    compiler.hooks.thisCompilation.tap("mf:generateTypes", (compilation) => {
      compilation.hooks.processAssets.tapPromise({
        name: "mf:generateTypes",
        stage: (
          // @ts-expect-error use runtime variable in case peer dep not installed
          compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER
        )
      }, () => __async(this, null, function* () {
        yield fetchRemoteTypeUrlsPromise;
        const emitTypesFilesPromise = emitTypesFiles(compilation);
        if (isProd) {
          yield emitTypesFilesPromise;
        }
      }));
    });
  }
};
__name(_GenerateTypesPlugin, "GenerateTypesPlugin");
var GenerateTypesPlugin = _GenerateTypesPlugin;

// packages/dts-plugin/src/plugins/DtsPlugin.ts
var _DtsPlugin = class _DtsPlugin {
  constructor(options) {
    __publicField(this, "options");
    this.options = options;
  }
  apply(compiler) {
    const { options } = this;
    const defaultGenerateTypes = {
      generateAPITypes: true,
      compileInChildProcess: true,
      abortOnError: false,
      extractThirdParty: false,
      extractRemoteTypes: false
    };
    const defaultConsumeTypes = {
      abortOnError: false,
      consumeAPITypes: true
    };
    const normalizedDtsOptions = normalizeOptions4(isTSProject(options.dts, compiler.context), {
      generateTypes: defaultGenerateTypes,
      consumeTypes: defaultConsumeTypes,
      extraOptions: {},
      displayErrorInTerminal: true
    }, "mfOptions.dts")(options.dts);
    if (typeof normalizedDtsOptions !== "object") {
      return;
    }
    let fetchRemoteTypeUrlsResolve;
    const fetchRemoteTypeUrlsPromise = new Promise((resolve2) => {
      fetchRemoteTypeUrlsResolve = resolve2;
    });
    let generateTypesPromiseResolve;
    const generateTypesPromise = new Promise((resolve2) => {
      generateTypesPromiseResolve = resolve2;
    });
    new DevPlugin(options, normalizedDtsOptions, generateTypesPromise, fetchRemoteTypeUrlsPromise).apply(compiler);
    new GenerateTypesPlugin(options, normalizedDtsOptions, defaultGenerateTypes, fetchRemoteTypeUrlsPromise, generateTypesPromiseResolve).apply(compiler);
    new ConsumeTypesPlugin(options, normalizedDtsOptions, defaultConsumeTypes, fetchRemoteTypeUrlsResolve).apply(compiler);
  }
};
__name(_DtsPlugin, "DtsPlugin");
var DtsPlugin = _DtsPlugin;
export {
  DtsPlugin
};
