@eventcatalog/sdk 2.13.2 → 2.14.1

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.mjs CHANGED
@@ -1,50 +1,533 @@
1
1
  // src/index.ts
2
2
  import { join as join18 } from "path";
3
3
 
4
+ // src/dsl/utils.ts
5
+ import { globSync } from "glob";
6
+ function serializeBaseFields(resource, indent = " ") {
7
+ const lines = [];
8
+ if (resource.version) {
9
+ lines.push(`${indent}version ${resource.version}`);
10
+ }
11
+ if (resource.name) {
12
+ lines.push(`${indent}name "${resource.name}"`);
13
+ }
14
+ if (resource.summary) {
15
+ lines.push(`${indent}summary "${resource.summary.trim()}"`);
16
+ }
17
+ if (resource.owners && resource.owners.length > 0) {
18
+ for (const owner of resource.owners) {
19
+ lines.push(`${indent}owner ${owner}`);
20
+ }
21
+ }
22
+ if (resource.deprecated === true) {
23
+ lines.push(`${indent}deprecated true`);
24
+ }
25
+ if (resource.draft === true) {
26
+ lines.push(`${indent}draft true`);
27
+ }
28
+ return lines.join("\n");
29
+ }
30
+ function buildMessageTypeIndex(catalogDir) {
31
+ const index = /* @__PURE__ */ new Map();
32
+ const types = ["events", "commands", "queries"];
33
+ const typeMap = { events: "event", commands: "command", queries: "query" };
34
+ for (const type of types) {
35
+ const matches = globSync(`**/${type}/*/index.{md,mdx}`, { cwd: catalogDir });
36
+ for (const match of matches) {
37
+ const parts = match.replace(/\\/g, "/").split("/");
38
+ const typeIdx = parts.lastIndexOf(type);
39
+ if (typeIdx !== -1 && typeIdx + 1 < parts.length) {
40
+ const id = parts[typeIdx + 1];
41
+ if (!index.has(id)) index.set(id, typeMap[type]);
42
+ }
43
+ }
44
+ }
45
+ return index;
46
+ }
47
+ function resolveMessageType(catalogDirOrIndex, id) {
48
+ if (typeof catalogDirOrIndex !== "string") {
49
+ return catalogDirOrIndex.get(id);
50
+ }
51
+ if (globSync(`**/events/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return "event";
52
+ if (globSync(`**/commands/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return "command";
53
+ if (globSync(`**/queries/${id}/index.{md,mdx}`, { cwd: catalogDirOrIndex }).length > 0) return "query";
54
+ return void 0;
55
+ }
56
+ function serializeChannelRef(channel) {
57
+ let ref = channel.id;
58
+ if (channel.version) ref += `@${channel.version}`;
59
+ return ref;
60
+ }
61
+ function serializeMessagePointers(items, direction, catalogDirOrIndex, indent = " ") {
62
+ const lines = [];
63
+ for (const item of items) {
64
+ const msgType = resolveMessageType(catalogDirOrIndex, item.id);
65
+ if (!msgType) continue;
66
+ let ref = `${item.id}`;
67
+ if (item.version) ref += `@${item.version}`;
68
+ const channels = direction === "sends" ? item.to : item.from;
69
+ const channelKeyword = direction === "sends" ? "to" : "from";
70
+ if (channels && channels.length === 1) {
71
+ lines.push(`${indent}${direction} ${msgType} ${ref} ${channelKeyword} ${serializeChannelRef(channels[0])}`);
72
+ } else if (channels && channels.length > 1) {
73
+ const channelRefs = channels.map(serializeChannelRef).join(", ");
74
+ lines.push(`${indent}${direction} ${msgType} ${ref} ${channelKeyword} ${channelRefs}`);
75
+ } else {
76
+ lines.push(`${indent}${direction} ${msgType} ${ref}`);
77
+ }
78
+ }
79
+ return lines.join("\n");
80
+ }
81
+
82
+ // src/dsl/message.ts
83
+ function messageToDSL(resource, type) {
84
+ const body = serializeBaseFields(resource);
85
+ if (!body) {
86
+ return `${type} ${resource.id}`;
87
+ }
88
+ return `${type} ${resource.id} {
89
+ ${body}
90
+ }`;
91
+ }
92
+
93
+ // src/dsl/service.ts
94
+ async function serviceToDSL(resource, options, getMessageFn) {
95
+ const { catalogDir, hydrate = false, _seen = /* @__PURE__ */ new Set() } = options;
96
+ const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);
97
+ const parts = [];
98
+ if (hydrate && getMessageFn) {
99
+ const allMessages = [...resource.sends || [], ...resource.receives || []];
100
+ for (const msg of allMessages) {
101
+ const key = `${msg.id}@${msg.version || "latest"}`;
102
+ if (_seen.has(key)) continue;
103
+ _seen.add(key);
104
+ const msgType = resolveMessageType(msgIndex, msg.id);
105
+ if (!msgType) continue;
106
+ const msgResource = await getMessageFn(msg.id, msg.version);
107
+ if (msgResource) {
108
+ parts.push(messageToDSL(msgResource, msgType));
109
+ }
110
+ }
111
+ }
112
+ const lines = [];
113
+ const baseFields = serializeBaseFields(resource);
114
+ if (baseFields) lines.push(baseFields);
115
+ if (resource.sends && resource.sends.length > 0) {
116
+ const sendsStr = serializeMessagePointers(resource.sends, "sends", msgIndex);
117
+ if (sendsStr) lines.push(sendsStr);
118
+ }
119
+ if (resource.receives && resource.receives.length > 0) {
120
+ const recvStr = serializeMessagePointers(resource.receives, "receives", msgIndex);
121
+ if (recvStr) lines.push(recvStr);
122
+ }
123
+ if (resource.writesTo && resource.writesTo.length > 0) {
124
+ for (const container of resource.writesTo) {
125
+ let ref = container.id;
126
+ if (container.version) ref += `@${container.version}`;
127
+ lines.push(` writes-to container ${ref}`);
128
+ }
129
+ }
130
+ if (resource.readsFrom && resource.readsFrom.length > 0) {
131
+ for (const container of resource.readsFrom) {
132
+ let ref = container.id;
133
+ if (container.version) ref += `@${container.version}`;
134
+ lines.push(` reads-from container ${ref}`);
135
+ }
136
+ }
137
+ const body = lines.join("\n");
138
+ parts.push(`service ${resource.id} {
139
+ ${body}
140
+ }`);
141
+ return parts.join("\n\n");
142
+ }
143
+
144
+ // src/dsl/channel.ts
145
+ function channelToDSL(resource) {
146
+ const lines = [];
147
+ if (resource.version) {
148
+ lines.push(` version ${resource.version}`);
149
+ }
150
+ if (resource.name) {
151
+ lines.push(` name "${resource.name}"`);
152
+ }
153
+ if (resource.address) {
154
+ lines.push(` address "${resource.address}"`);
155
+ }
156
+ if (resource.protocols && resource.protocols.length > 0) {
157
+ for (const protocol of resource.protocols) {
158
+ lines.push(` protocol "${protocol}"`);
159
+ }
160
+ }
161
+ if (resource.summary) {
162
+ lines.push(` summary "${resource.summary.trim()}"`);
163
+ }
164
+ if (!lines.length) {
165
+ return `channel ${resource.id}`;
166
+ }
167
+ return `channel ${resource.id} {
168
+ ${lines.join("\n")}
169
+ }`;
170
+ }
171
+
172
+ // src/dsl/owner.ts
173
+ function teamToDSL(team) {
174
+ const lines = [];
175
+ if (team.name) lines.push(` name "${team.name}"`);
176
+ if (team.avatarUrl) lines.push(` avatar "${team.avatarUrl}"`);
177
+ if (team.role) lines.push(` role "${team.role}"`);
178
+ if (team.summary) lines.push(` summary "${team.summary}"`);
179
+ if (team.email) lines.push(` email "${team.email}"`);
180
+ if (team.slackDirectMessageUrl) lines.push(` slack "${team.slackDirectMessageUrl}"`);
181
+ return `team ${team.id} {
182
+ ${lines.join("\n")}
183
+ }`;
184
+ }
185
+ function userToDSL(user) {
186
+ const lines = [];
187
+ if (user.name) lines.push(` name "${user.name}"`);
188
+ if (user.avatarUrl) lines.push(` avatar "${user.avatarUrl}"`);
189
+ if (user.role) lines.push(` role "${user.role}"`);
190
+ if (user.email) lines.push(` email "${user.email}"`);
191
+ if (user.slackDirectMessageUrl) lines.push(` slack "${user.slackDirectMessageUrl}"`);
192
+ return `user ${user.id} {
193
+ ${lines.join("\n")}
194
+ }`;
195
+ }
196
+
197
+ // src/dsl/domain.ts
198
+ async function hydrateOwners(owners, resolvers, seen, parts) {
199
+ if (!owners || !resolvers.getTeam || !resolvers.getUser) return;
200
+ for (const ownerId of owners) {
201
+ const key = `owner:${ownerId}`;
202
+ if (seen.has(key)) continue;
203
+ seen.add(key);
204
+ const team = await resolvers.getTeam(ownerId);
205
+ if (team) {
206
+ parts.push(teamToDSL(team));
207
+ continue;
208
+ }
209
+ const user = await resolvers.getUser(ownerId);
210
+ if (user) {
211
+ parts.push(userToDSL(user));
212
+ }
213
+ }
214
+ }
215
+ async function hydrateChannelsFromMessages(messages, resolvers, seen, parts) {
216
+ if (!resolvers.getChannel) return;
217
+ for (const msg of messages) {
218
+ const channels = msg.to || msg.from;
219
+ if (!channels) continue;
220
+ for (const ch of channels) {
221
+ const key = `channel:${ch.id}@${ch.version || "latest"}`;
222
+ if (seen.has(key)) continue;
223
+ seen.add(key);
224
+ const channel = await resolvers.getChannel(ch.id, ch.version);
225
+ if (channel) {
226
+ parts.push(channelToDSL(channel));
227
+ }
228
+ }
229
+ }
230
+ }
231
+ async function buildDomainBody(resource, options, resolvers, keyword) {
232
+ const { catalogDir, hydrate = false, _seen = /* @__PURE__ */ new Set() } = options;
233
+ const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);
234
+ const topLevelParts = [];
235
+ if (hydrate && resolvers) {
236
+ if (resource.services && resource.services.length > 0 && resolvers.getService) {
237
+ for (const svcRef of resource.services) {
238
+ const svcKey = `service:${svcRef.id}@${svcRef.version || "latest"}`;
239
+ if (_seen.has(svcKey)) continue;
240
+ _seen.add(svcKey);
241
+ const svc = await resolvers.getService(svcRef.id, svcRef.version);
242
+ if (svc) {
243
+ await hydrateOwners(svc.owners, resolvers, _seen, topLevelParts);
244
+ const svcMessages = [...svc.sends || [], ...svc.receives || []];
245
+ await hydrateChannelsFromMessages(svcMessages, resolvers, _seen, topLevelParts);
246
+ const svcDsl = await serviceToDSL(svc, { catalogDir, hydrate: true, _seen, _msgIndex: msgIndex }, resolvers.getMessage);
247
+ topLevelParts.push(svcDsl);
248
+ }
249
+ }
250
+ }
251
+ const domainMessages = [...resource.sends || [], ...resource.receives || []];
252
+ await hydrateChannelsFromMessages(domainMessages, resolvers, _seen, topLevelParts);
253
+ if (resolvers.getMessage) {
254
+ for (const msg of domainMessages) {
255
+ const key = `${msg.id}@${msg.version || "latest"}`;
256
+ if (_seen.has(key)) continue;
257
+ _seen.add(key);
258
+ const msgType = resolveMessageType(msgIndex, msg.id);
259
+ if (!msgType) continue;
260
+ const msgResource = await resolvers.getMessage(msg.id, msg.version);
261
+ if (msgResource) {
262
+ topLevelParts.push(messageToDSL(msgResource, msgType));
263
+ }
264
+ }
265
+ }
266
+ }
267
+ const lines = [];
268
+ const baseFields = serializeBaseFields(resource);
269
+ if (baseFields) lines.push(baseFields);
270
+ if (resource.services && resource.services.length > 0) {
271
+ for (const svc of resource.services) {
272
+ let ref = svc.id;
273
+ if (svc.version) ref += `@${svc.version}`;
274
+ lines.push(` service ${ref}`);
275
+ }
276
+ }
277
+ if (resource.sends && resource.sends.length > 0) {
278
+ const sendsStr = serializeMessagePointers(resource.sends, "sends", msgIndex);
279
+ if (sendsStr) lines.push(sendsStr);
280
+ }
281
+ if (resource.receives && resource.receives.length > 0) {
282
+ const recvStr = serializeMessagePointers(resource.receives, "receives", msgIndex);
283
+ if (recvStr) lines.push(recvStr);
284
+ }
285
+ if (resource.domains && resource.domains.length > 0) {
286
+ if (hydrate && resolvers?.getDomain) {
287
+ for (const subRef of resource.domains) {
288
+ const subKey = `domain:${subRef.id}@${subRef.version || "latest"}`;
289
+ if (_seen.has(subKey)) continue;
290
+ _seen.add(subKey);
291
+ const subDomain = await resolvers.getDomain(subRef.id, subRef.version);
292
+ if (subDomain) {
293
+ await hydrateOwners(subDomain.owners, resolvers, _seen, topLevelParts);
294
+ const sub = await buildDomainBody(
295
+ subDomain,
296
+ { catalogDir, hydrate, _seen, _msgIndex: msgIndex },
297
+ resolvers,
298
+ "subdomain"
299
+ );
300
+ topLevelParts.push(...sub.topLevelParts);
301
+ const indented = sub.block.split("\n").map((line) => ` ${line}`).join("\n");
302
+ lines.push(indented);
303
+ }
304
+ }
305
+ } else {
306
+ for (const sub of resource.domains) {
307
+ let ref = sub.id;
308
+ if (sub.version) ref += `@${sub.version}`;
309
+ lines.push(` subdomain ${ref}`);
310
+ }
311
+ }
312
+ }
313
+ const body = lines.join("\n");
314
+ const block = `${keyword} ${resource.id} {
315
+ ${body}
316
+ }`;
317
+ return { topLevelParts, block };
318
+ }
319
+ async function domainToDSL(resource, options, resolvers) {
320
+ const { catalogDir, hydrate = false, _seen = /* @__PURE__ */ new Set() } = options;
321
+ const msgIndex = options._msgIndex || buildMessageTypeIndex(catalogDir);
322
+ const result = await buildDomainBody(resource, { catalogDir, hydrate, _seen, _msgIndex: msgIndex }, resolvers, "domain");
323
+ const parts = [...result.topLevelParts, result.block];
324
+ return parts.join("\n\n");
325
+ }
326
+
327
+ // src/dsl/index.ts
328
+ function getMessage(resolvers, msgIndex) {
329
+ return async (id, version) => {
330
+ const msgType = resolveMessageType(msgIndex, id);
331
+ if (!msgType) return void 0;
332
+ switch (msgType) {
333
+ case "event":
334
+ return resolvers.getEvent(id, version);
335
+ case "command":
336
+ return resolvers.getCommand(id, version);
337
+ case "query":
338
+ return resolvers.getQuery(id, version);
339
+ }
340
+ };
341
+ }
342
+ async function hydrateChannels(resource, resolvers, seen, parts) {
343
+ const allMessages = [...resource.sends || [], ...resource.receives || []];
344
+ for (const msg of allMessages) {
345
+ const channels = "to" in msg ? msg.to : "from" in msg ? msg.from : void 0;
346
+ if (!channels) continue;
347
+ for (const ch of channels) {
348
+ const key = `channel:${ch.id}@${ch.version || "latest"}`;
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
+ }
355
+ }
356
+ }
357
+ }
358
+ async function hydrateOwners2(owners, resolvers, seen, parts) {
359
+ if (!owners) return;
360
+ for (const ownerId of owners) {
361
+ const key = `owner:${ownerId}`;
362
+ if (seen.has(key)) continue;
363
+ seen.add(key);
364
+ const team = await resolvers.getTeam(ownerId);
365
+ if (team) {
366
+ parts.push(teamToDSL(team));
367
+ continue;
368
+ }
369
+ const user = await resolvers.getUser(ownerId);
370
+ if (user) {
371
+ parts.push(userToDSL(user));
372
+ }
373
+ }
374
+ }
375
+ var toDSL = (catalogDir, resolvers) => async (resource, options) => {
376
+ const resources = Array.isArray(resource) ? resource : [resource];
377
+ const seen = /* @__PURE__ */ new Set();
378
+ const parts = [];
379
+ const msgIndex = buildMessageTypeIndex(catalogDir);
380
+ for (const res of resources) {
381
+ const key = `${options.type}:${res.id}@${res.version || "latest"}`;
382
+ if (seen.has(key)) continue;
383
+ seen.add(key);
384
+ switch (options.type) {
385
+ case "event":
386
+ case "command":
387
+ case "query":
388
+ if (options.hydrate) {
389
+ await hydrateOwners2(res.owners, resolvers, seen, parts);
390
+ }
391
+ parts.push(messageToDSL(res, options.type));
392
+ break;
393
+ case "service":
394
+ if (options.hydrate) {
395
+ await hydrateOwners2(res.owners, resolvers, seen, parts);
396
+ await hydrateChannels(res, resolvers, seen, parts);
397
+ }
398
+ parts.push(
399
+ await serviceToDSL(
400
+ res,
401
+ { catalogDir, hydrate: options.hydrate, _seen: seen, _msgIndex: msgIndex },
402
+ getMessage(resolvers, msgIndex)
403
+ )
404
+ );
405
+ break;
406
+ case "domain":
407
+ if (options.hydrate) {
408
+ await hydrateOwners2(res.owners, resolvers, seen, parts);
409
+ }
410
+ parts.push(
411
+ await domainToDSL(
412
+ res,
413
+ { catalogDir, hydrate: options.hydrate, _seen: seen, _msgIndex: msgIndex },
414
+ {
415
+ getService: resolvers.getService,
416
+ getDomain: resolvers.getDomain,
417
+ getMessage: getMessage(resolvers, msgIndex),
418
+ getChannel: resolvers.getChannel,
419
+ getTeam: resolvers.getTeam,
420
+ getUser: resolvers.getUser
421
+ }
422
+ )
423
+ );
424
+ break;
425
+ }
426
+ }
427
+ return parts.join("\n\n");
428
+ };
429
+
4
430
  // src/events.ts
