UNPKG

@intlayer/chokidar

Version:

Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.

128 lines (126 loc) 5.59 kB
import { parallelize } from "../utils/parallelize.mjs"; import { filterInvalidDictionaries } from "../filterInvalidDictionaries.mjs"; import { processContentDeclaration } from "../buildIntlayerDictionary/processContentDeclaration.mjs"; import { getIntlayerBundle } from "./getIntlayerBundle.mjs"; import { loadMarkdownContentDeclaration } from "./loadMarkdownContentDeclaration.mjs"; import { loadYamlContentDeclaration } from "./loadYamlContentDeclaration.mjs"; import { logTypeScriptErrors } from "./logTypeScriptErrors.mjs"; import { readFile, writeFile } from "node:fs/promises"; import { dirname, extname, join, relative } from "node:path"; import { cacheDisk, getPackageJsonPath, getProjectRequire } from "@intlayer/config/utils"; import { loadExternalFile } from "@intlayer/config/file"; //#region src/loadDictionaries/loadContentDeclaration.ts const formatLocalDictionaries = (dictionariesRecord, configuration) => Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({ ...dict, location: dict.location ?? configuration.dictionary?.location ?? "local", localId: `${dict.key}::local::${relativePath}`, filePath: relativePath })); const ensureIntlayerBundle = async (configuration) => { const { system } = configuration; const { set, isValid } = cacheDisk(configuration, ["intlayer-bundle"], { ttlMs: 1e3 * 60 * 60 * 24 * 5 }); const filePath = join(system.cacheDir, "intlayer-bundle.cjs"); if (!await isValid()) { await writeFile(filePath, await getIntlayerBundle(configuration)); await set("ok"); } return filePath; }; let cachedExternalDeps = null; const getExternalDeps = async (baseDir) => { if (cachedExternalDeps) return cachedExternalDeps; try { const packageJSON = await readFile(getPackageJsonPath(baseDir).packageJsonPath, "utf-8"); const parsedPackages = JSON.parse(packageJSON); const allDependencies = Object.keys({ ...parsedPackages.dependencies, ...parsedPackages.devDependencies }); const esmPackagesToBundle = []; const externalDeps = allDependencies.filter((dep) => !esmPackagesToBundle.includes(dep)); externalDeps.push("esbuild"); cachedExternalDeps = externalDeps; } catch (error) { console.warn("Could not read package.json for externalizing dependencies, fallback to empty array", error); cachedExternalDeps = ["esbuild"]; } return cachedExternalDeps; }; const loadContentDeclaration = async (path, configuration, bundleFilePath, options) => { if (extname(path) === ".md" || extname(path) === ".mdx") return loadMarkdownContentDeclaration(path); if (extname(path) === ".yaml" || extname(path) === ".yml") return loadYamlContentDeclaration(path); const { build, system } = configuration; const externalDeps = await getExternalDeps(system.baseDir); const resolvedBundleFilePath = bundleFilePath ?? await ensureIntlayerBundle(configuration); try { return await loadExternalFile(path, { logError: options?.logError, projectRequire: build.require ?? getProjectRequire(), buildOptions: { packages: void 0, external: externalDeps, banner: { js: [ `var __filename = ${JSON.stringify(path)};`, `var __dirname = ${JSON.stringify(dirname(path))};`, `globalThis.INTLAYER_FILE_PATH = '${path}';`, `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';` ].join("\n") } }, aliases: { intlayer: resolvedBundleFilePath }, preloadGlobals: { INTLAYER_FILE_PATH: path, INTLAYER_BASE_DIR: configuration.system.baseDir } }); } catch (error) { console.error(`Error loading content declaration at ${path}:`, error); return; } }; const loadContentDeclarations = async (contentDeclarationFilePath, configuration, onStatusUpdate, options) => { const { build, system } = configuration; if (build.checkTypes) logTypeScriptErrors(contentDeclarationFilePath, configuration).catch((e) => { console.error("Error during TypeScript validation:", e); }); const bundleFilePath = await ensureIntlayerBundle(configuration); try { const dictionariesPromises = contentDeclarationFilePath.map(async (path) => { return { relativePath: relative(system.baseDir, path), dictionary: await loadContentDeclaration(path, configuration, bundleFilePath, options) }; }); const contentDeclarations = formatLocalDictionaries((await Promise.all(dictionariesPromises)).reduce((acc, { relativePath, dictionary }) => { if (dictionary) acc[relativePath] = dictionary; return acc; }, {}), configuration).filter((dictionary) => dictionary.location !== "remote"); const listFoundDictionaries = contentDeclarations.map((declaration) => ({ dictionaryKey: declaration.key, type: "local", status: "found" })); onStatusUpdate?.(listFoundDictionaries); return filterInvalidDictionaries(await parallelize(contentDeclarations, async (contentDeclaration) => { if (!contentDeclaration) return; onStatusUpdate?.([{ dictionaryKey: contentDeclaration.key, type: "local", status: "building" }]); const processedContentDeclaration = await processContentDeclaration(contentDeclaration, configuration); if (!processedContentDeclaration) return; onStatusUpdate?.([{ dictionaryKey: processedContentDeclaration.key, type: "local", status: "built" }]); return processedContentDeclaration; }), configuration, { checkSchema: false }); } catch { console.error("Error loading content declarations"); } return []; }; //#endregion export { ensureIntlayerBundle, formatLocalDictionaries, loadContentDeclaration, loadContentDeclarations }; //# sourceMappingURL=loadContentDeclaration.mjs.map