* web: Prep ESBuild plugin for publish. * prettier-config: Update deps. * eslint-config: Update deps. * docusaurus-config: Update deps. * docs: Update deps. * docs: Enable linter. * docs: Lint. * web/sfe: Clean up types. Prep for monorepo. * esbuild-plugin-live-reload: Update deps. * web: Tidy ESLint, script commands. * web: Fix logs. * web: Lint. * web: Split compile check from cached version.
		
			
				
	
	
		
			100 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
 * @file Lit Localize build script.
 | 
						|
 *
 | 
						|
 * @remarks
 | 
						|
 * Determines if all the Xliff translation source files are present and
 | 
						|
 * if the Typescript source files generated from those sources are up-to-date.
 | 
						|
 *
 | 
						|
 * If they are not, it runs the locale building script, intercepting the
 | 
						|
 * long spew of "this string is not translated" and replacing it with a
 | 
						|
 * summary of how many strings are missing with respect to the source locale.
 | 
						|
 *
 | 
						|
 * @import { ConfigFile } from "@lit/localize-tools/lib/types/config"
 | 
						|
 * @import { Stats } from "fs";
 | 
						|
 */
 | 
						|
import { PackageRoot } from "#paths/node";
 | 
						|
import { spawnSync } from "node:child_process";
 | 
						|
import { readFileSync, statSync } from "node:fs";
 | 
						|
import path from "node:path";
 | 
						|
 | 
						|
/**
 | 
						|
 * @type {ConfigFile}
 | 
						|
 */
 | 
						|
const localizeRules = JSON.parse(
 | 
						|
    readFileSync(path.join(PackageRoot, "lit-localize.json"), "utf-8"),
 | 
						|
);
 | 
						|
 | 
						|
/**
 | 
						|
 *
 | 
						|
 * @param {string} loc
 | 
						|
 * @returns {boolean}
 | 
						|
 */
 | 
						|
function generatedFileIsUpToDateWithXliffSource(loc) {
 | 
						|
    const xliff = path.join("./xliff", `${loc}.xlf`);
 | 
						|
    const gened = path.join("./src/locales", `${loc}.ts`);
 | 
						|
 | 
						|
    // Returns false if: the expected XLF file doesn't exist, The expected
 | 
						|
    // generated file doesn't exist, or the XLF file is newer (has a higher date)
 | 
						|
    // than the generated file.  The missing XLF file is important enough it
 | 
						|
    // generates a unique error message and halts the build.
 | 
						|
 | 
						|
    /**
 | 
						|
     * @type {Stats}
 | 
						|
     */
 | 
						|
    let xlfStat;
 | 
						|
 | 
						|
    try {
 | 
						|
        xlfStat = statSync(xliff);
 | 
						|
    } catch (_error) {
 | 
						|
        console.error(`lit-localize expected '${loc}.xlf', but XLF file is not present`);
 | 
						|
        process.exit(1);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @type {Stats}
 | 
						|
     */
 | 
						|
    let genedStat;
 | 
						|
 | 
						|
    // If the generated file doesn't exist, of course it's not up to date.
 | 
						|
    try {
 | 
						|
        genedStat = statSync(gened);
 | 
						|
    } catch (_error) {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    // if the generated file is the same age or newer (date is greater) than the xliff file, it's
 | 
						|
    // presumed to have been generated by that file and is up-to-date.
 | 
						|
    return genedStat.mtimeMs >= xlfStat.mtimeMs;
 | 
						|
}
 | 
						|
 | 
						|
// For all the expected files, find out if any aren't up-to-date.
 | 
						|
const upToDate = localizeRules.targetLocales.reduce(
 | 
						|
    (acc, loc) => acc && generatedFileIsUpToDateWithXliffSource(loc),
 | 
						|
    true,
 | 
						|
);
 | 
						|
 | 
						|
if (!upToDate) {
 | 
						|
    const status = spawnSync("npm", ["run", "build-locales:build"], { encoding: "utf8" });
 | 
						|
 | 
						|
    // Count all the missing message warnings
 | 
						|
    const counts = status.stderr.split("\n").reduce((acc, line) => {
 | 
						|
        const match = /^([\w-]+) message/.exec(line);
 | 
						|
        if (!match) {
 | 
						|
            return acc;
 | 
						|
        }
 | 
						|
        acc.set(match[1], (acc.get(match[1]) || 0) + 1);
 | 
						|
        return acc;
 | 
						|
    }, new Map());
 | 
						|
 | 
						|
    const locales = Array.from(counts.keys());
 | 
						|
    locales.sort();
 | 
						|
 | 
						|
    const report = locales
 | 
						|
        .map((locale) => `Locale '${locale}' has ${counts.get(locale)} missing translations`)
 | 
						|
        .join("\n");
 | 
						|
 | 
						|
    console.log(`Translation tables rebuilt.\n${report}\n`);
 | 
						|
}
 | 
						|
 | 
						|
console.log("Locale ./src is up-to-date");
 |