codemods/selectors/program.selector.ts
codemods/selectors/program.selector.ts is a file in GovLab Extension Host. 46 lines of code and 20 definitions.
import { dirname, relative, resolve, sep } from "node:path";
import { MEMBER_ROOTS } from "../../shared/registries/location.registry.ts";
import { existsSync } from "node:fs";
import ts from "typescript";
const REPO_ROOT = process.cwd().split(sep).join("/");
const NODE_MODULES = "/node_modules/";
const ARGV_START = 2;
const TSCONFIG_FLAG = "--tsconfig";
const TSCONFIG = "tsconfig.json";
const ALL_TSCONFIGS: readonly string[] = MEMBER_ROOTS.map((member) => `${member}/${TSCONFIG}`).filter((file) =>
existsSync(resolve(process.cwd(), file)),
);
const requestedTsconfigs = function requestedTsconfigs(argv: readonly string[]): string[] {
const flagIndex = argv.indexOf(TSCONFIG_FLAG);
const value = flagIndex === -1 ? "" : (argv[flagIndex + 1] ?? "");
return value.split(",").filter((entry) => entry.length > 0);
};
const REQUESTED = requestedTsconfigs(process.argv.slice(ARGV_START));
export const CODEMOD_TSCONFIGS: readonly string[] = REQUESTED.length > 0 ? REQUESTED : ALL_TSCONFIGS;
export const toPosix = function toPosix(value: string): string {
return value.split(sep).join("/");
};
export const relPath = function relPath(fileName: string): string {
return toPosix(relative(process.cwd(), fileName));
};
export const inRepo = function inRepo(fileName: string): boolean {
return toPosix(fileName).startsWith(REPO_ROOT) && !toPosix(fileName).includes(NODE_MODULES);
};
export const programFor = function programFor(tsconfigPath: string): ts.Program {
const absolute = resolve(process.cwd(), tsconfigPath);
const configFile = ts.readConfigFile(absolute, (file) => ts.sys.readFile(file));
const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, dirname(absolute));
return ts.createProgram({
host: ts.createCompilerHost(parsed.options),
options: parsed.options,
rootNames: parsed.fileNames,
});
};
export const repoSourceFiles = function repoSourceFiles(program: ts.Program): ts.SourceFile[] {
return program
.getSourceFiles()
.filter((sourceFile) => !sourceFile.isDeclarationFile && inRepo(sourceFile.fileName));
};
export const lineOf = function lineOf(sourceFile: ts.SourceFile, node: ts.Node): number {
return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
};