core/loaders/strings.loader.ts

core/loaders/strings.loader.ts is a file in Bane's Lab Content. 52 lines of code and 11 definitions.

import { LITERAL_NODE_TYPE, STRINGS_SUFFIX, TYPESCRIPT_LANGUAGE } from "#configuration/constants/tone.constants";
import { absolutePath, relativePath } from "@ssot/paths";
import { parseCode, walk } from "@govlab/code-parse";
import { readFileSync, readdirSync } from "node:fs";
import type { StringsModule } from "#types/tone.types";
import { UTF8 } from "#configuration/constants/source.constants";
import { concernFolders } from "@ssot/govlab/shared/resolvers/container.resolver.ts";
import { join } from "node:path";
import { projectDirs } from "@ssot/govlab/shared/resolvers/anchor.resolver.ts";

const STRINGS_CONCERN = "strings";
const MEMBER = relativePath("app.member");
const MEMBER_BELOW_ROOT = `${MEMBER.slice(MEMBER.indexOf("/") + 1)}/`;

export const literalsOf = async function literalsOf(source: string): Promise<string[]> {
    const root = await parseCode(source, TYPESCRIPT_LANGUAGE);
    if (root === null) {
        return [];
    }
    const literals: string[] = [];
    walk(root, (node) => {
        if (node.type === LITERAL_NODE_TYPE && node.text !== undefined && node.text.length > 0) {
            literals.push(node.text);
        }
    });
    return literals;
};

export const stringsFolders = function stringsFolders(): string[] {
    return concernFolders(STRINGS_CONCERN, projectDirs())
        .filter((folder) => folder.startsWith(MEMBER_BELOW_ROOT))
        .map((folder) => absolutePath("app.root", folder));
};

const moduleFiles = function moduleFiles(): { readonly file: string; readonly name: string }[] {
    return stringsFolders().flatMap((folder) =>
        readdirSync(folder)
            .filter((name) => name.endsWith(STRINGS_SUFFIX))
            .sort((a, b) => a.localeCompare(b))
            .map((name) => ({ file: join(folder, name), name })),
    );
};

export const readStringsModules = async function readStringsModules(): Promise<StringsModule[]> {
    return Promise.all(
        moduleFiles().map(async (held) => ({
            literals: await literalsOf(readFileSync(held.file, UTF8)),
            module: held.name,
        })),
    );
};

export const toneTarget = function toneTarget(): string {
    return absolutePath("govlabHost.reports.content.tone");
};

export const baselineTarget = function baselineTarget(file: string): string {
    return absolutePath("docArch.generated", file);
};