@udohjeremiah/moniq 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +69 -69
- package/dist/cli.js.map +1 -1
- package/dist/{dist-B1TNZsla.js → dist-DVPiOZCC.js} +3 -5481
- package/dist/dist-DVPiOZCC.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/dist-B1TNZsla.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as loadConfig } from "./dist-
|
|
2
|
+
import { n as loadConfig } from "./dist-DVPiOZCC.js";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { stdin } from "node:process";
|
|
5
|
-
import { styleText } from "node:util";
|
|
6
4
|
import { execFile, execFileSync } from "node:child_process";
|
|
5
|
+
import { styleText } from "node:util";
|
|
6
|
+
import { stdin } from "node:process";
|
|
7
7
|
import { createInterface } from "node:readline/promises";
|
|
8
8
|
//#region ../../node_modules/.pnpm/cac@7.0.0/node_modules/cac/dist/index.js
|
|
9
9
|
function toArr(any) {
|
|
@@ -917,7 +917,7 @@ async function resolve(config, root, packages_) {
|
|
|
917
917
|
}
|
|
918
918
|
//#endregion
|
|
919
919
|
//#region ../cli/dist/index.js
|
|
920
|
-
var version = "0.3.
|
|
920
|
+
var version = "0.3.4";
|
|
921
921
|
function formatDiagnostics(diagnostics, options) {
|
|
922
922
|
if ((options?.format ?? "pretty") === "json") return formatJson(diagnostics);
|
|
923
923
|
return formatPretty(diagnostics, options?.isDryRun);
|
|
@@ -926,7 +926,7 @@ function formatJson(diagnostics) {
|
|
|
926
926
|
return `${JSON.stringify(diagnostics, void 0, 2)}\n`;
|
|
927
927
|
}
|
|
928
928
|
function formatPretty(diagnostics, isDryRun) {
|
|
929
|
-
if (diagnostics.length === 0) return styleText(["bold", "green"], "
|
|
929
|
+
if (diagnostics.length === 0) return styleText(["bold", "green"], "✔ No issues found.");
|
|
930
930
|
const lines = [];
|
|
931
931
|
const byPackage = /* @__PURE__ */ new Map();
|
|
932
932
|
for (const d of diagnostics) {
|
|
@@ -935,7 +935,7 @@ function formatPretty(diagnostics, isDryRun) {
|
|
|
935
935
|
else byPackage.set(d.packageName, [d]);
|
|
936
936
|
}
|
|
937
937
|
for (const [packageName, diags] of byPackage) {
|
|
938
|
-
lines.push("",
|
|
938
|
+
lines.push("", styleText(["bold", "cyan"], packageName));
|
|
939
939
|
for (const d of diags) pushDiagnostic(lines, d, isDryRun);
|
|
940
940
|
}
|
|
941
941
|
const errorCount = diagnostics.filter((d) => d.severity === "error").length;
|
|
@@ -944,25 +944,24 @@ function formatPretty(diagnostics, isDryRun) {
|
|
|
944
944
|
if (errorCount > 0) countParts.push(styleText("red", `${String(errorCount)} error(s)`));
|
|
945
945
|
if (warningCount > 0) countParts.push(styleText("yellow", `${String(warningCount)} warning(s)`));
|
|
946
946
|
const summary = countParts.join(", ");
|
|
947
|
-
const summaryLine =
|
|
947
|
+
const summaryLine = `${styleText("cyan", "ℹ")} Found ${String(diagnostics.length)} issue(s) — ${summary.length > 0 ? summary : "all clear"}`;
|
|
948
948
|
lines.push("", styleText("dim", summaryLine));
|
|
949
949
|
if (isDryRun) {
|
|
950
950
|
const fixableCount = diagnostics.filter((d) => d.fix && d.severity !== "off").length;
|
|
951
|
-
lines.push("", styleText("dim",
|
|
951
|
+
lines.push("", styleText("dim", `${styleText("cyan", "ℹ")} Dry-run: ${String(fixableCount)} fix(es) available`));
|
|
952
952
|
}
|
|
953
953
|
return lines.join("\n");
|
|
954
954
|
}
|
|
955
955
|
function pushDiagnostic(lines, d, isDryRun) {
|
|
956
956
|
const badge = severityBadge(d.severity);
|
|
957
|
-
const
|
|
958
|
-
lines.push(` ${
|
|
957
|
+
const icon = severityIcon(d.severity);
|
|
958
|
+
lines.push(` ${icon} ${badge} ${d.message}`);
|
|
959
959
|
if (d.expected && d.actual) lines.push(` ${styleText("dim", "Expected:")} ${styleText("cyan", d.expected)}`, ` ${styleText("dim", "Actual:")} ${styleText("red", d.actual)}`);
|
|
960
960
|
else if (d.expected) lines.push(` ${styleText("dim", "Expected:")} ${styleText("cyan", d.expected)}`);
|
|
961
961
|
else if (d.actual) lines.push(` ${styleText("dim", "Actual:")} ${styleText("red", d.actual)}`);
|
|
962
962
|
if (d.fix) {
|
|
963
963
|
const label = styleText("dim", isDryRun ? "Would fix:" : "Fix:");
|
|
964
|
-
|
|
965
|
-
lines.push(` ${icon} ${label} ${d.fix}`);
|
|
964
|
+
lines.push(` ${label} ${d.fix}`);
|
|
966
965
|
}
|
|
967
966
|
}
|
|
968
967
|
function severityBadge(severity) {
|
|
@@ -970,10 +969,10 @@ function severityBadge(severity) {
|
|
|
970
969
|
if (severity === "warn") return styleText(["bold", "yellow"], "WARN");
|
|
971
970
|
return styleText("gray", "OFF");
|
|
972
971
|
}
|
|
973
|
-
function
|
|
974
|
-
if (severity === "error") return "
|
|
975
|
-
if (severity === "warn") return "
|
|
976
|
-
return "
|
|
972
|
+
function severityIcon(severity) {
|
|
973
|
+
if (severity === "error") return styleText(["bold", "red"], "✘");
|
|
974
|
+
if (severity === "warn") return styleText(["bold", "yellow"], "⚠");
|
|
975
|
+
return " ";
|
|
977
976
|
}
|
|
978
977
|
async function applyScriptFixes(diagnostics, options) {
|
|
979
978
|
const fixable = diagnostics.filter((d) => d.fix && d.severity !== "off");
|
|
@@ -1022,46 +1021,31 @@ async function check(options) {
|
|
|
1022
1021
|
let config;
|
|
1023
1022
|
try {
|
|
1024
1023
|
config = await loadConfig(cwd);
|
|
1025
|
-
} catch {
|
|
1026
|
-
throw new Error(
|
|
1024
|
+
} catch (error) {
|
|
1025
|
+
throw new Error(`Failed to load moniq.config: ${String(error)}`, { cause: error });
|
|
1027
1026
|
}
|
|
1028
1027
|
const packages = await discoverWorkspace(cwd);
|
|
1029
1028
|
if (packages.length === 0) throw new Error("No workspace packages found.");
|
|
1030
1029
|
const diagnostics = await resolve(config, cwd, packages);
|
|
1031
1030
|
let fixSummary;
|
|
1032
1031
|
if (options.fix) fixSummary = await applyScriptFixes(diagnostics, { isDryRun: options.isDryRun });
|
|
1033
|
-
if (options.format !== "json") {
|
|
1034
|
-
console.log(` 🔍 Scanned ${String(packages.length)} package(s)`);
|
|
1035
|
-
console.log();
|
|
1036
|
-
}
|
|
1032
|
+
if (options.format !== "json") console.log(`${styleText("cyan", "ℹ")} Scanned ${String(packages.length)} package(s)`);
|
|
1037
1033
|
console.log(formatDiagnostics(diagnostics, {
|
|
1038
1034
|
format: options.format,
|
|
1039
1035
|
isDryRun: options.isDryRun
|
|
1040
1036
|
}));
|
|
1041
1037
|
if (fixSummary) if (fixSummary.isDryRun) {
|
|
1042
|
-
const message =
|
|
1038
|
+
const message = `${styleText("cyan", "ℹ")} Dry-run: ${String(fixSummary.fixed)} fix(es) available, ${String(fixSummary.errors)} error(s)`;
|
|
1043
1039
|
console.log(styleText("dim", message));
|
|
1044
1040
|
} else {
|
|
1045
|
-
const message =
|
|
1041
|
+
const message = `✔ Fixed ${String(fixSummary.fixed)} issue(s) across ${String(fixSummary.packageCount)} package(s)`;
|
|
1046
1042
|
console.log(styleText(["bold", "green"], message));
|
|
1047
1043
|
}
|
|
1048
1044
|
}
|
|
1049
1045
|
async function doctor() {
|
|
1050
1046
|
const cwd = process.cwd();
|
|
1051
1047
|
const issues = [];
|
|
1052
|
-
|
|
1053
|
-
const config = await loadConfig(cwd);
|
|
1054
|
-
issues.push({
|
|
1055
|
-
message: "moniq.config file found and loadable.",
|
|
1056
|
-
severity: "warn"
|
|
1057
|
-
});
|
|
1058
|
-
checkScriptPolicies(config, issues);
|
|
1059
|
-
} catch {
|
|
1060
|
-
issues.push({
|
|
1061
|
-
message: "No moniq.config file found in or above the current directory.",
|
|
1062
|
-
severity: "error"
|
|
1063
|
-
});
|
|
1064
|
-
}
|
|
1048
|
+
console.log(styleText("bold", "Configuration Doctor"));
|
|
1065
1049
|
try {
|
|
1066
1050
|
const packageCount = (await discoverWorkspace(cwd)).length;
|
|
1067
1051
|
if (packageCount === 0) issues.push({
|
|
@@ -1070,7 +1054,7 @@ async function doctor() {
|
|
|
1070
1054
|
});
|
|
1071
1055
|
else issues.push({
|
|
1072
1056
|
message: `Detected ${String(packageCount)} workspace package(s).`,
|
|
1073
|
-
severity: "
|
|
1057
|
+
severity: "info"
|
|
1074
1058
|
});
|
|
1075
1059
|
} catch {
|
|
1076
1060
|
issues.push({
|
|
@@ -1078,28 +1062,36 @@ async function doctor() {
|
|
|
1078
1062
|
severity: "error"
|
|
1079
1063
|
});
|
|
1080
1064
|
}
|
|
1065
|
+
try {
|
|
1066
|
+
const config = await loadConfig(cwd);
|
|
1067
|
+
issues.push({
|
|
1068
|
+
message: "moniq.config file found and loadable.",
|
|
1069
|
+
severity: "info"
|
|
1070
|
+
});
|
|
1071
|
+
checkScriptPolicies(config, issues);
|
|
1072
|
+
} catch (error) {
|
|
1073
|
+
issues.push({
|
|
1074
|
+
message: `Failed to load moniq.config: ${String(error)}`,
|
|
1075
|
+
severity: "error"
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1081
1078
|
console.log();
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
console.log(` ${styleText(["bold", "green"], "✅ Everything looks good!")}`);
|
|
1079
|
+
issues.sort((a, b) => severityIndex(a.severity) - severityIndex(b.severity));
|
|
1080
|
+
if (!issues.some((issue) => issue.severity !== "info")) {
|
|
1081
|
+
console.log(styleText(["bold", "green"], "✔ Everything looks good!"));
|
|
1086
1082
|
return;
|
|
1087
1083
|
}
|
|
1088
|
-
for (const issue of issues)
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
console.log(` ${icon} ${label} ${issue.message}`);
|
|
1092
|
-
}
|
|
1093
|
-
const errorCount = issues.filter((index) => index.severity === "error").length;
|
|
1094
|
-
const warningCount = issues.filter((index) => index.severity === "warn").length;
|
|
1084
|
+
for (const issue of issues) console.log(formatIssue(issue));
|
|
1085
|
+
const errorCount = issues.filter((issue) => issue.severity === "error").length;
|
|
1086
|
+
const warningCount = issues.filter((issue) => issue.severity === "warn").length;
|
|
1095
1087
|
const summary = styleText("dim", `Found ${`${String(errorCount)} error(s)`}, ${`${String(warningCount)} warning(s)`}`);
|
|
1096
1088
|
console.log();
|
|
1097
|
-
console.log(
|
|
1089
|
+
console.log(summary);
|
|
1098
1090
|
if (errorCount > 0) {
|
|
1099
|
-
const tip = styleText(["bold", "cyan"], "
|
|
1091
|
+
const tip = styleText(["bold", "cyan"], "Tip:");
|
|
1100
1092
|
const hint = styleText("dim", "moniq init");
|
|
1101
1093
|
console.log();
|
|
1102
|
-
console.log(
|
|
1094
|
+
console.log(`${tip} Run ${hint} to scaffold a starter configuration.`);
|
|
1103
1095
|
}
|
|
1104
1096
|
}
|
|
1105
1097
|
function checkScriptPolicies(config, issues) {
|
|
@@ -1120,6 +1112,16 @@ function checkScriptPolicies(config, issues) {
|
|
|
1120
1112
|
}
|
|
1121
1113
|
}
|
|
1122
1114
|
}
|
|
1115
|
+
function formatIssue(issue) {
|
|
1116
|
+
if (issue.severity === "error") return ` ${styleText(["bold", "red"], "✘")} ${styleText(["bold", "red"], "ERROR")} ${issue.message}`;
|
|
1117
|
+
if (issue.severity === "warn") return ` ${styleText(["bold", "yellow"], "⚠")} ${styleText(["bold", "yellow"], "WARN")} ${issue.message}`;
|
|
1118
|
+
return ` ${styleText("cyan", "ℹ")} ${styleText(["bold", "cyan"], "INFO")} ${issue.message}`;
|
|
1119
|
+
}
|
|
1120
|
+
function severityIndex(severity) {
|
|
1121
|
+
if (severity === "error") return 2;
|
|
1122
|
+
if (severity === "warn") return 1;
|
|
1123
|
+
return 0;
|
|
1124
|
+
}
|
|
1123
1125
|
const colorFns = [
|
|
1124
1126
|
(s) => styleText("cyan", s),
|
|
1125
1127
|
(s) => styleText("magenta", s),
|
|
@@ -1166,7 +1168,7 @@ const letterRows = [
|
|
|
1166
1168
|
"██║ ██║",
|
|
1167
1169
|
"██║ ██║",
|
|
1168
1170
|
"╚██████╔╝",
|
|
1169
|
-
"
|
|
1171
|
+
" ╚════╝╲╲ "
|
|
1170
1172
|
]
|
|
1171
1173
|
];
|
|
1172
1174
|
const DESCRIPTION = "Policy-driven workspace linter for JavaScript/TypeScript monorepos.";
|
|
@@ -1217,14 +1219,15 @@ export default defineConfig({
|
|
|
1217
1219
|
async function detectLang(cwd, packageJson) {
|
|
1218
1220
|
const rawDependencies = packageJson["dependencies"];
|
|
1219
1221
|
const rawDevelopmentDependencies = packageJson["devDependencies"];
|
|
1222
|
+
const isModule = packageJson["type"] === "module";
|
|
1220
1223
|
const { access } = await import("node:fs/promises");
|
|
1221
1224
|
try {
|
|
1222
1225
|
await access(path.join(cwd, "tsconfig.json"));
|
|
1223
|
-
return "ts";
|
|
1226
|
+
return isModule ? "ts" : "mts";
|
|
1224
1227
|
} catch {}
|
|
1225
|
-
if (typeof rawDependencies === "object" && rawDependencies !== null && Object.hasOwn(rawDependencies, "typescript")) return "ts";
|
|
1226
|
-
if (typeof rawDevelopmentDependencies === "object" && rawDevelopmentDependencies !== null && Object.hasOwn(rawDevelopmentDependencies, "typescript")) return "ts";
|
|
1227
|
-
return "js";
|
|
1228
|
+
if (typeof rawDependencies === "object" && rawDependencies !== null && Object.hasOwn(rawDependencies, "typescript")) return isModule ? "ts" : "mts";
|
|
1229
|
+
if (typeof rawDevelopmentDependencies === "object" && rawDevelopmentDependencies !== null && Object.hasOwn(rawDevelopmentDependencies, "typescript")) return isModule ? "ts" : "mts";
|
|
1230
|
+
return isModule ? "js" : "mjs";
|
|
1228
1231
|
}
|
|
1229
1232
|
async function init(options) {
|
|
1230
1233
|
const { _cwd, lang: explicitLang } = options;
|
|
@@ -1243,10 +1246,10 @@ async function init(options) {
|
|
|
1243
1246
|
const configPath = path.join(cwd, filename);
|
|
1244
1247
|
if (!await handleExistingConfig(configPath, filename)) return;
|
|
1245
1248
|
let workspaceLabel = "single package";
|
|
1246
|
-
let
|
|
1249
|
+
let workspacePackages = [];
|
|
1247
1250
|
try {
|
|
1248
|
-
|
|
1249
|
-
if (
|
|
1251
|
+
workspacePackages = await discoverWorkspace(cwd);
|
|
1252
|
+
if (workspacePackages.length > 1) workspaceLabel = `monorepo with ${String(workspacePackages.length)} packages`;
|
|
1250
1253
|
} catch {
|
|
1251
1254
|
workspaceLabel = "unknown (workspace detection failed)";
|
|
1252
1255
|
}
|
|
@@ -1264,7 +1267,7 @@ async function init(options) {
|
|
|
1264
1267
|
const labelIndent = " ".repeat(19);
|
|
1265
1268
|
console.log(topDivider);
|
|
1266
1269
|
console.log(` ${dim(labelPad("Workspace:"))} ${cyan(workspaceLabel)}`);
|
|
1267
|
-
if (
|
|
1270
|
+
if (workspacePackages.length > 1) for (const package_ of workspacePackages) {
|
|
1268
1271
|
const bullet = dim(`• ${path.relative(cwd, package_.path)}`);
|
|
1269
1272
|
console.log(` ${labelIndent}${bullet}`);
|
|
1270
1273
|
}
|
|
@@ -1273,15 +1276,14 @@ async function init(options) {
|
|
|
1273
1276
|
console.log(bottomDivider);
|
|
1274
1277
|
console.log();
|
|
1275
1278
|
if (!_cwd) {
|
|
1276
|
-
const stopSpinner = startSpinner(
|
|
1279
|
+
const stopSpinner = startSpinner(`Installing ${styleText("cyan", "@udohjeremiah/moniq")} as devDependency...`);
|
|
1277
1280
|
try {
|
|
1278
1281
|
await installPackage(pm, cwd, options.version);
|
|
1279
1282
|
stopSpinner();
|
|
1280
|
-
console.log(`
|
|
1281
|
-
console.log();
|
|
1283
|
+
console.log(` ${styleText(["bold", "green"], "✔ Installed @udohjeremiah/moniq as devDependency")}`);
|
|
1282
1284
|
} catch (error) {
|
|
1283
1285
|
stopSpinner();
|
|
1284
|
-
const styledError = styleText("red",
|
|
1286
|
+
const styledError = styleText("red", `✘ ${`Installation failed: ${String(error)}`}`);
|
|
1285
1287
|
console.log(` ${styledError}`);
|
|
1286
1288
|
console.log(` ${styleText("dim", "Make sure you have a working internet connection and try again.")}`);
|
|
1287
1289
|
console.log();
|
|
@@ -1291,11 +1293,9 @@ async function init(options) {
|
|
|
1291
1293
|
}
|
|
1292
1294
|
const { writeFile } = await import("node:fs/promises");
|
|
1293
1295
|
await writeFile(configPath, STARTER_CONFIG, "utf8");
|
|
1294
|
-
const createdMessage =
|
|
1296
|
+
const createdMessage = `✔ Created ${filename}`;
|
|
1295
1297
|
console.log(` ${styleText(["bold", "green"], createdMessage)}`);
|
|
1296
1298
|
console.log();
|
|
1297
|
-
await doctor();
|
|
1298
|
-
console.log();
|
|
1299
1299
|
console.log(` ${styleText("dim", "Next steps:")}`);
|
|
1300
1300
|
console.log(` 1. ${styleText("dim", "Edit")} ${styleText("cyan", filename)} ${styleText("dim", "to configure your policies.")}`);
|
|
1301
1301
|
console.log(` 2. ${styleText("dim", "Run")} ${styleText("cyan", "moniq check")} ${styleText("dim", "to validate your workspace.")}`);
|
|
@@ -1384,7 +1384,7 @@ function startSpinner(text) {
|
|
|
1384
1384
|
];
|
|
1385
1385
|
let index = 0;
|
|
1386
1386
|
const id = setInterval(() => {
|
|
1387
|
-
const styled = styleText("dim",
|
|
1387
|
+
const styled = `${styleText("dim", frames.at(index) ?? "")} ${text}`;
|
|
1388
1388
|
process.stdout.write(`\r ${styled}`);
|
|
1389
1389
|
index = (index + 1) % frames.length;
|
|
1390
1390
|
}, 80);
|