@traf/nx
Version:
A cli tool that wraps `@traf/core` to be used with Nx.
129 lines (127 loc) • 4.34 kB
JavaScript
import { dirname as __dirname__ } from 'path';import { fileURLToPath } from 'url';import { createRequire as topLevelCreateRequire } from 'module';const require = topLevelCreateRequire(import.meta.url);const __filename = fileURLToPath(import.meta.url);const __dirname = __dirname__(__filename);
// libs/nx/src/nx.ts
import { basename, dirname, join, resolve } from "path";
import { readFile } from "fs/promises";
import { globby } from "globby";
import { existsSync } from "fs";
import chalk from "chalk";
async function getNxProjects(cwd) {
const nxProjects = await getNxProjectJsonProjects(cwd);
const workspaceProjects = await getNxWorkspaceProjects(cwd);
const relevantWorkspaceProjects = workspaceProjects.filter(
(proj) => nxProjects.find((nested) => nested.name === proj.name) === void 0
);
return [...nxProjects, ...relevantWorkspaceProjects];
}
async function getNxWorkspaceProjects(cwd) {
try {
const path = resolve(cwd, "workspace.json");
const file = await readFile(path, "utf-8");
const workspace = JSON.parse(file);
return Object.entries(workspace.projects).filter(([, project]) => typeof project === "object").map(([name, project]) => ({
name,
path,
project
}));
} catch (e) {
return [];
}
}
async function getNxProjectJsonProjects(cwd) {
try {
const staticIgnores = ["node_modules", "**/node_modules", "dist", ".git"];
const projectGlobPatterns = [`project.json`, `**/project.json`];
const combinedProjectGlobPattern = "{" + projectGlobPatterns.join(",") + "}";
const files = await globby(combinedProjectGlobPattern, {
ignore: staticIgnores,
ignoreFiles: [".nxignore"],
absolute: true,
cwd,
dot: true,
suppressErrors: true,
gitignore: true
});
const projectFiles = [];
for (const file of files) {
const path = resolve(cwd, file);
const project = JSON.parse(await readFile(path, "utf-8"));
projectFiles.push({
name: project.name,
path,
project
});
}
return projectFiles;
} catch (e) {
return [];
}
}
async function getNxTrueAffectedProjects(cwd, { logger = console } = {}) {
const projects = await getNxProjects(cwd);
logger.debug(`Found ${chalk.bold(projects.length)} nx projects`);
return projects.map(({ name, path, project }) => {
let tsConfig = project.targets?.build?.options?.tsConfig;
const projectPathDir = dirname(path);
const projectName = name ?? basename(projectPathDir);
if (!name) {
logger.warn(
`Project at ${chalk.bold(
path
)} does not have a name property. Using project.json directory name ${chalk.bold(
projectName
)}.`
);
}
if (!project.sourceRoot) {
logger.warn(
`Project at ${chalk.bold(
path
)} does not have a sourceRoot property. Using project.json directory.`
);
}
if (!tsConfig) {
if (project.sourceRoot) {
logger.debug(
`Project at ${chalk.bold(
path
)} does not have a tsConfig property under '${chalk.bold(
"targets.build.options.tsConfig"
)}'. Trying to use '${chalk.bold("sourceRoot")}' `
);
} else {
logger.debug(
`Project at ${chalk.bold(
path
)} does not have a tsConfig property under '${chalk.bold(
"targets.build.options.tsConfig"
)}'. Using project.json directory.`
);
}
const projectRoot = project.sourceRoot ? join(project.sourceRoot, "..") : projectPathDir;
if (project.projectType === "library") {
tsConfig = join(projectRoot, "tsconfig.lib.json");
} else {
tsConfig = join(projectRoot, "tsconfig.app.json");
}
if (!existsSync(resolve(cwd, tsConfig))) {
tsConfig = join(projectRoot, "tsconfig.json");
}
}
logger.debug(
`Using tsconfig at ${chalk.bold(tsConfig)} for project ${chalk.bold(
projectName
)}`
);
return {
name: projectName,
sourceRoot: project.sourceRoot ?? projectPathDir,
implicitDependencies: project.implicitDependencies ?? [],
tsConfig,
targets: Object.keys(project.targets ?? {})
};
});
}
export {
getNxProjects,
getNxTrueAffectedProjects
};