import { bold, cyan, underline } from "kleur/colors"; import path from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; import { loadTSConfig } from "../core/config/tsconfig.js"; import { appendForwardSlash } from "../core/path.js"; import { createContentTypesGenerator } from "./types-generator.js"; import { getContentPaths, globalContentConfigObserver } from "./utils.js"; async function attachContentServerListeners({ viteServer, fs, logger, settings }) { const contentPaths = getContentPaths(settings.config, fs); if (fs.existsSync(contentPaths.contentDir)) { logger.debug( "content", `Watching ${cyan( contentPaths.contentDir.href.replace(settings.config.root.href, "") )} for changes` ); const maybeTsConfigStats = await getTSConfigStatsWhenAllowJsFalse({ contentPaths, settings }); if (maybeTsConfigStats) warnAllowJsIsFalse({ ...maybeTsConfigStats, logger }); await attachListeners(); } else { viteServer.watcher.on("addDir", contentDirListener); async function contentDirListener(dir) { if (appendForwardSlash(pathToFileURL(dir).href) === contentPaths.contentDir.href) { logger.debug("content", `Content directory found. Watching for changes`); await attachListeners(); viteServer.watcher.removeListener("addDir", contentDirListener); } } } async function attachListeners() { const contentGenerator = await createContentTypesGenerator({ fs, settings, logger, viteServer, contentConfigObserver: globalContentConfigObserver }); await contentGenerator.init(); logger.debug("content", "Types generated"); viteServer.watcher.on("add", (entry) => { contentGenerator.queueEvent({ name: "add", entry }); }); viteServer.watcher.on( "addDir", (entry) => contentGenerator.queueEvent({ name: "addDir", entry }) ); viteServer.watcher.on( "change", (entry) => contentGenerator.queueEvent({ name: "change", entry }) ); viteServer.watcher.on("unlink", (entry) => { contentGenerator.queueEvent({ name: "unlink", entry }); }); viteServer.watcher.on( "unlinkDir", (entry) => contentGenerator.queueEvent({ name: "unlinkDir", entry }) ); } } function warnAllowJsIsFalse({ logger, tsConfigFileName, contentConfigFileName }) { logger.warn( "content", `Make sure you have the ${bold("allowJs")} compiler option set to ${bold( "true" )} in your ${bold(tsConfigFileName)} file to have autocompletion in your ${bold( contentConfigFileName )} file. See ${underline( cyan("https://www.typescriptlang.org/tsconfig#allowJs") )} for more information.` ); } async function getTSConfigStatsWhenAllowJsFalse({ contentPaths, settings }) { const isContentConfigJsFile = [".js", ".mjs"].some( (ext) => contentPaths.config.url.pathname.endsWith(ext) ); if (!isContentConfigJsFile) return; const inputConfig = await loadTSConfig(fileURLToPath(settings.config.root)); if (typeof inputConfig === "string") return; const tsConfigFileName = inputConfig.tsconfigFile.split(path.sep).pop(); if (!tsConfigFileName) return; const contentConfigFileName = contentPaths.config.url.pathname.split(path.sep).pop(); const allowJSOption = inputConfig.tsconfig.compilerOptions?.allowJs; if (allowJSOption) return; return { tsConfigFileName, contentConfigFileName }; } export { attachContentServerListeners };