core/loaders/manifest.loader.ts

core/loaders/manifest.loader.ts is a file in Code Parse. 44 lines of code and 13 definitions.

import {
    FILE_TYPES_KEY,
    GRAMMARS_KEY,
    GRAMMAR_CONFIG_FILE,
    NAME_KEY,
    PACKAGE_GRAMMAR_KEY,
    PACKAGE_MANIFEST_FILE,
} from "#configuration/constants/grammar.constants";
import type { FileTypeEntry, GrammarMeta, GrammarSource } from "#types/grammar.types";
import { existsSync, readFileSync } from "node:fs";
import { isRecord } from "#core/predicates/record.predicate";
import { join } from "node:path";

const asStringArray = function asStringArray(value: unknown): string[] {
    return Array.isArray(value) ? value.filter((item): item is string => typeof item === "string") : [];
};

const readJson = function readJson(file: string): unknown {
    return existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : null;
};

const configEntries = function configEntries(packageRoot: string): FileTypeEntry[] {
    const parsed = readJson(join(packageRoot, GRAMMAR_CONFIG_FILE));
    const grammars = isRecord(parsed) && Array.isArray(parsed[GRAMMARS_KEY]) ? parsed[GRAMMARS_KEY] : [];
    return grammars
        .filter(isRecord)
        .map((grammar) => ({
            fileTypes: asStringArray(grammar[FILE_TYPES_KEY]),
            name: typeof grammar[NAME_KEY] === "string" ? grammar[NAME_KEY] : "",
        }))
        .filter((entry) => entry.name.length > 0);
};

const packageFileTypes = function packageFileTypes(packageRoot: string): string[] {
    const parsed = readJson(join(packageRoot, PACKAGE_MANIFEST_FILE));
    const meta = isRecord(parsed) ? parsed[PACKAGE_GRAMMAR_KEY] : null;
    const list: unknown[] = Array.isArray(meta) ? meta : [];
    return list.filter(isRecord).flatMap((entry) => asStringArray(entry[FILE_TYPES_KEY]));
};

export const readGrammarMeta = function readGrammarMeta(packageRoot: string): GrammarMeta {
    const entries = configEntries(packageRoot);
    const pool = [...new Set([...entries.flatMap((entry) => entry.fileTypes), ...packageFileTypes(packageRoot)])];
    return { entries, pool };
};

export const fileTypesForSource = function fileTypesForSource(source: GrammarSource, meta: GrammarMeta): string[] {
    const matched = meta.entries.find((entry) => entry.name === source.lang);
    return matched && matched.fileTypes.length > 0 ? matched.fileTypes : meta.pool;
};