"use strict"; var __webpack_require__ = {}; (()=>{ __webpack_require__.n = (module)=>{ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module; __webpack_require__.d(getter, { a: getter }); return getter; }; })(); (()=>{ __webpack_require__.d = (exports1, definition)=>{ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { enumerable: true, get: definition[key] }); }; })(); (()=>{ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); })(); (()=>{ __webpack_require__.r = (exports1)=>{ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { value: 'Module' }); Object.defineProperty(exports1, '__esModule', { value: true }); }; })(); var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { TsCheckerRspackPlugin: ()=>TsCheckerRspackPlugin }); const external_node_path_namespaceObject = require("node:path"); var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject); function getInfrastructureLogger(compiler) { const logger = compiler.getInfrastructureLogger('TsCheckerRspackPlugin'); return { log: logger.log.bind(logger), debug: logger.debug.bind(logger), error: logger.error.bind(logger), warn: logger.warn.bind(logger), info: logger.info.bind(logger) }; } const addTrailingSep = (dir)=>dir.endsWith(external_node_path_namespaceObject.sep) ? dir : dir + external_node_path_namespaceObject.sep; const isStrictSubdir = (parent, child)=>{ const parentDir = addTrailingSep(parent); const childDir = addTrailingSep(child); return parentDir !== childDir && childDir.startsWith(parentDir); }; function excludeOutputPath(dependencies, compiler) { const isContextIncluded = dependencies.dirs.includes(compiler.context); if (!isContextIncluded) return dependencies; const outputPath = 'string' == typeof compiler.options.output?.path ? compiler.options.output.path : compiler.outputPath; if (!outputPath || !isStrictSubdir(compiler.context, outputPath) || dependencies.dirs.includes(outputPath)) return dependencies; const excluded = new Set(dependencies.excluded); excluded.add(outputPath); return { ...dependencies, excluded: Array.from(excluded) }; } function tapAfterCompileToAddDependencies(compiler, config, state) { const { debug } = getInfrastructureLogger(compiler); compiler.hooks.afterCompile.tapPromise('TsCheckerRspackPlugin', async (compilation)=>{ if (compilation.compiler !== compiler) return; const dependencies = await state.dependenciesPromise; debug("Got dependencies from the getDependenciesWorker.", dependencies); if (dependencies) { const sanitizedDependencies = excludeOutputPath(dependencies, compiler); state.lastDependencies = sanitizedDependencies; sanitizedDependencies.files.forEach((file)=>{ compilation.fileDependencies.add(file); }); } }); } const external_chokidar_namespaceObject = require("chokidar"); var external_chokidar_default = /*#__PURE__*/ __webpack_require__.n(external_chokidar_namespaceObject); const external_minimatch_namespaceObject = require("minimatch"); const external_is_glob_namespaceObject = require("is-glob"); var external_is_glob_default = /*#__PURE__*/ __webpack_require__.n(external_is_glob_namespaceObject); const IGNORED_FILES = [ 'package.json' ]; const isIgnoredFile = (file)=>IGNORED_FILES.some((ignoredFile)=>file.endsWith(`/${ignoredFile}`) || file.endsWith(`\\${ignoredFile}`)); const compilerFilesChangeMap = new WeakMap(); function getFilesChange(compiler) { const { changedFiles = [], deletedFiles = [] } = compilerFilesChangeMap.get(compiler) || { changedFiles: [], deletedFiles: [] }; return { changedFiles: changedFiles.filter((changedFile)=>!isIgnoredFile(changedFile)), deletedFiles: deletedFiles.filter((deletedFile)=>!isIgnoredFile(deletedFile)) }; } function consumeFilesChange(compiler) { const change = getFilesChange(compiler); clearFilesChange(compiler); return change; } function updateFilesChange(compiler, change) { compilerFilesChangeMap.set(compiler, aggregateFilesChanges([ getFilesChange(compiler), change ])); } function clearFilesChange(compiler) { compilerFilesChangeMap.delete(compiler); } function aggregateFilesChanges(changes) { const changedFilesSet = new Set(); const deletedFilesSet = new Set(); for (const { changedFiles = [], deletedFiles = [] } of changes){ for (const changedFile of changedFiles){ changedFilesSet.add(changedFile); deletedFilesSet.delete(changedFile); } for (const deletedFile of deletedFiles){ changedFilesSet.delete(deletedFile); deletedFilesSet.add(deletedFile); } } return { changedFiles: Array.from(changedFilesSet), deletedFiles: Array.from(deletedFilesSet) }; } function isInsideAnotherPath(parent, directory) { const relativePart = (0, external_node_path_namespaceObject.relative)(parent, directory); if (relativePart.startsWith('..')) return false; if (0 === relativePart.length) return false; if ((0, external_node_path_namespaceObject.isAbsolute)(relativePart)) return false; return true; } function _define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } const BUILTIN_IGNORED_DIRS = [ '.git' ]; function createIsIgnored(ignored, excluded) { const ignoredPatterns = ignored ? Array.isArray(ignored) ? [ ...ignored ] : [ ignored ] : []; const filteredExcluded = excluded.filter((pattern)=>{ if (external_is_glob_default()(pattern)) { const shouldAppendStar = pattern.includes('**') && !pattern.endsWith('*'); if (shouldAppendStar) ignoredPatterns.push(pattern.endsWith('/') ? `${pattern}**` : `${pattern}/**`); else ignoredPatterns.push(pattern); return false; } return true; }); const ignoredFunctions = ignoredPatterns.map((pattern)=>{ if ('string' == typeof pattern) return (path)=>(0, external_minimatch_namespaceObject.minimatch)(path, pattern); if (pattern instanceof RegExp) return (path)=>pattern.test(path); return ()=>false; }); ignoredFunctions.push((path)=>filteredExcluded.some((excludedPath)=>isInsideAnotherPath(excludedPath, path))); ignoredFunctions.push((path)=>BUILTIN_IGNORED_DIRS.some((ignoredDir)=>path.includes(`/${ignoredDir}/`) || path.includes(`\\${ignoredDir}\\`))); return function(path) { return ignoredFunctions.some((ignoredFunction)=>ignoredFunction(path)); }; } class InclusiveNodeWatchFileSystem { get watcher() { return this.watchFileSystem.watcher || this.watchFileSystem.wfs?.watcher; } constructor(watchFileSystem, compiler, pluginState){ _define_property(this, "watchFileSystem", void 0); _define_property(this, "compiler", void 0); _define_property(this, "pluginState", void 0); _define_property(this, "dirsWatchers", void 0); _define_property(this, "paused", void 0); _define_property(this, "deletedFiles", void 0); _define_property(this, "watch", void 0); this.watchFileSystem = watchFileSystem; this.compiler = compiler; this.pluginState = pluginState; this.paused = true; this.watch = (files, dirs, missing, startTime, options, callback, callbackUndelayed)=>{ const { debug } = getInfrastructureLogger(this.compiler); clearFilesChange(this.compiler); const isIgnored = createIsIgnored(options?.ignored, this.pluginState.lastDependencies?.excluded || []); const standardWatcher = this.watchFileSystem.watch(files, dirs, missing, startTime, options, callback, callbackUndelayed); this.watcher?.on('change', (file)=>{ if ('string' != typeof file) return; if (isIgnored(file)) debug("Detected file change but it's ignored", file); else { debug('Detected file change', file); this.deletedFiles.delete(file); updateFilesChange(this.compiler, { changedFiles: [ file ] }); } }); this.watcher?.on('remove', (file)=>{ if ('string' != typeof file) return; if (this.deletedFiles.has(file)) return void debug('Skipping duplicated remove event.'); if (isIgnored(file)) debug("Detected file remove but it's ignored", file); else { debug('Detected file remove', file); this.deletedFiles.add(file); updateFilesChange(this.compiler, { deletedFiles: [ file ] }); } }); const prevDirs = Array.from(this.dirsWatchers.keys()); const nextDirs = Array.from(this.pluginState.lastDependencies?.dirs || []); const dirsToUnwatch = prevDirs.filter((prevDir)=>!nextDirs.includes(prevDir)); const dirsToWatch = nextDirs.filter((nextDir)=>!prevDirs.includes(nextDir) && !isIgnored(nextDir)); dirsToUnwatch.forEach((dirToUnwatch)=>{ this.dirsWatchers.get(dirToUnwatch)?.close(); this.dirsWatchers.delete(dirToUnwatch); }); dirsToWatch.forEach((dirToWatch)=>{ const interval = 'number' == typeof options?.poll ? options.poll : void 0; const dirWatcher = external_chokidar_default().watch(dirToWatch, { ignoreInitial: true, ignorePermissionErrors: true, ignored: (path)=>isIgnored(path), usePolling: options?.poll ? true : void 0, interval: interval, binaryInterval: interval, alwaysStat: true, atomic: true, awaitWriteFinish: true }); dirWatcher.on('add', (file, stats)=>{ if (this.paused) return; const extension = (0, external_node_path_namespaceObject.extname)(file); const supportedExtensions = this.pluginState.lastDependencies?.extensions || []; if (!supportedExtensions.includes(extension)) return void debug('Detected new file add but extension is not supported', file); debug('Detected new file add', file); this.deletedFiles.delete(file); updateFilesChange(this.compiler, { changedFiles: [ file ] }); this.watcher?._onChange(file, stats?.mtimeMs || stats?.ctimeMs || 1, file, 'rename'); }); dirWatcher.on('unlink', (file)=>{ if (this.paused) return; const extension = (0, external_node_path_namespaceObject.extname)(file); const supportedExtensions = this.pluginState.lastDependencies?.extensions || []; if (!supportedExtensions.includes(extension)) return void debug('Detected new file remove but extension is not supported', file); if (this.deletedFiles.has(file)) return void debug('Skipping duplicated unlink event.'); debug('Detected new file remove', file); this.deletedFiles.add(file); updateFilesChange(this.compiler, { deletedFiles: [ file ] }); this.watcher?._onRemove(dirToWatch, file, 'rename'); }); this.dirsWatchers.set(dirToWatch, dirWatcher); }); this.paused = false; return { ...standardWatcher, close: ()=>{ clearFilesChange(this.compiler); if (standardWatcher) standardWatcher.close(); this.dirsWatchers.forEach((dirWatcher)=>{ dirWatcher?.close(); }); this.dirsWatchers.clear(); this.paused = true; }, pause: ()=>{ if (standardWatcher) standardWatcher.pause(); this.paused = true; } }; }; this.dirsWatchers = new Map(); this.deletedFiles = new Set(); } } function tapAfterEnvironmentToPatchWatching(compiler, state) { const { debug } = getInfrastructureLogger(compiler); compiler.hooks.afterEnvironment.tap('TsCheckerRspackPlugin', ()=>{ const watchFileSystem = compiler.watchFileSystem; if (watchFileSystem) { debug("Overwriting Rspack's watch file system."); compiler.watchFileSystem = new InclusiveNodeWatchFileSystem(watchFileSystem, compiler, state); } else debug('No watch file system found - plugin may not work correctly.'); }); } const external_picocolors_namespaceObject = require("picocolors"); var external_picocolors_default = /*#__PURE__*/ __webpack_require__.n(external_picocolors_namespaceObject); const lite_tapable_namespaceObject = require("@rspack/lite-tapable"); const compilerHookMap = new WeakMap(); function createPluginHooks() { return { start: new lite_tapable_namespaceObject.AsyncSeriesWaterfallHook([ 'change', 'compilation' ]), waiting: new lite_tapable_namespaceObject.SyncHook([ 'compilation' ]), canceled: new lite_tapable_namespaceObject.SyncHook([ 'compilation' ]), error: new lite_tapable_namespaceObject.SyncHook([ 'error', 'compilation' ]), issues: new lite_tapable_namespaceObject.SyncWaterfallHook([ 'issues', 'compilation' ]) }; } function forwardPluginHooks(source, target) { source.start.tapPromise('TsCheckerRspackPlugin', target.start.promise); source.waiting.tap('TsCheckerRspackPlugin', target.waiting.call); source.canceled.tap('TsCheckerRspackPlugin', target.canceled.call); source.error.tap('TsCheckerRspackPlugin', target.error.call); source.issues.tap('TsCheckerRspackPlugin', target.issues.call); } function getPluginHooks(compiler) { let hooks = compilerHookMap.get(compiler); if (void 0 === hooks) { hooks = createPluginHooks(); compilerHookMap.set(compiler, hooks); if ('compilers' in compiler) compiler.compilers.forEach((childCompiler)=>{ const childHooks = getPluginHooks(childCompiler); if (hooks) forwardPluginHooks(childHooks, hooks); }); } return hooks; } const external_node_process_namespaceObject = require("node:process"); function createControlledPromise() { let resolve = ()=>void 0; let reject = ()=>void 0; const promise = new Promise((aResolve, aReject)=>{ resolve = aResolve; reject = aReject; }); return { promise, resolve, reject }; } function rpc_error_define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } class RpcExitError extends Error { constructor(message, code, signal){ super(message), rpc_error_define_property(this, "code", void 0), rpc_error_define_property(this, "signal", void 0), this.code = code, this.signal = signal; this.name = 'RpcExitError'; } } function wrapRpc(childProcess) { return async (...args)=>{ if (childProcess.send) { if (!childProcess.connected) throw new Error(`Process ${childProcess.pid} doesn't have open IPC channels`); } else throw new Error(`Process ${childProcess.pid} doesn't have IPC channels`); const id = uuid(); const { promise: resultPromise, resolve: resolveResult, reject: rejectResult } = createControlledPromise(); const { promise: sendPromise, resolve: resolveSend, reject: rejectSend } = createControlledPromise(); const handleMessage = (message)=>{ if (message?.id === id) { if ('resolve' === message.type) { resolveResult(message.value); removeHandlers(); } else if ('reject' === message.type) { rejectResult(message.error); removeHandlers(); } } }; const handleClose = (code, signal)=>{ rejectResult(new RpcExitError(code ? `Process ${childProcess.pid} exited with code ${code}` + (signal ? ` [${signal}]` : '') : `Process ${childProcess.pid} exited` + (signal ? ` [${signal}]` : ''), code, signal)); removeHandlers(); }; const removeHandlers = ()=>{ childProcess.off('message', handleMessage); childProcess.off('close', handleClose); }; childProcess.on('message', handleMessage); childProcess.on('close', handleClose); childProcess.send({ type: 'call', id, args }, (error)=>{ if (error) { rejectSend(error); removeHandlers(); } else resolveSend(void 0); }); return sendPromise.then(()=>resultPromise); }; } function uuid() { return new Array(4).fill(0).map(()=>Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)).join('-'); } const external_node_child_process_namespaceObject = require("node:child_process"); const WORKER_DATA_ENV_KEY = 'WORKER_DATA'; function createRpcWorker(modulePath, data, memoryLimit) { const options = { env: { ...external_node_process_namespaceObject.env, [WORKER_DATA_ENV_KEY]: JSON.stringify(data || {}) }, stdio: [ 'inherit', 'inherit', 'inherit', 'ipc' ], serialization: 'advanced' }; if (memoryLimit) options.execArgv = [ `--max-old-space-size=${memoryLimit}` ]; let childProcess; let remoteMethod; const worker = { connect () { if (childProcess && !childProcess.connected) { childProcess.kill('SIGTERM'); childProcess = void 0; remoteMethod = void 0; } if (!childProcess?.connected) { childProcess = external_node_child_process_namespaceObject.fork(modulePath, options); remoteMethod = wrapRpc(childProcess); } }, terminate () { if (childProcess) { childProcess.kill('SIGTERM'); childProcess = void 0; remoteMethod = void 0; } }, get connected () { return Boolean(childProcess?.connected); }, get process () { return childProcess; } }; return Object.assign((...args)=>{ if (!worker.connected) worker.connect(); if (!remoteMethod) return Promise.reject('Worker is not connected - cannot perform RPC.'); return remoteMethod(...args); }, worker); } class AbortError extends Error { static throwIfAborted(signal) { if (signal?.aborted) throw new AbortError(); } constructor(message = 'Task aborted.'){ super(message); this.name = 'AbortError'; } } function tapErrorToLogMessage(compiler, config) { const hooks = getPluginHooks(compiler); hooks.error.tap('TsCheckerRspackPlugin', (error)=>{ if (error instanceof AbortError) return; config.logger.error(String(error)); if (error instanceof RpcExitError) if ('SIGINT' === error.signal) config.logger.error(external_picocolors_default().red("[type-check] Issues checking service interrupted - If running in a docker container, this may be caused by the container running out of memory. If so, try increasing the container's memory limit or lowering the `memoryLimit` value in the TsCheckerRspackPlugin configuration.")); else config.logger.error(external_picocolors_default().red("[type-check] Issues checking service aborted - probably out of memory. Check the `memoryLimit` option in the TsCheckerRspackPlugin configuration.\nIf increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript.")); }); } const external_node_os_namespaceObject = require("node:os"); var external_node_os_default = /*#__PURE__*/ __webpack_require__.n(external_node_os_namespaceObject); function createPool(size) { let pendingPromises = []; const pool = { async submit (task, signal) { while(pendingPromises.length >= pool.size){ AbortError.throwIfAborted(signal); await Promise.race(pendingPromises).catch(()=>void 0); } AbortError.throwIfAborted(signal); const taskPromise = task(signal).finally(()=>{ pendingPromises = pendingPromises.filter((pendingPromise)=>pendingPromise !== taskPromise); }); pendingPromises.push(taskPromise); return taskPromise; }, size, get pending () { return pendingPromises.length; }, get drained () { return new Promise(async (resolve)=>{ while(pendingPromises.length > 0)await Promise.race(pendingPromises).catch(()=>void 0); resolve(void 0); }); } }; return pool; } const issuesPool = createPool(Math.max(1, external_node_os_namespaceObject.cpus().length)); const dependenciesPool = createPool(Math.max(1, external_node_os_namespaceObject.cpus().length)); function interceptDoneToGetDevServerTap(compiler, config, state) { const { debug } = getInfrastructureLogger(compiler); compiler.hooks.done.intercept({ register: (tap)=>{ if ([ 'webpack-dev-server', 'rsbuild-dev-server' ].includes(tap.name) && 'sync' === tap.type && config.devServer) { debug('Intercepting dev-server tap.'); state.DevServerDoneTap = tap; } return tap; } }); } function forwardSlash(input) { return external_node_path_default().normalize(input).replace(/\\+/g, '/'); } function relativeToContext(file, context) { let fileInContext = forwardSlash(external_node_path_default().relative(context, file)); if (!fileInContext.startsWith('../')) fileInContext = './' + fileInContext; return fileInContext; } function formatIssueLocation(location) { return `${location.start.line}:${location.start.column}`; } function issue_rspack_error_define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } class IssueRspackError extends Error { constructor(message, pathType, issue){ super(message), issue_rspack_error_define_property(this, "issue", void 0), issue_rspack_error_define_property(this, "hideStack", void 0), issue_rspack_error_define_property(this, "file", void 0), this.issue = issue, this.hideStack = true; if (issue.file) { this.file = 'absolute' === pathType ? forwardSlash(external_node_path_default().resolve(issue.file)) : relativeToContext(issue.file, process.cwd()); if (issue.location) this.file += `:${formatIssueLocation(issue.location)}`; } Error.captureStackTrace(this, this.constructor); } } function tapAfterCompileToGetIssues(compiler, config, state) { const hooks = getPluginHooks(compiler); const { debug } = getInfrastructureLogger(compiler); compiler.hooks.afterCompile.tapPromise('TsCheckerRspackPlugin', async (compilation)=>{ if (compilation.compiler !== compiler) return; let issues = []; try { issues = await state.issuesPromise; } catch (error) { hooks.error.call(error, compilation); return; } debug('Got issues from getIssuesWorker.', issues?.length); if (!issues) return; issues = issues.filter(config.issue.predicate); issues = hooks.issues.call(issues, compilation); issues.forEach((issue)=>{ const error = new IssueRspackError(config.formatter.format(issue), config.formatter.pathType, issue); if ('warning' === issue.severity) compilation.warnings.push(error); else compilation.errors.push(error); }); }); } function statsFormatter(issues, stats) { const errorsNumber = issues.filter((issue)=>'error' === issue.severity).length; const warningsNumber = issues.filter((issue)=>'warning' === issue.severity).length; const errorsFormatted = errorsNumber ? external_picocolors_default().bold(external_picocolors_default().red(`${errorsNumber} ${1 === errorsNumber ? 'error' : 'errors'}`)) : ''; const warningsFormatted = warningsNumber ? external_picocolors_default().bold(external_picocolors_default().yellow(`${warningsNumber} ${1 === warningsNumber ? 'warning' : 'warnings'}`)) : ''; const timeFormatted = stats.startTime ? Math.round(Date.now() - stats.startTime) : 0; if (!errorsFormatted && !warningsFormatted) return external_picocolors_default().green(`[type-check] no errors found in ${timeFormatted} ms`); return [ '[type-check] found ', errorsFormatted, errorsFormatted && warningsFormatted ? ' and ' : '', warningsFormatted, timeFormatted ? ` in ${timeFormatted} ms` : '' ].join(''); } function createRspackFormatter(formatter, pathType) { return function(issue) { const color = 'warning' === issue.severity ? external_picocolors_default().yellow : external_picocolors_default().red; const severity = issue.severity.toUpperCase(); if (!issue.file) return [ `${external_picocolors_default().bold(color(severity))} in ` + formatter(issue), '' ].join(external_node_os_default().EOL); { let location = external_picocolors_default().bold('absolute' === pathType ? forwardSlash(external_node_path_default().resolve(issue.file)) : relativeToContext(issue.file, process.cwd())); if (issue.location) location += `:${external_picocolors_default().bold(external_picocolors_default().green(formatIssueLocation(issue.location)))}`; return [ `${external_picocolors_default().bold(color(severity))} in ${location}`, formatter(issue), '' ].join(external_node_os_default().EOL); } }; } function isPending(promise, timeout = 100) { return Promise.race([ promise.then(()=>false).catch(()=>false), new Promise((resolve)=>setTimeout(()=>resolve(true), timeout)) ]); } function wait(timeout) { return new Promise((resolve)=>setTimeout(resolve, timeout)); } function tapDoneToAsyncGetIssues(compiler, config, state) { const hooks = getPluginHooks(compiler); const { debug } = getInfrastructureLogger(compiler); compiler.hooks.done.tap('TsCheckerRspackPlugin', async (stats)=>{ if (stats.compilation.compiler !== compiler) return; const issuesPromise = state.issuesPromise; let issues; try { if (await isPending(issuesPromise)) { hooks.waiting.call(stats.compilation); config.logger.log(external_picocolors_default().cyan('[type-check] in progress...')); } else await wait(10); issues = await issuesPromise; } catch (error) { hooks.error.call(error, stats.compilation); return; } if (!issues || state.issuesPromise !== issuesPromise) return; debug(`Got ${issues?.length || 0} issues from getIssuesWorker.`); issues = issues.filter(config.issue.predicate); issues = hooks.issues.call(issues, stats.compilation); const formatter = createRspackFormatter(config.formatter.format, config.formatter.pathType); if (issues.length) config.logger.error(issues.map((issue)=>formatter(issue)).join('\n')); config.logger.log(statsFormatter(issues, stats)); if (issues.length && state.DevServerDoneTap) { issues.forEach((issue)=>{ const error = new IssueRspackError(config.formatter.format(issue), config.formatter.pathType, issue); if ('warning' === issue.severity) stats.compilation.warnings.push(error); else stats.compilation.errors.push(error); }); debug('Sending issues to the dev-server.'); state.DevServerDoneTap.fn(stats); } }); } function tapStartToRunWorkers(compiler, getIssuesWorker, getDependenciesWorker, config, state) { const hooks = getPluginHooks(compiler); const { log, debug } = getInfrastructureLogger(compiler); compiler.hooks.run.tap('TsCheckerRspackPlugin', ()=>{ if (!state.initialized) { debug('Initializing plugin for single run (not async).'); state.initialized = true; state.watching = false; tapAfterCompileToGetIssues(compiler, config, state); } }); compiler.hooks.watchRun.tap('TsCheckerRspackPlugin', async ()=>{ if (!state.initialized) { state.initialized = true; state.watching = true; if (config.async) { debug('Initializing plugin for watch run (async).'); tapDoneToAsyncGetIssues(compiler, config, state); interceptDoneToGetDevServerTap(compiler, config, state); } else { debug('Initializing plugin for watch run (not async).'); tapAfterCompileToGetIssues(compiler, config, state); } } }); compiler.hooks.compilation.tap('TsCheckerRspackPlugin', async (compilation)=>{ if (compilation.compiler !== compiler) return; const iteration = ++state.iteration; if (state.abortController) { debug(`Aborting iteration ${iteration - 1}.`); state.abortController.abort(); } const abortController = new AbortController(); state.abortController = abortController; let filesChange = {}; if (state.watching) { filesChange = consumeFilesChange(compiler); log([ 'Calling reporter service for incremental check.', ` Changed files: ${JSON.stringify(filesChange.changedFiles)}`, ` Deleted files: ${JSON.stringify(filesChange.deletedFiles)}` ].join('\n')); } else log('Calling reporter service for single check.'); filesChange = await hooks.start.promise(filesChange, compilation); let aggregatedFilesChange = filesChange; if (state.aggregatedFilesChange) { aggregatedFilesChange = aggregateFilesChanges([ aggregatedFilesChange, filesChange ]); debug([ `Aggregating with previous files change, iteration ${iteration}.`, ` Changed files: ${JSON.stringify(aggregatedFilesChange.changedFiles)}`, ` Deleted files: ${JSON.stringify(aggregatedFilesChange.deletedFiles)}` ].join('\n')); } state.aggregatedFilesChange = aggregatedFilesChange; state.issuesPromise = (state.issuesPromise || Promise.resolve()).catch(()=>void 0).then(()=>{ if (abortController.signal.aborted) return; debug(`Submitting the getIssuesWorker to the pool, iteration ${iteration}.`); return issuesPool.submit(async ()=>{ try { debug(`Running the getIssuesWorker, iteration ${iteration}.`); const issues = await getIssuesWorker(aggregatedFilesChange, state.watching, config.issue.defaultSeverity); if (state.aggregatedFilesChange === aggregatedFilesChange) state.aggregatedFilesChange = void 0; if (state.abortController === abortController) state.abortController = void 0; return issues; } catch (error) { hooks.error.call(error, compilation); return; } finally{ debug(`The getIssuesWorker finished its job, iteration ${iteration}.`); } }, abortController.signal); }); debug(`Submitting the getDependenciesWorker to the pool, iteration ${iteration}.`); state.dependenciesPromise = dependenciesPool.submit(async ()=>{ try { debug(`Running the getDependenciesWorker, iteration ${iteration}.`); return await getDependenciesWorker(filesChange); } catch (error) { hooks.error.call(error, compilation); return; } finally{ debug(`The getDependenciesWorker finished its job, iteration ${iteration}.`); } }); }); } function tapStopToTerminateWorkers(compiler, getIssuesWorker, getDependenciesWorker, state) { const { debug } = getInfrastructureLogger(compiler); const terminateWorkers = ()=>{ debug('Compiler is going to close - terminating workers...'); getIssuesWorker.terminate(); getDependenciesWorker.terminate(); }; compiler.hooks.watchClose.tap('TsCheckerRspackPlugin', ()=>{ terminateWorkers(); }); compiler.hooks.done.tap('TsCheckerRspackPlugin', ()=>{ if (!state.watching) terminateWorkers(); }); compiler.hooks.failed.tap('TsCheckerRspackPlugin', ()=>{ if (!state.watching) terminateWorkers(); }); } function createBasicFormatter() { return function(issue) { return external_picocolors_default().gray(issue.code + ': ') + issue.message; }; } const code_frame_namespaceObject = require("@babel/code-frame"); const external_node_fs_namespaceObject = require("node:fs"); var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject); function createCodeFrameFormatter(options) { const basicFormatter = createBasicFormatter(); return function(issue) { const source = issue.file && external_node_fs_default().existsSync(issue.file) && external_node_fs_default().readFileSync(issue.file, 'utf-8'); let frame = ''; if (source && issue.location) frame = (0, code_frame_namespaceObject.codeFrameColumns)(source, issue.location, { highlightCode: true, ...options || {} }).split('\n').map((line)=>' ' + line).join(external_node_os_default().EOL); const lines = [ basicFormatter(issue) ]; if (frame) lines.push(frame); return lines.join(external_node_os_default().EOL); }; } function createFormatterConfig(options) { if ('function' == typeof options) return { format: options, pathType: 'relative' }; const type = options ? 'object' == typeof options ? options.type || 'codeframe' : options : 'codeframe'; const pathType = options && 'object' == typeof options ? options.pathType || 'relative' : 'relative'; if (!type || 'basic' === type) return { format: createBasicFormatter(), pathType }; if ('codeframe' === type) { const config = options && 'object' == typeof options ? options.options || {} : {}; return { format: createCodeFrameFormatter(config), pathType }; } throw new Error(`Unknown "${type}" formatter. Available types are: "basic", "codeframe" or a custom function.`); } function createIssuePredicateFromIssueMatch(context, match) { return (issue)=>{ const matchesSeverity = !match.severity || match.severity === issue.severity; const matchesCode = !match.code || match.code === issue.code; const matchesFile = !issue.file || !!issue.file && (!match.file || (0, external_minimatch_namespaceObject.minimatch)(forwardSlash(external_node_path_default().relative(context, issue.file)), match.file)); return matchesSeverity && matchesCode && matchesFile; }; } function createTrivialIssuePredicate(result) { return ()=>result; } function composeIssuePredicates(predicates) { return (issue)=>predicates.some((predicate)=>predicate(issue)); } function createIssuePredicateFromOption(context, option) { if (Array.isArray(option)) return composeIssuePredicates(option.map((option)=>'function' == typeof option ? option : createIssuePredicateFromIssueMatch(context, option))); return 'function' == typeof option ? option : createIssuePredicateFromIssueMatch(context, option); } function createIssueConfig(compiler, options) { const context = compiler.options.context || process.cwd(); if (!options) options = {}; const include = options.include ? createIssuePredicateFromOption(context, options.include) : createTrivialIssuePredicate(true); const exclude = options.exclude ? createIssuePredicateFromOption(context, options.exclude) : createTrivialIssuePredicate(false); const defaultSeverity = options.defaultSeverity ?? 'auto'; return { predicate: (issue)=>include(issue) && !exclude(issue), defaultSeverity }; } function createTypeScriptWorkerConfig(compiler, options) { let configFile = 'object' == typeof options ? options.configFile || 'tsconfig.json' : 'tsconfig.json'; configFile = external_node_path_default().normalize(external_node_path_default().isAbsolute(configFile) ? configFile : external_node_path_default().resolve(compiler.options.context || process.cwd(), configFile)); const optionsAsObject = 'object' == typeof options ? options : {}; const typescriptPath = optionsAsObject.typescriptPath || require.resolve("typescript"); return { enabled: Boolean(options) || void 0 === options, memoryLimit: 8192, build: false, mode: optionsAsObject.build ? 'write-tsbuildinfo' : 'readonly', profile: false, ...optionsAsObject, configFile: configFile, configOverwrite: optionsAsObject.configOverwrite || {}, context: optionsAsObject.context || external_node_path_default().dirname(configFile), diagnosticOptions: { syntactic: false, semantic: true, declaration: false, global: false, ...optionsAsObject.diagnosticOptions || {} }, typescriptPath: typescriptPath }; } function createPluginConfig(compiler, options = {}) { return { async: void 0 === options.async ? 'development' === compiler.options.mode : options.async, typescript: createTypeScriptWorkerConfig(compiler, options.typescript), issue: createIssueConfig(compiler, options.issue), formatter: createFormatterConfig(options.formatter), logger: 'webpack-infrastructure' === options.logger ? (()=>{ const { info, error } = getInfrastructureLogger(compiler); return { log: info, error }; })() : options.logger || console, devServer: false !== options.devServer }; } function createPluginState() { return { issuesPromise: Promise.resolve(void 0), dependenciesPromise: Promise.resolve(void 0), abortController: void 0, aggregatedFilesChange: void 0, lastDependencies: void 0, watching: false, initialized: false, iteration: 0, DevServerDoneTap: void 0 }; } function assertTypeScriptSupport(config) { let typescriptVersion; try { typescriptVersion = require(config.typescriptPath).version; } catch {} if (!typescriptVersion) throw new Error("When you use TsCheckerRspackPlugin with typescript reporter enabled, you must install `typescript` package."); if (!external_node_fs_default().existsSync(config.configFile)) throw new Error([ `Cannot find the "${config.configFile}" file.`, "Please check Rspack and TsCheckerRspackPlugin configuration.", "Possible errors:", ' - wrong `context` directory in Rspack configuration (if `configFile` is not set or is a relative path in the fork plugin configuration)', " - wrong `typescript.configFile` path in the plugin configuration (should be a relative or absolute path)" ].join(external_node_os_default().EOL)); } function plugin_define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } const pkgJson = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(external_node_path_namespaceObject.join(__dirname, '../package.json'), 'utf-8')); class TsCheckerRspackPlugin { static getCompilerHooks(compiler) { return getPluginHooks(compiler); } apply(compiler) { const config = createPluginConfig(compiler, this.options); const state = createPluginState(); assertTypeScriptSupport(config.typescript); const getIssuesWorker = createRpcWorker(external_node_path_namespaceObject.resolve(__dirname, './getIssuesWorker.js'), config.typescript, config.typescript.memoryLimit); const getDependenciesWorker = createRpcWorker(external_node_path_namespaceObject.resolve(__dirname, './getDependenciesWorker.js'), config.typescript); tapAfterEnvironmentToPatchWatching(compiler, state); tapStartToRunWorkers(compiler, getIssuesWorker, getDependenciesWorker, config, state); tapAfterCompileToAddDependencies(compiler, config, state); tapStopToTerminateWorkers(compiler, getIssuesWorker, getDependenciesWorker, state); tapErrorToLogMessage(compiler, config); } constructor(options = {}){ plugin_define_property(this, "options", void 0); this.options = options; } } plugin_define_property(TsCheckerRspackPlugin, "version", pkgJson.version); plugin_define_property(TsCheckerRspackPlugin, "issuesPool", issuesPool); plugin_define_property(TsCheckerRspackPlugin, "dependenciesPool", dependenciesPool); plugin_define_property(TsCheckerRspackPlugin, "pool", issuesPool); exports.TsCheckerRspackPlugin = __webpack_exports__.TsCheckerRspackPlugin; for(var __webpack_i__ in __webpack_exports__)if (-1 === [ "TsCheckerRspackPlugin" ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; Object.defineProperty(exports, '__esModule', { value: true });