5
431
  import fs2 from "fs/promises";
6
432
  import { join as join3 } from "path";
7
433
 
8
434
  // src/internal/utils.ts
9
- import { globSync } from "glob";
435
+ import { globSync as globSync2 } from "glob";
10
436
  import fsSync from "fs";
11
437
  import { copy } from "fs-extra";
12
438
  import { join, dirname, normalize, resolve, relative } from "path";
13
439
  import matter from "gray-matter";
14
440
  import { satisfies, validRange } from "semver";
441
+ var _fileIndexCache = null;
442
+ var _fileIndexCatalogDir = null;
443
+ var _matterCache = null;
444
+ var _fileIndexMtimeMs = 0;
445
+ function buildFileCache(catalogDir) {
446
+ const files = globSync2("**/index.{md,mdx}", {
447
+ cwd: catalogDir,
448
+ ignore: ["node_modules/**"],
449
+ absolute: true,
450
+ nodir: true
451
+ }).map(normalize);
452
+ const index = /* @__PURE__ */ new Map();
453
+ const matterResults = /* @__PURE__ */ new Map();
454
+ for (const file of files) {
455
+ const content = fsSync.readFileSync(file, "utf-8");
456
+ const parsed = matter(content);
457
+ matterResults.set(file, parsed);
458
+ const id = parsed.data.id;
459
+ if (!id) continue;
460
+ const version = parsed.data.version || "";
461
+ const isVersioned = file.includes("versioned");
462
+ const entry = { path: file, id, version: String(version), isVersioned };
463
+ const existing = index.get(id);
464
+ if (existing) {
465
+ existing.push(entry);
466
+ } else {
467
+ index.set(id, [entry]);
468
+ }
469
+ }
470
+ _fileIndexCache = index;
471
+ _fileIndexCatalogDir = catalogDir;
472
+ _matterCache = matterResults;
473
+ try {
474
+ _fileIndexMtimeMs = fsSync.statSync(catalogDir).mtimeMs;
475
+ } catch {
476
+ _fileIndexMtimeMs = 0;
477
+ }
478
+ }
479
+ function ensureFileCache(catalogDir) {
480
+ if (!_fileIndexCache || _fileIndexCatalogDir !== catalogDir) {
481
+ buildFileCache(catalogDir);
482
+ return;
483
+ }
484
+ try {
485
+ const currentMtime = fsSync.statSync(catalogDir).mtimeMs;
486
+ if (currentMtime !== _fileIndexMtimeMs) {
487
+ buildFileCache(catalogDir);
488
+ }
489
+ } catch {
490
+ buildFileCache(catalogDir);
491
+ }
492
+ }
493
+ function invalidateFileCache() {
494
+ _fileIndexCache = null;
495
+ _fileIndexCatalogDir = null;
496
+ _matterCache = null;
497
+ }
498
+ function cachedMatterRead(filePath) {
499
+ if (_matterCache) {
500
+ const cached = _matterCache.get(filePath);
501
+ if (cached) return cached;
502
+ }
503
+ return matter.read(filePath);
504
+ }
15
505
  var versionExists = async (catalogDir, id, version) => {
16
- const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
17
- const matchedFiles = await searchFilesForId(files, id, version) || [];
18
- return matchedFiles.length > 0;
506
+ ensureFileCache(catalogDir);
507
+ const entries = _fileIndexCache.get(id);
508
+ if (!entries) return false;
509
+ return entries.some((e) => e.version === version);
19
510
  };
