@eventcatalog/cli 0.5.4 → 0.5.6

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.
@@ -1248,7 +1248,15 @@ var loadGovernanceConfig = (catalogDir) => {
1248
1248
  }
1249
1249
  const content = fs.readFileSync(configPath, "utf-8");
1250
1250
  const parsed = yaml.load(content);
1251
- return { rules: parsed?.rules || [] };
1251
+ const rules = parsed?.rules || [];
1252
+ for (const rule of rules) {
1253
+ for (const action of rule.actions) {
1254
+ if (action.type === "fail" && action.message !== void 0 && typeof action.message !== "string") {
1255
+ throw new Error(`Invalid "message" in fail action for rule "${rule.name}". Must be a string.`);
1256
+ }
1257
+ }
1258
+ }
1259
+ return { rules };
1252
1260
  };
1253
1261
  var TRIGGER_FILTERS = {
1254
1262
  consumer_added: (c2) => c2.direction === "receives" && c2.changeType === "added",
@@ -1716,6 +1724,17 @@ var formatGovernanceOutput = (results) => {
1716
1724
  }
1717
1725
  return lines.join("\n");
1718
1726
  };
1727
+ var formatFailureOutput = (failures) => {
1728
+ if (failures.length === 0) return "";
1729
+ const lines = [];
1730
+ for (const f of failures) {
1731
+ lines.push(`FAILED: ${f.ruleName}`);
1732
+ for (const msg of f.messages) {
1733
+ lines.push(` ${msg}`);
1734
+ }
1735
+ }
1736
+ return lines.join("\n");
1737
+ };
1719
1738
 
1720
1739
  // src/cli/governance/check.ts
1721
1740
  import path3 from "path";
@@ -1773,9 +1792,16 @@ var governanceCheck = async (opts) => {
1773
1792
  const diff = await baseSDK.diffSnapshots(baseResult.filePath, targetResult.filePath);
1774
1793
  const config = loadGovernanceConfig(dir);
1775
1794
  if (config.rules.length === 0) {
1776
- return "No governance.yaml (or governance.yml) found or no rules defined.";
1795
+ return { output: "No governance.yaml (or governance.yml) found or no rules defined.", exitCode: 0, failures: [] };
1777
1796
  }
1778
1797
  const results = evaluateGovernanceRules(diff, config, targetResult.snapshot, baseResult.snapshot);
1798
+ for (const result of results) {
1799
+ const failActions = result.rule.actions.filter((a) => a.type === "fail");
1800
+ if (failActions.length > 0) {
1801
+ result.failed = true;
1802
+ result.failMessages = failActions.map((a) => "message" in a && a.message ? resolveEnvVars(a.message) : void 0).filter((m) => m !== void 0);
1803
+ }
1804
+ }
1779
1805
  await enrichSchemaContent(results, baseTmpDir, targetCatalogDir);
1780
1806
  const messageTypes = buildMessageTypeMap(targetResult.snapshot);
1781
1807
  const serviceOwners = buildServiceOwnersMap(targetResult.snapshot);
@@ -1786,8 +1812,20 @@ var governanceCheck = async (opts) => {
1786
1812
  baseRef: baseBranch,
1787
1813
  targetRef: opts.target || "working-directory"
1788
1814
  });
1815
+ const failures = results.filter((r) => r.failed).map((r) => ({ ruleName: r.rule.name, messages: r.failMessages || [] }));
1789
1816
  if (opts.format === "json") {
1790
- return JSON.stringify({ baseBranch, target: opts.target || "working directory", results, diff: diff.summary }, null, 2);
1817
+ const jsonOutput = {
1818
+ baseBranch,
1819
+ target: opts.target || "working directory",
1820
+ results,
1821
+ summary: {
1822
+ rulesTriggered: results.length,
1823
+ failures: failures.length,
1824
+ passed: failures.length === 0
1825
+ },
1826
+ diff: diff.summary
1827
+ };
1828
+ return { output: JSON.stringify(jsonOutput, null, 2), exitCode: failures.length > 0 ? 1 : 0, failures };
1791
1829
  }
1792
1830
  const targetLabel = opts.target || "working directory";
1793
1831
  const lines = [`Governance check: comparing ${targetLabel} against ${baseBranch}`, ""];
@@ -1803,7 +1841,12 @@ var governanceCheck = async (opts) => {
1803
1841
  lines.push("");
1804
1842
  lines.push(parts.join(", ") + ".");
1805
1843
  }
1806
- return lines.join("\n");
1844
+ const failureOutput = formatFailureOutput(failures);
1845
+ if (failureOutput) {
1846
+ lines.push("");
1847
+ lines.push(failureOutput);
1848
+ }
1849
+ return { output: lines.join("\n"), exitCode: failures.length > 0 ? 1 : 0, failures };
1807
1850
  } finally {
1808
1851
  for (const d of tempDirs) {
1809
1852
  rmSync2(d, { recursive: true, force: true });
@@ -1929,7 +1972,8 @@ governance.command("check").description("Compare catalog against a base branch a
1929
1972
  status: opts.status,
1930
1973
  dir
1931
1974
  });
1932
- console.log(result);
1975
+ console.log(result.output);
1976
+ process.exitCode = result.exitCode;
1933
1977
  } catch (error) {
1934
1978
  console.error(error instanceof Error ? error.message : String(error));
1935
1979
  process.exit(1);