@eventcatalog/sdk 2.14.3 → 2.15.0
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/index.js +210 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +210 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,22 @@ import { join as join18 } from "path";
|
|
|
3
3
|
|
|
4
4
|
// src/dsl/utils.ts
|
|
5
5
|
import { globSync } from "glob";
|
|
6
|
+
import { satisfies, validRange } from "semver";
|
|
7
|
+
function msgVersionMatches(pointerVersion, messageVersion) {
|
|
8
|
+
if (!pointerVersion) return true;
|
|
9
|
+
if (!messageVersion) return false;
|
|
10
|
+
if (pointerVersion === messageVersion) return true;
|
|
11
|
+
try {
|
|
12
|
+
if (validRange(pointerVersion)) {
|
|
13
|
+
if (satisfies(messageVersion, pointerVersion)) return true;
|
|
14
|
+
}
|
|
15
|
+
if (validRange(messageVersion)) {
|
|
16
|
+
if (satisfies(pointerVersion, messageVersion)) return true;
|
|
17
|
+
}
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
6
22
|
function serializeBaseFields(resource, indent = " ") {
|
|
7
23
|
const lines = [];
|
|
8
24
|
if (resource.version) {
|
|
@@ -91,10 +107,12 @@ ${body}
|
|
|
91
107
|
}
|
|
92
108
|
|
|
93
109
|
// src/dsl/service.ts
|
|
110
|
+
import { valid as semverValid } from "semver";
|
|
94
111
|
async function serviceToDSL(resource, options, getMessageFn) {
|
|
95
112
|
const { catalogDir, hydrate = false, _seen = /* @__PURE__ */ new Set() } = options;
|
|
96
113
|
const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);
|
|
97
114
|
const parts = [];
|
|
115
|
+
const resolvedVersions = /* @__PURE__ */ new Map();
|
|
98
116
|
if (hydrate && getMessageFn) {
|
|
99
117
|
const allMessages = [...resource.sends || [], ...resource.receives || []];
|
|
100
118
|
for (const msg of allMessages) {
|
|
@@ -106,18 +124,30 @@ async function serviceToDSL(resource, options, getMessageFn) {
|
|
|
106
124
|
const msgResource = await getMessageFn(msg.id, msg.version);
|
|
107
125
|
if (msgResource) {
|
|
108
126
|
parts.push(messageToDSL(msgResource, msgType));
|
|
127
|
+
if (msg.version && !semverValid(msg.version) && msgResource.version) {
|
|
128
|
+
resolvedVersions.set(`${msg.id}@${msg.version}`, msgResource.version);
|
|
129
|
+
}
|
|
109
130
|
}
|
|
110
131
|
}
|
|
111
132
|
}
|
|
133
|
+
const resolvePointers = (pointers) => pointers.map((p) => {
|
|
134
|
+
if (p.version && !semverValid(p.version)) {
|
|
135
|
+
const resolved = resolvedVersions.get(`${p.id}@${p.version}`);
|
|
136
|
+
if (resolved) return { ...p, version: resolved };
|
|
137
|
+
}
|
|
138
|
+
return p;
|
|
139
|
+
});
|
|
140
|
+
const sends = resource.sends ? resolvePointers(resource.sends) : void 0;
|
|
141
|
+
const receives = resource.receives ? resolvePointers(resource.receives) : void 0;
|
|
112
142
|
const lines = [];
|
|
113
143
|
const baseFields = serializeBaseFields(resource);
|
|
114
144
|
if (baseFields) lines.push(baseFields);
|
|
115
|
-
if (
|
|
116
|
-
const sendsStr = serializeMessagePointers(
|
|
145
|
+
if (sends && sends.length > 0) {
|
|
146
|
+
const sendsStr = serializeMessagePointers(sends, "sends", msgIndex);
|
|
117
147
|
if (sendsStr) lines.push(sendsStr);
|
|
118
148
|
}
|
|
119
|
-
if (
|
|
120
|
-
const recvStr = serializeMessagePointers(
|
|
149
|
+
if (receives && receives.length > 0) {
|
|
150
|
+
const recvStr = serializeMessagePointers(receives, "receives", msgIndex);
|
|
121
151
|
if (recvStr) lines.push(recvStr);
|
|
122
152
|
}
|
|
123
153
|
if (resource.writesTo && resource.writesTo.length > 0) {
|
|
@@ -161,6 +191,13 @@ function channelToDSL(resource) {
|
|
|
161
191
|
if (resource.summary) {
|
|
162
192
|
lines.push(` summary "${resource.summary.trim()}"`);
|
|
163
193
|
}
|
|
194
|
+
if (resource.routes && resource.routes.length > 0) {
|
|
195
|
+
for (const route of resource.routes) {
|
|
196
|
+
let ref = route.id;
|
|
197
|
+
if (route.version) ref += `@${route.version}`;
|
|
198
|
+
lines.push(` route ${ref}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
164
201
|
if (!lines.length) {
|
|
165
202
|
return `channel ${resource.id}`;
|
|
166
203
|
}
|
|
@@ -324,6 +361,38 @@ async function domainToDSL(resource, options, resolvers) {
|
|
|
324
361
|
return parts.join("\n\n");
|
|
325
362
|
}
|
|
326
363
|
|
|
364
|
+
// src/dsl/container.ts
|
|
365
|
+
function containerToDSL(resource) {
|
|
366
|
+
const lines = [];
|
|
367
|
+
const baseFields = serializeBaseFields(resource);
|
|
368
|
+
if (baseFields) lines.push(baseFields);
|
|
369
|
+
if (resource.container_type) {
|
|
370
|
+
lines.push(` container-type ${resource.container_type}`);
|
|
371
|
+
}
|
|
372
|
+
if (resource.technology) {
|
|
373
|
+
lines.push(` technology "${resource.technology}"`);
|
|
374
|
+
}
|
|
375
|
+
if (resource.authoritative === true) {
|
|
376
|
+
lines.push(` authoritative true`);
|
|
377
|
+
}
|
|
378
|
+
if (resource.access_mode) {
|
|
379
|
+
lines.push(` access-mode ${resource.access_mode}`);
|
|
380
|
+
}
|
|
381
|
+
if (resource.classification) {
|
|
382
|
+
lines.push(` classification ${resource.classification}`);
|
|
383
|
+
}
|
|
384
|
+
if (resource.residency) {
|
|
385
|
+
lines.push(` residency "${resource.residency}"`);
|
|
386
|
+
}
|
|
387
|
+
if (resource.retention) {
|
|
388
|
+
lines.push(` retention "${resource.retention}"`);
|
|
389
|
+
}
|
|
390
|
+
const body = lines.join("\n");
|
|
391
|
+
return `container ${resource.id} {
|
|
392
|
+
${body}
|
|
393
|
+
}`;
|
|
394
|
+
}
|
|
395
|
+
|
|
327
396
|
// src/dsl/index.ts
|
|
328
397
|
function getMessage(resolvers, msgIndex) {
|
|
329
398
|
return async (id, version) => {
|
|
@@ -339,22 +408,55 @@ function getMessage(resolvers, msgIndex) {
|
|
|
339
408
|
}
|
|
340
409
|
};
|
|
341
410
|
}
|
|
411
|
+
async function hydrateChannel(channelId, channelVersion, resolvers, seen, parts) {
|
|
412
|
+
const key = `channel:${channelId}@${channelVersion || "latest"}`;
|
|
413
|
+
if (seen.has(key)) return;
|
|
414
|
+
seen.add(key);
|
|
415
|
+
const channel = await resolvers.getChannel(channelId, channelVersion);
|
|
416
|
+
if (!channel) return;
|
|
417
|
+
if (channel.routes && channel.routes.length > 0) {
|
|
418
|
+
for (const route of channel.routes) {
|
|
419
|
+
await hydrateChannel(route.id, route.version, resolvers, seen, parts);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
const allChannels = await resolvers.getChannels({ latestOnly: false }) || [];
|
|
423
|
+
const targetVersion = channelVersion || channel.version;
|
|
424
|
+
for (const upstream of allChannels) {
|
|
425
|
+
if (!upstream.routes) continue;
|
|
426
|
+
const routesToThis = upstream.routes.some((route) => {
|
|
427
|
+
if (route.id !== channelId) return false;
|
|
428
|
+
if (!route.version) {
|
|
429
|
+
return !channelVersion;
|
|
430
|
+
}
|
|
431
|
+
return msgVersionMatches(route.version, targetVersion);
|
|
432
|
+
});
|
|
433
|
+
if (routesToThis) {
|
|
434
|
+
await hydrateChannel(upstream.id, upstream.version, resolvers, seen, parts);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
parts.push(channelToDSL(channel));
|
|
438
|
+
}
|
|
342
439
|
async function hydrateChannels(resource, resolvers, seen, parts) {
|
|
343
440
|
const allMessages = [...resource.sends || [], ...resource.receives || []];
|
|
344
441
|
for (const msg of allMessages) {
|
|
345
442
|
const channels = "to" in msg ? msg.to : "from" in msg ? msg.from : void 0;
|
|
346
443
|
if (!channels) continue;
|
|
347
444
|
for (const ch of channels) {
|
|
348
|
-
|
|
349
|
-
if (seen.has(key)) continue;
|
|
350
|
-
seen.add(key);
|
|
351
|
-
const channel = await resolvers.getChannel(ch.id, ch.version);
|
|
352
|
-
if (channel) {
|
|
353
|
-
parts.push(channelToDSL(channel));
|
|
354
|
-
}
|
|
445
|
+
await hydrateChannel(ch.id, ch.version, resolvers, seen, parts);
|
|
355
446
|
}
|
|
356
447
|
}
|
|
357
448
|
}
|
|
449
|
+
async function hydrateContainers(resource, resolvers, seen, parts) {
|
|
450
|
+
const allContainers = [...resource.writesTo || [], ...resource.readsFrom || []];
|
|
451
|
+
for (const ref of allContainers) {
|
|
452
|
+
const key = `container:${ref.id}@${ref.version || "latest"}`;
|
|
453
|
+
if (seen.has(key)) continue;
|
|
454
|
+
seen.add(key);
|
|
455
|
+
const container = await resolvers.getContainer(ref.id, ref.version);
|
|
456
|
+
if (!container) continue;
|
|
457
|
+
parts.push(containerToDSL(container));
|
|
458
|
+
}
|
|
459
|
+
}
|
|
358
460
|
async function hydrateOwners2(owners, resolvers, seen, parts) {
|
|
359
461
|
if (!owners) return;
|
|
360
462
|
for (const ownerId of owners) {
|
|
@@ -372,6 +474,67 @@ async function hydrateOwners2(owners, resolvers, seen, parts) {
|
|
|
372
474
|
}
|
|
373
475
|
}
|
|
374
476
|
}
|
|
477
|
+
async function hydrateMessageServices(messageId, messageVersion, resolvers, seen, parts, catalogDir, msgIndex) {
|
|
478
|
+
const services = await resolvers.getServices({ latestOnly: false }) || [];
|
|
479
|
+
for (const service of services) {
|
|
480
|
+
const key = `service:${service.id}@${service.version || "latest"}`;
|
|
481
|
+
if (seen.has(key)) continue;
|
|
482
|
+
const referencesMessage = [...service.sends || [], ...service.receives || []].some(
|
|
483
|
+
(msg) => msg.id === messageId && msgVersionMatches(msg.version, messageVersion)
|
|
484
|
+
);
|
|
485
|
+
if (referencesMessage) {
|
|
486
|
+
seen.add(key);
|
|
487
|
+
const matchMsg = (msg) => msg.id === messageId && msgVersionMatches(msg.version, messageVersion);
|
|
488
|
+
const resolvePointerVersion = (msg) => {
|
|
489
|
+
if (msg.id === messageId && msg.version && msg.version !== messageVersion && messageVersion) {
|
|
490
|
+
return { ...msg, version: messageVersion };
|
|
491
|
+
}
|
|
492
|
+
return msg;
|
|
493
|
+
};
|
|
494
|
+
const filtered = {
|
|
495
|
+
...service,
|
|
496
|
+
sends: service.sends?.filter(matchMsg).map(resolvePointerVersion),
|
|
497
|
+
receives: service.receives?.filter(matchMsg).map(resolvePointerVersion)
|
|
498
|
+
};
|
|
499
|
+
await hydrateChannels(filtered, resolvers, seen, parts);
|
|
500
|
+
parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
async function hydrateRelatedServices(messages, direction, resolvers, seen, parts, catalogDir, msgIndex) {
|
|
505
|
+
if (!messages.length) return;
|
|
506
|
+
const referencesHydratedMessage = (msg) => messages.some((input) => msg.id === input.id && msgVersionMatches(msg.version, input.version));
|
|
507
|
+
const services = await resolvers.getServices({ latestOnly: false }) || [];
|
|
508
|
+
for (const service of services) {
|
|
509
|
+
const key = `service:${service.id}@${service.version || "latest"}`;
|
|
510
|
+
if (seen.has(key)) continue;
|
|
511
|
+
if (direction === "sends") {
|
|
512
|
+
const matchedPointers = (service.sends || []).filter(referencesHydratedMessage);
|
|
513
|
+
if (matchedPointers.length > 0) {
|
|
514
|
+
seen.add(key);
|
|
515
|
+
const filtered = {
|
|
516
|
+
...service,
|
|
517
|
+
sends: matchedPointers,
|
|
518
|
+
receives: void 0
|
|
519
|
+
};
|
|
520
|
+
await hydrateChannels(filtered, resolvers, seen, parts);
|
|
521
|
+
parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));
|
|
522
|
+
}
|
|
523
|
+
} else {
|
|
524
|
+
const matchedPointers = (service.receives || []).filter(referencesHydratedMessage);
|
|
525
|
+
if (matchedPointers.length > 0) {
|
|
526
|
+
seen.add(key);
|
|
527
|
+
const filtered = {
|
|
528
|
+
...service,
|
|
529
|
+
sends: void 0,
|
|
530
|
+
receives: matchedPointers
|
|
531
|
+
};
|
|
532
|
+
await hydrateChannels(filtered, resolvers, seen, parts);
|
|
533
|
+
parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
375
538
|
var toDSL = (catalogDir, resolvers) => async (resource, options) => {
|
|
376
539
|
const resources = Array.isArray(resource) ? resource : [resource];
|
|
377
540
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -387,6 +550,7 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
|
|
|
387
550
|
case "query":
|
|
388
551
|
if (options.hydrate) {
|
|
389
552
|
await hydrateOwners2(res.owners, resolvers, seen, parts);
|
|
553
|
+
await hydrateMessageServices(res.id, res.version, resolvers, seen, parts, catalogDir, msgIndex);
|
|
390
554
|
}
|
|
391
555
|
parts.push(messageToDSL(res, options.type));
|
|
392
556
|
break;
|
|
@@ -394,6 +558,7 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
|
|
|
394
558
|
if (options.hydrate) {
|
|
395
559
|
await hydrateOwners2(res.owners, resolvers, seen, parts);
|
|
396
560
|
await hydrateChannels(res, resolvers, seen, parts);
|
|
561
|
+
await hydrateContainers(res, resolvers, seen, parts);
|
|
397
562
|
}
|
|
398
563
|
parts.push(
|
|
399
564
|
await serviceToDSL(
|
|
@@ -402,6 +567,11 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
|
|
|
402
567
|
getMessage(resolvers, msgIndex)
|
|
403
568
|
)
|
|
404
569
|
);
|
|
570
|
+
if (options.hydrate) {
|
|
571
|
+
const svc = res;
|
|
572
|
+
await hydrateRelatedServices(svc.sends || [], "receives", resolvers, seen, parts, catalogDir, msgIndex);
|
|
573
|
+
await hydrateRelatedServices(svc.receives || [], "sends", resolvers, seen, parts, catalogDir, msgIndex);
|
|
574
|
+
}
|
|
405
575
|
break;
|
|
406
576
|
case "domain":
|
|
407
577
|
if (options.hydrate) {
|
|
@@ -421,6 +591,22 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
|
|
|
421
591
|
}
|
|
422
592
|
)
|
|
423
593
|
);
|
|
594
|
+
if (options.hydrate) {
|
|
595
|
+
const domain = res;
|
|
596
|
+
const allSends = [];
|
|
597
|
+
const allReceives = [];
|
|
598
|
+
if (domain.services?.length) {
|
|
599
|
+
for (const svcRef of domain.services) {
|
|
600
|
+
const svc = await resolvers.getService(svcRef.id, svcRef.version);
|
|
601
|
+
if (svc) {
|
|
602
|
+
allSends.push(...svc.sends || []);
|
|
603
|
+
allReceives.push(...svc.receives || []);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
await hydrateRelatedServices(allSends, "receives", resolvers, seen, parts, catalogDir, msgIndex);
|
|
608
|
+
await hydrateRelatedServices(allReceives, "sends", resolvers, seen, parts, catalogDir, msgIndex);
|
|
609
|
+
}
|
|
424
610
|
break;
|
|
425
611
|
}
|
|
426
612
|
}
|
|
@@ -437,7 +623,7 @@ import fsSync from "fs";
|
|
|
437
623
|
import { copy } from "fs-extra";
|
|
438
624
|
import { join, dirname, normalize, sep as pathSeparator, resolve, relative } from "path";
|
|
439
625
|
import matter from "gray-matter";
|
|
440
|
-
import { satisfies, validRange } from "semver";
|
|
626
|
+
import { satisfies as satisfies2, validRange as validRange2 } from "semver";
|
|
441
627
|
var _fileIndexCache = null;
|
|
442
628
|
var _fileIndexCatalogDir = null;
|
|
443
629
|
var _matterCache = null;
|
|
@@ -569,11 +755,11 @@ var findFileById = async (catalogDir, id, version) => {
|
|
|
569
755
|
}
|
|
570
756
|
const exactMatch = entries.find((e) => e.version === version);
|
|
571
757
|
if (exactMatch) return exactMatch.path;
|
|
572
|
-
const semverRange =
|
|
758
|
+
const semverRange = validRange2(version);
|
|
573
759
|
if (semverRange) {
|
|
574
760
|
const match = entries.find((e) => {
|
|
575
761
|
try {
|
|
576
|
-
return
|
|
762
|
+
return satisfies2(e.version, semverRange);
|
|
577
763
|
} catch {
|
|
578
764
|
return false;
|
|
579
765
|
}
|
|
@@ -659,7 +845,7 @@ import { dirname as dirname2, join as join2 } from "path";
|
|
|
659
845
|
import matter2 from "gray-matter";
|
|
660
846
|
import fs from "fs/promises";
|
|
661
847
|
import fsSync2 from "fs";
|
|
662
|
-
import { satisfies as
|
|
848
|
+
import { satisfies as satisfies3 } from "semver";
|
|
663
849
|
import { lock, unlock } from "proper-lockfile";
|
|
664
850
|
import { basename as basename2 } from "path";
|
|
665
851
|
import path from "path";
|
|
@@ -725,7 +911,7 @@ var writeResource = async (catalogDir, resource, options = {
|
|
|
725
911
|
if (options.versionExistingContent && !exists) {
|
|
726
912
|
const currentResource = await getResource(catalogDir, resource.id);
|
|
727
913
|
if (currentResource) {
|
|
728
|
-
if (
|
|
914
|
+
if (satisfies3(resource.version, `>${currentResource.version}`)) {
|
|
729
915
|
await versionResource(catalogDir, resource.id);
|
|
730
916
|
} else {
|
|
731
917
|
throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);
|
|
@@ -1399,7 +1585,7 @@ var addMessageToChannel = (directory, collection) => async (id, _message, versio
|
|
|
1399
1585
|
// src/messages.ts
|
|
1400
1586
|
import { dirname as dirname5 } from "path";
|
|
1401
1587
|
import matter4 from "gray-matter";
|
|
1402
|
-
import { satisfies as
|
|
1588
|
+
import { satisfies as satisfies4, validRange as validRange3 } from "semver";
|
|
1403
1589
|
var getMessageBySchemaPath = (directory) => async (path6, options) => {
|
|
1404
1590
|
const pathToMessage = dirname5(path6);
|
|
1405
1591
|
try {
|
|
@@ -1438,9 +1624,9 @@ var getProducersAndConsumersForMessage = (directory) => async (id, version, opti
|
|
|
1438
1624
|
for (const service of services) {
|
|
1439
1625
|
const servicePublishesMessage = service.sends?.some((_message) => {
|
|
1440
1626
|
if (_message.version) {
|
|
1441
|
-
const isServiceUsingSemverRange =
|
|
1627
|
+
const isServiceUsingSemverRange = validRange3(_message.version);
|
|
1442
1628
|
if (isServiceUsingSemverRange) {
|
|
1443
|
-
return _message.id === message.id &&
|
|
1629
|
+
return _message.id === message.id && satisfies4(message.version, _message.version);
|
|
1444
1630
|
} else {
|
|
1445
1631
|
return _message.id === message.id && message.version === _message.version;
|
|
1446
1632
|
}
|
|
@@ -1452,9 +1638,9 @@ var getProducersAndConsumersForMessage = (directory) => async (id, version, opti
|
|
|
1452
1638
|
});
|
|
1453
1639
|
const serviceSubscribesToMessage = service.receives?.some((_message) => {
|
|
1454
1640
|
if (_message.version) {
|
|
1455
|
-
const isServiceUsingSemverRange =
|
|
1641
|
+
const isServiceUsingSemverRange = validRange3(_message.version);
|
|
1456
1642
|
if (isServiceUsingSemverRange) {
|
|
1457
|
-
return _message.id === message.id &&
|
|
1643
|
+
return _message.id === message.id && satisfies4(message.version, _message.version);
|
|
1458
1644
|
} else {
|
|
1459
1645
|
return _message.id === message.id && message.version === _message.version;
|
|
1460
1646
|
}
|
|
@@ -2982,8 +3168,11 @@ var src_default = (path6) => {
|
|
|
2982
3168
|
getCommand: getCommand(join18(path6)),
|
|
2983
3169
|
getQuery: getQuery(join18(path6)),
|
|
2984
3170
|
getService: getService(join18(path6)),
|
|
3171
|
+
getServices: getServices(join18(path6)),
|
|
2985
3172
|
getDomain: getDomain(join18(path6, "domains")),
|
|
2986
3173
|
getChannel: getChannel(join18(path6)),
|
|
3174
|
+
getChannels: getChannels(join18(path6)),
|
|
3175
|
+
getContainer: getDataStore(join18(path6)),
|
|
2987
3176
|
getTeam: getTeam(join18(path6, "teams")),
|
|
2988
3177
|
getUser: getUser(join18(path6, "users"))
|
|
2989
3178
|
})
|