20
511
  var findFileById = async (catalogDir, id, version) => {
21
- const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
22
- const matchedFiles = await searchFilesForId(files, id) || [];
23
- const latestVersion = matchedFiles.find((path6) => !path6.includes("versioned"));
24
- if (!version) {
25
- return latestVersion;
26
- }
27
- const parsedFiles = matchedFiles.map((path6) => {
28
- const { data } = matter.read(path6);
29
- return { ...data, path: path6 };
30
- });
31
- if (version === "latest") {
32
- return latestVersion;
33
- }
34
- const exactMatch = parsedFiles.find((c) => c.version === version);
35
- if (exactMatch) {
36
- return exactMatch.path;
512
+ ensureFileCache(catalogDir);
513
+ const entries = _fileIndexCache.get(id);
514
+ if (!entries || entries.length === 0) return void 0;
515
+ const latestEntry = entries.find((e) => !e.isVersioned);
516
+ if (!version || version === "latest") {
517
+ return latestEntry?.path;
37
518
  }
519
+ const exactMatch = entries.find((e) => e.version === version);
520
+ if (exactMatch) return exactMatch.path;
38
521
  const semverRange = validRange(version);
39
522
  if (semverRange) {
40
- const match = parsedFiles.filter((c) => {
523
+ const match = entries.find((e) => {
41
524
  try {
42
- return satisfies(c.version, semverRange);
43
- } catch (error) {
525
+ return satisfies(e.version, semverRange);
526
+ } catch {
44
527
  return false;
45
528
  }
46
529
  });
47
- return match.length > 0 ? match[0].path : void 0;
530
+ return match?.path;
48
531
  }
49
532
  return void 0;
50
533
  };
@@ -57,7 +540,7 @@ var getFiles = async (pattern, ignore = "") => {
57
540
  let relativePattern = relative(absoluteBaseDir, normalizedInputPattern);
58
541
  relativePattern = relativePattern.replace(/\\/g, "/");
59
542
  const ignoreList = Array.isArray(ignore) ? ignore : [ignore];
60
- const files = globSync(relativePattern, {
543
+ const files = globSync2(relativePattern, {
61
544
  cwd: absoluteBaseDir,
62
545
  ignore: ["node_modules/**", ...ignoreList],
63
546
  absolute: true,
@@ -160,6 +643,7 @@ var versionResource = async (catalogDir, id) => {
160
643
  })
161
644
  );
162
645
  });
646
+ invalidateFileCache();
163
647
  };
164
648
  var writeResource = async (catalogDir, resource, options = {
165
649
  path: "",
@@ -199,6 +683,7 @@ var writeResource = async (catalogDir, resource, options = {
199
683
  }
200
684
  const document = matter2.stringify(markdown.trim(), frontmatter);
201
685
  fsSync2.writeFileSync(lockPath, document);
686
+ invalidateFileCache();
202
687
  } finally {
203
688
  await unlock(lockPath).catch(() => {
204
689
  });
@@ -208,7 +693,7 @@ var getResource = async (catalogDir, id, version, options, filePath) => {
208
693
  const attachSchema = options?.attachSchema || false;
209
694
  const file = filePath || (id ? await findFileById(catalogDir, id, version) : void 0);
210
695
  if (!file || !fsSync2.existsSync(file)) return;
211
- const { data, content } = matter2.read(file);
696
+ const { data, content } = cachedMatterRead(file);
212
697
  if (attachSchema && data?.schemaPath) {
213
698
  const resourceDirectory = dirname2(file);
214
699
  const pathToSchema = join2(resourceDirectory, data.schemaPath);
@@ -259,7 +744,7 @@ var getResources = async (catalogDir, {
259
744
  const files = await getFiles(filePattern, [ignoreList, ...ignore]);
260
745
  if (files.length === 0) return;
261
746
  return files.map((file) => {
262
- const { data, content } = matter2.read(file);
747
+ const { data, content } = cachedMatterRead(file);
263
748
  if (attachSchema && data?.schemaPath) {
264
749
  const resourceDirectory = dirname2(file);
265
750
  const pathToSchema = join2(resourceDirectory, data.schemaPath);
@@ -300,6 +785,7 @@ var rmResourceById = async (catalogDir, id, version, options) => {
300
785
  })
301
786
  );
302
787
  }
788
+ invalidateFileCache();
303
789
  };
304
790
  var waitForFileRemoval = async (path6, maxRetries = 50, delay = 10) => {
305
791
  for (let i = 0; i < maxRetries; i++) {
@@ -365,6 +851,7 @@ var writeEventToService = (directory) => async (event, service, options = { path
365
851
  };
366
852
  var rmEvent = (directory) => async (path6) => {
367
853
  await fs2.rm(join3(directory, path6), { recursive: true });
854
+ invalidateFileCache();
368
855
  };
369
856
  var rmEventById = (directory) => async (id, version, persistFiles) => {
370
857
  await rmResourceById(directory, id, version, { type: "event", persistFiles });
@@ -401,6 +888,7 @@ var writeCommandToService = (directory) => async (command, service, options = {
401
888
  };
402
889
  var rmCommand = (directory) => async (path6) => {
403
890
  await fs3.rm(join4(directory, path6), { recursive: true });
891
+ invalidateFileCache();
404
892
  };
405
893
  var rmCommandById = (directory) => async (id, version, persistFiles) => rmResourceById(directory, id, version, { type: "command", persistFiles });
406
894
  var versionCommand = (directory) => async (id) => versionResource(directory, id);
@@ -435,6 +923,7 @@ var writeQueryToService = (directory) => async (query, service, options = { path
435
923
  };
436
924
  var rmQuery = (directory) => async (path6) => {
437
925
  await fs4.rm(join5(directory, path6), { recursive: true });
926
+ invalidateFileCache();
438
927
  };
439
928
  var rmQueryById = (directory) => async (id, version, persistFiles) => {
440
929
  await rmResourceById(directory, id, version, { type: "query", persistFiles });
@@ -459,7 +948,18 @@ var getServiceByPath = (directory) => async (path6) => {
459
948
  };
460
949
  var getServices = (directory) => async (options) => getResources(directory, {
461
950
  type: "services",
462
- ignore: ["**/events/**", "**/commands/**", "**/queries/**", "**/entities/**", "**/subdomains/**/entities/**"],
951
+ ignore: [
952
+ "**/events/**",
953
+ "**/commands/**",
954
+ "**/queries/**",
955
+ "**/entities/**",
956
+ "**/channels/**",
957
+ "**/containers/**",
958
+ "**/data-products/**",
959
+ "**/data-stores/**",
960
+ "**/flows/**",
961
+ "**/subdomains/**/entities/**"
962
+ ],
463
963
  ...options
464
964
  });
465
965
  var writeService = (directory) => async (service, options = {
@@ -489,6 +989,7 @@ var writeServiceToDomain = (directory) => async (service, domain, options = { pa
489
989
  var versionService = (directory) => async (id) => versionResource(directory, id);
490
990
  var rmService = (directory) => async (path6) => {
491
991
  await fs5.rm(join6(directory, path6), { recursive: true });
992
+ invalidateFileCache();
492
993
  };
493
994
  var rmServiceById = (directory) => async (id, version, persistFiles) => {
494
995
  await rmResourceById(directory, id, version, { type: "service", persistFiles });
@@ -665,6 +1166,7 @@ var writeDomain = (directory) => async (domain, options = {
665
1166
  var versionDomain = (directory) => async (id) => versionResource(directory, id);
666
1167
  var rmDomain = (directory) => async (path6) => {
667
1168
  await fs6.rm(join7(directory, path6), { recursive: true });
1169
+ invalidateFileCache();
668
1170
  };
669
1171
  var rmDomainById = (directory) => async (id, version, persistFiles) => rmResourceById(directory, id, version, { type: "domain", persistFiles });
670
1172
  var addFileToDomain = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
@@ -796,6 +1298,7 @@ var getChannels = (directory) => async (options) => getResources(directory, { ty
796
1298
  var writeChannel = (directory) => async (channel, options = { path: "" }) => writeResource(directory, { ...channel }, { ...options, type: "channel" });
797
1299
  var rmChannel = (directory) => async (path6) => {
798
1300
  await fs7.rm(join8(directory, path6), { recursive: true });
1301
+ invalidateFileCache();
799
1302
  };
800
1303
  var rmChannelById = (directory) => async (id, version, persistFiles) => rmResourceById(directory, id, version, { type: "channel", persistFiles });
801
1304
  var versionChannel = (directory) => async (id) => versionResource(directory, id);
@@ -822,8 +1325,8 @@ var addMessageToChannel = (directory, collection) => async (id, _message, versio
822
1325
  writeMessage: writeQuery
823
1326
  }
824
1327
  };
825
- const { getMessage, rmMessageById, writeMessage } = functions[collection];
826
- const message = await getMessage(directory)(_message.id, _message.version);
1328
+ const { getMessage: getMessage2, rmMessageById, writeMessage } = functions[collection];
1329
+ const message = await getMessage2(directory)(_message.id, _message.version);
827
1330
  const messagePath = await getResourcePath(directory, _message.id, _message.version);
828
1331
  const extension = extname2(messagePath?.fullPath || "");
829
1332
  if (!message) throw new Error(`Message ${_message.id} with version ${_message.version} not found`);
@@ -968,10 +1471,12 @@ var writeCustomDoc = (directory) => async (customDoc, options = { path: "" }) =>
968
1471
  fsSync4.mkdirSync(path3.dirname(fullPath), { recursive: true });
969
1472
  const document = matter5.stringify(customDoc.markdown.trim(), rest);
970
1473
  fsSync4.writeFileSync(fullPath, document);
1474
+ invalidateFileCache();
971
1475
  };
972
1476
  var rmCustomDoc = (directory) => async (filePath) => {
973
1477
  const withExtension = filePath.endsWith(".mdx") ? filePath : `${filePath}.mdx`;
974
1478
  await fs8.rm(join10(directory, withExtension), { recursive: true });
1479
+ invalidateFileCache();
975
1480
  };
976
1481
 
977
1482
  // src/teams.ts
@@ -1023,9 +1528,11 @@ var writeUser = (catalogDir) => async (user, options = {}) => {
1023
1528
  const document = matter6.stringify(markdown, frontmatter);
1024
1529
  fsSync5.mkdirSync(join11(catalogDir, ""), { recursive: true });
1025
1530
  fsSync5.writeFileSync(join11(catalogDir, "", `${resource.id}.mdx`), document);
1531
+ invalidateFileCache();
1026
1532
  };
1027
1533
  var rmUserById = (catalogDir) => async (id) => {
1028
1534
  fsSync5.rmSync(join11(catalogDir, `${id}.mdx`), { recursive: true });
1535
+ invalidateFileCache();
1029
1536
  };
1030
1537
 
1031
1538
  // src/teams.ts
@@ -1065,9 +1572,11 @@ var writeTeam = (catalogDir) => async (team, options = {}) => {
1065
1572
  const document = matter7.stringify(markdown, frontmatter);
1066
1573
  fsSync6.mkdirSync(join12(catalogDir, ""), { recursive: true });
1067
1574
  fsSync6.writeFileSync(join12(catalogDir, "", `${resource.id}.mdx`), document);
1575
+ invalidateFileCache();
1068
1576
  };
1069
1577
  var rmTeamById = (catalogDir) => async (id) => {
1070
1578
  await fs9.rm(join12(catalogDir, `${id}.mdx`), { recursive: true });
1579
+ invalidateFileCache();
1071
1580
  };
1072
1581
  var getOwnersForResource = (catalogDir) => async (id, version) => {
1073
1582
  const resource = await getResource(catalogDir, id, version);
@@ -1197,6 +1706,7 @@ var writeEntity = (directory) => async (entity, options = {
1197
1706
  }) => writeResource(directory, { ...entity }, { ...options, type: "entity" });
1198
1707
  var rmEntity = (directory) => async (path6) => {
1199
1708
  await fs11.rm(join14(directory, path6), { recursive: true });
1709
+ invalidateFileCache();
1200
1710
  };
1201
1711
  var rmEntityById = (directory) => async (id, version, persistFiles) => {
1202
1712
  await rmResourceById(directory, id, version, { type: "entity", persistFiles });
@@ -1220,6 +1730,7 @@ var writeContainer = (directory) => async (data, options = {
1220
1730
  var versionContainer = (directory) => async (id) => versionResource(directory, id);
1221
1731
  var rmContainer = (directory) => async (path6) => {
1222
1732
  await fs12.rm(join15(directory, path6), { recursive: true });
1733
+ invalidateFileCache();
1223
1734
  };
1224
1735
  var rmContainerById = (directory) => async (id, version, persistFiles) => {
1225
1736
  await rmResourceById(directory, id, version, { type: "container", persistFiles });
@@ -1267,6 +1778,7 @@ var writeDataProductToDomain = (directory) => async (dataProduct, domain, option
1267
1778
  };
1268
1779
  var rmDataProduct = (directory) => async (path6) => {
1269
1780
  await fs13.rm(join16(directory, path6), { recursive: true });
1781
+ invalidateFileCache();
1270
1782
  };
1271
1783
  var rmDataProductById = (directory) => async (id, version, persistFiles) => {
1272
1784
  await rmResourceById(directory, id, version, { type: "data-product", persistFiles });
@@ -1290,6 +1802,7 @@ var writeDiagram = (directory) => async (diagram, options = {
1290
1802
  }) => writeResource(directory, { ...diagram }, { ...options, type: "diagram" });
1291
1803
  var rmDiagram = (directory) => async (path6) => {
1292
1804
  await fs14.rm(join17(directory, path6), { recursive: true });
1805
+ invalidateFileCache();
1293
1806
  };
1294
1807
  var rmDiagramById = (directory) => async (id, version, persistFiles) => {
1295
1808
  await rmResourceById(directory, id, version, { type: "diagram", persistFiles });
@@ -2394,7 +2907,35 @@ var src_default = (path6) => {
2394
2907
  * @param version - Optional version of the diagram to add the file to
2395
2908
  * @returns
2396
2909
  */
2397
- addFileToDiagram: addFileToDiagram(join18(path6))
2910
+ addFileToDiagram: addFileToDiagram(join18(path6)),
2911
+ /**
2912
+ * ================================
2913
+ * DSL
2914
+ * ================================
2915
+ */
2916
+ /**
2917
+ * Converts catalog resources to EventCatalog DSL (.ec) format strings.
2918
+ *
2919
+ * @param resource - A resource or array of resources to convert
2920
+ * @param options - Options including type ('event'|'command'|'query'|'service'|'domain') and optional hydrate flag
2921
+ * @returns A DSL string representation
2922
+ *
2923
+ * @example
2924
+ * ```ts
2925
+ * const dsl = await sdk.toDSL(event, { type: 'event' });
2926
+ * const dsl = await sdk.toDSL(services, { type: 'service', hydrate: true });
2927
+ * ```
2928
+ */
2929
+ toDSL: toDSL(join18(path6), {
2930
+ getEvent: getEvent(join18(path6)),
2931
+ getCommand: getCommand(join18(path6)),
2932
+ getQuery: getQuery(join18(path6)),
2933
+ getService: getService(join18(path6)),
2934
+ getDomain: getDomain(join18(path6, "domains")),
2935
+ getChannel: getChannel(join18(path6)),
2936
+ getTeam: getTeam(join18(path6, "teams")),
2937
+ getUser: getUser(join18(path6, "users"))
2938
+ })
2398
2939
  };
2399
2940
  };
2400
2941
  export {