@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.
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/{chunk-FDXJIZ74.js → chunk-2BYTIH4L.js} +1 -1
- package/dist/{chunk-7QTCSRAC.js → chunk-EUZT4RKY.js} +1 -1
- package/dist/{chunk-RIUHZZRA.js → chunk-GYYYAUJD.js} +128 -56
- package/dist/chunk-JJPB6EOZ.js +159 -0
- package/dist/{chunk-ZIABX6SP.js → chunk-QJRY6Q7S.js} +1 -1
- package/dist/{chunk-ZXVQXBTT.js → chunk-QQPH6RCB.js} +24 -1
- package/dist/chunk-WRNH5C3U.js +118 -0
- package/dist/{chunk-TLWM7WRZ.js → chunk-ZBPMCEXS.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +540 -194
- package/dist/eventcatalog.config.d.cts +9 -3
- package/dist/eventcatalog.config.d.ts +9 -3
- package/dist/eventcatalog.js +37 -39
- package/dist/federation/diagnostics.cjs +187 -0
- package/dist/federation/diagnostics.d.cts +23 -0
- package/dist/federation/diagnostics.d.ts +23 -0
- package/dist/federation/diagnostics.js +14 -0
- package/dist/federation/federate.cjs +442 -117
- package/dist/federation/federate.d.cts +8 -1
- package/dist/federation/federate.d.ts +8 -1
- package/dist/federation/federate.js +6 -2
- package/dist/federation/output-transaction.cjs +152 -0
- package/dist/federation/output-transaction.d.cts +3 -0
- package/dist/federation/output-transaction.d.ts +3 -0
- package/dist/federation/output-transaction.js +6 -0
- package/dist/generate.cjs +24 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +24 -1
- package/dist/utils/cli-logger.d.cts +6 -0
- package/dist/utils/cli-logger.d.ts +6 -0
- package/dist/utils/cli-logger.js +2 -2
- package/package.json +3 -3
|
@@ -85,11 +85,17 @@ type FederationSourceConfig = {
|
|
|
85
85
|
path?: string;
|
|
86
86
|
/** Branch or tag to federate from a GitHub source. Not supported for filesystem sources. @default 'main' */
|
|
87
87
|
ref?: string;
|
|
88
|
-
/** Materialize source files or retain graph references only. @default 'hydrate' */
|
|
89
|
-
mode?: 'hydrate' | 'reference';
|
|
90
88
|
};
|
|
89
|
+
type FederationRuleId = 'federation/duplicate-source' | 'federation/type-collision' | 'federation/pointer-type-mismatch' | 'federation/facet-disagreement' | 'federation/asset-collision' | 'federation/missing-resource' | 'federation/unresolved-version';
|
|
90
|
+
type FederationRuleLevel = 'off' | 'warn' | 'error';
|
|
91
|
+
type FederationRulesConfig = Partial<Record<FederationRuleId, FederationRuleLevel>>;
|
|
91
92
|
type FederationConfig = {
|
|
92
93
|
sources: FederationSourceConfig[];
|
|
94
|
+
/**
|
|
95
|
+
* Override federation validation rule levels. Unconfigured rules keep their defaults.
|
|
96
|
+
* `off` hides the diagnostic, `warn` reports and continues, and `error` stops before hydration.
|
|
97
|
+
*/
|
|
98
|
+
rules?: FederationRulesConfig;
|
|
93
99
|
};
|
|
94
100
|
type DirectoryEntry = {
|
|
95
101
|
id: string;
|
|
@@ -402,4 +408,4 @@ interface Config {
|
|
|
402
408
|
federation?: FederationConfig;
|
|
403
409
|
}
|
|
404
410
|
|
|
405
|
-
export type { Config, FederationSourceConfig };
|
|
411
|
+
export type { Config, FederationRuleId, FederationRuleLevel, FederationRulesConfig, FederationSourceConfig };
|
|
@@ -85,11 +85,17 @@ type FederationSourceConfig = {
|
|
|
85
85
|
path?: string;
|
|
86
86
|
/** Branch or tag to federate from a GitHub source. Not supported for filesystem sources. @default 'main' */
|
|
87
87
|
ref?: string;
|
|
88
|
-
/** Materialize source files or retain graph references only. @default 'hydrate' */
|
|
89
|
-
mode?: 'hydrate' | 'reference';
|
|
90
88
|
};
|
|
89
|
+
type FederationRuleId = 'federation/duplicate-source' | 'federation/type-collision' | 'federation/pointer-type-mismatch' | 'federation/facet-disagreement' | 'federation/asset-collision' | 'federation/missing-resource' | 'federation/unresolved-version';
|
|
90
|
+
type FederationRuleLevel = 'off' | 'warn' | 'error';
|
|
91
|
+
type FederationRulesConfig = Partial<Record<FederationRuleId, FederationRuleLevel>>;
|
|
91
92
|
type FederationConfig = {
|
|
92
93
|
sources: FederationSourceConfig[];
|
|
94
|
+
/**
|
|
95
|
+
* Override federation validation rule levels. Unconfigured rules keep their defaults.
|
|
96
|
+
* `off` hides the diagnostic, `warn` reports and continues, and `error` stops before hydration.
|
|
97
|
+
*/
|
|
98
|
+
rules?: FederationRulesConfig;
|
|
93
99
|
};
|
|
94
100
|
type DirectoryEntry = {
|
|
95
101
|
id: string;
|
|
@@ -402,4 +408,4 @@ interface Config {
|
|
|
402
408
|
federation?: FederationConfig;
|
|
403
409
|
}
|
|
404
410
|
|
|
405
|
-
export type { Config, FederationSourceConfig };
|
|
411
|
+
export type { Config, FederationRuleId, FederationRuleLevel, FederationRulesConfig, FederationSourceConfig };
|
package/dist/eventcatalog.js
CHANGED
|
@@ -4,18 +4,24 @@ import {
|
|
|
4
4
|
import "./chunk-CA4U2JP7.js";
|
|
5
5
|
import {
|
|
6
6
|
log_build_default
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-QJRY6Q7S.js";
|
|
8
|
+
import "./chunk-2BYTIH4L.js";
|
|
9
9
|
import "./chunk-K2XIENVT.js";
|
|
10
10
|
import {
|
|
11
11
|
FederationConflictError,
|
|
12
|
+
FederationDiagnosticError,
|
|
12
13
|
federateCatalog
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-GYYYAUJD.js";
|
|
15
|
+
import "./chunk-WRNH5C3U.js";
|
|
16
|
+
import "./chunk-5EPNFDT5.js";
|
|
14
17
|
import "./chunk-A2RZR3U4.js";
|
|
15
18
|
import "./chunk-R7Z5ALYI.js";
|
|
19
|
+
import {
|
|
20
|
+
getFederationDiagnosticCounts,
|
|
21
|
+
getVisibleFederationDiagnostics
|
|
22
|
+
} from "./chunk-JJPB6EOZ.js";
|
|
16
23
|
import "./chunk-SDZQJTJW.js";
|
|
17
24
|
import "./chunk-352FGP6W.js";
|
|
18
|
-
import "./chunk-5EPNFDT5.js";
|
|
19
25
|
import {
|
|
20
26
|
getProjectOutDir,
|
|
21
27
|
isAuthEnabled,
|
|
@@ -24,10 +30,10 @@ import {
|
|
|
24
30
|
} from "./chunk-B7HCX5HM.js";
|
|
25
31
|
import {
|
|
26
32
|
generate
|
|
27
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-EUZT4RKY.js";
|
|
28
34
|
import {
|
|
29
35
|
logger
|
|
30
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-QQPH6RCB.js";
|
|
31
37
|
import {
|
|
32
38
|
resolve_catalog_dependencies_default
|
|
33
39
|
} from "./chunk-LHR4G2UO.js";
|
|
@@ -47,7 +53,7 @@ import {
|
|
|
47
53
|
import "./chunk-W5JQON7Z.js";
|
|
48
54
|
import {
|
|
49
55
|
VERSION
|
|
50
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-ZBPMCEXS.js";
|
|
51
57
|
import {
|
|
52
58
|
linkCoreNodeModules,
|
|
53
59
|
resolveInstalledCoreNodeModules
|
|
@@ -1128,7 +1134,7 @@ program.command("generate [siteDir]").description("Start the generator scripts."
|
|
|
1128
1134
|
}
|
|
1129
1135
|
await generate(dir);
|
|
1130
1136
|
});
|
|
1131
|
-
var reportFederationProgress = (event) => {
|
|
1137
|
+
var reportFederationProgress = (event, verbose = false) => {
|
|
1132
1138
|
switch (event.type) {
|
|
1133
1139
|
case "configured":
|
|
1134
1140
|
if (event.sources > 0)
|
|
@@ -1168,34 +1174,32 @@ var reportFederationProgress = (event) => {
|
|
|
1168
1174
|
);
|
|
1169
1175
|
return;
|
|
1170
1176
|
case "resolved":
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1177
|
+
const counts = getFederationDiagnosticCounts(event.diagnostics);
|
|
1178
|
+
const showDiagnosticDetails = verbose || counts.errors > 0;
|
|
1179
|
+
if (counts.errors === 0) {
|
|
1180
|
+
logger.success(
|
|
1181
|
+
`Graph resolved: ${event.graph.entities.length} remote resources, ${event.graph.edges.length} relationships`,
|
|
1174
1182
|
"federation"
|
|
1175
1183
|
);
|
|
1176
|
-
for (const conflict of event.graph.conflicts.slice(0, 10)) {
|
|
1177
|
-
logger.error(`${conflict.id}: ${conflict.sources.join(", ")}`, "federation");
|
|
1178
|
-
}
|
|
1179
|
-
if (event.graph.conflicts.length > 10) {
|
|
1180
|
-
logger.error(`...and ${event.graph.conflicts.length - 10} more`, "federation");
|
|
1181
|
-
}
|
|
1182
|
-
return;
|
|
1183
1184
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1185
|
+
if (counts.errors + counts.warnings === 0) return;
|
|
1186
|
+
if (showDiagnosticDetails) {
|
|
1187
|
+
const diagnostics = getVisibleFederationDiagnostics(event.diagnostics, verbose);
|
|
1188
|
+
logger.info("Federation diagnostics", "federation");
|
|
1189
|
+
logger.line();
|
|
1190
|
+
for (const diagnostic of diagnostics) {
|
|
1191
|
+
logger.diagnostic(diagnostic.severity, diagnostic.message, diagnostic.rule, diagnostic.attributes);
|
|
1192
|
+
logger.line();
|
|
1193
|
+
}
|
|
1194
|
+
logger.diagnosticSummary(counts.errors, counts.warnings);
|
|
1195
|
+
} else {
|
|
1189
1196
|
logger.warning(
|
|
1190
|
-
`${
|
|
1197
|
+
`${counts.warnings} problem${counts.warnings === 1 ? "" : "s"} (0 errors, ${counts.warnings} warning${counts.warnings === 1 ? "" : "s"})`,
|
|
1191
1198
|
"federation"
|
|
1192
1199
|
);
|
|
1193
1200
|
}
|
|
1194
|
-
if (
|
|
1195
|
-
logger.warning
|
|
1196
|
-
`${event.graph.externals.length} reference${event.graph.externals.length === 1 ? "" : "s"} remain external`,
|
|
1197
|
-
"federation"
|
|
1198
|
-
);
|
|
1201
|
+
if (!verbose && counts.warnings > 0) {
|
|
1202
|
+
logger.info("Run with --verbose to see warning details.", "federation");
|
|
1199
1203
|
}
|
|
1200
1204
|
return;
|
|
1201
1205
|
case "hydrating":
|
|
@@ -1216,22 +1220,16 @@ var reportFederationProgress = (event) => {
|
|
|
1216
1220
|
`Public assets: ${event.result.copied} copied, ${event.result.skipped} preserved from the main catalog, ${event.result.removed} stale removed`,
|
|
1217
1221
|
"federation"
|
|
1218
1222
|
);
|
|
1219
|
-
if (event.result.overwritten > 0) {
|
|
1220
|
-
logger.warning(
|
|
1221
|
-
`${event.result.overwritten} public asset conflict${event.result.overwritten === 1 ? "" : "s"} resolved using the last configured source`,
|
|
1222
|
-
"federation"
|
|
1223
|
-
);
|
|
1224
|
-
}
|
|
1225
1223
|
return;
|
|
1226
1224
|
case "complete":
|
|
1227
1225
|
logger.success(
|
|
1228
1226
|
`Federation complete: ${event.result.sources} sources, ${event.result.resources} remote resources, ${event.result.hydrate.written} files written (${event.result.hydrate.fetched} downloaded, ${event.result.hydrate.written - event.result.hydrate.fetched} cached)`,
|
|
1229
1227
|
"federation"
|
|
1230
1228
|
);
|
|
1231
|
-
logger.info(`
|
|
1229
|
+
logger.info(`Recorded resolved source state in ${path2.relative(dir, event.result.lockPath)}`, "federation");
|
|
1232
1230
|
}
|
|
1233
1231
|
};
|
|
1234
|
-
program.command("federate").description("Fetch, resolve, and hydrate the catalogs configured in federation.sources.").option("--no-cache", "Download all federation content and refresh the cache.").action(async (commandOptions) => {
|
|
1232
|
+
program.command("federate").description("Fetch, resolve, and hydrate the catalogs configured in federation.sources.").option("--no-cache", "Download all federation content and refresh the cache.").option("-v, --verbose", "Show detailed federation diagnostics.").action(async (commandOptions) => {
|
|
1235
1233
|
logger.welcome();
|
|
1236
1234
|
if (fs3.existsSync(path2.join(dir, ".env"))) {
|
|
1237
1235
|
dotenv.config({ path: path2.join(dir, ".env") });
|
|
@@ -1243,7 +1241,7 @@ program.command("federate").description("Fetch, resolve, and hydrate the catalog
|
|
|
1243
1241
|
isFederationEnabled: isEventCatalogScaleEnabled,
|
|
1244
1242
|
onProgress: (event) => {
|
|
1245
1243
|
if (event.type === "cleanup:complete") cleanedPreviousOutput = true;
|
|
1246
|
-
reportFederationProgress(event);
|
|
1244
|
+
reportFederationProgress(event, commandOptions.verbose);
|
|
1247
1245
|
}
|
|
1248
1246
|
});
|
|
1249
1247
|
if (!result && !cleanedPreviousOutput) logger.warning("No federation sources configured; nothing to do.", "federation");
|
|
@@ -1257,6 +1255,6 @@ program.addHelpText(
|
|
|
1257
1255
|
`
|
|
1258
1256
|
);
|
|
1259
1257
|
program.parseAsync().then(() => process.exit(0)).catch((err) => {
|
|
1260
|
-
if (!(err instanceof FederationConflictError)) console.error(err);
|
|
1258
|
+
if (!(err instanceof FederationConflictError) && !(err instanceof FederationDiagnosticError)) console.error(err);
|
|
1261
1259
|
process.exit(1);
|
|
1262
1260
|
});
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/federation/diagnostics.ts
|
|
21
|
+
var diagnostics_exports = {};
|
|
22
|
+
__export(diagnostics_exports, {
|
|
23
|
+
federationRuleDefaults: () => federationRuleDefaults,
|
|
24
|
+
getFederationDiagnosticCounts: () => getFederationDiagnosticCounts,
|
|
25
|
+
getFederationDiagnostics: () => getFederationDiagnostics,
|
|
26
|
+
getVisibleFederationDiagnostics: () => getVisibleFederationDiagnostics,
|
|
27
|
+
resolveFederationRules: () => resolveFederationRules
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(diagnostics_exports);
|
|
30
|
+
var federationRuleDefaults = {
|
|
31
|
+
"federation/duplicate-source": "error",
|
|
32
|
+
"federation/type-collision": "error",
|
|
33
|
+
"federation/pointer-type-mismatch": "error",
|
|
34
|
+
"federation/facet-disagreement": "error",
|
|
35
|
+
"federation/asset-collision": "warn",
|
|
36
|
+
"federation/missing-resource": "warn",
|
|
37
|
+
"federation/unresolved-version": "warn"
|
|
38
|
+
};
|
|
39
|
+
var resolveFederationRules = (rules = {}) => {
|
|
40
|
+
for (const [rule, level] of Object.entries(rules)) {
|
|
41
|
+
if (!Object.hasOwn(federationRuleDefaults, rule)) throw new Error(`Unknown federation rule "${rule}".`);
|
|
42
|
+
if (level !== "off" && level !== "warn" && level !== "error") {
|
|
43
|
+
throw new Error(`Invalid level "${String(level)}" for federation rule "${rule}". Expected off, warn, or error.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { ...federationRuleDefaults, ...rules };
|
|
47
|
+
};
|
|
48
|
+
var getExternalResource = (external) => `${external.id}${external.version === void 0 ? "" : `@${external.version}`}`;
|
|
49
|
+
var getVersionedResource = (id, version) => `${id}${version == null ? "" : `@${version}`}`;
|
|
50
|
+
var getDocumentedResourceType = (type) => {
|
|
51
|
+
const usesAn = type === "adr" || type === "agent" || type === "entity" || type === "event";
|
|
52
|
+
return `documented as ${usesAn ? "an" : "a"} ${type}`;
|
|
53
|
+
};
|
|
54
|
+
var getConflictDiagnostic = (conflict, graph) => {
|
|
55
|
+
const catalogs = { label: "catalogs", value: conflict.sources.join(", ") };
|
|
56
|
+
switch (conflict.kind) {
|
|
57
|
+
case "duplicate-source":
|
|
58
|
+
return {
|
|
59
|
+
severity: "error",
|
|
60
|
+
message: "Resource has multiple owners",
|
|
61
|
+
rule: "federation/duplicate-source",
|
|
62
|
+
attributes: [
|
|
63
|
+
{ label: "resource", value: conflict.id },
|
|
64
|
+
catalogs,
|
|
65
|
+
{ label: "resolution", value: "assign a single owning catalog" }
|
|
66
|
+
]
|
|
67
|
+
};
|
|
68
|
+
case "type-collision": {
|
|
69
|
+
const types = [
|
|
70
|
+
...new Map(
|
|
71
|
+
graph.entities.filter((entity) => entity.id === conflict.id).map(
|
|
72
|
+
(entity) => [
|
|
73
|
+
`${entity.resolvedFrom.source}:${entity.type}`,
|
|
74
|
+
{ label: entity.resolvedFrom.source, value: getDocumentedResourceType(entity.type) }
|
|
75
|
+
]
|
|
76
|
+
)
|
|
77
|
+
).values()
|
|
78
|
+
];
|
|
79
|
+
return {
|
|
80
|
+
severity: "error",
|
|
81
|
+
message: "Resource ID has conflicting types",
|
|
82
|
+
rule: "federation/type-collision",
|
|
83
|
+
attributes: [{ label: "resource", value: conflict.id }, ...types.length > 0 ? types : [catalogs]]
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
case "pointer-type-mismatch": {
|
|
87
|
+
const typeMismatch = /^Expected (.+) but found (.+)$/.exec(conflict.detail ?? "");
|
|
88
|
+
return {
|
|
89
|
+
severity: "error",
|
|
90
|
+
message: "Reference type does not match resource",
|
|
91
|
+
rule: "federation/pointer-type-mismatch",
|
|
92
|
+
attributes: [
|
|
93
|
+
{ label: "resource", value: conflict.id },
|
|
94
|
+
...typeMismatch ? [
|
|
95
|
+
{ label: "expected type", value: typeMismatch[1] },
|
|
96
|
+
{ label: "actual type", value: typeMismatch[2] }
|
|
97
|
+
] : conflict.detail ? [{ label: "detail", value: conflict.detail }] : [],
|
|
98
|
+
catalogs
|
|
99
|
+
]
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
case "facet-disagreement":
|
|
103
|
+
return {
|
|
104
|
+
severity: "error",
|
|
105
|
+
message: "Catalogs disagree about this resource",
|
|
106
|
+
rule: "federation/facet-disagreement",
|
|
107
|
+
attributes: [
|
|
108
|
+
{ label: "resource", value: conflict.id },
|
|
109
|
+
...conflict.detail ? [{ label: "detail", value: conflict.detail }] : [],
|
|
110
|
+
catalogs
|
|
111
|
+
]
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
var getFederationDiagnostics = (graph, rules = {}) => {
|
|
116
|
+
const resolvedRules = resolveFederationRules(rules);
|
|
117
|
+
const diagnostics = graph.conflicts.map((conflict) => getConflictDiagnostic(conflict, graph));
|
|
118
|
+
for (const external of graph.externals) {
|
|
119
|
+
const resource = getExternalResource(external);
|
|
120
|
+
for (const referencedBy of external.referencedBy) {
|
|
121
|
+
const referrer = graph.entities.find((entity) => entity.id === referencedBy);
|
|
122
|
+
diagnostics.push({
|
|
123
|
+
severity: "warning",
|
|
124
|
+
message: "Referenced EventCatalog resource does not exist",
|
|
125
|
+
rule: "federation/missing-resource",
|
|
126
|
+
attributes: [
|
|
127
|
+
{ label: "source catalog", value: referrer?.resolvedFrom.source ?? "unknown" },
|
|
128
|
+
{ label: "referenced by", value: referencedBy },
|
|
129
|
+
{ label: "missing resource", value: resource }
|
|
130
|
+
]
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
for (const edge of graph.edges.filter((edge2) => edge2.status === "unresolved")) {
|
|
135
|
+
const availableVersions = [
|
|
136
|
+
...new Set(graph.entities.filter((entity) => entity.id === edge.to).map((entity) => entity.version ?? "unversioned"))
|
|
137
|
+
].sort((left, right) => left.localeCompare(right, void 0, { numeric: true }));
|
|
138
|
+
diagnostics.push({
|
|
139
|
+
severity: "warning",
|
|
140
|
+
message: "Referenced EventCatalog resource version does not exist",
|
|
141
|
+
rule: "federation/unresolved-version",
|
|
142
|
+
attributes: [
|
|
143
|
+
{ label: "source catalog", value: edge.fromResolvedFrom.source },
|
|
144
|
+
{ label: "referenced by", value: getVersionedResource(edge.from, edge.fromVersion) },
|
|
145
|
+
{ label: "resource", value: edge.to },
|
|
146
|
+
{ label: "requested version", value: edge.pointer ?? "unspecified" },
|
|
147
|
+
{ label: "available versions", value: availableVersions.join(", ") }
|
|
148
|
+
]
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
for (const warning of graph.warnings) {
|
|
152
|
+
diagnostics.push({
|
|
153
|
+
severity: "warning",
|
|
154
|
+
message: "Asset collision",
|
|
155
|
+
rule: "federation/asset-collision",
|
|
156
|
+
attributes: [
|
|
157
|
+
{ label: "asset", value: warning.path },
|
|
158
|
+
{ label: "sources", value: warning.sources.join(", ") },
|
|
159
|
+
{ label: "winner", value: warning.winner },
|
|
160
|
+
{ label: "resolution", value: "last configured source wins" }
|
|
161
|
+
]
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return diagnostics.flatMap((diagnostic) => {
|
|
165
|
+
const level = resolvedRules[diagnostic.rule];
|
|
166
|
+
if (level === "off") return [];
|
|
167
|
+
return [{ ...diagnostic, severity: level === "error" ? "error" : "warning" }];
|
|
168
|
+
}).sort(
|
|
169
|
+
(left, right) => (left.severity === right.severity ? 0 : left.severity === "error" ? -1 : 1) || left.rule.localeCompare(right.rule) || (left.attributes[0]?.value ?? "").localeCompare(right.attributes[0]?.value ?? "")
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
var getFederationDiagnosticCounts = (diagnostics) => diagnostics.reduce(
|
|
173
|
+
(counts, diagnostic) => ({
|
|
174
|
+
errors: counts.errors + (diagnostic.severity === "error" ? 1 : 0),
|
|
175
|
+
warnings: counts.warnings + (diagnostic.severity === "warning" ? 1 : 0)
|
|
176
|
+
}),
|
|
177
|
+
{ errors: 0, warnings: 0 }
|
|
178
|
+
);
|
|
179
|
+
var getVisibleFederationDiagnostics = (diagnostics, verbose) => diagnostics.filter((diagnostic) => verbose || diagnostic.severity === "error");
|
|
180
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
181
|
+
0 && (module.exports = {
|
|
182
|
+
federationRuleDefaults,
|
|
183
|
+
getFederationDiagnosticCounts,
|
|
184
|
+
getFederationDiagnostics,
|
|
185
|
+
getVisibleFederationDiagnostics,
|
|
186
|
+
resolveFederationRules
|
|
187
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ResolvedGraph } from '@eventcatalog/sdk';
|
|
2
|
+
import { FederationRuleId, FederationRuleLevel, FederationRulesConfig } from '../eventcatalog.config.cjs';
|
|
3
|
+
|
|
4
|
+
type FederationDiagnostic = {
|
|
5
|
+
severity: 'error' | 'warning';
|
|
6
|
+
message: string;
|
|
7
|
+
rule: FederationRuleId;
|
|
8
|
+
attributes: {
|
|
9
|
+
label: string;
|
|
10
|
+
value: string;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
declare const federationRuleDefaults: Record<FederationRuleId, FederationRuleLevel>;
|
|
14
|
+
type ResolvedFederationRules = Record<FederationRuleId, FederationRuleLevel>;
|
|
15
|
+
declare const resolveFederationRules: (rules?: FederationRulesConfig) => ResolvedFederationRules;
|
|
16
|
+
declare const getFederationDiagnostics: (graph: ResolvedGraph, rules?: FederationRulesConfig) => FederationDiagnostic[];
|
|
17
|
+
declare const getFederationDiagnosticCounts: (diagnostics: FederationDiagnostic[]) => {
|
|
18
|
+
errors: number;
|
|
19
|
+
warnings: number;
|
|
20
|
+
};
|
|
21
|
+
declare const getVisibleFederationDiagnostics: (diagnostics: FederationDiagnostic[], verbose: boolean) => FederationDiagnostic[];
|
|
22
|
+
|
|
23
|
+
export { type FederationDiagnostic, type ResolvedFederationRules, federationRuleDefaults, getFederationDiagnosticCounts, getFederationDiagnostics, getVisibleFederationDiagnostics, resolveFederationRules };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ResolvedGraph } from '@eventcatalog/sdk';
|
|
2
|
+
import { FederationRuleId, FederationRuleLevel, FederationRulesConfig } from '../eventcatalog.config.js';
|
|
3
|
+
|
|
4
|
+
type FederationDiagnostic = {
|
|
5
|
+
severity: 'error' | 'warning';
|
|
6
|
+
message: string;
|
|
7
|
+
rule: FederationRuleId;
|
|
8
|
+
attributes: {
|
|
9
|
+
label: string;
|
|
10
|
+
value: string;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
declare const federationRuleDefaults: Record<FederationRuleId, FederationRuleLevel>;
|
|
14
|
+
type ResolvedFederationRules = Record<FederationRuleId, FederationRuleLevel>;
|
|
15
|
+
declare const resolveFederationRules: (rules?: FederationRulesConfig) => ResolvedFederationRules;
|
|
16
|
+
declare const getFederationDiagnostics: (graph: ResolvedGraph, rules?: FederationRulesConfig) => FederationDiagnostic[];
|
|
17
|
+
declare const getFederationDiagnosticCounts: (diagnostics: FederationDiagnostic[]) => {
|
|
18
|
+
errors: number;
|
|
19
|
+
warnings: number;
|
|
20
|
+
};
|
|
21
|
+
declare const getVisibleFederationDiagnostics: (diagnostics: FederationDiagnostic[], verbose: boolean) => FederationDiagnostic[];
|
|
22
|
+
|
|
23
|
+
export { type FederationDiagnostic, type ResolvedFederationRules, federationRuleDefaults, getFederationDiagnosticCounts, getFederationDiagnostics, getVisibleFederationDiagnostics, resolveFederationRules };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
federationRuleDefaults,
|
|
3
|
+
getFederationDiagnosticCounts,
|
|
4
|
+
getFederationDiagnostics,
|
|
5
|
+
getVisibleFederationDiagnostics,
|
|
6
|
+
resolveFederationRules
|
|
7
|
+
} from "../chunk-JJPB6EOZ.js";
|
|
8
|
+
export {
|
|
9
|
+
federationRuleDefaults,
|
|
10
|
+
getFederationDiagnosticCounts,
|
|
11
|
+
getFederationDiagnostics,
|
|
12
|
+
getVisibleFederationDiagnostics,
|
|
13
|
+
resolveFederationRules
|
|
14
|
+
};
|