UNPKG

@intlayer/chokidar

Version:

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

157 lines (155 loc) 6.22 kB
import { readDictionariesFromDisk } from "../utils/readDictionariesFromDisk.mjs"; import { getFormatFromExtension } from "../utils/getFormatFromExtension.mjs"; import { detectFormatCommand } from "../detectFormatCommand.mjs"; import { processContentDeclarationContent } from "./processContentDeclarationContent.mjs"; import { transformJSONFile } from "./transformJSONFile.mjs"; import { writeJSFile } from "./writeJSFile.mjs"; import { writeMarkdownFile } from "./writeMarkdownFile.mjs"; import { writeYamlFile } from "./writeYamlFile.mjs"; import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises"; import { basename, dirname, extname, join, resolve } from "node:path"; import { existsSync } from "node:fs"; import { COMPILER_NO_METADATA } from "@intlayer/config/defaultValues"; import { getFilteredLocalesDictionary, getPerLocaleDictionary } from "@intlayer/core/plugins"; import { execSync } from "node:child_process"; import { isDeepStrictEqual } from "node:util"; //#region src/writeContentDeclaration/writeContentDeclaration.ts const formatContentDeclaration = async (dictionary, configuration, localeList) => { /** * Clean Markdown, Insertion, File, etc. node metadata */ const processedDictionary = await processContentDeclarationContent(dictionary); let content = processedDictionary.content; /** * Filter locales content */ if (dictionary.locale) content = getPerLocaleDictionary(processedDictionary, dictionary.locale).content; else if (localeList) content = getFilteredLocalesDictionary(processedDictionary, localeList).content; let pluginFormatResult = { ...dictionary, content }; /** * Format the dictionary with the plugins */ for await (const plugin of configuration.plugins ?? []) if (plugin.formatOutput) { const formattedResult = await plugin.formatOutput?.({ dictionary: pluginFormatResult, configuration }); if (formattedResult) pluginFormatResult = formattedResult; } if (!(pluginFormatResult.content && pluginFormatResult.key)) return pluginFormatResult; let result = { key: dictionary.key, id: dictionary.id, title: dictionary.title, description: dictionary.description, tags: dictionary.tags, locale: dictionary.locale, fill: dictionary.fill, filled: dictionary.filled, priority: dictionary.priority, importMode: dictionary.importMode, version: dictionary.version, content }; if (getFormatFromExtension(dictionary.filePath ? extname(dictionary.filePath) : ".json") === "json" && pluginFormatResult.content && pluginFormatResult.key) result = { $schema: "https://intlayer.org/schema.json", ...result }; return result; }; const defaultOptions = { newDictionariesPath: "intlayer-dictionaries" }; const writeContentDeclaration = async (dictionary, configuration, options) => { const { system, compiler } = configuration; const { baseDir } = system; const noMetadata = compiler?.noMetadata ?? COMPILER_NO_METADATA; const { newDictionariesPath, localeList } = { ...defaultOptions, ...options }; const newDictionaryLocationPath = join(baseDir, newDictionariesPath); const existingDictionary = readDictionariesFromDisk(configuration.system.unmergedDictionariesDir)[dictionary.key]?.find((el) => el.localId === dictionary.localId); const formattedContentDeclaration = await formatContentDeclaration(dictionary, configuration, localeList); if (existingDictionary?.filePath) { const isSameContent = isDeepStrictEqual(existingDictionary, dictionary); const filePath = resolve(configuration.system.baseDir, existingDictionary.filePath); if (isSameContent) return { status: "up-to-date", path: filePath }; await writeFileWithDirectories(filePath, formattedContentDeclaration, configuration, noMetadata); return { status: "updated", path: filePath }; } if (dictionary.filePath) { const filePath = resolve(configuration.system.baseDir, dictionary.filePath); await writeFileWithDirectories(filePath, formattedContentDeclaration, configuration, noMetadata); return { status: "created", path: filePath }; } const contentDeclarationPath = join(newDictionaryLocationPath, `${dictionary.key}.content.json`); await writeFileWithDirectories(contentDeclarationPath, formattedContentDeclaration, configuration, noMetadata); return { status: "imported", path: contentDeclarationPath }; }; const writeFileWithDirectories = async (absoluteFilePath, dictionary, configuration, noMetadata) => { await mkdir(dirname(absoluteFilePath), { recursive: true }); const extension = extname(absoluteFilePath); if (extension === ".md" || extension === ".mdx") { await writeMarkdownFile(absoluteFilePath, dictionary, configuration); return; } if (extension === ".yaml" || extension === ".yml") { await writeYamlFile(absoluteFilePath, dictionary, configuration); return; } if ([ ".json", ".jsonc", ".json5" ].includes(extension)) { let fileContent = "{}"; if (existsSync(absoluteFilePath)) try { fileContent = await readFile(absoluteFilePath, "utf-8"); } catch {} const transformedContent = transformJSONFile(fileContent, dictionary, noMetadata); const tempDir = configuration.system?.tempDir; if (tempDir) await mkdir(tempDir, { recursive: true }); const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`; const tempPath = tempDir ? join(tempDir, tempFileName) : `${absoluteFilePath}.${tempFileName}`; try { await writeFile(tempPath, transformedContent, "utf-8"); await rename(tempPath, absoluteFilePath); } catch (error) { try { await rm(tempPath, { force: true }); } catch {} throw error; } const formatCommand = detectFormatCommand(configuration); if (formatCommand) try { execSync(formatCommand.replace("{{file}}", absoluteFilePath), { stdio: "inherit", cwd: configuration.system.baseDir }); } catch (error) { console.error(error); } return; } await writeJSFile(absoluteFilePath, dictionary, configuration, noMetadata); try { await rm(join(configuration.system.cacheDir, "intlayer-prepared.lock"), { recursive: true }); } catch {} }; //#endregion export { writeContentDeclaration }; //# sourceMappingURL=writeContentDeclaration.mjs.map