@eventcatalog/core 5.0.0-beta.7 → 5.0.0-beta.9
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/LICENSE +227 -128
- package/dist/analytics/analytics.cjs +18 -3
- package/dist/analytics/analytics.d.cts +1 -1
- package/dist/analytics/analytics.d.ts +1 -1
- package/dist/analytics/analytics.js +3 -2
- package/dist/analytics/log-build.cjs +70 -34
- package/dist/analytics/log-build.js +5 -4
- package/dist/analytics/telemetry.cjs +42 -0
- package/dist/analytics/telemetry.d.cts +20 -0
- package/dist/analytics/telemetry.d.ts +20 -0
- package/dist/analytics/telemetry.js +8 -0
- package/dist/{chunk-3VBB2ZMP.js → chunk-4CFZUHGG.js} +9 -3
- package/dist/{chunk-PIYJM642.js → chunk-AWOO63ME.js} +70 -44
- package/dist/chunk-CPW6G62V.js +17 -0
- package/dist/{chunk-MDWB5HLO.js → chunk-ENAG6UH7.js} +5 -0
- package/dist/{chunk-FARBIZ7Y.js → chunk-EUNQJO3J.js} +1 -1
- package/dist/{chunk-S7ODHVII.js → chunk-GAHKCOQM.js} +1 -1
- package/dist/{chunk-BOKAG5XC.js → chunk-JQMYHZWI.js} +58 -35
- package/dist/{chunk-SJJKWZYZ.js → chunk-TZVDMWQX.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +207 -123
- package/dist/eventcatalog.config.d.cts +55 -0
- package/dist/eventcatalog.config.d.ts +55 -0
- package/dist/eventcatalog.js +39 -19
- package/dist/features.cjs +8 -2
- package/dist/features.d.cts +3 -1
- package/dist/features.d.ts +3 -1
- package/dist/features.js +5 -3
- package/dist/federation/federate.js +4 -4
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +70 -44
- package/dist/utils/license-status.d.cts +14 -5
- package/dist/utils/license-status.d.ts +14 -5
- package/dist/utils/license-status.js +1 -1
- package/eventcatalog/integrations/studio-server.mjs +15 -3
- package/eventcatalog/src/components/Header.astro +3 -3
- package/eventcatalog/src/features/integrations/eventcatalog-features.ts +10 -2
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +9 -1
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +9 -2
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +70 -69
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +69 -69
- package/eventcatalog/src/features/mcp/mcp-server.ts +5 -3
- package/eventcatalog/src/features/studio/agent-choreography.ts +8 -5
- package/eventcatalog/src/features/studio/canvas-actions.ts +148 -21
- package/eventcatalog/src/features/studio/canvas-doc.ts +138 -9
- package/eventcatalog/src/features/studio/canvas-preview.ts +53 -0
- package/eventcatalog/src/features/studio/catalog-resources.ts +5 -2
- package/eventcatalog/src/features/studio/clipboard.ts +97 -0
- package/eventcatalog/src/features/studio/components/CanvasControls.tsx +4 -3
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +39 -22
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +117 -0
- package/eventcatalog/src/features/studio/components/Comments.tsx +345 -30
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +140 -76
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +144 -0
- package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +1 -1
- package/eventcatalog/src/features/studio/components/DragGhost.tsx +115 -0
- package/eventcatalog/src/features/studio/components/JoinForm.tsx +0 -24
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +131 -35
- package/eventcatalog/src/features/studio/components/Picture.tsx +21 -0
- package/eventcatalog/src/features/studio/components/Presence.tsx +2 -0
- package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +187 -50
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +260 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +442 -40
- package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +198 -22
- package/eventcatalog/src/features/studio/components/icons.ts +6 -1
- package/eventcatalog/src/features/studio/components/status.ts +30 -1
- package/eventcatalog/src/features/studio/edges.ts +2 -0
- package/eventcatalog/src/features/studio/grouping.ts +95 -2
- package/eventcatalog/src/features/studio/hooks/presence-store.ts +5 -1
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +13 -3
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +8 -1
- package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +7 -2
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +174 -27
- package/eventcatalog/src/features/studio/identity.ts +35 -0
- package/eventcatalog/src/features/studio/layout.ts +7 -4
- package/eventcatalog/src/features/studio/levels.ts +138 -72
- package/eventcatalog/src/features/studio/node-types.ts +35 -3
- package/eventcatalog/src/features/studio/pages/[id].astro +7 -2
- package/eventcatalog/src/features/studio/pages/index.astro +555 -2
- package/eventcatalog/src/features/studio/pages/new.astro +24 -0
- package/eventcatalog/src/features/studio/pages/wake.ts +15 -0
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +48 -13
- package/eventcatalog/src/features/studio/server/runtime.ts +193 -14
- package/eventcatalog/src/features/studio/server/sign-in.ts +18 -0
- package/eventcatalog/src/features/studio/server/storage.ts +110 -0
- package/eventcatalog/src/features/studio/studio.css +184 -0
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +1 -1
- package/eventcatalog/src/utils/feature.ts +7 -3
- package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +0 -2
- package/package.json +3 -3
- package/dist/{chunk-AYNZXUB5.js → chunk-ZEY2XUJN.js} +7 -7
package/dist/eventcatalog.cjs
CHANGED
|
@@ -181,7 +181,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
|
|
|
181
181
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
182
182
|
|
|
183
183
|
// package.json
|
|
184
|
-
var version = "5.0.0-beta.
|
|
184
|
+
var version = "5.0.0-beta.9";
|
|
185
185
|
|
|
186
186
|
// src/constants.ts
|
|
187
187
|
var VERSION = version;
|
|
@@ -191,8 +191,8 @@ var getTimestamp = () => {
|
|
|
191
191
|
const now = /* @__PURE__ */ new Date();
|
|
192
192
|
return now.toLocaleTimeString("en-US", { hour12: false });
|
|
193
193
|
};
|
|
194
|
-
var formatMessage = (tag,
|
|
195
|
-
return `${import_picocolors.default.dim(getTimestamp())} ${tagColor(`[${tag}]`)} ${
|
|
194
|
+
var formatMessage = (tag, message2, tagColor) => {
|
|
195
|
+
return `${import_picocolors.default.dim(getTimestamp())} ${tagColor(`[${tag}]`)} ${message2}`;
|
|
196
196
|
};
|
|
197
197
|
var logger = {
|
|
198
198
|
welcome: () => {
|
|
@@ -208,28 +208,28 @@ var logger = {
|
|
|
208
208
|
);
|
|
209
209
|
console.log();
|
|
210
210
|
},
|
|
211
|
-
info: (
|
|
212
|
-
console.log(formatMessage(tag,
|
|
211
|
+
info: (message2, tag = "info") => {
|
|
212
|
+
console.log(formatMessage(tag, message2, import_picocolors.default.blue));
|
|
213
213
|
},
|
|
214
|
-
success: (
|
|
215
|
-
console.log(formatMessage(tag,
|
|
214
|
+
success: (message2, tag = "success") => {
|
|
215
|
+
console.log(formatMessage(tag, message2, import_picocolors.default.green));
|
|
216
216
|
},
|
|
217
|
-
error: (
|
|
218
|
-
console.log(formatMessage(tag,
|
|
217
|
+
error: (message2, tag = "error") => {
|
|
218
|
+
console.log(formatMessage(tag, message2, import_picocolors.default.red));
|
|
219
219
|
},
|
|
220
|
-
warning: (
|
|
221
|
-
console.log(formatMessage(tag,
|
|
220
|
+
warning: (message2, tag = "warn") => {
|
|
221
|
+
console.log(formatMessage(tag, message2, import_picocolors.default.yellow));
|
|
222
222
|
},
|
|
223
|
-
line: (
|
|
224
|
-
console.log(
|
|
223
|
+
line: (message2 = "") => {
|
|
224
|
+
console.log(message2);
|
|
225
225
|
},
|
|
226
|
-
diagnostic: (severity,
|
|
226
|
+
diagnostic: (severity, message2, rule, attributes = []) => {
|
|
227
227
|
const isError = severity === "error";
|
|
228
228
|
const color = isError ? import_picocolors.default.red : import_picocolors.default.yellow;
|
|
229
229
|
const icon = isError ? "\u2716" : "\u26A0";
|
|
230
|
-
const label = `${icon} ${severity.padEnd(7)} ${
|
|
230
|
+
const label = `${icon} ${severity.padEnd(7)} ${message2}`;
|
|
231
231
|
const ruleSpacing = " ".repeat(Math.max(2, 72 - label.length));
|
|
232
|
-
console.log(` ${color(icon)} ${color(severity.padEnd(7))} ${
|
|
232
|
+
console.log(` ${color(icon)} ${color(severity.padEnd(7))} ${message2}${ruleSpacing}${import_picocolors.default.gray(rule)}`);
|
|
233
233
|
for (const attribute of attributes) {
|
|
234
234
|
console.log(` - ${import_picocolors.default.dim(`${attribute.label}:`)} ${attribute.value}`);
|
|
235
235
|
}
|
|
@@ -243,8 +243,8 @@ var logger = {
|
|
|
243
243
|
const warningCount = `${warnings} warning${warnings === 1 ? "" : "s"}`;
|
|
244
244
|
console.log(color(`${icon} ${problems} (${errorCount}, ${warningCount})`));
|
|
245
245
|
},
|
|
246
|
-
dim: (
|
|
247
|
-
console.log(import_picocolors.default.dim(
|
|
246
|
+
dim: (message2) => {
|
|
247
|
+
console.log(import_picocolors.default.dim(message2));
|
|
248
248
|
}
|
|
249
249
|
};
|
|
250
250
|
|
|
@@ -304,7 +304,23 @@ var generate = async (PROJECT_DIRECTORY) => {
|
|
|
304
304
|
|
|
305
305
|
// src/analytics/analytics.js
|
|
306
306
|
var import_os = __toESM(require("os"), 1);
|
|
307
|
-
|
|
307
|
+
|
|
308
|
+
// src/analytics/telemetry.ts
|
|
309
|
+
var TELEMETRY_REQUEST_TIMEOUT_MS = 2e3;
|
|
310
|
+
var isOptOutEnvValue = (value) => {
|
|
311
|
+
if (typeof value !== "string") return false;
|
|
312
|
+
const normalized = value.trim().toLowerCase();
|
|
313
|
+
return normalized === "1" || normalized === "true";
|
|
314
|
+
};
|
|
315
|
+
var isTelemetryDisabled = (config, env) => {
|
|
316
|
+
if (isOptOutEnvValue(env.EVENTCATALOG_TELEMETRY_DISABLED)) return true;
|
|
317
|
+
if (isOptOutEnvValue(env.DO_NOT_TRACK)) return true;
|
|
318
|
+
return config?.telemetry === false;
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// src/analytics/analytics.js
|
|
322
|
+
async function raiseEvent(eventData, config) {
|
|
323
|
+
if (isTelemetryDisabled(config, process.env)) return;
|
|
308
324
|
if (typeof eventData?.command !== "string" || typeof eventData?.cId !== "string") return;
|
|
309
325
|
const url = "https://queue.simpleanalyticscdn.com/events";
|
|
310
326
|
const userAgent = `@eventcatalog/eventcatalog@${VERSION} (${import_os.default.platform()}; ${import_os.default.arch()}; Node/${process.version})`;
|
|
@@ -326,7 +342,8 @@ async function raiseEvent(eventData) {
|
|
|
326
342
|
const response = await fetch(url, {
|
|
327
343
|
method: "POST",
|
|
328
344
|
headers,
|
|
329
|
-
body: JSON.stringify(payload)
|
|
345
|
+
body: JSON.stringify(payload),
|
|
346
|
+
signal: AbortSignal.timeout(TELEMETRY_REQUEST_TIMEOUT_MS)
|
|
330
347
|
});
|
|
331
348
|
if (!response.ok) {
|
|
332
349
|
throw new Error(`Failed to raise analytics event: ${response.status}`);
|
|
@@ -403,6 +420,7 @@ function serializeCounts(counts) {
|
|
|
403
420
|
|
|
404
421
|
// src/utils/license-status.ts
|
|
405
422
|
var import_boxen = __toESM(require("boxen"), 1);
|
|
423
|
+
var import_picocolors2 = __toESM(require("picocolors"), 1);
|
|
406
424
|
var import_license2 = require("@eventcatalog/license");
|
|
407
425
|
|
|
408
426
|
// eventcatalog/src/utils/trial.ts
|
|
@@ -525,75 +543,100 @@ var getLicenseAnalytics = (license = { state: "none" }, tsd) => ({
|
|
|
525
543
|
});
|
|
526
544
|
var formatDate = (date) => date.toLocaleDateString(void 0, { dateStyle: "medium" });
|
|
527
545
|
var formatDays = (days) => `${days} ${days === 1 ? "day" : "days"}`;
|
|
528
|
-
var
|
|
546
|
+
var PLAIN = { bold: (text) => text, dim: (text) => text, link: (text) => text };
|
|
547
|
+
var COLOURS = { bold: import_picocolors2.default.bold, dim: import_picocolors2.default.dim, link: (text) => import_picocolors2.default.cyan(text) };
|
|
548
|
+
var render = ({ headline, rows, links }, colours) => {
|
|
549
|
+
const width = Math.max(0, ...[...rows, ...links].map(([label]) => label.length));
|
|
550
|
+
const row = ([label, value]) => `${colours.dim(label.padEnd(width))} ${value}`;
|
|
551
|
+
return [
|
|
552
|
+
colours.bold(headline),
|
|
553
|
+
...rows.length ? ["", ...rows.map(row)] : [],
|
|
554
|
+
...links.length ? ["", ...links.map(([label, url]) => row([label, colours.link(url)]))] : []
|
|
555
|
+
].join("\n");
|
|
556
|
+
};
|
|
557
|
+
var message = (content) => ({
|
|
558
|
+
...content,
|
|
559
|
+
text: render(content, PLAIN)
|
|
560
|
+
});
|
|
561
|
+
var getTrialRow = (tsd, now) => {
|
|
529
562
|
const trial = getTrialStatus(tsd, now);
|
|
530
563
|
if (!trial) return;
|
|
531
|
-
return
|
|
564
|
+
return [
|
|
565
|
+
"Trial",
|
|
566
|
+
trial.ended ? `Ended ${formatDate(trial.endsAt)}` : `${formatDays(trial.daysLeft)} left of ${TRIAL_LENGTH_DAYS} (ends ${formatDate(trial.endsAt)})`
|
|
567
|
+
];
|
|
532
568
|
};
|
|
533
569
|
var getLicenseStatusMessage = (license, tsd, now = Date.now()) => {
|
|
570
|
+
const licensing = ["Licensing", LICENSE_FAQ_URL];
|
|
571
|
+
const renew = ["Renew", LICENSE_RENEW_URL];
|
|
572
|
+
const licensedTo = "org" in license && license.org ? [["Licensed to", license.org]] : [];
|
|
534
573
|
if (license.state === "licensed") {
|
|
535
574
|
const daysLeft = Math.max(0, Math.ceil((license.expiresAt.getTime() - now) / DAY_IN_MS2));
|
|
536
|
-
const licensedTo = license.org ? `Licensed to ${license.org}` : "Licensed";
|
|
537
575
|
if (daysLeft < LICENSE_REMINDER_DAYS) {
|
|
538
|
-
return {
|
|
539
|
-
title: "EventCatalog
|
|
576
|
+
return message({
|
|
577
|
+
title: "EventCatalog license",
|
|
540
578
|
color: "yellow",
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
].join("\n")
|
|
546
|
-
};
|
|
579
|
+
headline: `Your commercial license expires in ${formatDays(daysLeft)}`,
|
|
580
|
+
rows: [...licensedTo, ["Expires", formatDate(license.expiresAt)]],
|
|
581
|
+
links: [renew]
|
|
582
|
+
});
|
|
547
583
|
}
|
|
548
|
-
return {
|
|
549
|
-
title: "EventCatalog
|
|
584
|
+
return message({
|
|
585
|
+
title: "EventCatalog license",
|
|
550
586
|
color: "green",
|
|
551
|
-
|
|
552
|
-
Valid until
|
|
553
|
-
|
|
587
|
+
headline: "Commercial license active",
|
|
588
|
+
rows: [...licensedTo, ["Valid until", `${formatDate(license.expiresAt)} (${formatDays(daysLeft)} left)`]],
|
|
589
|
+
links: []
|
|
590
|
+
});
|
|
554
591
|
}
|
|
555
592
|
if (license.state === "plan") return;
|
|
556
|
-
const
|
|
593
|
+
const trialRow = getTrialRow(tsd, now);
|
|
594
|
+
const trialRows = trialRow ? [trialRow] : [];
|
|
557
595
|
if (license.state === "none") {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
return {
|
|
596
|
+
const trial = getTrialStatus(tsd, now);
|
|
597
|
+
if (!trial || !trialRow) return;
|
|
598
|
+
return message({
|
|
561
599
|
title: "EventCatalog trial",
|
|
562
|
-
color: ended ? "yellow" : "green",
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
600
|
+
color: trial.ended ? "yellow" : "green",
|
|
601
|
+
headline: trial.ended ? "Your EventCatalog trial has ended" : `You're on the ${TRIAL_LENGTH_DAYS}-day EventCatalog trial`,
|
|
602
|
+
rows: trialRows,
|
|
603
|
+
links: trial.ended ? [["Get a license", LICENSE_RENEW_URL], licensing] : [licensing]
|
|
604
|
+
});
|
|
566
605
|
}
|
|
567
606
|
if (license.state === "expired") {
|
|
568
|
-
const expiredOn = license.expiresAt ?
|
|
569
|
-
|
|
570
|
-
|
|
607
|
+
const expiredOn = license.expiresAt ? [
|
|
608
|
+
[
|
|
609
|
+
"Expired",
|
|
610
|
+
`${formatDate(license.expiresAt)} (${formatDays(Math.floor((now - license.expiresAt.getTime()) / DAY_IN_MS2))} ago)`
|
|
611
|
+
]
|
|
612
|
+
] : [];
|
|
613
|
+
return message({
|
|
614
|
+
title: "EventCatalog license",
|
|
571
615
|
color: "yellow",
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
`Learn about licensing: ${LICENSE_FAQ_URL}`
|
|
577
|
-
].filter(Boolean).join("\n")
|
|
578
|
-
};
|
|
616
|
+
headline: "Your commercial license has expired",
|
|
617
|
+
rows: [...licensedTo, ...expiredOn, ...trialRows],
|
|
618
|
+
links: [renew, licensing]
|
|
619
|
+
});
|
|
579
620
|
}
|
|
580
|
-
return {
|
|
621
|
+
return message({
|
|
581
622
|
title: "EventCatalog license",
|
|
582
623
|
color: "yellow",
|
|
583
|
-
|
|
584
|
-
|
|
624
|
+
headline: "Your license.jwt couldn't be verified",
|
|
625
|
+
rows: [["Reason", license.reason.charAt(0).toUpperCase() + license.reason.slice(1)], ...trialRows],
|
|
626
|
+
links: [licensing]
|
|
627
|
+
});
|
|
585
628
|
};
|
|
586
629
|
var printLicenseStatus = (license, tsd) => {
|
|
587
|
-
const
|
|
588
|
-
if (!
|
|
630
|
+
const status = getLicenseStatusMessage(license, tsd);
|
|
631
|
+
if (!status) return;
|
|
589
632
|
console.log(
|
|
590
|
-
(0, import_boxen.default)(
|
|
591
|
-
padding: 1,
|
|
633
|
+
(0, import_boxen.default)(render(status, COLOURS), {
|
|
634
|
+
padding: { top: 1, bottom: 1, left: 2, right: 2 },
|
|
592
635
|
margin: 1,
|
|
593
636
|
borderStyle: "round",
|
|
594
|
-
borderColor:
|
|
595
|
-
title:
|
|
596
|
-
titleAlignment: "
|
|
637
|
+
borderColor: status.color,
|
|
638
|
+
title: status.title,
|
|
639
|
+
titleAlignment: "left"
|
|
597
640
|
})
|
|
598
641
|
);
|
|
599
642
|
};
|
|
@@ -653,50 +696,69 @@ var toCloudResourceCounts = (counts) => ({
|
|
|
653
696
|
customPages: counts.customPages || 0,
|
|
654
697
|
customApis: counts.customApis || 0
|
|
655
698
|
});
|
|
656
|
-
var
|
|
699
|
+
var getEnabledCloudAnalytics = (configFile) => {
|
|
657
700
|
const analytics = configFile.cloud?.analytics;
|
|
658
|
-
if (!analytics?.enabled || !analytics.trackingId || !analytics.writeKey) return;
|
|
701
|
+
if (!analytics?.enabled || !analytics.trackingId || !analytics.writeKey) return null;
|
|
702
|
+
return analytics;
|
|
703
|
+
};
|
|
704
|
+
var reportCloudResourceInventory = async (configFile, resourceCounts) => {
|
|
705
|
+
const analytics = getEnabledCloudAnalytics(configFile);
|
|
706
|
+
if (!analytics) return;
|
|
659
707
|
const endpoint = analytics.endpoint || CLOUD_ANALYTICS_ENDPOINT;
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
708
|
+
try {
|
|
709
|
+
await fetch(endpoint, {
|
|
710
|
+
method: "POST",
|
|
711
|
+
headers: {
|
|
712
|
+
"Content-Type": "application/json",
|
|
713
|
+
"X-EventCatalog-Analytics-Key": analytics.writeKey
|
|
714
|
+
},
|
|
715
|
+
body: JSON.stringify({
|
|
716
|
+
trackingId: analytics.trackingId,
|
|
717
|
+
event: "catalog.resource_inventory_reported",
|
|
718
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
719
|
+
counts: toCloudResourceCounts(resourceCounts)
|
|
720
|
+
}),
|
|
721
|
+
signal: AbortSignal.timeout(TELEMETRY_REQUEST_TIMEOUT_MS)
|
|
722
|
+
});
|
|
723
|
+
} catch {
|
|
724
|
+
}
|
|
673
725
|
};
|
|
674
726
|
var main = async (projectDir, { command = "build", license } = {}) => {
|
|
675
727
|
try {
|
|
676
728
|
await verifyRequiredFieldsAreInCatalogConfigFile(projectDir);
|
|
677
729
|
const configFile = await getEventCatalogConfigFile(projectDir);
|
|
730
|
+
if (isTelemetryDisabled(configFile, process.env)) {
|
|
731
|
+
if (getEnabledCloudAnalytics(configFile)) {
|
|
732
|
+
const resourceCounts2 = await countResources(projectDir);
|
|
733
|
+
await reportCloudResourceInventory(configFile, resourceCounts2);
|
|
734
|
+
}
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
678
737
|
const { cId, tsd, organizationName, generators = [] } = configFile;
|
|
679
738
|
const generatorNames = generators.length > 0 ? generators.map((generator) => generator[0]) : ["none"];
|
|
680
739
|
const features = await getFeatures(configFile);
|
|
681
740
|
const resourceCounts = await countResources(projectDir);
|
|
682
741
|
const contentHash = await hashCatalogContent(projectDir);
|
|
683
742
|
await reportCloudResourceInventory(configFile, resourceCounts);
|
|
684
|
-
await raiseEvent(
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
743
|
+
await raiseEvent(
|
|
744
|
+
{
|
|
745
|
+
command,
|
|
746
|
+
org: organizationName,
|
|
747
|
+
cId,
|
|
748
|
+
// Trial start date (unix ms) from eventcatalog.config.js
|
|
749
|
+
tsd,
|
|
750
|
+
// Commercial license or trial, and when each expires (unix ms)
|
|
751
|
+
...getLicenseAnalytics(license, tsd),
|
|
752
|
+
// CI redeploys and human-run builds are different signals; tag rather than suppress
|
|
753
|
+
ci: process.env.CI ? "true" : "false",
|
|
754
|
+
contentHash,
|
|
755
|
+
generators: generatorNames.toString(),
|
|
756
|
+
features: Object.keys(features).map((feature) => `${feature}:${features[feature]}`).join(","),
|
|
757
|
+
directorySources: serializeDirectorySources(configFile),
|
|
758
|
+
resources: serializeCounts(resourceCounts)
|
|
759
|
+
},
|
|
760
|
+
configFile
|
|
761
|
+
);
|
|
700
762
|
} catch (error) {
|
|
701
763
|
}
|
|
702
764
|
};
|
|
@@ -769,6 +831,10 @@ var isOutputServer = async () => {
|
|
|
769
831
|
const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
|
|
770
832
|
return config?.output === "server";
|
|
771
833
|
};
|
|
834
|
+
var isStudioEnabled = async () => {
|
|
835
|
+
const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
|
|
836
|
+
return config?.output === "server" && config?.studio?.enabled === true;
|
|
837
|
+
};
|
|
772
838
|
var isIndexedSearchEnabled = async () => {
|
|
773
839
|
const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
|
|
774
840
|
return config?.search?.type === "indexed";
|
|
@@ -836,13 +902,13 @@ var message_channels_to_service_channels_default = async (dir2) => {
|
|
|
836
902
|
absolute: true
|
|
837
903
|
}
|
|
838
904
|
);
|
|
839
|
-
const messagesWithChannels = messages.reduce((acc,
|
|
840
|
-
const file = import_node_fs5.default.readFileSync(
|
|
905
|
+
const messagesWithChannels = messages.reduce((acc, message2) => {
|
|
906
|
+
const file = import_node_fs5.default.readFileSync(message2, "utf8");
|
|
841
907
|
const { data } = (0, import_gray_matter3.default)(file);
|
|
842
908
|
if (data.channels?.length > 0) {
|
|
843
909
|
acc.push({
|
|
844
910
|
...data,
|
|
845
|
-
path:
|
|
911
|
+
path: message2
|
|
846
912
|
});
|
|
847
913
|
}
|
|
848
914
|
return acc;
|
|
@@ -853,9 +919,9 @@ var message_channels_to_service_channels_default = async (dir2) => {
|
|
|
853
919
|
const servicesWithChannels = services.reduce((acc, service) => {
|
|
854
920
|
const file = import_node_fs5.default.readFileSync(service, "utf8");
|
|
855
921
|
const { data } = (0, import_gray_matter3.default)(file);
|
|
856
|
-
const isSending = data.sends?.some((send) => messagesWithChannels.some((
|
|
922
|
+
const isSending = data.sends?.some((send) => messagesWithChannels.some((message2) => message2.id === send.id));
|
|
857
923
|
const isReceiving = data.receives?.some(
|
|
858
|
-
(receive) => messagesWithChannels.some((
|
|
924
|
+
(receive) => messagesWithChannels.some((message2) => message2.id === receive.id)
|
|
859
925
|
);
|
|
860
926
|
if (isSending || isReceiving) {
|
|
861
927
|
acc.push({
|
|
@@ -868,16 +934,16 @@ var message_channels_to_service_channels_default = async (dir2) => {
|
|
|
868
934
|
for (const service of servicesWithChannels) {
|
|
869
935
|
const file = import_node_fs5.default.readFileSync(service.path, "utf8");
|
|
870
936
|
const { data } = (0, import_gray_matter3.default)(file);
|
|
871
|
-
const messagesTheServiceSendsThatNeedUpdating = data.sends?.filter((send) => messagesWithChannels.some((
|
|
872
|
-
const messagesTheServiceReceivesThatNeedUpdating = data.receives?.filter((receive) => messagesWithChannels.some((
|
|
937
|
+
const messagesTheServiceSendsThatNeedUpdating = data.sends?.filter((send) => messagesWithChannels.some((message2) => message2.id === send.id)) ?? [];
|
|
938
|
+
const messagesTheServiceReceivesThatNeedUpdating = data.receives?.filter((receive) => messagesWithChannels.some((message2) => message2.id === receive.id)) ?? [];
|
|
873
939
|
if (messagesTheServiceSendsThatNeedUpdating.length > 0 || messagesTheServiceReceivesThatNeedUpdating.length > 0) {
|
|
874
940
|
const newSends = (data.sends ?? []).map((send) => {
|
|
875
|
-
const match = messagesWithChannels.find((
|
|
941
|
+
const match = messagesWithChannels.find((message2) => message2.id === send.id);
|
|
876
942
|
if (!match) return send;
|
|
877
943
|
return { ...send, to: (match.channels ?? []).filter((channel) => channel !== null) };
|
|
878
944
|
});
|
|
879
945
|
const newReceives = (data.receives ?? []).map((receive) => {
|
|
880
|
-
const match = messagesWithChannels.find((
|
|
946
|
+
const match = messagesWithChannels.find((message2) => message2.id === receive.id);
|
|
881
947
|
if (!match) return receive;
|
|
882
948
|
return { ...receive, from: (match.channels ?? []).filter((channel) => channel !== null) };
|
|
883
949
|
});
|
|
@@ -889,11 +955,11 @@ var message_channels_to_service_channels_default = async (dir2) => {
|
|
|
889
955
|
import_node_fs5.default.writeFileSync(service.path, import_gray_matter3.default.stringify(file, newData));
|
|
890
956
|
}
|
|
891
957
|
}
|
|
892
|
-
for (const
|
|
893
|
-
const file = import_node_fs5.default.readFileSync(
|
|
958
|
+
for (const message2 of messagesWithChannels) {
|
|
959
|
+
const file = import_node_fs5.default.readFileSync(message2.path, "utf8");
|
|
894
960
|
const parsed = (0, import_gray_matter3.default)(file);
|
|
895
961
|
const { channels, ...newData } = parsed.data;
|
|
896
|
-
import_node_fs5.default.writeFileSync(
|
|
962
|
+
import_node_fs5.default.writeFileSync(message2.path, import_gray_matter3.default.stringify(parsed.content, newData));
|
|
897
963
|
}
|
|
898
964
|
console.log("\u2714 Channels migrated to new services API");
|
|
899
965
|
};
|
|
@@ -1055,7 +1121,7 @@ var FieldsDatabase = class _FieldsDatabase {
|
|
|
1055
1121
|
format,
|
|
1056
1122
|
type,
|
|
1057
1123
|
messageType,
|
|
1058
|
-
message,
|
|
1124
|
+
message: message2,
|
|
1059
1125
|
producer,
|
|
1060
1126
|
consumer,
|
|
1061
1127
|
required,
|
|
@@ -1089,9 +1155,9 @@ var FieldsDatabase = class _FieldsDatabase {
|
|
|
1089
1155
|
conditions.push(`f.message_type IN (${types2.map(() => "?").join(", ")})`);
|
|
1090
1156
|
bindings.push(...types2);
|
|
1091
1157
|
}
|
|
1092
|
-
if (
|
|
1158
|
+
if (message2) {
|
|
1093
1159
|
conditions.push(`f.message_id = ?`);
|
|
1094
|
-
bindings.push(
|
|
1160
|
+
bindings.push(message2);
|
|
1095
1161
|
}
|
|
1096
1162
|
if (required) {
|
|
1097
1163
|
conditions.push(`f.required = 1`);
|
|
@@ -1904,8 +1970,8 @@ var KNOWN_EVENTCATALOG_COLLECTIONS = /* @__PURE__ */ new Set([
|
|
|
1904
1970
|
var EMPTY_COLLECTION_MESSAGE = /^The collection ("(?:\\.|[^"\\])*") does not exist or is empty\. Please check your content config file for errors\.$/;
|
|
1905
1971
|
var ANSI_PATTERN = /\u001B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
|
|
1906
1972
|
var ASTRO_CONTENT_WARN_PREFIX = /^[^[\]]*\[WARN\]\s+\[content\](?:\s+\[[^\]]+\])*\s*$/;
|
|
1907
|
-
function collectionNameFromEmptyWarning(
|
|
1908
|
-
const match =
|
|
1973
|
+
function collectionNameFromEmptyWarning(message2) {
|
|
1974
|
+
const match = message2.match(EMPTY_COLLECTION_MESSAGE);
|
|
1909
1975
|
if (!match) return null;
|
|
1910
1976
|
try {
|
|
1911
1977
|
const name = JSON.parse(match[1]);
|
|
@@ -1914,8 +1980,8 @@ function collectionNameFromEmptyWarning(message) {
|
|
|
1914
1980
|
return null;
|
|
1915
1981
|
}
|
|
1916
1982
|
}
|
|
1917
|
-
function isIntentionalEmptyCollectionMessage(
|
|
1918
|
-
const name = collectionNameFromEmptyWarning(
|
|
1983
|
+
function isIntentionalEmptyCollectionMessage(message2) {
|
|
1984
|
+
const name = collectionNameFromEmptyWarning(message2);
|
|
1919
1985
|
return name !== null && KNOWN_EVENTCATALOG_COLLECTIONS.has(name);
|
|
1920
1986
|
}
|
|
1921
1987
|
function isIntentionalEmptyCollectionLine(line) {
|
|
@@ -1923,8 +1989,8 @@ function isIntentionalEmptyCollectionLine(line) {
|
|
|
1923
1989
|
const marker = 'The collection "';
|
|
1924
1990
|
const start = plain.indexOf(marker);
|
|
1925
1991
|
if (start === -1) return false;
|
|
1926
|
-
const
|
|
1927
|
-
if (!isIntentionalEmptyCollectionMessage(
|
|
1992
|
+
const message2 = plain.slice(start).trim();
|
|
1993
|
+
if (!isIntentionalEmptyCollectionMessage(message2)) return false;
|
|
1928
1994
|
const before = plain.slice(0, start).trim();
|
|
1929
1995
|
return before.length === 0 || ASTRO_CONTENT_WARN_PREFIX.test(before);
|
|
1930
1996
|
}
|
|
@@ -2768,8 +2834,8 @@ var federateCatalog = async (projectDirectory, options = {}) => {
|
|
|
2768
2834
|
generated: resolved.generated
|
|
2769
2835
|
});
|
|
2770
2836
|
} catch (error) {
|
|
2771
|
-
const
|
|
2772
|
-
throw new Error(`Failed to federate source "${source.id}": ${
|
|
2837
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
2838
|
+
throw new Error(`Failed to federate source "${source.id}": ${message2}`, { cause: error });
|
|
2773
2839
|
}
|
|
2774
2840
|
}
|
|
2775
2841
|
const outDir = import_node_path19.default.join(projectDirectory, "federated");
|
|
@@ -3114,10 +3180,10 @@ Upgrade now: npm i @eventcatalog/core@beta`;
|
|
|
3114
3180
|
if (!installedVersion) return;
|
|
3115
3181
|
const pkg = { name: "@eventcatalog/core", version: installedVersion };
|
|
3116
3182
|
const notifier = (0, import_update_notifier.default)({ pkg, updateCheckInterval: 0 });
|
|
3117
|
-
const
|
|
3118
|
-
if (
|
|
3183
|
+
const message2 = getEventCatalogUpdateMessage(installedVersion, notifier.update?.latest);
|
|
3184
|
+
if (message2) {
|
|
3119
3185
|
console.log(
|
|
3120
|
-
(0, import_boxen2.default)(
|
|
3186
|
+
(0, import_boxen2.default)(message2, {
|
|
3121
3187
|
padding: 1,
|
|
3122
3188
|
margin: 1,
|
|
3123
3189
|
align: "center",
|
|
@@ -3278,15 +3344,33 @@ var previewCatalog = async ({ command }) => {
|
|
|
3278
3344
|
shouldFilterLine: createAstroLineFilter()
|
|
3279
3345
|
});
|
|
3280
3346
|
};
|
|
3347
|
+
var SERVER_BOOTSTRAP = `
|
|
3348
|
+
const entry = await import(process.argv[1]);
|
|
3349
|
+
const { server } = entry.startServer();
|
|
3350
|
+
globalThis[Symbol.for('eventcatalog.http-server')] = server.server;
|
|
3351
|
+
const wake = process.env.EVENTCATALOG_STUDIO_WAKE_PATH;
|
|
3352
|
+
if (wake) {
|
|
3353
|
+
server.server.once('listening', () => {
|
|
3354
|
+
// Where the server listens (HOST can be one address only); loopback when it listens on every address
|
|
3355
|
+
const { address, port } = server.server.address();
|
|
3356
|
+
const host = ['0.0.0.0', '::'].includes(address) ? '127.0.0.1' : address.includes(':') ? '[' + address + ']' : address;
|
|
3357
|
+
fetch('http://' + host + ':' + port + wake).catch((error) => console.error('[studio] Could not start Studio:', error.message));
|
|
3358
|
+
});
|
|
3359
|
+
}
|
|
3360
|
+
`;
|
|
3281
3361
|
var startServerCatalog = async () => {
|
|
3282
3362
|
const serverEntryPath = import_node_path21.default.join(dir, "dist", "server", "entry.mjs");
|
|
3363
|
+
const config = await getEventCatalogConfigFile(dir);
|
|
3364
|
+
const base = (config?.base || "/").replace(/\/$/, "");
|
|
3283
3365
|
await runCommandWithFilteredOutput({
|
|
3284
3366
|
command: process.execPath,
|
|
3285
|
-
args: [serverEntryPath],
|
|
3367
|
+
args: ["--input-type=module", "-e", SERVER_BOOTSTRAP, (0, import_node_url2.pathToFileURL)(serverEntryPath).href],
|
|
3286
3368
|
cwd: dir,
|
|
3287
3369
|
env: {
|
|
3288
3370
|
PROJECT_DIR: dir,
|
|
3289
|
-
CATALOG_DIR: core
|
|
3371
|
+
CATALOG_DIR: core,
|
|
3372
|
+
ASTRO_NODE_AUTOSTART: "disabled",
|
|
3373
|
+
...await isStudioEnabled() && { EVENTCATALOG_STUDIO_WAKE_PATH: `${base}/_eventcatalog/studio/wake` }
|
|
3290
3374
|
},
|
|
3291
3375
|
shouldFilterLine: createAstroLineFilter()
|
|
3292
3376
|
});
|
|
@@ -197,6 +197,40 @@ type McpConfig = {
|
|
|
197
197
|
enabled?: boolean;
|
|
198
198
|
auth?: McpAuthConfig;
|
|
199
199
|
};
|
|
200
|
+
/**
|
|
201
|
+
* Where EventCatalog Studio keeps canvases. People and agents always work on the copy held in memory by the
|
|
202
|
+
* server, so storage doesn't slow editing down: it's read when the server starts and written a moment after a
|
|
203
|
+
* canvas changes (and as the server stops).
|
|
204
|
+
*/
|
|
205
|
+
type StudioStorageConfig =
|
|
206
|
+
/** Kept only while the server runs: canvases are lost when it restarts or redeploys (the default) */
|
|
207
|
+
{
|
|
208
|
+
type: 'memory';
|
|
209
|
+
}
|
|
210
|
+
/** A SQLite database file. Uses Node.js's built-in SQLite, so needs Node.js 22.13 or later. */
|
|
211
|
+
| {
|
|
212
|
+
type: 'sqlite';
|
|
213
|
+
/**
|
|
214
|
+
* The database file, relative to the catalog. In a container, put it on a volume (e.g. `/data/studio.db`)
|
|
215
|
+
* so canvases survive redeploys.
|
|
216
|
+
* @default '.eventcatalog/studio.db'
|
|
217
|
+
*/
|
|
218
|
+
path?: string;
|
|
219
|
+
};
|
|
220
|
+
type StudioConfig = {
|
|
221
|
+
/**
|
|
222
|
+
* Turns Studio on in production (`output: 'server'`, served with `eventcatalog start`). It's on in the dev server
|
|
223
|
+
* unless this is `false`, which turns it off everywhere. Experimental. With authentication on, only signed-in people
|
|
224
|
+
* can open canvases, and they're shown by the name and picture they signed in with.
|
|
225
|
+
* @default false
|
|
226
|
+
*/
|
|
227
|
+
enabled?: boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Where canvases are kept between restarts.
|
|
230
|
+
* @default { type: 'memory' }
|
|
231
|
+
*/
|
|
232
|
+
storage?: StudioStorageConfig;
|
|
233
|
+
};
|
|
200
234
|
type GA4Config = {
|
|
201
235
|
measurementId: string;
|
|
202
236
|
};
|
|
@@ -257,6 +291,17 @@ interface Config {
|
|
|
257
291
|
};
|
|
258
292
|
security?: {
|
|
259
293
|
checkOrigin?: boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Hosts to trust in a proxy's X-Forwarded-Host and X-Forwarded-Proto headers (server output), e.g. when deployed
|
|
296
|
+
* behind Fly.io, Railway or a load balancer that serves HTTPS. Without it, form posts (like starting a canvas in
|
|
297
|
+
* Studio) fail the origin check. Passed to Astro's `security.allowedDomains`.
|
|
298
|
+
* @example [{ hostname: 'catalog.example.com', protocol: 'https' }]
|
|
299
|
+
*/
|
|
300
|
+
allowedDomains?: {
|
|
301
|
+
hostname?: string;
|
|
302
|
+
protocol?: string;
|
|
303
|
+
port?: string;
|
|
304
|
+
}[];
|
|
260
305
|
};
|
|
261
306
|
/**
|
|
262
307
|
* Theme for the catalog UI.
|
|
@@ -270,6 +315,8 @@ interface Config {
|
|
|
270
315
|
theme?: CatalogTheme;
|
|
271
316
|
auth?: AuthConfig;
|
|
272
317
|
mcp?: McpConfig;
|
|
318
|
+
/** EventCatalog Studio: collaborative canvases (experimental) */
|
|
319
|
+
studio?: StudioConfig;
|
|
273
320
|
rss?: {
|
|
274
321
|
enabled?: boolean;
|
|
275
322
|
limit?: number;
|
|
@@ -410,6 +457,14 @@ interface Config {
|
|
|
410
457
|
queries?: {
|
|
411
458
|
tableConfiguration?: TableConfiguration;
|
|
412
459
|
};
|
|
460
|
+
/**
|
|
461
|
+
* Anonymous telemetry for `eventcatalog dev` and `eventcatalog build`.
|
|
462
|
+
* On by default. Set to false to opt out.
|
|
463
|
+
* `EVENTCATALOG_TELEMETRY_DISABLED` or `DO_NOT_TRACK` set to `1` or `true` also opts out.
|
|
464
|
+
* `cloud.analytics` stays its own opt-in for EventCatalog Cloud.
|
|
465
|
+
* @default true
|
|
466
|
+
*/
|
|
467
|
+
telemetry?: boolean;
|
|
413
468
|
cloud?: EventCatalogCloudConfig;
|
|
414
469
|
integrations?: IntegrationsConfig;
|
|
415
470
|
scalarConfiguration?: ScalarConfiguration;
|