core/counters/source.counter.ts
core/counters/source.counter.ts is a file in GovLab Docs. 40 lines of code and 16 definitions.
import { type PathExclusion, excludeMatcher } from "@govlab/quality/config";
import { ROOT } from "@ssot/paths";
import type { SourceStats } from "#types/index.types";
import path from "node:path";
import { readFileSync } from "node:fs";
import { walkFiles } from "#core/loaders/base.loader";
const SOURCE_SUFFIXES: readonly string[] = [".ts", ".mts", ".cts", ".css", ".html", ".json"];
const COUNTABLE_SUFFIXES: readonly string[] = [".ts", ".js"];
const CONFIG_SUFFIXES: readonly string[] = [".config.js", ".config.ts"];
const BARREL_FILE = "index.ts";
const GENERATED_MARK = ".generated.";
const LINE_COMMENT = "//";
const isExcluded = await excludeMatcher(ROOT);
const isSourceFile = function isSourceFile(file: string): boolean {
return !file.includes(GENERATED_MARK) && SOURCE_SUFFIXES.some((suffix) => file.endsWith(suffix));
};
export const countSourceFiles = function countSourceFiles(dir: string): number {
return walkFiles(dir, isExcluded).filter((file) => isSourceFile(path.basename(file))).length;
};
const isCountableSource = function isCountableSource(file: string): boolean {
const base = path.basename(file);
if (!COUNTABLE_SUFFIXES.some((suffix) => file.endsWith(suffix)) || base === BARREL_FILE) {
return false;
}
return !CONFIG_SUFFIXES.some((suffix) => base.endsWith(suffix));
};
const countLoc = function countLoc(raw: string): number {
return raw.split("\n").filter((line) => {
const trimmed = line.trim();
return trimmed.length > 0 && !trimmed.startsWith(LINE_COMMENT);
}).length;
};
export const collectSourceStats = function collectSourceStats(
packageDir: string,
excluded: PathExclusion,
): SourceStats {
const files = walkFiles(packageDir, excluded).filter(isCountableSource);
const loc = files.reduce((total, file) => total + countLoc(readFileSync(file, "utf8")), 0);
return { fileCount: files.length, loc };
};