{"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["import { spawn } from 'node:child_process'\nimport { npmRunPathEnv, type ProcessEnv } from 'npm-run-path'\nimport colors from 'picocolors'\n\nimport type { ConfigEnv, Logger, Plugin } from 'vite'\nimport { Checker } from './Checker.js'\nimport {\n composePreambleCode,\n RUNTIME_CLIENT_ENTRY_PATH,\n RUNTIME_CLIENT_RUNTIME_PATH,\n runtimeCode,\n WS_CHECKER_RECONNECT_EVENT,\n wrapVirtualPrefix,\n} from './client/index.js'\nimport {\n ACTION_TYPES,\n type Action,\n type BuildCheckBinStr,\n type BuildInCheckerNames,\n type ClientDiagnosticPayload,\n type ClientReconnectPayload,\n type PluginConfig,\n type ServeAndBuildChecker,\n type UserPluginConfig,\n} from './types.js'\n\nconst buildInCheckerKeys: BuildInCheckerNames[] = [\n 'typescript',\n 'vueTsc',\n 'eslint',\n 'stylelint',\n 'biome',\n 'oxlint',\n]\n\nasync function createCheckers(\n userConfig: UserPluginConfig,\n env: ConfigEnv,\n): Promise {\n const serveAndBuildCheckers: ServeAndBuildChecker[] = []\n const { enableBuild, overlay } = userConfig\n const sharedConfig = { enableBuild, overlay }\n\n // buildInCheckerKeys.forEach(async (name: BuildInCheckerNames) => {\n for (const name of buildInCheckerKeys) {\n if (!userConfig[name]) continue\n const { createServeAndBuild } = await import(`./checkers/${name}/main.js`)\n serveAndBuildCheckers.push(\n createServeAndBuild({ [name]: userConfig[name], ...sharedConfig }, env),\n )\n }\n\n return serveAndBuildCheckers\n}\n\nexport function checker(userConfig: UserPluginConfig): Plugin {\n const enableBuild = userConfig?.enableBuild ?? true\n const enableOverlay = userConfig?.overlay !== false\n const enableTerminal = userConfig?.terminal !== false\n const overlayConfig =\n typeof userConfig?.overlay === 'object' ? userConfig?.overlay : {}\n let initialized = false\n let initializeCounter = 0\n let checkers: ServeAndBuildChecker[] = []\n let isProduction = false\n let baseWithOrigin: string\n let viteMode: ConfigEnv['command'] | undefined\n let buildWatch = false\n let logger: Logger | null = null\n let checkerPromise: Promise | null = null\n\n return {\n name: 'vite-plugin-checker',\n enforce: 'pre',\n // @ts-expect-error\n __internal__checker: Checker,\n config: async (_config, env) => {\n // for dev mode (1/2)\n // Initialize checker with config\n viteMode = env.command\n // avoid running twice when running in SSR\n if (initializeCounter === 0) {\n initializeCounter++\n } else {\n initialized = true\n return\n }\n\n checkers = await createCheckers(userConfig || {}, env)\n if (viteMode !== 'serve') return\n\n for (const checker of checkers) {\n const workerConfig = checker.serve.config\n workerConfig({\n enableOverlay,\n enableTerminal,\n env,\n })\n }\n },\n configResolved(config) {\n logger = config.logger\n baseWithOrigin = config.server.origin\n ? config.server.origin + config.base\n : config.base\n isProduction ||= config.isProduction || config.command === 'build'\n buildWatch = !!config.build.watch\n },\n async buildEnd() {\n if (viteMode !== 'serve') {\n await checkerPromise\n }\n\n if (initialized) return\n\n if (viteMode === 'serve') {\n for (const checker of checkers) {\n const { worker } = checker.serve\n worker.terminate()\n }\n }\n },\n resolveId(id) {\n if (\n id === RUNTIME_CLIENT_RUNTIME_PATH ||\n id === RUNTIME_CLIENT_ENTRY_PATH\n ) {\n return wrapVirtualPrefix(id)\n }\n\n return\n },\n load(id) {\n if (id === wrapVirtualPrefix(RUNTIME_CLIENT_RUNTIME_PATH)) {\n return runtimeCode\n }\n\n if (id === wrapVirtualPrefix(RUNTIME_CLIENT_ENTRY_PATH)) {\n return composePreambleCode({\n baseWithOrigin,\n overlayConfig,\n useBase: false,\n })\n }\n\n return\n },\n transformIndexHtml() {\n if (initialized) return\n if (isProduction) return\n\n return [\n {\n tag: 'script',\n attrs: { type: 'module' },\n children: composePreambleCode({ baseWithOrigin, overlayConfig }),\n },\n ]\n },\n buildStart: () => {\n if (initialized) return\n // only run in build mode\n // run a bin command in a separated process\n if (!isProduction || !enableBuild) return\n\n const localEnv = npmRunPathEnv({\n env: process.env,\n cwd: process.cwd(),\n execPath: process.execPath,\n })\n\n const spawnedCheckers = checkers.map((checker) =>\n spawnChecker(checker, userConfig, localEnv),\n )\n\n // wait for checker states while avoiding blocking the build from continuing in parallel\n checkerPromise = Promise.all(spawnedCheckers).then((exitCodes) => {\n const exitCode = exitCodes.find((code) => code !== 0) ?? 0\n // do not exit the process if run `vite build --watch`\n if (exitCode !== 0 && !buildWatch) {\n process.exit(exitCode)\n }\n })\n },\n configureServer(server) {\n if (initialized) return\n\n const latestOverlayErrors: ClientReconnectPayload['data'] = new Array(\n checkers.length,\n )\n // for dev mode (2/2)\n // Get the server instance and keep reference in a closure\n checkers.forEach((checker, index) => {\n const { worker, configureServer: workerConfigureServer } = checker.serve\n workerConfigureServer({ root: userConfig.root || server.config.root })\n worker.on('message', (action: Action) => {\n if (action.type === ACTION_TYPES.overlayError) {\n latestOverlayErrors[index] =\n action.payload as ClientDiagnosticPayload\n if (action.payload) {\n server.ws.send('vite-plugin-checker', action.payload)\n }\n } else if (action.type === ACTION_TYPES.console) {\n if (Checker.logger.length) {\n // for test injection and customize logger in the future\n Checker.log(action)\n } else {\n logger![action.level](action.payload)\n }\n }\n })\n })\n\n if (server.ws.on) {\n server.watcher.on('change', () => {\n logger!.clearScreen('error')\n })\n server.ws.on('vite-plugin-checker', (data) => {\n // NOTE: sync modification with packages /packages/runtime/src/ws.js\n if (data.event === 'runtime-loaded') {\n server.ws.send('vite-plugin-checker', {\n event: WS_CHECKER_RECONNECT_EVENT,\n data: latestOverlayErrors.filter(Boolean),\n })\n }\n })\n } else {\n setTimeout(() => {\n logger!.warn(\n colors.yellow(\n '[vite-plugin-checker]: `server.ws.on` is introduced to Vite in 2.6.8, see [PR](https://github.com/vitejs/vite/pull/5273) and [changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md#268-2021-10-18). \\nvite-plugin-checker relies on `server.ws.on` to send overlay message to client. Support for Vite < 2.6.8 will be removed in the next major version release.',\n ),\n )\n // make a delay to avoid flush by Vite's console\n }, 5000)\n }\n },\n }\n}\n\nfunction spawnChecker(\n checker: ServeAndBuildChecker,\n userConfig: Partial,\n localEnv: ProcessEnv,\n) {\n return new Promise((resolve) => {\n const buildBin = checker.build.buildBin\n const finalBin: BuildCheckBinStr =\n typeof buildBin === 'function' ? buildBin(userConfig) : buildBin\n\n const [command, args] = finalBin\n const commandWithArgs = [command, ...args].join(' ')\n\n const proc = spawn(commandWithArgs, {\n cwd: process.cwd(),\n stdio: 'inherit',\n env: localEnv,\n // shell is necessary on windows to get the process to even start.\n // Command line args constructed by checkers therefore need to escape double quotes\n // to have them not striped out by cmd.exe. Using shell on all platforms lets us avoid\n // having to perform platform-specific logic around escaping quotes since all platform\n // shells will strip out unescaped double quotes. E.g. shell=false on linux only would\n // result in escaped quotes not being unescaped.\n shell: true,\n })\n\n proc.on('exit', (code) => {\n if (code !== null && code !== 0) {\n resolve(code)\n } else {\n resolve(0)\n }\n })\n })\n}\n\nexport default checker\n"],"mappings":"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"}