@eventcatalog/cli 0.5.4 → 0.5.5

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/index.js CHANGED
@@ -1264,7 +1264,15 @@ var loadGovernanceConfig = (catalogDir) => {
1264
1264
  }
1265
1265
  const content = import_node_fs5.default.readFileSync(configPath, "utf-8");
1266
1266
  const parsed = import_js_yaml.default.load(content);
1267
- return { rules: parsed?.rules || [] };
1267
+ const rules = parsed?.rules || [];
1268
+ for (const rule of rules) {
1269
+ for (const action of rule.actions) {
1270
+ if (action.type === "fail" && action.message !== void 0 && typeof action.message !== "string") {
1271
+ throw new Error(`Invalid "message" in fail action for rule "${rule.name}". Must be a string.`);
1272
+ }
1273
+ }
1274
+ }
1275
+ return { rules };
1268
1276
  };
1269
1277
  var TRIGGER_FILTERS = {
1270
1278
  consumer_added: (c2) => c2.direction === "receives" && c2.changeType === "added",
@@ -1732,6 +1740,17 @@ var formatGovernanceOutput = (results) => {
1732
1740
  }
1733
1741
  return lines.join("\n");
1734
1742
  };
1743
+ var formatFailureOutput = (failures) => {
1744
+ if (failures.length === 0) return "";
1745
+ const lines = [];
1746
+ for (const f of failures) {
1747
+ lines.push(`FAILED: ${f.ruleName}`);
1748
+ for (const msg of f.messages) {
1749
+ lines.push(` ${msg}`);
1750
+ }
1751
+ }
1752
+ return lines.join("\n");
1753
+ };
1735
1754
 
1736
1755
  // src/cli/governance/check.ts
1737
1756
  var import_node_path5 = __toESM(require("path"));
@@ -1789,9 +1808,16 @@ var governanceCheck = async (opts) => {
1789
1808
  const diff = await baseSDK.diffSnapshots(baseResult.filePath, targetResult.filePath);
1790
1809
  const config = loadGovernanceConfig(dir);
1791
1810
  if (config.rules.length === 0) {
1792
- return "No governance.yaml (or governance.yml) found or no rules defined.";
1811
+ return { output: "No governance.yaml (or governance.yml) found or no rules defined.", exitCode: 0, failures: [] };
1793
1812
  }
1794
1813
  const results = evaluateGovernanceRules(diff, config, targetResult.snapshot, baseResult.snapshot);
1814
+ for (const result of results) {
1815
+ const failActions = result.rule.actions.filter((a) => a.type === "fail");
1816
+ if (failActions.length > 0) {
1817
+ result.failed = true;
1818
+ result.failMessages = failActions.map((a) => "message" in a && a.message ? resolveEnvVars(a.message) : void 0).filter((m) => m !== void 0);
1819
+ }
1820
+ }
1795
1821
  await enrichSchemaContent(results, baseTmpDir, targetCatalogDir);
1796
1822
  const messageTypes = buildMessageTypeMap(targetResult.snapshot);
1797
1823
  const serviceOwners = buildServiceOwnersMap(targetResult.snapshot);
@@ -1802,8 +1828,20 @@ var governanceCheck = async (opts) => {
1802
1828
  baseRef: baseBranch,
1803
1829
  targetRef: opts.target || "working-directory"
1804
1830
  });
1831
+ const failures = results.filter((r) => r.failed).map((r) => ({ ruleName: r.rule.name, messages: r.failMessages || [] }));
1805
1832
  if (opts.format === "json") {
1806
- return JSON.stringify({ baseBranch, target: opts.target || "working directory", results, diff: diff.summary }, null, 2);
1833
+ const jsonOutput = {
1834
+ baseBranch,
1835
+ target: opts.target || "working directory",
1836
+ results,
1837
+ summary: {
1838
+ rulesTriggered: results.length,
1839
+ failures: failures.length,
1840
+ passed: failures.length === 0
1841
+ },
1842
+ diff: diff.summary
1843
+ };
1844
+ return { output: JSON.stringify(jsonOutput, null, 2), exitCode: failures.length > 0 ? 1 : 0, failures };
1807
1845
  }
1808
1846
  const targetLabel = opts.target || "working directory";
1809
1847
  const lines = [`Governance check: comparing ${targetLabel} against ${baseBranch}`, ""];
@@ -1819,7 +1857,12 @@ var governanceCheck = async (opts) => {
1819
1857
  lines.push("");
1820
1858
  lines.push(parts.join(", ") + ".");
1821
1859
  }
1822
- return lines.join("\n");
1860
+ const failureOutput = formatFailureOutput(failures);
1861
+ if (failureOutput) {
1862
+ lines.push("");
1863
+ lines.push(failureOutput);
1864
+ }
1865
+ return { output: lines.join("\n"), exitCode: failures.length > 0 ? 1 : 0, failures };
1823
1866
  } finally {
1824
1867
  for (const d of tempDirs) {
1825
1868
  (0, import_node_fs6.rmSync)(d, { recursive: true, force: true });
@@ -1945,7 +1988,8 @@ governance.command("check").description("Compare catalog against a base branch a
1945
1988
  status: opts.status,
1946
1989
  dir
1947
1990
  });
1948
- console.log(result);
1991
+ console.log(result.output);
1992
+ process.exitCode = result.exitCode;
1949
1993
  } catch (error) {
1950
1994
  console.error(error instanceof Error ? error.message : String(error));
1951
1995
  process.exit(1);