# core/loaders/strings.loader.ts

> 52 lines of code and 11 definitions.

Tree: Build tree
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/build#file-build-core-loaders-strings-loader-ts
Source text: https://banes-lab.com/assets/sources/source.a93bb0cd51e47189d04453e274f7957f61a6c622c7695498739dd99388e1de56.generated.txt

## Definitions

- `moduleFiles` (lexical_declaration, line 35)
- `literalsOf` (lexical_declaration, line 15, exported)
- `stringsFolders` (lexical_declaration, line 29, exported)
- `readStringsModules` (lexical_declaration, line 44, exported)
- `STRINGS_CONCERN` (lexical_declaration, line 11)
- `MEMBER` (lexical_declaration, line 12)
- `MEMBER_BELOW_ROOT` (lexical_declaration, line 13)
- `root` (lexical_declaration, line 16, exported)
- `literals` (lexical_declaration, line 20, exported)
- `toneTarget` (lexical_declaration, line 53, exported)
- `baselineTarget` (lexical_declaration, line 57, exported)

## Source

```typescript
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);
};
```
