UNPKG

hybrids

Version:

A JavaScript framework for creating fully-featured web applications, components libraries, and single web components with unique declarative and functional architecture

102 lines (83 loc) 2.85 kB
import { existsSync, readFileSync, writeFileSync } from "node:fs"; import { resolve } from "node:path"; import { cwd, resolveFileOrDir } from "../utils/fs.js"; const HELP_MSG = `hybrids - translation message extractor from source files Pass a single file or a directory, which will be recursively scanned for .js and .ts files with messages. If no output file is specified, the output will be pushed to stdout. Usage: hybrids extract [options] <file or directory> [<output file>] Options: -e, --empty-message\t Set default message body to empty string -f, --force\t\t Overwrite output file instead of merge it with existing messages -p, --include-path\t Include file path in message description -h, --help\t\t Show this help --format=type\t\t Transform messages to the desired format; supported types: chrome.i18n `; import task from "./task.js"; function normalizeOptions(options) { return { emptyMessage: options["empty-message"] || options.e, force: options.force || options.f, includePath: options["include-path"] || options.p, format: options.format, }; } export default function extract(args, options) { options = normalizeOptions(options); if (args[0]) { const fileOrDirPath = resolve(cwd, args[0]); const targetPath = args[1] && resolve(cwd, args[1]); const messages = []; resolveFileOrDir(fileOrDirPath, (content, path) => { messages.push( ...task(content, options.format).map((m) => ({ ...m, path })), ); }); const getDesc = (text = "", path) => { return `${options.includePath && path ? `${path}:\n` : ""}${text}`; }; const touched = new Set(); const body = messages.reduce( (acc, m) => { const c = acc[m.key]; let description = (m.description || options.includePath) && getDesc(m.description, m.path); if (m.description) { description = `${ touched.has(m.key) ? `${c.description}\n` : "" }${getDesc(m.description, m.path)}`; touched.add(m.key); } acc[m.key] = { message: options.emptyMessage ? (c?.message ?? "") : m.message, ...c, description, }; return acc; }, !options.force && targetPath && existsSync(targetPath) ? JSON.parse(readFileSync(targetPath, "utf8")) : {}, ); const targetContent = JSON.stringify( Object.fromEntries( Object.entries(body).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" }), ), ), null, 2, ) + "\n"; if (targetPath) { writeFileSync(targetPath, targetContent); } else { console.log(targetContent); } } else if (!args.length || options.help) { console.log(HELP_MSG); process.exit(1); } }