@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
JavaScript
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