@eventcatalog/core 4.7.4 → 4.7.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.
Files changed (37) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/{chunk-FDXJIZ74.js → chunk-2BYTIH4L.js} +1 -1
  6. package/dist/{chunk-7QTCSRAC.js → chunk-EUZT4RKY.js} +1 -1
  7. package/dist/{chunk-RIUHZZRA.js → chunk-GYYYAUJD.js} +128 -56
  8. package/dist/chunk-JJPB6EOZ.js +159 -0
  9. package/dist/{chunk-ZIABX6SP.js → chunk-QJRY6Q7S.js} +1 -1
  10. package/dist/{chunk-ZXVQXBTT.js → chunk-QQPH6RCB.js} +24 -1
  11. package/dist/chunk-WRNH5C3U.js +118 -0
  12. package/dist/{chunk-TLWM7WRZ.js → chunk-ZBPMCEXS.js} +1 -1
  13. package/dist/constants.cjs +1 -1
  14. package/dist/constants.js +1 -1
  15. package/dist/eventcatalog.cjs +540 -194
  16. package/dist/eventcatalog.config.d.cts +9 -3
  17. package/dist/eventcatalog.config.d.ts +9 -3
  18. package/dist/eventcatalog.js +37 -39
  19. package/dist/federation/diagnostics.cjs +187 -0
  20. package/dist/federation/diagnostics.d.cts +23 -0
  21. package/dist/federation/diagnostics.d.ts +23 -0
  22. package/dist/federation/diagnostics.js +14 -0
  23. package/dist/federation/federate.cjs +442 -117
  24. package/dist/federation/federate.d.cts +8 -1
  25. package/dist/federation/federate.d.ts +8 -1
  26. package/dist/federation/federate.js +6 -2
  27. package/dist/federation/output-transaction.cjs +152 -0
  28. package/dist/federation/output-transaction.d.cts +3 -0
  29. package/dist/federation/output-transaction.d.ts +3 -0
  30. package/dist/federation/output-transaction.js +6 -0
  31. package/dist/generate.cjs +24 -1
  32. package/dist/generate.js +3 -3
  33. package/dist/utils/cli-logger.cjs +24 -1
  34. package/dist/utils/cli-logger.d.cts +6 -0
  35. package/dist/utils/cli-logger.d.ts +6 -0
  36. package/dist/utils/cli-logger.js +2 -2
  37. package/package.json +3 -3
@@ -1,5 +1,6 @@
1
1
  import { ResolvedGraph, HydrateResult, Conflict } from '@eventcatalog/sdk';
2
2
  import { FederationSourceConfig } from '../eventcatalog.config.cjs';
3
+ import { FederationDiagnostic } from './diagnostics.cjs';
3
4
  import { PublicAssetCompositionResult } from './public-assets.cjs';
4
5
  import { FederationSourceProvider } from './types.cjs';
5
6
 
