@eventcatalog/sdk 2.14.2 → 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 CHANGED
@@ -37,6 +37,22 @@ var import_node_path20 = require("path");
37
37
 
38
38
  // src/dsl/utils.ts
39
39
  var import_glob = require("glob");
40
+ var import_semver = require("semver");
41
+ function msgVersionMatches(pointerVersion, messageVersion) {
42
+ if (!pointerVersion) return true;
43
+ if (!messageVersion) return false;
44
+ if (pointerVersion === messageVersion) return true;
45
+ try {
46
+ if ((0, import_semver.validRange)(pointerVersion)) {
47
+ if ((0, import_semver.satisfies)(messageVersion, pointerVersion)) return true;
48
+ }
49
+ if ((0, import_semver.validRange)(messageVersion)) {
50
+ if ((0, import_semver.satisfies)(pointerVersion, messageVersion)) return true;
51
+ }
52
+ } catch {
53
+ }
54
+ return false;
55
+ }
40
56
  function serializeBaseFields(resource, indent = " ") {
41
57
  const lines = [];
42
58
  if (resource.version) {
@@ -125,10 +141,12 @@ ${body}
125
141
  }
126
142
 
127
143
  // src/dsl/service.ts
144
+ var import_semver2 = require("semver");
128
145
  async function serviceToDSL(resource, options, getMessageFn) {
129
146
  const { catalogDir, hydrate = false, _seen = /* @__PURE__ */ new Set() } = options;
130
147
  const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);
131
148
  const parts = [];
149
+ const resolvedVersions = /* @__PURE__ */ new Map();
132
150
  if (hydrate && getMessageFn) {
133
151
  const allMessages = [...resource.sends || [], ...resource.receives || []];
134
152
  for (const msg of allMessages) {
@@ -140,18 +158,30 @@ async function serviceToDSL(resource, options, getMessageFn) {
140
158
  const msgResource = await getMessageFn(msg.id, msg.version);
141
159
  if (msgResource) {
142
160
  parts.push(messageToDSL(msgResource, msgType));
161
+ if (msg.version && !(0, import_semver2.valid)(msg.version) && msgResource.version) {
162
+ resolvedVersions.set(`${msg.id}@${msg.version}`, msgResource.version);
163
+ }
143
164
  }
144
165
  }
145
166
  }
167
+ const resolvePointers = (pointers) => pointers.map((p) => {
168
+ if (p.version && !(0, import_semver2.valid)(p.version)) {
169
+ const resolved = resolvedVersions.get(`${p.id}@${p.version}`);
170
+ if (resolved) return { ...p, version: resolved };
171
+ }
172
+ return p;
173
+ });
174
+ const sends = resource.sends ? resolvePointers(resource.sends) : void 0;
175
+ const receives = resource.receives ? resolvePointers(resource.receives) : void 0;
146
176
  const lines = [];
147
177
  const baseFields = serializeBaseFields(resource);
148
178
  if (baseFields) lines.push(baseFields);
149
- if (resource.sends && resource.sends.length > 0) {
150
- const sendsStr = serializeMessagePointers(resource.sends, "sends", msgIndex);
179
+ if (sends && sends.length > 0) {
180
+ const sendsStr = serializeMessagePointers(sends, "sends", msgIndex);
151
181
  if (sendsStr) lines.push(sendsStr);
152
182
  }
153
- if (resource.receives && resource.receives.length > 0) {
154
- const recvStr = serializeMessagePointers(resource.receives, "receives", msgIndex);
183
+ if (receives && receives.length > 0) {
184
+ const recvStr = serializeMessagePointers(receives, "receives", msgIndex);
155
185
  if (recvStr) lines.push(recvStr);
156
186
  }
157
187
  if (resource.writesTo && resource.writesTo.length > 0) {
@@ -195,6 +225,13 @@ function channelToDSL(resource) {
195
225
  if (resource.summary) {
196
226
  lines.push(` summary "${resource.summary.trim()}"`);
197
227
  }
228
+ if (resource.routes && resource.routes.length > 0) {
229
+ for (const route of resource.routes) {
230
+ let ref = route.id;
231
+ if (route.version) ref += `@${route.version}`;
232
+ lines.push(` route ${ref}`);
233
+ }
234
+ }
198
235
  if (!lines.length) {
199
236
  return `channel ${resource.id}`;
200
237
  }
@@ -358,6 +395,38 @@ async function domainToDSL(resource, options, resolvers) {
358
395
  return parts.join("\n\n");
359
396
  }
360
397
 
398
+ // src/dsl/container.ts
399
+ function containerToDSL(resource) {
400
+ const lines = [];
401
+ const baseFields = serializeBaseFields(resource);
402
+ if (baseFields) lines.push(baseFields);
403
+ if (resource.container_type) {
404
+ lines.push(` container-type ${resource.container_type}`);
405
+ }
406
+ if (resource.technology) {
407
+ lines.push(` technology "${resource.technology}"`);
408
+ }
409
+ if (resource.authoritative === true) {
410
+ lines.push(` authoritative true`);
411
+ }
412
+ if (resource.access_mode) {
413
+ lines.push(` access-mode ${resource.access_mode}`);
414
+ }
415
+ if (resource.classification) {
416
+ lines.push(` classification ${resource.classification}`);
417
+ }
418
+ if (resource.residency) {
419
+ lines.push(` residency "${resource.residency}"`);
420
+ }
421
+ if (resource.retention) {
422
+ lines.push(` retention "${resource.retention}"`);
423
+ }
424
+ const body = lines.join("\n");
425
+ return `container ${resource.id} {
426
+ ${body}
427
+ }`;
428
+ }
429
+
361
430
  // src/dsl/index.ts
362
431
  function getMessage(resolvers, msgIndex) {
363
432
  return async (id, version) => {
@@ -373,22 +442,55 @@ function getMessage(resolvers, msgIndex) {
373
442
  }
374
443
  };
375
444
  }
445
+ async function hydrateChannel(channelId, channelVersion, resolvers, seen, parts) {
446
+ const key = `channel:${channelId}@${channelVersion || "latest"}`;
447
+ if (seen.has(key)) return;
448
+ seen.add(key);
449
+ const channel = await resolvers.getChannel(channelId, channelVersion);
450
+ if (!channel) return;
451
+ if (channel.routes && channel.routes.length > 0) {
452
+ for (const route of channel.routes) {
453
+ await hydrateChannel(route.id, route.version, resolvers, seen, parts);
454
+ }
455
+ }
456
+ const allChannels = await resolvers.getChannels({ latestOnly: false }) || [];
457
+ const targetVersion = channelVersion || channel.version;
458
+ for (const upstream of allChannels) {
459
+ if (!upstream.routes) continue;
460
+ const routesToThis = upstream.routes.some((route) => {
461
+ if (route.id !== channelId) return false;
462
+ if (!route.version) {
463
+ return !channelVersion;
464
+ }
465
+ return msgVersionMatches(route.version, targetVersion);
466
+ });
467
+ if (routesToThis) {
468
+ await hydrateChannel(upstream.id, upstream.version, resolvers, seen, parts);
469
+ }
470
+ }
471
+ parts.push(channelToDSL(channel));
472
+ }
376
473
  async function hydrateChannels(resource, resolvers, seen, parts) {
377
474
  const allMessages = [...resource.sends || [], ...resource.receives || []];
378
475
  for (const msg of allMessages) {
379
476
  const channels = "to" in msg ? msg.to : "from" in msg ? msg.from : void 0;
380
477
  if (!channels) continue;
381
478
  for (const ch of channels) {
382
- const key = `channel:${ch.id}@${ch.version || "latest"}`;
383
- if (seen.has(key)) continue;
384
- seen.add(key);
385
- const channel = await resolvers.getChannel(ch.id, ch.version);
386
- if (channel) {
387
- parts.push(channelToDSL(channel));
388
- }
479
+ await hydrateChannel(ch.id, ch.version, resolvers, seen, parts);
389
480
  }
390
481
  }
391
482
  }
483
+ async function hydrateContainers(resource, resolvers, seen, parts) {
484
+ const allContainers = [...resource.writesTo || [], ...resource.readsFrom || []];
485
+ for (const ref of allContainers) {
486
+ const key = `container:${ref.id}@${ref.version || "latest"}`;
487
+ if (seen.has(key)) continue;
488
+ seen.add(key);
489
+ const container = await resolvers.getContainer(ref.id, ref.version);
490
+ if (!container) continue;
491
+ parts.push(containerToDSL(container));
492
+ }
493
+ }
392
494
  async function hydrateOwners2(owners, resolvers, seen, parts) {
393
495
  if (!owners) return;
394
496
  for (const ownerId of owners) {
@@ -406,6 +508,67 @@ async function hydrateOwners2(owners, resolvers, seen, parts) {
406
508
  }
407
509
  }
408
510
  }
511
+ async function hydrateMessageServices(messageId, messageVersion, resolvers, seen, parts, catalogDir, msgIndex) {
512
+ const services = await resolvers.getServices({ latestOnly: false }) || [];
513
+ for (const service of services) {
514
+ const key = `service:${service.id}@${service.version || "latest"}`;
515
+ if (seen.has(key)) continue;
516
+ const referencesMessage = [...service.sends || [], ...service.receives || []].some(
517
+ (msg) => msg.id === messageId && msgVersionMatches(msg.version, messageVersion)
518
+ );
519
+ if (referencesMessage) {
520
+ seen.add(key);
521
+ const matchMsg = (msg) => msg.id === messageId && msgVersionMatches(msg.version, messageVersion);
522
+ const resolvePointerVersion = (msg) => {
523
+ if (msg.id === messageId && msg.version && msg.version !== messageVersion && messageVersion) {
524
+ return { ...msg, version: messageVersion };
525
+ }
526
+ return msg;
527
+ };
528
+ const filtered = {
529
+ ...service,
530
+ sends: service.sends?.filter(matchMsg).map(resolvePointerVersion),
531
+ receives: service.receives?.filter(matchMsg).map(resolvePointerVersion)
532
+ };
533
+ await hydrateChannels(filtered, resolvers, seen, parts);
534
+ parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));
535
+ }
536
+ }
537
+ }
538
+ async function hydrateRelatedServices(messages, direction, resolvers, seen, parts, catalogDir, msgIndex) {
539
+ if (!messages.length) return;
540
+ const referencesHydratedMessage = (msg) => messages.some((input) => msg.id === input.id && msgVersionMatches(msg.version, input.version));
541
+ const services = await resolvers.getServices({ latestOnly: false }) || [];
542
+ for (const service of services) {
543
+ const key = `service:${service.id}@${service.version || "latest"}`;
544
+ if (seen.has(key)) continue;
545
+ if (direction === "sends") {
546
+ const matchedPointers = (service.sends || []).filter(referencesHydratedMessage);
547
+ if (matchedPointers.length > 0) {
548
+ seen.add(key);
549
+ const filtered = {
550
+ ...service,
551
+ sends: matchedPointers,
552
+ receives: void 0
553
+ };
554
+ await hydrateChannels(filtered, resolvers, seen, parts);
555
+ parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));
556
+ }
557
+ } else {
558
+ const matchedPointers = (service.receives || []).filter(referencesHydratedMessage);
559
+ if (matchedPointers.length > 0) {
560
+ seen.add(key);
561
+ const filtered = {
562
+ ...service,
563
+ sends: void 0,
564
+ receives: matchedPointers
565
+ };
566
+ await hydrateChannels(filtered, resolvers, seen, parts);
567
+ parts.push(await serviceToDSL(filtered, { catalogDir, hydrate: false, _seen: new Set(seen), _msgIndex: msgIndex }));
568
+ }
569
+ }
570
+ }
571
+ }
409
572
  var toDSL = (catalogDir, resolvers) => async (resource, options) => {
410
573
  const resources = Array.isArray(resource) ? resource : [resource];
411
574
  const seen = /* @__PURE__ */ new Set();
@@ -421,6 +584,7 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
421
584
  case "query":
422
585
  if (options.hydrate) {
423
586
  await hydrateOwners2(res.owners, resolvers, seen, parts);
587
+ await hydrateMessageServices(res.id, res.version, resolvers, seen, parts, catalogDir, msgIndex);
424
588
  }
425
589
  parts.push(messageToDSL(res, options.type));
426
590
  break;
@@ -428,6 +592,7 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
428
592
  if (options.hydrate) {
429
593
  await hydrateOwners2(res.owners, resolvers, seen, parts);
430
594
  await hydrateChannels(res, resolvers, seen, parts);
595
+ await hydrateContainers(res, resolvers, seen, parts);
431
596
  }
432
597
  parts.push(
433
598
  await serviceToDSL(
@@ -436,6 +601,11 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
436
601
  getMessage(resolvers, msgIndex)
437
602
  )
438
603
  );
604
+ if (options.hydrate) {
605
+ const svc = res;
606
+ await hydrateRelatedServices(svc.sends || [], "receives", resolvers, seen, parts, catalogDir, msgIndex);
607
+ await hydrateRelatedServices(svc.receives || [], "sends", resolvers, seen, parts, catalogDir, msgIndex);
608
+ }
439
609
  break;
440
610
  case "domain":
441
611
  if (options.hydrate) {
@@ -455,6 +625,22 @@ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
455
625
  }
456
626
  )
457
627
  );
628
+ if (options.hydrate) {
629
+ const domain = res;
630
+ const allSends = [];
631
+ const allReceives = [];
632
+ if (domain.services?.length) {
633
+ for (const svcRef of domain.services) {
634
+ const svc = await resolvers.getService(svcRef.id, svcRef.version);
635
+ if (svc) {
636
+ allSends.push(...svc.sends || []);
637
+ allReceives.push(...svc.receives || []);
638
+ }
639
+ }
640
+ }
641
+ await hydrateRelatedServices(allSends, "receives", resolvers, seen, parts, catalogDir, msgIndex);
642
+ await hydrateRelatedServices(allReceives, "sends", resolvers, seen, parts, catalogDir, msgIndex);
643
+ }
458
644
  break;
459
645
  }
