@pagopa/dx-cli
Version:
A CLI useful to manage DX tools.
70 lines (69 loc) • 2.56 kB
JavaScript
import { err, ok } from "neverthrow";
import { z } from "zod/v4";
const ScriptName = z.string().brand();
export const scriptSchema = z.object({
name: ScriptName,
script: z.string(),
});
export const dependencySchema = z.object({
name: z.string(),
version: z.string(),
});
const PackageName = z.string().min(1).brand();
const scriptsSchema = z
.record(ScriptName, z.string())
.optional()
.transform((obj) => new Map(obj
? Object.entries(obj).map(([name, script]) => [
ScriptName.parse(name),
script,
])
: []));
const dependenciesSchema = z
// An object where keys are Dependency["name"] and values are their versions (string for now, but we could type them as well)
.record(z.string(), z.string())
.optional()
// Transform the record into a Map<Dependency["name"], Dependency["version"]>
.transform((obj) => new Map(obj
? Object.entries(obj).map(([name, version]) => [name, version])
: []));
const packageManagerSchema = z.enum(["npm", "pnpm", "yarn"]);
export const packageJsonSchema = z.object({
dependencies: dependenciesSchema,
devDependencies: dependenciesSchema,
name: PackageName,
packageManager: z
.string()
.transform((str) => str.split("@")[0])
.pipe(packageManagerSchema)
.optional(),
scripts: scriptsSchema,
});
const findMissingScripts = (availableScripts, requiredScripts) => {
const availableScriptNames = new Set(availableScripts.keys());
const requiredScriptNames = new Set(requiredScripts.keys());
// Returns a set of scripts that are required, but not listed in the package.json
return requiredScriptNames.difference(availableScriptNames);
};
export const checkMonorepoScripts = async (dependencies, repositoryRoot) => {
const { packageJsonReader } = dependencies;
const checkName = "Monorepo Scripts";
const scriptsResult = await packageJsonReader.getScripts(repositoryRoot);
if (scriptsResult.isErr()) {
return err(scriptsResult.error);
}
const requiredScriptsMap = packageJsonReader.getRootRequiredScripts();
const missingScripts = findMissingScripts(scriptsResult.value, requiredScriptsMap);
if (missingScripts.size === 0) {
return ok({
checkName,
isValid: true,
successMessage: "Monorepo scripts are correctly set up",
});
}
return ok({
checkName,
errorMessage: `Missing required scripts: ${Array.from(missingScripts).join(", ")}`,
isValid: false,
});
};