@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 CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { n as loadConfig } from "./dist-B1TNZsla.js";
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.2";
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"], " No issues found.");
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("", `📦 ${styleText(["bold", "cyan"], packageName)}`);
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 = `📋 Found ${String(diagnostics.length)} issue(s) — ${summary.length > 0 ? summary : "all clear"}`;
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", `🔮 Dry-run: ${String(fixableCount)} fix(es) available`));
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 emoji = severityEmoji(d.severity);
958
- lines.push(` ${emoji} ${badge} ${d.message}`);
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
- const icon = isDryRun ? "🔮" : "🔧";
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 severityEmoji(severity) {
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("No moniq.config file found in or above the current directory.");
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 = `🔮 Dry-run: ${String(fixSummary.fixed)} fix(es) available, ${String(fixSummary.errors)} error(s)`;
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 = `✅ Fixed ${String(fixSummary.fixed)} issue(s) across ${String(fixSummary.packageCount)} package(s)`;
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
- try {
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: "warn"
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
- console.log(` ${styleText("bold", "🏥 Configuration Doctor")}`);
1083
- console.log();
1084
- if (issues.length === 0) {
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
- const icon = issue.severity === "error" ? "❌" : "⚠️ ";
1090
- const label = issue.severity === "error" ? styleText(["bold", "red"], "ERROR") : styleText(["bold", "yellow"], "WARN");
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(` ${summary}`);
1089
+ console.log(summary);
1098
1090
  if (errorCount > 0) {
1099
- const tip = styleText(["bold", "cyan"], "💡 Tip:");
1091
+ const tip = styleText(["bold", "cyan"], "Tip:");
1100
1092
  const hint = styleText("dim", "moniq init");
1101
1093
  console.log();
1102
- console.log(` ${tip} Run ${hint} to scaffold a starter configuration.`);
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 packages = [];
1249
+ let workspacePackages = [];
1247
1250
  try {
1248
- packages = await discoverWorkspace(cwd);
1249
- if (packages.length > 1) workspaceLabel = `monorepo with ${String(packages.length)} packages`;
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 (packages.length > 1) for (const package_ of packages) {
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("Installing @udohjeremiah/moniq as devDependency...");
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(` Installed @udohjeremiah/moniq as devDependency`);
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", `❌ ${`Installation failed: ${String(error)}`}`);
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 = `✅ Created ${filename}`;
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", `${frames.at(index) ?? ""} ${text}`);
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);