Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_Action = require('./Action-CzhPMw2i.js'); const require_Broker = require('./Broker-DRFgFvXI.js'); const require_expose_rpc = require('./expose-rpc-mEaCWCcd.js'); const require_consumeTypes = require('./consumeTypes-CFK17Cck.js'); require('./core.js'); let fs = require("fs"); fs = require_Action.__toESM(fs); let path = require("path"); path = require_Action.__toESM(path); let fs_promises = require("fs/promises"); let _module_federation_sdk = require("@module-federation/sdk"); //#region src/dev-worker/DevWorker.ts var DevWorker = class { constructor(options) { this._options = require_expose_rpc.cloneDeepOptions(options); this.removeUnSerializationOptions(); this._rpcWorker = require_consumeTypes.createRpcWorker(path.default.resolve(__dirname, "./fork-dev-worker.js"), {}, void 0, false); this._res = this._rpcWorker.connect(this._options); } removeUnSerializationOptions() { delete this._options.host?.moduleFederationConfig?.manifest; delete this._options.remote?.moduleFederationConfig?.manifest; } get controlledPromise() { return this._res; } update() { this._rpcWorker.process?.send?.({ type: require_expose_rpc.RpcGMCallTypes.CALL, id: this._rpcWorker.id, args: [void 0, "update"] }); } exit() { this._rpcWorker?.terminate(); } }; //#endregion //#region src/dev-worker/createDevWorker.ts async function removeLogFile() { try { await (0, fs_promises.rm)(path.resolve(process.cwd(), ".mf/typesGenerate.log"), { force: true, recursive: true }); } catch (err) { console.error("removeLogFile error", "forkDevWorker", err); } } function createDevWorker(options) { removeLogFile(); return new DevWorker({ ...options }); } //#endregion //#region src/plugins/utils.ts function isDev() { return process.env["NODE_ENV"] === "development"; } function isPrd() { return process.env["NODE_ENV"] === "production"; } function getCompilerOutputDir(compiler) { try { return path.default.relative(compiler.context, compiler.outputPath || compiler.options.output.path); } catch (err) { return ""; } } //#endregion //#region src/plugins/DevPlugin.ts var PROCESS_EXIT_CODE = /* @__PURE__ */ function(PROCESS_EXIT_CODE) { PROCESS_EXIT_CODE[PROCESS_EXIT_CODE["SUCCESS"] = 0] = "SUCCESS"; PROCESS_EXIT_CODE[PROCESS_EXIT_CODE["FAILURE"] = 1] = "FAILURE"; return PROCESS_EXIT_CODE; }(PROCESS_EXIT_CODE || {}); function ensureTempDir(filePath) { try { const dir = path.default.dirname(filePath); fs.default.mkdirSync(dir, { recursive: true }); } catch (_err) {} } var DevPlugin = class DevPlugin { constructor(options, dtsOptions, generateTypesPromise, fetchRemoteTypeUrlsPromise) { this.name = "MFDevPlugin"; this._options = options; this.generateTypesPromise = generateTypesPromise; this.dtsOptions = dtsOptions; this.fetchRemoteTypeUrlsPromise = fetchRemoteTypeUrlsPromise; } static ensureLiveReloadEntry(options, filePath) { ensureTempDir(filePath); const liveReloadEntryWithOptions = fs.default.readFileSync(path.default.join(__dirname, "./iife/launch-web-client.iife.js")).toString("utf-8").replace(require_Action.WEB_CLIENT_OPTIONS_IDENTIFIER, JSON.stringify(options)); fs.default.writeFileSync(filePath, liveReloadEntryWithOptions); } _stopWhenSIGTERMOrSIGINT() { process.on("SIGTERM", () => { require_Broker.logger.info(`${this._options.name} Process(${process.pid}) SIGTERM, mf server will exit...`); this._exit(PROCESS_EXIT_CODE.SUCCESS); }); process.on("SIGINT", () => { require_Broker.logger.info(`${this._options.name} Process(${process.pid}) SIGINT, mf server will exit...`); this._exit(PROCESS_EXIT_CODE.SUCCESS); }); } _handleUnexpectedExit() { process.on("unhandledRejection", (error) => { require_Broker.logger.error(error); require_Broker.logger.error(`Process(${process.pid}) unhandledRejection, mf server will exit...`); this._exit(PROCESS_EXIT_CODE.FAILURE); }); process.on("uncaughtException", (error) => { require_Broker.logger.error(error); require_Broker.logger.error(`Process(${process.pid}) uncaughtException, mf server will exit...`); this._exit(PROCESS_EXIT_CODE.FAILURE); }); } _exit(exitCode = 0) { this._devWorker?.exit(); process.exit(exitCode); } _afterEmit() { this._devWorker?.update(); } apply(compiler) { const { _options: { name, dev, dts } } = this; const normalizedDev = (0, _module_federation_sdk.normalizeOptions)(true, { disableLiveReload: true, disableHotTypesReload: false, disableDynamicRemoteTypeHints: false }, "mfOptions.dev")(dev); if (!isDev() || normalizedDev === false) return; new compiler.webpack.DefinePlugin({ FEDERATION_IPV4: JSON.stringify(require_Broker.getIPV4()) }).apply(compiler); 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(path.default.resolve(__dirname, "dynamic-remote-type-hints-plugin.js")); } if (!normalizedDev.disableLiveReload) { const TEMP_DIR = path.default.join(`${process.cwd()}/node_modules`, _module_federation_sdk.TEMP_DIR); const filepath = path.default.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 = (0, _module_federation_sdk.normalizeOptions)(require_expose_rpc.isTSProject(dts, compiler.context), { generateTypes: defaultGenerateTypes, consumeTypes: defaultConsumeTypes, extraOptions: {}, displayErrorInTerminal: this.dtsOptions?.displayErrorInTerminal }, "mfOptions.dts")(dts); const normalizedGenerateTypes = (0, _module_federation_sdk.normalizeOptions)(Boolean(normalizedDtsOptions), defaultGenerateTypes, "mfOptions.dts.generateTypes")(normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.generateTypes); const remote = normalizedGenerateTypes === false ? void 0 : { implementation: normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.implementation, context: compiler.context, outputDir: getCompilerOutputDir(compiler), moduleFederationConfig: { ...this._options }, hostRemoteTypesFolder: normalizedGenerateTypes.typesFolder || "@mf-types", ...normalizedGenerateTypes, typesFolder: `.dev-server` }; const normalizedConsumeTypes = (0, _module_federation_sdk.normalizeOptions)(Boolean(normalizedDtsOptions), defaultConsumeTypes, "mfOptions.dts.consumeTypes")(normalizedDtsOptions === false ? void 0 : normalizedDtsOptions.consumeTypes); const host = normalizedConsumeTypes === false ? void 0 : { 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?.tsConfigPath && typeof normalizedDtsOptions === "object" && normalizedDtsOptions.tsConfigPath) remote.tsConfigPath = normalizedDtsOptions.tsConfigPath; Promise.all([this.generateTypesPromise, this.fetchRemoteTypeUrlsPromise]).then(([_, remoteTypeUrls]) => { this._devWorker = createDevWorker({ name, remote, host: { moduleFederationConfig: {}, ...host, remoteTypeUrls }, extraOptions, disableLiveReload: normalizedDev.disableHotTypesReload, disableHotTypesReload: normalizedDev.disableHotTypesReload }); }); this._stopWhenSIGTERMOrSIGINT(); this._handleUnexpectedExit(); compiler.hooks.afterEmit.tap(this.name, this._afterEmit.bind(this)); } }; //#endregion //#region src/plugins/ConsumeTypesPlugin.ts const DEFAULT_CONSUME_TYPES = { abortOnError: false, consumeAPITypes: true, typesOnBuild: false }; const normalizeConsumeTypesOptions = ({ context, dtsOptions, pluginOptions }) => { const normalizedConsumeTypes = (0, _module_federation_sdk.normalizeOptions)(true, DEFAULT_CONSUME_TYPES, "mfOptions.dts.consumeTypes")(dtsOptions.consumeTypes); if (!normalizedConsumeTypes) return; const dtsManagerOptions = { host: { implementation: dtsOptions.implementation, context, moduleFederationConfig: pluginOptions, ...normalizedConsumeTypes }, extraOptions: dtsOptions.extraOptions || {}, displayErrorInTerminal: dtsOptions.displayErrorInTerminal }; require_expose_rpc.validateOptions(dtsManagerOptions.host); return dtsManagerOptions; }; const consumeTypesAPI = async (dtsManagerOptions, cb) => { return (typeof dtsManagerOptions.host.remoteTypeUrls === "function" ? dtsManagerOptions.host.remoteTypeUrls() : Promise.resolve(dtsManagerOptions.host.remoteTypeUrls)).then((remoteTypeUrls) => { require_consumeTypes.consumeTypes({ ...dtsManagerOptions, host: { ...dtsManagerOptions.host, remoteTypeUrls } }).then(() => { typeof cb === "function" && cb(remoteTypeUrls); }).catch(() => { typeof cb === "function" && cb(remoteTypeUrls); }); }); }; var ConsumeTypesPlugin = class { constructor(pluginOptions, dtsOptions, fetchRemoteTypeUrlsResolve) { this.pluginOptions = pluginOptions; this.dtsOptions = dtsOptions; this.fetchRemoteTypeUrlsResolve = fetchRemoteTypeUrlsResolve; } apply(compiler) { const { dtsOptions, pluginOptions, fetchRemoteTypeUrlsResolve } = this; const dtsManagerOptions = normalizeConsumeTypesOptions({ context: compiler.context, dtsOptions, pluginOptions }); if (!dtsManagerOptions) { fetchRemoteTypeUrlsResolve(void 0); return; } if (isPrd() && !dtsManagerOptions.host.typesOnBuild) { fetchRemoteTypeUrlsResolve(void 0); return; } _module_federation_sdk.infrastructureLogger.debug("start fetching remote types..."); const promise = consumeTypesAPI(dtsManagerOptions, fetchRemoteTypeUrlsResolve); compiler.hooks.thisCompilation.tap("mf:generateTypes", (compilation) => { compilation.hooks.processAssets.tapPromise({ name: "mf:generateTypes", stage: compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER - 1 }, async () => { await promise; _module_federation_sdk.infrastructureLogger.debug("fetch remote types success!"); }); }); } }; //#endregion //#region src/plugins/GenerateTypesPlugin.ts const DEFAULT_GENERATE_TYPES = { generateAPITypes: true, compileInChildProcess: true, abortOnError: false, extractThirdParty: false, extractRemoteTypes: false }; const normalizeGenerateTypesOptions = ({ context, outputDir, dtsOptions, pluginOptions }) => { const normalizedGenerateTypes = (0, _module_federation_sdk.normalizeOptions)(true, DEFAULT_GENERATE_TYPES, "mfOptions.dts.generateTypes")(dtsOptions.generateTypes); if (!normalizedGenerateTypes) return; const normalizedConsumeTypes = (0, _module_federation_sdk.normalizeOptions)(true, {}, "mfOptions.dts.consumeTypes")(dtsOptions.consumeTypes); const finalOptions = { remote: { implementation: dtsOptions.implementation, context, outputDir, moduleFederationConfig: pluginOptions, ...normalizedGenerateTypes }, host: normalizedConsumeTypes === false ? void 0 : { context, moduleFederationConfig: pluginOptions, ...normalizedConsumeTypes, remoteTypeUrls: typeof normalizedConsumeTypes?.remoteTypeUrls === "object" ? normalizedConsumeTypes?.remoteTypeUrls : void 0 }, extraOptions: dtsOptions.extraOptions || {}, displayErrorInTerminal: dtsOptions.displayErrorInTerminal }; if (dtsOptions.tsConfigPath && !finalOptions.remote.tsConfigPath) finalOptions.remote.tsConfigPath = dtsOptions.tsConfigPath; require_expose_rpc.validateOptions(finalOptions.remote); return finalOptions; }; const getGenerateTypesFn = (dtsManagerOptions) => { let fn = require_expose_rpc.generateTypes; if (dtsManagerOptions.remote.compileInChildProcess) fn = require_consumeTypes.generateTypesInChildProcess; return fn; }; const generateTypesAPI = ({ dtsManagerOptions }) => { return getGenerateTypesFn(dtsManagerOptions)(dtsManagerOptions).then(async () => { await callAfterGenerateHook({ dtsManagerOptions, generatedTypes: require_expose_rpc.retrieveTypesAssetsInfo(dtsManagerOptions.remote) }); }); }; const callAfterGenerateHook = async ({ dtsManagerOptions, generatedTypes }) => { const afterGenerate = dtsManagerOptions.remote.afterGenerate; if (!afterGenerate) return; try { await afterGenerate(generatedTypes); } catch (error) { if (dtsManagerOptions.remote.abortOnError === false) { if (dtsManagerOptions.displayErrorInTerminal) _module_federation_sdk.logger.error(error); return; } throw error; } }; const WINDOWS_ABSOLUTE_PATH_REGEXP = /^[a-zA-Z]:[\\/]/; const isSafeRelativePath = (relativePath) => { return Boolean(relativePath) && !relativePath.startsWith("..") && !path.default.isAbsolute(relativePath) && !WINDOWS_ABSOLUTE_PATH_REGEXP.test(relativePath); }; const resolveEmitAssetName = ({ compilerOutputPath, assetPath, fallbackName }) => { if (!assetPath) return fallbackName; const relativePath = path.default.relative(compilerOutputPath, assetPath); return isSafeRelativePath(relativePath) ? relativePath : fallbackName; }; var GenerateTypesPlugin = class { constructor(pluginOptions, dtsOptions, fetchRemoteTypeUrlsPromise, callback) { this.pluginOptions = pluginOptions; this.dtsOptions = dtsOptions; this.fetchRemoteTypeUrlsPromise = fetchRemoteTypeUrlsPromise; this.callback = callback; } apply(compiler) { const { dtsOptions, pluginOptions, fetchRemoteTypeUrlsPromise, callback } = this; const outputDir = getCompilerOutputDir(compiler); const context = compiler.context; const dtsManagerOptions = normalizeGenerateTypesOptions({ context, outputDir, dtsOptions, pluginOptions }); if (!dtsManagerOptions) { callback(); return; } const isProd = !isDev(); const compilerOutputPath = path.default.resolve(context, outputDir); const emitTypesFiles = async (compilation) => { try { const { zipTypesPath, apiTypesPath, zipName, apiFileName } = require_expose_rpc.retrieveTypesAssetsInfo(dtsManagerOptions.remote); const emitZipName = resolveEmitAssetName({ compilerOutputPath, assetPath: zipTypesPath, fallbackName: zipName }); const emitApiFileName = resolveEmitAssetName({ compilerOutputPath, assetPath: apiTypesPath, fallbackName: apiFileName }); if (isProd && emitZipName && compilation.getAsset(emitZipName)) { callback(); return; } _module_federation_sdk.logger.debug("start generating types..."); await generateTypesAPI({ dtsManagerOptions }); _module_federation_sdk.logger.debug("generate types success!"); if (isProd) { if (zipTypesPath && !compilation.getAsset(emitZipName) && fs.default.existsSync(zipTypesPath)) compilation.emitAsset(emitZipName, new compiler.webpack.sources.RawSource(fs.default.readFileSync(zipTypesPath))); if (apiTypesPath && !compilation.getAsset(emitApiFileName) && fs.default.existsSync(apiTypesPath)) compilation.emitAsset(emitApiFileName, new compiler.webpack.sources.RawSource(fs.default.readFileSync(apiTypesPath))); callback(); } else { const isEEXIST = (err) => { return err.code == "EEXIST"; }; if (zipTypesPath && fs.default.existsSync(zipTypesPath)) { const zipContent = fs.default.readFileSync(zipTypesPath); const zipOutputPath = path.default.join(compiler.outputPath, emitZipName); await new Promise((resolve, reject) => { compiler.outputFileSystem.mkdir(path.default.dirname(zipOutputPath), { recursive: true }, (err) => { if (err && !isEEXIST(err)) reject(err); else compiler.outputFileSystem.writeFile(zipOutputPath, zipContent, (writeErr) => { if (writeErr && !isEEXIST(writeErr)) reject(writeErr); else resolve(); }); }); }); } if (apiTypesPath && fs.default.existsSync(apiTypesPath)) { const apiContent = fs.default.readFileSync(apiTypesPath); const apiOutputPath = path.default.join(compiler.outputPath, emitApiFileName); await new Promise((resolve, reject) => { compiler.outputFileSystem.mkdir(path.default.dirname(apiOutputPath), { recursive: true }, (err) => { if (err && !isEEXIST(err)) reject(err); else compiler.outputFileSystem.writeFile(apiOutputPath, apiContent, (writeErr) => { if (writeErr && !isEEXIST(writeErr)) reject(writeErr); else resolve(); }); }); }); } callback(); } } catch (err) { callback(); if (dtsManagerOptions.displayErrorInTerminal) console.error(err); _module_federation_sdk.logger.debug("generate types fail!"); } }; compiler.hooks.thisCompilation.tap("mf:generateTypes", (compilation) => { compilation.hooks.processAssets.tapPromise({ name: "mf:generateTypes", stage: compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER }, async () => { await fetchRemoteTypeUrlsPromise; const emitTypesFilesPromise = emitTypesFiles(compilation); if (isProd) await emitTypesFilesPromise; }); }); } }; //#endregion //#region src/plugins/DtsPlugin.ts const normalizeDtsOptions = (options, context, defaultOptions) => { return (0, _module_federation_sdk.normalizeOptions)(require_expose_rpc.isTSProject(options.dts, context), { generateTypes: defaultOptions?.defaultGenerateOptions || DEFAULT_GENERATE_TYPES, consumeTypes: defaultOptions?.defaultConsumeOptions || DEFAULT_CONSUME_TYPES, extraOptions: {}, displayErrorInTerminal: true }, "mfOptions.dts")(options.dts); }; const excludeDts = (filepath) => { if (typeof filepath !== "string") return false; const [_p, query] = filepath.split("?"); if (query && query.startsWith("exclude-mf-dts")) return true; return false; }; var DtsPlugin = class { constructor(options) { this.options = options; this.clonedOptions = { ...options }; } apply(compiler) { const { options, clonedOptions } = this; if (options.exposes && typeof options.exposes === "object") { const cleanedExposes = {}; Object.entries(options.exposes).forEach(([key, value]) => { if (typeof value === "string") { const [filepath, _query] = value.split("?"); if (excludeDts(value)) return; cleanedExposes[key] = filepath; } else { if (typeof value === "object" && Array.isArray(value.import) && value.import.some((v) => excludeDts(v))) return; cleanedExposes[key] = value; } }); clonedOptions.exposes = cleanedExposes; } const normalizedDtsOptions = normalizeDtsOptions(clonedOptions, compiler.context); if (typeof normalizedDtsOptions !== "object") return; let fetchRemoteTypeUrlsResolve; const fetchRemoteTypeUrlsPromise = new Promise((resolve) => { fetchRemoteTypeUrlsResolve = resolve; }); let generateTypesPromiseResolve; new DevPlugin(clonedOptions, normalizedDtsOptions, new Promise((resolve) => { generateTypesPromiseResolve = resolve; }), fetchRemoteTypeUrlsPromise).apply(compiler); new GenerateTypesPlugin(clonedOptions, normalizedDtsOptions, fetchRemoteTypeUrlsPromise, generateTypesPromiseResolve).apply(compiler); new ConsumeTypesPlugin(clonedOptions, normalizedDtsOptions, fetchRemoteTypeUrlsResolve).apply(compiler); } addRuntimePlugins() { const { options, clonedOptions } = this; if (!clonedOptions.runtimePlugins) return; if (!options.runtimePlugins) options.runtimePlugins = []; clonedOptions.runtimePlugins.forEach((plugin) => { options.runtimePlugins.includes(plugin) || options.runtimePlugins.push(plugin); }); } }; //#endregion exports.DtsPlugin = DtsPlugin; exports.consumeTypesAPI = consumeTypesAPI; exports.generateTypesAPI = generateTypesAPI; exports.isTSProject = require_expose_rpc.isTSProject; exports.normalizeConsumeTypesOptions = normalizeConsumeTypesOptions; exports.normalizeDtsOptions = normalizeDtsOptions; exports.normalizeGenerateTypesOptions = normalizeGenerateTypesOptions;