@@ -38,6 +39,7 @@ type FederationProgressEvent = {
38
39
  } | {
39
40
  type: 'resolved';
40
41
  graph: ResolvedGraph;
42
+ diagnostics: FederationDiagnostic[];
41
43
  } | {
42
44
  type: 'hydrating';
43
45
  outDir: string;
@@ -60,6 +62,7 @@ type FederateCatalogResult = {
60
62
  sources: number;
61
63
  resources: number;
62
64
  graph: ResolvedGraph;
65
+ diagnostics: FederationDiagnostic[];
63
66
  hydrate: HydrateResult;
64
67
  public: PublicAssetCompositionResult;
65
68
  outDir: string;
@@ -76,6 +79,10 @@ declare class FederationConflictError extends Error {
76
79
  conflicts: Conflict[];
77
80
  constructor(conflicts: Conflict[]);
78
81
  }
82
+ declare class FederationDiagnosticError extends Error {
83
+ diagnostics: FederationDiagnostic[];
84
+ constructor(diagnostics: FederationDiagnostic[]);
85
+ }
79
86
  declare const federateCatalog: (projectDirectory: string, options?: FederateCatalogOptions) => Promise<FederateCatalogResult | null>;
80
87
 
81
- export { type FederateCatalogResult, FederationConflictError, type FederationProgressEvent, federateCatalog };
88
+ export { type FederateCatalogResult, FederationConflictError, FederationDiagnosticError, type FederationProgressEvent, federateCatalog };
@@ -1,5 +1,6 @@
1
1
  import { ResolvedGraph, HydrateResult, Conflict } from '@eventcatalog/sdk';
2
2
  import { FederationSourceConfig } from '../eventcatalog.config.js';
3
+ import { FederationDiagnostic } from './diagnostics.js';
3
4
  import { PublicAssetCompositionResult } from './public-assets.js';
4
5
  import { FederationSourceProvider } from './types.js';
5
6
 
@@ -38,6 +39,7 @@ type FederationProgressEvent = {
38
39
  } | {
39
40
  type: 'resolved';
40
41
  graph: ResolvedGraph;
42
+ diagnostics: FederationDiagnostic[];
41
43
  } | {
42
44
  type: 'hydrating';
43
45
  outDir: string;
@@ -60,6 +62,7 @@ type FederateCatalogResult = {
60
62
  sources: number;
61
63
  resources: number;
62
64
  graph: ResolvedGraph;
65
+ diagnostics: FederationDiagnostic[];
63
66
  hydrate: HydrateResult;
64
67
  public: PublicAssetCompositionResult;
65
68
  outDir: string;
@@ -76,6 +79,10 @@ declare class FederationConflictError extends Error {
76
79
  conflicts: Conflict[];
77
80
  constructor(conflicts: Conflict[]);
78
81
  }
82
+ declare class FederationDiagnosticError extends Error {
83
+ diagnostics: FederationDiagnostic[];
84
+ constructor(diagnostics: FederationDiagnostic[]);
85
+ }
79
86
  declare const federateCatalog: (projectDirectory: string, options?: FederateCatalogOptions) => Promise<FederateCatalogResult | null>;
80
87
 
81
- export { type FederateCatalogResult, FederationConflictError, type FederationProgressEvent, federateCatalog };
88
+ export { type FederateCatalogResult, FederationConflictError, FederationDiagnosticError, type FederationProgressEvent, federateCatalog };
@@ -1,14 +1,18 @@
1
1
  import {
2
2
  FederationConflictError,
3
+ FederationDiagnosticError,
3
4
  federateCatalog
4
- } from "../chunk-RIUHZZRA.js";
5
+ } from "../chunk-GYYYAUJD.js";
6
+ import "../chunk-WRNH5C3U.js";
7
+ import "../chunk-5EPNFDT5.js";
5
8
  import "../chunk-A2RZR3U4.js";
6
9
  import "../chunk-R7Z5ALYI.js";
10
+ import "../chunk-JJPB6EOZ.js";
7
11
  import "../chunk-SDZQJTJW.js";
8
12
  import "../chunk-352FGP6W.js";
9
- import "../chunk-5EPNFDT5.js";
10
13
  import "../chunk-6QENHZZP.js";
11
14
  export {
12
15
  FederationConflictError,
16
+ FederationDiagnosticError,
13
17
  federateCatalog
14
18
  };
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/federation/output-transaction.ts
31
+ var output_transaction_exports = {};
32
+ __export(output_transaction_exports, {
33
+ withFederationOutputTransaction: () => withFederationOutputTransaction
34
+ });
35
+ module.exports = __toCommonJS(output_transaction_exports);
36
+ var import_promises = __toESM(require("fs/promises"), 1);
37
+ var import_node_path = __toESM(require("path"), 1);
38
+ var getSafePublicPath = (publicDirectory, relativePath) => {
39
+ const normalizedPath = import_node_path.default.posix.normalize(relativePath);
40
+ const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
41
+ if (unsafe) return void 0;
42
+ const destinationPath = import_node_path.default.resolve(publicDirectory, relativePath);
43
+ const relativeDestinationPath = import_node_path.default.relative(publicDirectory, destinationPath);
44
+ return relativeDestinationPath !== "" && relativeDestinationPath !== ".." && !relativeDestinationPath.startsWith(`..${import_node_path.default.sep}`) && !import_node_path.default.isAbsolute(relativeDestinationPath) ? destinationPath : void 0;
45
+ };
46
+ var beginFederationOutputTransaction = async (projectDirectory, outDir, relativePublicPaths) => {
47
+ const transactionDirectory = await import_promises.default.mkdtemp(import_node_path.default.join(projectDirectory, ".eventcatalog-federation-transaction-"));
48
+ const previousOutDir = import_node_path.default.join(transactionDirectory, "federated");
49
+ const publicBackupDirectory = import_node_path.default.join(transactionDirectory, "public");
50
+ const publicDirectory = import_node_path.default.resolve(projectDirectory, "public");
51
+ const publicSnapshots = [];
52
+ const missingPublicDirectories = /* @__PURE__ */ new Set();
53
+ let hadPreviousOutDir = false;
54
+ try {
55
+ for (const relativePath of new Set(relativePublicPaths)) {
56
+ const destinationPath = getSafePublicPath(publicDirectory, relativePath);
57
+ if (!destinationPath) continue;
58
+ try {
59
+ const stat = await import_promises.default.lstat(destinationPath);
60
+ if (!stat.isFile()) continue;
61
+ const backupPath = import_node_path.default.join(publicBackupDirectory, `${publicSnapshots.length}`);
62
+ await import_promises.default.mkdir(import_node_path.default.dirname(backupPath), { recursive: true });
63
+ await import_promises.default.copyFile(destinationPath, backupPath);
64
+ publicSnapshots.push({ backupPath, destinationPath, state: "file" });
65
+ } catch (error) {
66
+ const code = error.code;
67
+ if (code === "ENOTDIR") continue;
68
+ if (code !== "ENOENT") throw error;
69
+ publicSnapshots.push({ destinationPath, state: "missing" });
70
+ let directory = import_node_path.default.dirname(destinationPath);
71
+ while (directory !== publicDirectory) {
72
+ try {
73
+ await import_promises.default.lstat(directory);
74
+ break;
75
+ } catch (directoryError) {
76
+ const directoryCode = directoryError.code;
77
+ if (directoryCode === "ENOTDIR") break;
78
+ if (directoryCode !== "ENOENT") throw directoryError;
79
+ missingPublicDirectories.add(directory);
80
+ directory = import_node_path.default.dirname(directory);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ try {
86
+ await import_promises.default.rename(outDir, previousOutDir);
87
+ hadPreviousOutDir = true;
88
+ } catch (error) {
89
+ if (error.code !== "ENOENT") throw error;
90
+ }
91
+ } catch (error) {
92
+ await import_promises.default.rm(transactionDirectory, { recursive: true, force: true });
93
+ throw error;
94
+ }
95
+ return {
96
+ commit: async () => {
97
+ await import_promises.default.rm(transactionDirectory, { recursive: true, force: true }).catch(() => void 0);
98
+ },
99
+ rollback: async () => {
100
+ const rollbackErrors = [];
101
+ const attempt = async (operation) => {
102
+ try {
103
+ await operation();
104
+ } catch (error) {
105
+ rollbackErrors.push(error);
106
+ }
107
+ };
108
+ await attempt(() => import_promises.default.rm(outDir, { recursive: true, force: true }));
109
+ if (hadPreviousOutDir) await attempt(() => import_promises.default.rename(previousOutDir, outDir));
110
+ for (const snapshot of publicSnapshots) {
111
+ if (snapshot.state === "missing") {
112
+ await attempt(() => import_promises.default.rm(snapshot.destinationPath, { force: true }));
113
+ continue;
114
+ }
115
+ await attempt(async () => {
116
+ await import_promises.default.mkdir(import_node_path.default.dirname(snapshot.destinationPath), { recursive: true });
117
+ await import_promises.default.copyFile(snapshot.backupPath, snapshot.destinationPath);
118
+ });
119
+ }
120
+ for (const directory of [...missingPublicDirectories].sort((left, right) => right.length - left.length)) {
121
+ await attempt(async () => {
122
+ try {
123
+ await import_promises.default.rmdir(directory);
124
+ } catch (error) {
125
+ if (!["ENOENT", "ENOTEMPTY"].includes(error.code ?? "")) throw error;
126
+ }
127
+ });
128
+ }
129
+ await attempt(() => import_promises.default.rm(transactionDirectory, { recursive: true, force: true }));
130
+ if (rollbackErrors.length > 0) throw new AggregateError(rollbackErrors, "Failed to restore the previous federation output");
131
+ }
132
+ };
133
+ };
134
+ var withFederationOutputTransaction = async (projectDirectory, outDir, relativePublicPaths, update) => {
135
+ const transaction = await beginFederationOutputTransaction(projectDirectory, outDir, relativePublicPaths);
136
+ try {
137
+ const result = await update();
138
+ await transaction.commit();
139
+ return result;
140
+ } catch (error) {
141
+ try {
142
+ await transaction.rollback();
143
+ } catch (rollbackError) {
144
+ throw new AggregateError([error, rollbackError], "Federation failed and the previous output could not be restored");
145
+ }
146
+ throw error;
147
+ }
148
+ };
149
+ // Annotate the CommonJS export names for ESM import in node:
150
+ 0 && (module.exports = {
151
+ withFederationOutputTransaction
152
+ });
@@ -0,0 +1,3 @@
1
+ declare const withFederationOutputTransaction: <Result>(projectDirectory: string, outDir: string, relativePublicPaths: Iterable<string>, update: () => Promise<Result>) => Promise<Result>;
2
+
3
+ export { withFederationOutputTransaction };
@@ -0,0 +1,3 @@
1
+ declare const withFederationOutputTransaction: <Result>(projectDirectory: string, outDir: string, relativePublicPaths: Iterable<string>, update: () => Promise<Result>) => Promise<Result>;
2
+
3
+ export { withFederationOutputTransaction };
@@ -0,0 +1,6 @@
1
+ import {
2
+ withFederationOutputTransaction
3
+ } from "../chunk-WRNH5C3U.js";
4
+ export {
5
+ withFederationOutputTransaction
6
+ };
package/dist/generate.cjs CHANGED
@@ -108,7 +108,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
108
108
  var import_picocolors = __toESM(require("picocolors"), 1);
109
109
 
110
110
  // package.json
111
- var version = "4.7.4";
111
+ var version = "4.7.5";
112
112
 
113
113
  // src/constants.ts
114
114
  var VERSION = version;
@@ -147,6 +147,29 @@ var logger = {
147
147
  warning: (message, tag = "warn") => {
148
148
  console.log(formatMessage(tag, message, import_picocolors.default.yellow));
149
149
  },
150
+ line: (message = "") => {
151
+ console.log(message);
152
+ },
153
+ diagnostic: (severity, message, rule, attributes = []) => {
154
+ const isError = severity === "error";
155
+ const color = isError ? import_picocolors.default.red : import_picocolors.default.yellow;
156
+ const icon = isError ? "\u2716" : "\u26A0";
157
+ const label = `${icon} ${severity.padEnd(7)} ${message}`;
158
+ const ruleSpacing = " ".repeat(Math.max(2, 72 - label.length));
159
+ console.log(` ${color(icon)} ${color(severity.padEnd(7))} ${message}${ruleSpacing}${import_picocolors.default.gray(rule)}`);
160
+ for (const attribute of attributes) {
161
+ console.log(` - ${import_picocolors.default.dim(`${attribute.label}:`)} ${attribute.value}`);
162
+ }
163
+ },
164
+ diagnosticSummary: (errors, warnings) => {
165
+ const total = errors + warnings;
166
+ const color = errors > 0 ? import_picocolors.default.red : import_picocolors.default.yellow;
167
+ const icon = errors > 0 ? "\u2716" : "\u26A0";
168
+ const problems = `${total} problem${total === 1 ? "" : "s"}`;
169
+ const errorCount = `${errors} error${errors === 1 ? "" : "s"}`;
170
+ const warningCount = `${warnings} warning${warnings === 1 ? "" : "s"}`;
171
+ console.log(color(`${icon} ${problems} (${errorCount}, ${warningCount})`));
172
+ },
150
173
  dim: (message) => {
151
174
  console.log(import_picocolors.default.dim(message));
152
175
  }
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-7QTCSRAC.js";
4
- import "./chunk-ZXVQXBTT.js";
5
- import "./chunk-TLWM7WRZ.js";
3
+ } from "./chunk-EUZT4RKY.js";
4
+ import "./chunk-QQPH6RCB.js";
5
+ import "./chunk-ZBPMCEXS.js";
6
6
  import "./chunk-6QENHZZP.js";
7
7
  export {
8
8
  generate
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "4.7.4";
39
+ var version = "4.7.5";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -75,6 +75,29 @@ var logger = {
75
75
  warning: (message, tag = "warn") => {
76
76
  console.log(formatMessage(tag, message, import_picocolors.default.yellow));
77
77
  },
78
+ line: (message = "") => {
79
+ console.log(message);
80
+ },
81
+ diagnostic: (severity, message, rule, attributes = []) => {
82
+ const isError = severity === "error";
83
+ const color = isError ? import_picocolors.default.red : import_picocolors.default.yellow;
84
+ const icon = isError ? "\u2716" : "\u26A0";
85
+ const label = `${icon} ${severity.padEnd(7)} ${message}`;
86
+ const ruleSpacing = " ".repeat(Math.max(2, 72 - label.length));
87
+ console.log(` ${color(icon)} ${color(severity.padEnd(7))} ${message}${ruleSpacing}${import_picocolors.default.gray(rule)}`);
88
+ for (const attribute of attributes) {
89
+ console.log(` - ${import_picocolors.default.dim(`${attribute.label}:`)} ${attribute.value}`);
90
+ }
91
+ },
92
+ diagnosticSummary: (errors, warnings) => {
93
+ const total = errors + warnings;
94
+ const color = errors > 0 ? import_picocolors.default.red : import_picocolors.default.yellow;
95
+ const icon = errors > 0 ? "\u2716" : "\u26A0";
96
+ const problems = `${total} problem${total === 1 ? "" : "s"}`;
97
+ const errorCount = `${errors} error${errors === 1 ? "" : "s"}`;
98
+ const warningCount = `${warnings} warning${warnings === 1 ? "" : "s"}`;
99
+ console.log(color(`${icon} ${problems} (${errorCount}, ${warningCount})`));
100
+ },
78
101
  dim: (message) => {
79
102
  console.log(import_picocolors.default.dim(message));
80
103
  }
@@ -4,6 +4,12 @@ declare const logger: {
4
4
  success: (message: string, tag?: string) => void;
5
5
  error: (message: string, tag?: string) => void;
6
6
  warning: (message: string, tag?: string) => void;
7
+ line: (message?: string) => void;
8
+ diagnostic: (severity: "error" | "warning", message: string, rule: string, attributes?: {
9
+ label: string;
10
+ value: string;
11
+ }[]) => void;
12
+ diagnosticSummary: (errors: number, warnings: number) => void;
7
13
  dim: (message: string) => void;
8
14
  };
9
15
 
@@ -4,6 +4,12 @@ declare const logger: {
4
4
  success: (message: string, tag?: string) => void;
5
5
  error: (message: string, tag?: string) => void;
6
6
  warning: (message: string, tag?: string) => void;
7
+ line: (message?: string) => void;
8
+ diagnostic: (severity: "error" | "warning", message: string, rule: string, attributes?: {
9
+ label: string;
10
+ value: string;
11
+ }[]) => void;
12
+ diagnosticSummary: (errors: number, warnings: number) => void;
7
13
  dim: (message: string) => void;
8
14
  };
9
15
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-ZXVQXBTT.js";
4
- import "../chunk-TLWM7WRZ.js";
3
+ } from "../chunk-QQPH6RCB.js";
4
+ import "../chunk-ZBPMCEXS.js";
5
5
  export {
6
6
  logger
7
7
  };
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "license": "SEE LICENSE IN LICENSE",
9
9
  "type": "module",
10
- "version": "4.7.4",
10
+ "version": "4.7.5",
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
@@ -119,8 +119,8 @@
119
119
  "update-notifier": "^7.3.1",
120
120
  "uuid": "^11.1.1",
121
121
  "zod": "^4.3.6",
122
- "@eventcatalog/linter": "1.1.13",
123
- "@eventcatalog/sdk": "2.27.3",
122
+ "@eventcatalog/linter": "1.1.14",
123
+ "@eventcatalog/sdk": "2.27.4",
124
124
  "@eventcatalog/visualiser": "^4.1.3"
125
125
  },
126
126
  "devDependencies": {