@nlabs/lex
Version:
100 lines (99 loc) • 12.3 kB
JavaScript
/**
* Copyright (c) 2025-Present, Nitrogen Labs, Inc.
* Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
*/ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import { sync as globSync } from 'glob';
import { resolve as pathResolve } from 'path';
import { log } from './log.js';
const flattenTranslations = (obj, prefix = '')=>{
let flattened = {};
for(const key in obj){
const value = obj[key];
const newKey = prefix ? `${prefix}.${key}` : key;
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
flattened = {
...flattened,
...flattenTranslations(value, newKey)
};
} else {
flattened[newKey] = String(value);
}
}
return flattened;
};
const findTranslationFiles = (sourcePath)=>{
const patterns = [
'**/translations/*.json',
'**/i18n/*.json',
'**/locales/*.json',
'**/lang/*.json'
];
const files = [];
patterns.forEach((pattern)=>{
try {
const matches = globSync(pattern, {
absolute: true,
cwd: sourcePath,
nodir: true
});
files.push(...matches);
} catch {}
});
return files;
};
export const processTranslations = async (sourcePath, outputPath, quiet = false)=>{
if (!existsSync(sourcePath)) {
log(`Source path does not exist: ${sourcePath}`, 'error', quiet);
return;
}
log('Finding translation files...', 'info', quiet);
const translationFiles = findTranslationFiles(sourcePath);
if (translationFiles.length === 0) {
log('No translation files found', 'warn', quiet);
return;
}
log(`Found ${translationFiles.length} translation files`, 'info', quiet);
let allTranslations = {};
for (const filePath of translationFiles){
try {
const content = readFileSync(filePath, 'utf8');
const data = JSON.parse(content);
allTranslations = {
...allTranslations,
...data
};
log(`Processed: ${filePath}`, 'info', quiet);
} catch (error) {
log(`Error processing ${filePath}: ${error.message}`, 'error', quiet);
}
}
const flattenedTranslations = flattenTranslations(allTranslations);
const outputFile = pathResolve(outputPath, 'translations.json');
try {
const outputDir = pathResolve(outputPath);
if (!existsSync(outputDir)) {
mkdirSync(outputDir, {
recursive: true
});
}
writeFileSync(outputFile, JSON.stringify(flattenedTranslations, null, 2), 'utf8');
log(`Translations written to: ${outputFile}`, 'info', quiet);
} catch (error) {
log(`Error writing translations file: ${error.message}`, 'error', quiet);
}
const srcDir = pathResolve(sourcePath, 'src');
const srcOutputFile = existsSync(srcDir) ? pathResolve(srcDir, 'translations.json') : pathResolve(sourcePath, 'translations.json');
try {
const ensureDir = existsSync(srcDir) ? srcDir : sourcePath;
if (!existsSync(ensureDir)) {
mkdirSync(ensureDir, {
recursive: true
});
}
writeFileSync(srcOutputFile, JSON.stringify(flattenedTranslations, null, 2), 'utf8');
log(`Translations written to: ${srcOutputFile}`, 'info', quiet);
} catch (error) {
log(`Error writing translations file to src: ${error.message}`, 'error', quiet);
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy90cmFuc2xhdGlvbnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjUtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhpc3RzU3luYywgbWtkaXJTeW5jLCByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmN9IGZyb20gJ2ZzJztcbmltcG9ydCB7c3luYyBhcyBnbG9iU3luY30gZnJvbSAnZ2xvYic7XG5pbXBvcnQge3Jlc29sdmUgYXMgcGF0aFJlc29sdmV9IGZyb20gJ3BhdGgnO1xuXG5pbXBvcnQge2xvZ30gZnJvbSAnLi9sb2cuanMnO1xuXG5jb25zdCBmbGF0dGVuVHJhbnNsYXRpb25zID0gKG9iajogYW55LCBwcmVmaXggPSAnJyk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPT4ge1xuICBsZXQgZmxhdHRlbmVkOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgZm9yKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICBjb25zdCB2YWx1ZSA9IG9ialtrZXldO1xuICAgIGNvbnN0IG5ld0tleSA9IHByZWZpeCA/IGAke3ByZWZpeH0uJHtrZXl9YCA6IGtleTtcblxuICAgIGlmKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICBmbGF0dGVuZWQgPSB7Li4uZmxhdHRlbmVkLCAuLi5mbGF0dGVuVHJhbnNsYXRpb25zKHZhbHVlLCBuZXdLZXkpfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdHRlbmVkW25ld0tleV0gPSBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmbGF0dGVuZWQ7XG59O1xuXG5jb25zdCBmaW5kVHJhbnNsYXRpb25GaWxlcyA9IChzb3VyY2VQYXRoOiBzdHJpbmcpOiBzdHJpbmdbXSA9PiB7XG4gIGNvbnN0IHBhdHRlcm5zID0gW1xuICAgICcqKi90cmFuc2xhdGlvbnMvKi5qc29uJyxcbiAgICAnKiovaTE4bi8qLmpzb24nLFxuICAgICcqKi9sb2NhbGVzLyouanNvbicsXG4gICAgJyoqL2xhbmcvKi5qc29uJ1xuICBdO1xuXG4gIGNvbnN0IGZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHBhdHRlcm5zLmZvckVhY2goKHBhdHRlcm4pID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbWF0Y2hlcyA9IGdsb2JTeW5jKHBhdHRlcm4sIHtcbiAgICAgICAgYWJzb2x1dGU6IHRydWUsXG4gICAgICAgIGN3ZDogc291cmNlUGF0aCxcbiAgICAgICAgbm9kaXI6IHRydWVcbiAgICAgIH0pO1xuICAgICAgZmlsZXMucHVzaCguLi5tYXRjaGVzKTtcbiAgICB9IGNhdGNoe1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGZpbGVzO1xufTtcblxuZXhwb3J0IGNvbnN0IHByb2Nlc3NUcmFuc2xhdGlvbnMgPSBhc3luYyAoXG4gIHNvdXJjZVBhdGg6IHN0cmluZyxcbiAgb3V0cHV0UGF0aDogc3RyaW5nLFxuICBxdWlldDogYm9vbGVhbiA9IGZhbHNlXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgaWYoIWV4aXN0c1N5bmMoc291cmNlUGF0aCkpIHtcbiAgICBsb2coYFNvdXJjZSBwYXRoIGRvZXMgbm90IGV4aXN0OiAke3NvdXJjZVBhdGh9YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxvZygnRmluZGluZyB0cmFuc2xhdGlvbiBmaWxlcy4uLicsICdpbmZvJywgcXVpZXQpO1xuXG4gIGNvbnN0IHRyYW5zbGF0aW9uRmlsZXMgPSBmaW5kVHJhbnNsYXRpb25GaWxlcyhzb3VyY2VQYXRoKTtcblxuICBpZih0cmFuc2xhdGlvbkZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIGxvZygnTm8gdHJhbnNsYXRpb24gZmlsZXMgZm91bmQnLCAnd2FybicsIHF1aWV0KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBsb2coYEZvdW5kICR7dHJhbnNsYXRpb25GaWxlcy5sZW5ndGh9IHRyYW5zbGF0aW9uIGZpbGVzYCwgJ2luZm8nLCBxdWlldCk7XG5cbiAgbGV0IGFsbFRyYW5zbGF0aW9uczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuXG4gIGZvcihjb25zdCBmaWxlUGF0aCBvZiB0cmFuc2xhdGlvbkZpbGVzKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVN5bmMoZmlsZVBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZShjb250ZW50KTtcblxuICAgICAgYWxsVHJhbnNsYXRpb25zID0gey4uLmFsbFRyYW5zbGF0aW9ucywgLi4uZGF0YX07XG5cbiAgICAgIGxvZyhgUHJvY2Vzc2VkOiAke2ZpbGVQYXRofWAsICdpbmZvJywgcXVpZXQpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGxvZyhgRXJyb3IgcHJvY2Vzc2luZyAke2ZpbGVQYXRofTogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBmbGF0dGVuZWRUcmFuc2xhdGlvbnMgPSBmbGF0dGVuVHJhbnNsYXRpb25zKGFsbFRyYW5zbGF0aW9ucyk7XG4gIGNvbnN0IG91dHB1dEZpbGUgPSBwYXRoUmVzb2x2ZShvdXRwdXRQYXRoLCAndHJhbnNsYXRpb25zLmpzb24nKTtcblxuICB0cnkge1xuICAgIGNvbnN0IG91dHB1dERpciA9IHBhdGhSZXNvbHZlKG91dHB1dFBhdGgpO1xuXG4gICAgaWYoIWV4aXN0c1N5bmMob3V0cHV0RGlyKSkge1xuICAgICAgbWtkaXJTeW5jKG91dHB1dERpciwge3JlY3Vyc2l2ZTogdHJ1ZX0pO1xuICAgIH1cblxuICAgIHdyaXRlRmlsZVN5bmMob3V0cHV0RmlsZSwgSlNPTi5zdHJpbmdpZnkoZmxhdHRlbmVkVHJhbnNsYXRpb25zLCBudWxsLCAyKSwgJ3V0ZjgnKTtcbiAgICBsb2coYFRyYW5zbGF0aW9ucyB3cml0dGVuIHRvOiAke291dHB1dEZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2coYEVycm9yIHdyaXRpbmcgdHJhbnNsYXRpb25zIGZpbGU6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG4gIH1cblxuICBjb25zdCBzcmNEaXIgPSBwYXRoUmVzb2x2ZShzb3VyY2VQYXRoLCAnc3JjJyk7XG4gIGNvbnN0IHNyY091dHB1dEZpbGUgPSBleGlzdHNTeW5jKHNyY0RpcikgPyBwYXRoUmVzb2x2ZShzcmNEaXIsICd0cmFuc2xhdGlvbnMuanNvbicpIDogcGF0aFJlc29sdmUoc291cmNlUGF0aCwgJ3RyYW5zbGF0aW9ucy5qc29uJyk7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBlbnN1cmVEaXIgPSBleGlzdHNTeW5jKHNyY0RpcikgPyBzcmNEaXIgOiBzb3VyY2VQYXRoO1xuXG4gICAgaWYoIWV4aXN0c1N5bmMoZW5zdXJlRGlyKSkge1xuICAgICAgbWtkaXJTeW5jKGVuc3VyZURpciwge3JlY3Vyc2l2ZTogdHJ1ZX0pO1xuICAgIH1cblxuICAgIHdyaXRlRmlsZVN5bmMoc3JjT3V0cHV0RmlsZSwgSlNPTi5zdHJpbmdpZnkoZmxhdHRlbmVkVHJhbnNsYXRpb25zLCBudWxsLCAyKSwgJ3V0ZjgnKTtcbiAgICBsb2coYFRyYW5zbGF0aW9ucyB3cml0dGVuIHRvOiAke3NyY091dHB1dEZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2coYEVycm9yIHdyaXRpbmcgdHJhbnNsYXRpb25zIGZpbGUgdG8gc3JjOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuICB9XG59OyJdLCJuYW1lcyI6WyJleGlzdHNTeW5jIiwibWtkaXJTeW5jIiwicmVhZEZpbGVTeW5jIiwid3JpdGVGaWxlU3luYyIsInN5bmMiLCJnbG9iU3luYyIsInJlc29sdmUiLCJwYXRoUmVzb2x2ZSIsImxvZyIsImZsYXR0ZW5UcmFuc2xhdGlvbnMiLCJvYmoiLCJwcmVmaXgiLCJmbGF0dGVuZWQiLCJrZXkiLCJ2YWx1ZSIsIm5ld0tleSIsIkFycmF5IiwiaXNBcnJheSIsIlN0cmluZyIsImZpbmRUcmFuc2xhdGlvbkZpbGVzIiwic291cmNlUGF0aCIsInBhdHRlcm5zIiwiZmlsZXMiLCJmb3JFYWNoIiwicGF0dGVybiIsIm1hdGNoZXMiLCJhYnNvbHV0ZSIsImN3ZCIsIm5vZGlyIiwicHVzaCIsInByb2Nlc3NUcmFuc2xhdGlvbnMiLCJvdXRwdXRQYXRoIiwicXVpZXQiLCJ0cmFuc2xhdGlvbkZpbGVzIiwibGVuZ3RoIiwiYWxsVHJhbnNsYXRpb25zIiwiZmlsZVBhdGgiLCJjb250ZW50IiwiZGF0YSIsIkpTT04iLCJwYXJzZSIsImVycm9yIiwibWVzc2FnZSIsImZsYXR0ZW5lZFRyYW5zbGF0aW9ucyIsIm91dHB1dEZpbGUiLCJvdXRwdXREaXIiLCJyZWN1cnNpdmUiLCJzdHJpbmdpZnkiLCJzcmNEaXIiLCJzcmNPdXRwdXRGaWxlIiwiZW5zdXJlRGlyIl0sIm1hcHBpbmdzIjoiQUFBQTs7O0NBR0MsR0FDRCxTQUFRQSxVQUFVLEVBQUVDLFNBQVMsRUFBRUMsWUFBWSxFQUFFQyxhQUFhLFFBQU8sS0FBSztBQUN0RSxTQUFRQyxRQUFRQyxRQUFRLFFBQU8sT0FBTztBQUN0QyxTQUFRQyxXQUFXQyxXQUFXLFFBQU8sT0FBTztBQUU1QyxTQUFRQyxHQUFHLFFBQU8sV0FBVztBQUU3QixNQUFNQyxzQkFBc0IsQ0FBQ0MsS0FBVUMsU0FBUyxFQUFFO0lBQ2hELElBQUlDLFlBQW9DLENBQUM7SUFFekMsSUFBSSxNQUFNQyxPQUFPSCxJQUFLO1FBQ3BCLE1BQU1JLFFBQVFKLEdBQUcsQ0FBQ0csSUFBSTtRQUN0QixNQUFN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