460
646
  }
@@ -471,7 +657,7 @@ var import_node_fs = __toESM(require("fs"));
471
657
  var import_fs_extra = require("fs-extra");
472
658
  var import_node_path = require("path");
473
659
  var import_gray_matter = __toESM(require("gray-matter"));
474
- var import_semver = require("semver");
660
+ var import_semver3 = require("semver");
475
661
  var _fileIndexCache = null;
476
662
  var _fileIndexCatalogDir = null;
477
663
  var _matterCache = null;
@@ -603,11 +789,11 @@ var findFileById = async (catalogDir, id, version) => {
603
789
  }
604
790
  const exactMatch = entries.find((e) => e.version === version);
605
791
  if (exactMatch) return exactMatch.path;
606
- const semverRange = (0, import_semver.validRange)(version);
792
+ const semverRange = (0, import_semver3.validRange)(version);
607
793
  if (semverRange) {
608
794
  const match = entries.find((e) => {
609
795
  try {
610
- return (0, import_semver.satisfies)(e.version, semverRange);
796
+ return (0, import_semver3.satisfies)(e.version, semverRange);
611
797
  } catch {
612
798
  return false;
613
799
  }
@@ -693,7 +879,7 @@ var import_path = require("path");
693
879
  var import_gray_matter2 = __toESM(require("gray-matter"));
694
880
  var import_promises = __toESM(require("fs/promises"));
695
881
  var import_node_fs2 = __toESM(require("fs"));
696
- var import_semver2 = require("semver");
882
+ var import_semver4 = require("semver");
697
883
  var import_proper_lockfile = require("proper-lockfile");
698
884
  var import_node_path2 = require("path");
699
885
  var import_node_path3 = __toESM(require("path"));
@@ -759,7 +945,7 @@ var writeResource = async (catalogDir, resource, options = {
759
945
  if (options.versionExistingContent && !exists) {
760
946
  const currentResource = await getResource(catalogDir, resource.id);
761
947
  if (currentResource) {
762
- if ((0, import_semver2.satisfies)(resource.version, `>${currentResource.version}`)) {
948
+ if ((0, import_semver4.satisfies)(resource.version, `>${currentResource.version}`)) {
763
949
  await versionResource(catalogDir, resource.id);
764
950
  } else {
765
951
  throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);
@@ -1433,7 +1619,7 @@ var addMessageToChannel = (directory, collection) => async (id, _message, versio
1433
1619
  // src/messages.ts
1434
1620
  var import_node_path10 = require("path");
1435
1621
  var import_gray_matter4 = __toESM(require("gray-matter"));
1436
- var import_semver3 = require("semver");
1622
+ var import_semver5 = require("semver");
1437
1623
  var getMessageBySchemaPath = (directory) => async (path6, options) => {
1438
1624
  const pathToMessage = (0, import_node_path10.dirname)(path6);
1439
1625
  try {
@@ -1472,9 +1658,9 @@ var getProducersAndConsumersForMessage = (directory) => async (id, version, opti
1472
1658
  for (const service of services) {
1473
1659
  const servicePublishesMessage = service.sends?.some((_message) => {
1474
1660
  if (_message.version) {
1475
- const isServiceUsingSemverRange = (0, import_semver3.validRange)(_message.version);
1661
+ const isServiceUsingSemverRange = (0, import_semver5.validRange)(_message.version);
1476
1662
  if (isServiceUsingSemverRange) {
1477
- return _message.id === message.id && (0, import_semver3.satisfies)(message.version, _message.version);
1663
+ return _message.id === message.id && (0, import_semver5.satisfies)(message.version, _message.version);
1478
1664
  } else {
1479
1665
  return _message.id === message.id && message.version === _message.version;
1480
1666
  }
@@ -1486,9 +1672,9 @@ var getProducersAndConsumersForMessage = (directory) => async (id, version, opti
1486
1672
  });
1487
1673
  const serviceSubscribesToMessage = service.receives?.some((_message) => {
1488
1674
  if (_message.version) {
1489
- const isServiceUsingSemverRange = (0, import_semver3.validRange)(_message.version);
1675
+ const isServiceUsingSemverRange = (0, import_semver5.validRange)(_message.version);
1490
1676
  if (isServiceUsingSemverRange) {
1491
- return _message.id === message.id && (0, import_semver3.satisfies)(message.version, _message.version);
1677
+ return _message.id === message.id && (0, import_semver5.satisfies)(message.version, _message.version);
1492
1678
  } else {
1493
1679
  return _message.id === message.id && message.version === _message.version;
1494
1680
  }
@@ -3016,8 +3202,11 @@ var src_default = (path6) => {
3016
3202
  getCommand: getCommand((0, import_node_path20.join)(path6)),
3017
3203
  getQuery: getQuery((0, import_node_path20.join)(path6)),
3018
3204
  getService: getService((0, import_node_path20.join)(path6)),
3205
+ getServices: getServices((0, import_node_path20.join)(path6)),
3019
3206
  getDomain: getDomain((0, import_node_path20.join)(path6, "domains")),
3020
3207
  getChannel: getChannel((0, import_node_path20.join)(path6)),
3208
+ getChannels: getChannels((0, import_node_path20.join)(path6)),
3209
+ getContainer: getDataStore((0, import_node_path20.join)(path6)),
3021
3210
  getTeam: getTeam((0, import_node_path20.join)(path6, "teams")),
3022
3211
  getUser: getUser((0, import_node_path20.join)(path6, "users"))
3023
3212
  })