@eventcatalog/sdk 2.2.1 → 2.2.3

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.
@@ -0,0 +1,1414 @@
1
+ // src/eventcatalog.ts
2
+ import fs10 from "fs";
3
+ import path3, { join as join13 } from "node:path";
4
+
5
+ // src/index.ts
6
+ import { join as join12 } from "node:path";
7
+
8
+ // src/events.ts
9
+ import fs2 from "node:fs/promises";
10
+ import { join as join3 } from "node:path";
11
+
12
+ // src/internal/utils.ts
13
+ import { globSync } from "glob";
14
+ import fsSync from "node:fs";
15
+ import { copy } from "fs-extra";
16
+ import { join } from "node:path";
17
+ import matter from "gray-matter";
18
+ import { satisfies, validRange, valid } from "semver";
19
+ var versionExists = async (catalogDir, id, version) => {
20
+ const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
21
+ const matchedFiles = await searchFilesForId(files, id, version) || [];
22
+ return matchedFiles.length > 0;
23
+ };
24
+ var findFileById = async (catalogDir, id, version) => {
25
+ const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
26
+ const matchedFiles = await searchFilesForId(files, id) || [];
27
+ const latestVersion = matchedFiles.find((path4) => !path4.includes("versioned"));
28
+ if (!version) {
29
+ return latestVersion;
30
+ }
31
+ const parsedFiles = matchedFiles.map((path4) => {
32
+ const { data } = matter.read(path4);
33
+ return { ...data, path: path4 };
34
+ });
35
+ const semverRange = validRange(version);
36
+ if (semverRange && valid(version)) {
37
+ const match2 = parsedFiles.filter((c) => satisfies(c.version, semverRange));
38
+ return match2.length > 0 ? match2[0].path : void 0;
39
+ }
40
+ const sorted = parsedFiles.sort((a, b) => {
41
+ return a.version.localeCompare(b.version);
42
+ });
43
+ const match = sorted.length > 0 ? [sorted[sorted.length - 1]] : [];
44
+ if (match.length > 0) {
45
+ return match[0].path;
46
+ }
47
+ };
48
+ var getFiles = async (pattern, ignore = "") => {
49
+ try {
50
+ const ignoreList = Array.isArray(ignore) ? ignore : [ignore];
51
+ const files = globSync(pattern, { ignore: ["node_modules/**", ...ignoreList] });
52
+ return files;
53
+ } catch (error) {
54
+ throw new Error(`Error finding files: ${error}`);
55
+ }
56
+ };
57
+ var readMdxFile = async (path4) => {
58
+ const { data } = matter.read(path4);
59
+ const { markdown, ...frontmatter } = data;
60
+ return { ...frontmatter, markdown };
61
+ };
62
+ var searchFilesForId = async (files, id, version) => {
63
+ const idRegex = new RegExp(`^id:\\s*(['"]|>-)?\\s*${id}['"]?\\s*$`, "m");
64
+ const versionRegex = new RegExp(`^version:\\s*['"]?${version}['"]?\\s*$`, "m");
65
+ const matches = files.map((file) => {
66
+ const content = fsSync.readFileSync(file, "utf-8");
67
+ const hasIdMatch = content.match(idRegex);
68
+ if (version && !content.match(versionRegex)) {
69
+ return void 0;
70
+ }
71
+ if (hasIdMatch) {
72
+ return file;
73
+ }
74
+ });
75
+ return matches.filter(Boolean).filter((file) => file !== void 0);
76
+ };
77
+ var copyDir = async (catalogDir, source, target, filter) => {
78
+ const tmpDirectory = join(catalogDir, "tmp");
79
+ fsSync.mkdirSync(tmpDirectory, { recursive: true });
80
+ await copy(source, tmpDirectory, {
81
+ overwrite: true,
82
+ filter
83
+ });
84
+ await copy(tmpDirectory, target, {
85
+ overwrite: true,
86
+ filter
87
+ });
88
+ fsSync.rmSync(tmpDirectory, { recursive: true });
89
+ };
90
+ var uniqueVersions = (messages) => {
91
+ const uniqueSet = /* @__PURE__ */ new Set();
92
+ return messages.filter((message) => {
93
+ const key = `${message.id}-${message.version}`;
94
+ if (!uniqueSet.has(key)) {
95
+ uniqueSet.add(key);
96
+ return true;
97
+ }
98
+ return false;
99
+ });
100
+ };
101
+
102
+ // src/internal/resources.ts
103
+ import { dirname, join as join2 } from "path";
104
+ import matter2 from "gray-matter";
105
+ import fs from "node:fs/promises";
106
+ import fsSync2 from "node:fs";
107
+ import { satisfies as satisfies2 } from "semver";
108
+ import { lock, unlock } from "proper-lockfile";
109
+ var versionResource = async (catalogDir, id) => {
110
+ const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
111
+ const matchedFiles = await searchFilesForId(files, id);
112
+ if (matchedFiles.length === 0) {
113
+ throw new Error(`No resource found with id: ${id}`);
114
+ }
115
+ const file = matchedFiles[0];
116
+ const sourceDirectory = dirname(file);
117
+ const { data: { version = "0.0.1" } = {} } = matter2.read(file);
118
+ const targetDirectory = getVersionedDirectory(sourceDirectory, version);
119
+ fsSync2.mkdirSync(targetDirectory, { recursive: true });
120
+ await copyDir(catalogDir, sourceDirectory, targetDirectory, (src) => {
121
+ return !src.includes("versioned");
122
+ });
123
+ await fs.readdir(sourceDirectory).then(async (resourceFiles) => {
124
+ await Promise.all(
125
+ resourceFiles.map(async (file2) => {
126
+ if (file2 !== "versioned") {
127
+ fsSync2.rmSync(join2(sourceDirectory, file2), { recursive: true });
128
+ }
129
+ })
130
+ );
131
+ });
132
+ };
133
+ var writeResource = async (catalogDir, resource, options = {
134
+ path: "",
135
+ type: "",
136
+ override: false,
137
+ versionExistingContent: false
138
+ }) => {
139
+ const path4 = options.path || `/${resource.id}`;
140
+ const fullPath = join2(catalogDir, path4);
141
+ fsSync2.mkdirSync(fullPath, { recursive: true });
142
+ const lockPath = join2(fullPath, "index.mdx");
143
+ if (!fsSync2.existsSync(lockPath)) {
144
+ fsSync2.writeFileSync(lockPath, "");
145
+ }
146
+ try {
147
+ await lock(lockPath, {
148
+ retries: 5,
149
+ stale: 1e4
150
+ // 10 seconds
151
+ });
152
+ const exists = await versionExists(catalogDir, resource.id, resource.version);
153
+ if (exists && !options.override) {
154
+ throw new Error(`Failed to write ${resource.id} (${options.type}) as the version ${resource.version} already exists`);
155
+ }
156
+ const { markdown, ...frontmatter } = resource;
157
+ if (options.versionExistingContent && !exists) {
158
+ const currentResource = await getResource(catalogDir, resource.id);
159
+ if (currentResource) {
160
+ if (satisfies2(resource.version, `>${currentResource.version}`)) {
161
+ await versionResource(catalogDir, resource.id);
162
+ } else {
163
+ throw new Error(`New version ${resource.version} is not greater than current version ${currentResource.version}`);
164
+ }
165
+ }
166
+ }
167
+ const document = matter2.stringify(markdown.trim(), frontmatter);
168
+ fsSync2.writeFileSync(lockPath, document);
169
+ } finally {
170
+ await unlock(lockPath).catch(() => {
171
+ });
172
+ }
173
+ };
174
+ var getResource = async (catalogDir, id, version, options) => {
175
+ const file = await findFileById(catalogDir, id, version);
176
+ if (!file) return;
177
+ const { data, content } = matter2.read(file);
178
+ return {
179
+ ...data,
180
+ markdown: content.trim()
181
+ };
182
+ };
183
+ var getResourcePath = async (catalogDir, id, version) => {
184
+ const file = await findFileById(catalogDir, id, version);
185
+ if (!file) return;
186
+ return {
187
+ fullPath: file,
188
+ relativePath: file.replace(catalogDir, ""),
189
+ directory: dirname(file.replace(catalogDir, ""))
190
+ };
191
+ };
192
+ var getResources = async (catalogDir, {
193
+ type,
194
+ latestOnly = false,
195
+ ignore = [],
196
+ pattern = ""
197
+ }) => {
198
+ const ignoreList = latestOnly ? `**/versioned/**` : "";
199
+ const filePattern = pattern || `${catalogDir}/**/${type}/**/index.{md,mdx}`;
200
+ const files = await getFiles(filePattern, [ignoreList, ...ignore]);
201
+ if (files.length === 0) return;
202
+ return files.map((file) => {
203
+ const { data, content } = matter2.read(file);
204
+ return {
205
+ ...data,
206
+ markdown: content.trim()
207
+ };
208
+ });
209
+ };
210
+ var rmResourceById = async (catalogDir, id, version, options) => {
211
+ const files = await getFiles(`${catalogDir}/**/index.{md,mdx}`);
212
+ const matchedFiles = await searchFilesForId(files, id, version);
213
+ if (matchedFiles.length === 0) {
214
+ throw new Error(`No ${options?.type || "resource"} found with id: ${id}`);
215
+ }
216
+ if (options?.persistFiles) {
217
+ await Promise.all(
218
+ matchedFiles.map(async (file) => {
219
+ await fs.rm(file, { recursive: true });
220
+ })
221
+ );
222
+ } else {
223
+ await Promise.all(
224
+ matchedFiles.map(async (file) => {
225
+ const directory = dirname(file);
226
+ await fs.rm(directory, { recursive: true, force: true });
227
+ })
228
+ );
229
+ }
230
+ };
231
+ var addFileToResource = async (catalogDir, id, file, version) => {
232
+ const pathToResource = await findFileById(catalogDir, id, version);
233
+ if (!pathToResource) throw new Error("Cannot find directory to write file to");
234
+ fsSync2.writeFileSync(join2(dirname(pathToResource), file.fileName), file.content);
235
+ };
236
+ var getFileFromResource = async (catalogDir, id, file, version) => {
237
+ const pathToResource = await findFileById(catalogDir, id, version);
238
+ if (!pathToResource) throw new Error("Cannot find directory of resource");
239
+ const exists = await fs.access(join2(dirname(pathToResource), file.fileName)).then(() => true).catch(() => false);
240
+ if (!exists) throw new Error(`File ${file.fileName} does not exist in resource ${id} v(${version})`);
241
+ return fsSync2.readFileSync(join2(dirname(pathToResource), file.fileName), "utf-8");
242
+ };
243
+ var getVersionedDirectory = (sourceDirectory, version) => {
244
+ return join2(sourceDirectory, "versioned", version);
245
+ };
246
+
247
+ // src/events.ts
248
+ var getEvent = (directory) => async (id, version) => getResource(directory, id, version, { type: "event" });
249
+ var getEvents = (directory) => async (options) => getResources(directory, { type: "events", ...options });
250
+ var writeEvent = (directory) => async (event, options = { path: "", override: false }) => writeResource(directory, { ...event }, { ...options, type: "event" });
251
+ var writeEventToService = (directory) => async (event, service, options = { path: "" }) => {
252
+ const resourcePath = await getResourcePath(directory, service.id, service.version);
253
+ if (!resourcePath) {
254
+ throw new Error("Service not found");
255
+ }
256
+ let pathForEvent = service.version && service.version !== "latest" ? `${resourcePath.directory}/versioned/${service.version}/events` : `${resourcePath.directory}/events`;
257
+ pathForEvent = join3(pathForEvent, event.id);
258
+ await writeResource(directory, { ...event }, { ...options, path: pathForEvent, type: "event" });
259
+ };
260
+ var rmEvent = (directory) => async (path4) => {
261
+ await fs2.rm(join3(directory, path4), { recursive: true });
262
+ };
263
+ var rmEventById = (directory) => async (id, version, persistFiles) => {
264
+ await rmResourceById(directory, id, version, { type: "event", persistFiles });
265
+ };
266
+ var versionEvent = (directory) => async (id) => versionResource(directory, id);
267
+ var addFileToEvent = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
268
+ var addSchemaToEvent = (directory) => async (id, schema, version) => {
269
+ await addFileToEvent(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);
270
+ };
271
+ var eventHasVersion = (directory) => async (id, version) => {
272
+ const file = await findFileById(directory, id, version);
273
+ return !!file;
274
+ };
275
+
276
+ // src/commands.ts
277
+ import fs3 from "node:fs/promises";
278
+ import { join as join4 } from "node:path";
279
+ var getCommand = (directory) => async (id, version) => getResource(directory, id, version, { type: "command" });
280
+ var getCommands = (directory) => async (options) => getResources(directory, { type: "commands", ...options });
281
+ var writeCommand = (directory) => async (command, options = { path: "" }) => writeResource(directory, { ...command }, { ...options, type: "command" });
282
+ var writeCommandToService = (directory) => async (command, service, options = { path: "" }) => {
283
+ const resourcePath = await getResourcePath(directory, service.id, service.version);
284
+ if (!resourcePath) {
285
+ throw new Error("Service not found");
286
+ }
287
+ let pathForCommand = service.version && service.version !== "latest" ? `${resourcePath.directory}/versioned/${service.version}/commands` : `${resourcePath.directory}/commands`;
288
+ pathForCommand = join4(pathForCommand, command.id);
289
+ await writeResource(directory, { ...command }, { ...options, path: pathForCommand, type: "command" });
290
+ };
291
+ var rmCommand = (directory) => async (path4) => {
292
+ await fs3.rm(join4(directory, path4), { recursive: true });
293
+ };
294
+ var rmCommandById = (directory) => async (id, version, persistFiles) => rmResourceById(directory, id, version, { type: "command", persistFiles });
295
+ var versionCommand = (directory) => async (id) => versionResource(directory, id);
296
+ var addFileToCommand = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
297
+ var addSchemaToCommand = (directory) => async (id, schema, version) => {
298
+ await addFileToCommand(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);
299
+ };
300
+ var commandHasVersion = (directory) => async (id, version) => {
301
+ const file = await findFileById(directory, id, version);
302
+ return !!file;
303
+ };
304
+
305
+ // src/queries.ts
306
+ import fs4 from "node:fs/promises";
307
+ import { join as join5 } from "node:path";
308
+ var getQuery = (directory) => async (id, version) => getResource(directory, id, version, { type: "query" });
309
+ var writeQuery = (directory) => async (query, options = { path: "" }) => writeResource(directory, { ...query }, { ...options, type: "query" });
310
+ var getQueries = (directory) => async (options) => getResources(directory, { type: "queries", ...options });
311
+ var writeQueryToService = (directory) => async (query, service, options = { path: "" }) => {
312
+ const resourcePath = await getResourcePath(directory, service.id, service.version);
313
+ if (!resourcePath) {
314
+ throw new Error("Service not found");
315
+ }
316
+ let pathForQuery = service.version && service.version !== "latest" ? `${resourcePath.directory}/versioned/${service.version}/queries` : `${resourcePath.directory}/queries`;
317
+ pathForQuery = join5(pathForQuery, query.id);
318
+ await writeResource(directory, { ...query }, { ...options, path: pathForQuery, type: "query" });
319
+ };
320
+ var rmQuery = (directory) => async (path4) => {
321
+ await fs4.rm(join5(directory, path4), { recursive: true });
322
+ };
323
+ var rmQueryById = (directory) => async (id, version, persistFiles) => {
324
+ await rmResourceById(directory, id, version, { type: "query", persistFiles });
325
+ };
326
+ var versionQuery = (directory) => async (id) => versionResource(directory, id);
327
+ var addFileToQuery = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
328
+ var addSchemaToQuery = (directory) => async (id, schema, version) => {
329
+ await addFileToQuery(directory)(id, { content: schema.schema, fileName: schema.fileName }, version);
330
+ };
331
+ var queryHasVersion = (directory) => async (id, version) => {
332
+ const file = await findFileById(directory, id, version);
333
+ return !!file;
334
+ };
335
+
336
+ // src/services.ts
337
+ import fs5 from "node:fs/promises";
338
+ import { join as join6, dirname as dirname3 } from "node:path";
339
+ var getService = (directory) => async (id, version) => getResource(directory, id, version, { type: "service" });
340
+ var getServices = (directory) => async (options) => getResources(directory, {
341
+ type: "services",
342
+ ignore: ["**/events/**", "**/commands/**", "**/queries/**"],
343
+ ...options
344
+ });
345
+ var writeService = (directory) => async (service, options = { path: "" }) => {
346
+ const resource = { ...service };
347
+ if (Array.isArray(service.sends)) {
348
+ resource.sends = uniqueVersions(service.sends);
349
+ }
350
+ if (Array.isArray(service.receives)) {
351
+ resource.receives = uniqueVersions(service.receives);
352
+ }
353
+ return await writeResource(directory, resource, { ...options, type: "service" });
354
+ };
355
+ var writeVersionedService = (directory) => async (service) => {
356
+ const resource = { ...service };
357
+ const path4 = getVersionedDirectory(service.id, service.version);
358
+ return await writeService(directory)(resource, { path: path4 });
359
+ };
360
+ var writeServiceToDomain = (directory) => async (service, domain, options = { path: "" }) => {
361
+ let pathForService = domain.version && domain.version !== "latest" ? `/${domain.id}/versioned/${domain.version}/services` : `/${domain.id}/services`;
362
+ pathForService = join6(pathForService, service.id);
363
+ await writeResource(directory, { ...service }, { ...options, path: pathForService, type: "service" });
364
+ };
365
+ var versionService = (directory) => async (id) => versionResource(directory, id);
366
+ var rmService = (directory) => async (path4) => {
367
+ await fs5.rm(join6(directory, path4), { recursive: true });
368
+ };
369
+ var rmServiceById = (directory) => async (id, version, persistFiles) => rmResourceById(directory, id, version, { type: "service", persistFiles });
370
+ var addFileToService = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
371
+ var getSpecificationFilesForService = (directory) => async (id, version) => {
372
+ let service = await getService(directory)(id, version);
373
+ const filePathToService = await findFileById(directory, id, version);
374
+ if (!filePathToService) throw new Error("Cannot find directory of service");
375
+ let specs = [];
376
+ if (service.specifications) {
377
+ const serviceSpecifications = service.specifications;
378
+ const specificationFiles = Object.keys(serviceSpecifications);
379
+ const getSpecs = specificationFiles.map(async (specFile) => {
380
+ const fileName = serviceSpecifications[specFile];
381
+ if (!fileName) {
382
+ throw new Error(`Specification file name for ${specFile} is undefined`);
383
+ }
384
+ const rawFile = await getFileFromResource(directory, id, { fileName }, version);
385
+ return { key: specFile, content: rawFile, fileName, path: join6(dirname3(filePathToService), fileName) };
386
+ });
387
+ specs = await Promise.all(getSpecs);
388
+ }
389
+ return specs;
390
+ };
391
+ var addMessageToService = (directory) => async (id, direction, event, version) => {
392
+ let service = await getService(directory)(id, version);
393
+ if (direction === "sends") {
394
+ if (service.sends === void 0) {
395
+ service.sends = [];
396
+ }
397
+ for (let i = 0; i < service.sends.length; i++) {
398
+ if (service.sends[i].id === event.id && service.sends[i].version === event.version) {
399
+ return;
400
+ }
401
+ }
402
+ service.sends.push({ id: event.id, version: event.version });
403
+ } else if (direction === "receives") {
404
+ if (service.receives === void 0) {
405
+ service.receives = [];
406
+ }
407
+ for (let i = 0; i < service.receives.length; i++) {
408
+ if (service.receives[i].id === event.id && service.receives[i].version === event.version) {
409
+ return;
410
+ }
411
+ }
412
+ service.receives.push({ id: event.id, version: event.version });
413
+ } else {
414
+ throw new Error(`Direction ${direction} is invalid, only 'receives' and 'sends' are supported`);
415
+ }
416
+ const existingResource = await findFileById(directory, id, version);
417
+ if (!existingResource) {
418
+ throw new Error(`Cannot find service ${id} in the catalog`);
419
+ }
420
+ const path4 = existingResource.split("/services")[0];
421
+ const pathToResource = join6(path4, "services");
422
+ await rmServiceById(directory)(id, version);
423
+ await writeService(pathToResource)(service);
424
+ };
425
+ var serviceHasVersion = (directory) => async (id, version) => {
426
+ const file = await findFileById(directory, id, version);
427
+ return !!file;
428
+ };
429
+
430
+ // src/domains.ts
431
+ import fs6 from "node:fs/promises";
432
+ import path, { join as join7 } from "node:path";
433
+ import fsSync3 from "node:fs";
434
+ import matter3 from "gray-matter";
435
+ var getDomain = (directory) => async (id, version) => getResource(directory, id, version, { type: "domain" });
436
+ var getDomains = (directory) => async (options) => getResources(directory, {
437
+ type: "domains",
438
+ ignore: ["**/services/**", "**/events/**", "**/commands/**", "**/queries/**", "**/flows/**"],
439
+ ...options
440
+ });
441
+ var writeDomain = (directory) => async (domain, options = { path: "" }) => {
442
+ const resource = { ...domain };
443
+ if (Array.isArray(domain.services)) {
444
+ resource.services = uniqueVersions(domain.services);
445
+ }
446
+ return await writeResource(directory, resource, { ...options, type: "domain" });
447
+ };
448
+ var versionDomain = (directory) => async (id) => versionResource(directory, id);
449
+ var rmDomain = (directory) => async (path4) => {
450
+ await fs6.rm(join7(directory, path4), { recursive: true });
451
+ };
452
+ var rmDomainById = (directory) => async (id, version, persistFiles) => rmResourceById(directory, id, version, { type: "domain", persistFiles });
453
+ var addFileToDomain = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
454
+ var addUbiquitousLanguageToDomain = (directory) => async (id, ubiquitousLanguageDictionary, version) => {
455
+ const content = matter3.stringify("", {
456
+ ...ubiquitousLanguageDictionary
457
+ });
458
+ await addFileToResource(directory, id, { content, fileName: "ubiquitous-language.mdx" }, version);
459
+ };
460
+ var getUbiquitousLanguageFromDomain = (directory) => async (id, version) => {
461
+ const pathToDomain = await findFileById(directory, id, version) || "";
462
+ const pathToUbiquitousLanguage = path.join(path.dirname(pathToDomain), "ubiquitous-language.mdx");
463
+ const fileExists = fsSync3.existsSync(pathToUbiquitousLanguage);
464
+ if (!fileExists) {
465
+ return void 0;
466
+ }
467
+ const content = await readMdxFile(pathToUbiquitousLanguage);
468
+ return content;
469
+ };
470
+ var domainHasVersion = (directory) => async (id, version) => {
471
+ const file = await findFileById(directory, id, version);
472
+ return !!file;
473
+ };
474
+ var addServiceToDomain = (directory) => async (id, service, version) => {
475
+ let domain = await getDomain(directory)(id, version);
476
+ if (domain.services === void 0) {
477
+ domain.services = [];
478
+ }
479
+ const serviceExistsInList = domain.services.some((s) => s.id === service.id && s.version === service.version);
480
+ if (serviceExistsInList) {
481
+ return;
482
+ }
483
+ domain.services.push(service);
484
+ await rmDomainById(directory)(id, version, true);
485
+ await writeDomain(directory)(domain);
486
+ };
487
+
488
+ // src/channels.ts
489
+ import fs7 from "node:fs/promises";
490
+ import { join as join8 } from "node:path";
491
+ var getChannel = (directory) => async (id, version) => getResource(directory, id, version, { type: "channel" });
492
+ var getChannels = (directory) => async (options) => getResources(directory, { type: "channels", ...options });
493
+ var writeChannel = (directory) => async (channel, options = { path: "" }) => writeResource(directory, { ...channel }, { ...options, type: "channel" });
494
+ var rmChannel = (directory) => async (path4) => {
495
+ await fs7.rm(join8(directory, path4), { recursive: true });
496
+ };
497
+ var rmChannelById = (directory) => async (id, version, persistFiles) => rmResourceById(directory, id, version, { type: "channel", persistFiles });
498
+ var versionChannel = (directory) => async (id) => versionResource(directory, id);
499
+ var channelHasVersion = (directory) => async (id, version) => {
500
+ const file = await findFileById(directory, id, version);
501
+ return !!file;
502
+ };
503
+ var addMessageToChannel = (directory, collection) => async (id, _message, version) => {
504
+ let channel = await getChannel(directory)(id, version);
505
+ const functions = {
506
+ events: {
507
+ getMessage: getEvent,
508
+ rmMessageById: rmEventById,
509
+ writeMessage: writeEvent
510
+ },
511
+ commands: {
512
+ getMessage: getCommand,
513
+ rmMessageById: rmCommandById,
514
+ writeMessage: writeCommand
515
+ },
516
+ queries: {
517
+ getMessage: getQuery,
518
+ rmMessageById: rmQueryById,
519
+ writeMessage: writeQuery
520
+ }
521
+ };
522
+ const { getMessage, rmMessageById, writeMessage } = functions[collection];
523
+ const message = await getMessage(directory)(_message.id, _message.version);
524
+ if (!message) throw new Error(`Message ${_message.id} with version ${_message.version} not found`);
525
+ if (message.channels === void 0) {
526
+ message.channels = [];
527
+ }
528
+ const channelInfo = { id, version: channel.version, ..._message.parameters && { parameters: _message.parameters } };
529
+ message.channels.push(channelInfo);
530
+ const existingResource = await findFileById(directory, _message.id, _message.version);
531
+ if (!existingResource) {
532
+ throw new Error(`Cannot find message ${id} in the catalog`);
533
+ }
534
+ const path4 = existingResource.split(`/${collection}`)[0];
535
+ const pathToResource = join8(path4, collection);
536
+ await rmMessageById(directory)(_message.id, _message.version, true);
537
+ await writeMessage(pathToResource)(message);
538
+ };
539
+
540
+ // src/custom-docs.ts
541
+ import path2, { join as join9 } from "node:path";
542
+ import fsSync4 from "node:fs";
543
+ import fs8 from "node:fs/promises";
544
+ import matter4 from "gray-matter";
545
+ import slugify from "slugify";
546
+ var getCustomDoc = (directory) => async (filePath) => {
547
+ const fullPath = path2.join(directory, filePath);
548
+ const fullPathWithExtension = fullPath.endsWith(".mdx") ? fullPath : `${fullPath}.mdx`;
549
+ const fileExists = fsSync4.existsSync(fullPathWithExtension);
550
+ if (!fileExists) {
551
+ return void 0;
552
+ }
553
+ return readMdxFile(fullPathWithExtension);
554
+ };
555
+ var getCustomDocs = (directory) => async (options) => {
556
+ if (options?.path) {
557
+ const pattern = `${directory}/${options.path}/**/*.{md,mdx}`;
558
+ return getResources(directory, { type: "docs", pattern });
559
+ }
560
+ return getResources(directory, { type: "docs", pattern: `${directory}/**/*.{md,mdx}` });
561
+ };
562
+ var writeCustomDoc = (directory) => async (customDoc, options = { path: "" }) => {
563
+ const { fileName, ...rest } = customDoc;
564
+ const name = fileName || slugify(customDoc.title, { lower: true });
565
+ const withExtension = name.endsWith(".mdx") ? name : `${name}.mdx`;
566
+ const fullPath = path2.join(directory, options.path || "", withExtension);
567
+ fsSync4.mkdirSync(path2.dirname(fullPath), { recursive: true });
568
+ const document = matter4.stringify(customDoc.markdown.trim(), rest);
569
+ fsSync4.writeFileSync(fullPath, document);
570
+ };
571
+ var rmCustomDoc = (directory) => async (filePath) => {
572
+ const withExtension = filePath.endsWith(".mdx") ? filePath : `${filePath}.mdx`;
573
+ await fs8.rm(join9(directory, withExtension), { recursive: true });
574
+ };
575
+
576
+ // src/teams.ts
577
+ import fs9 from "node:fs/promises";
578
+ import fsSync5 from "node:fs";
579
+ import { join as join10 } from "node:path";
580
+ import matter5 from "gray-matter";
581
+ var getTeam = (catalogDir) => async (id) => {
582
+ const files = await getFiles(`${catalogDir}/${id}.{md,mdx}`);
583
+ if (files.length == 0) return void 0;
584
+ const file = files[0];
585
+ const { data, content } = matter5.read(file);
586
+ return {
587
+ ...data,
588
+ id: data.id,
589
+ name: data.name,
590
+ markdown: content.trim()
591
+ };
592
+ };
593
+ var getTeams = (catalogDir) => async (options) => {
594
+ const files = await getFiles(`${catalogDir}/teams/*.{md,mdx}`);
595
+ if (files.length === 0) return [];
596
+ return files.map((file) => {
597
+ const { data, content } = matter5.read(file);
598
+ return {
599
+ ...data,
600
+ id: data.id,
601
+ name: data.name,
602
+ markdown: content.trim()
603
+ };
604
+ });
605
+ };
606
+ var writeTeam = (catalogDir) => async (team, options = {}) => {
607
+ const resource = { ...team };
608
+ const currentTeam = await getTeam(catalogDir)(resource.id);
609
+ const exists = currentTeam !== void 0;
610
+ if (exists && !options.override) {
611
+ throw new Error(`Failed to write ${resource.id} (team) as it already exists`);
612
+ }
613
+ const { markdown, ...frontmatter } = resource;
614
+ const document = matter5.stringify(markdown, frontmatter);
615
+ fsSync5.mkdirSync(join10(catalogDir, ""), { recursive: true });
616
+ fsSync5.writeFileSync(join10(catalogDir, "", `${resource.id}.mdx`), document);
617
+ };
618
+ var rmTeamById = (catalogDir) => async (id) => {
619
+ await fs9.rm(join10(catalogDir, `${id}.mdx`), { recursive: true });
620
+ };
621
+
622
+ // src/users.ts
623
+ import fsSync6 from "node:fs";
624
+ import { join as join11 } from "node:path";
625
+ import matter6 from "gray-matter";
626
+ var getUser = (catalogDir) => async (id) => {
627
+ const files = await getFiles(`${catalogDir}/${id}.{md,mdx}`);
628
+ if (files.length == 0) return void 0;
629
+ const file = files[0];
630
+ const { data, content } = matter6.read(file);
631
+ return {
632
+ ...data,
633
+ id: data.id,
634
+ name: data.name,
635
+ avatarUrl: data.avatarUrl,
636
+ markdown: content.trim()
637
+ };
638
+ };
639
+ var getUsers = (catalogDir) => async (options) => {
640
+ const files = await getFiles(`${catalogDir}/users/*.{md,mdx}`);
641
+ if (files.length === 0) return [];
642
+ return files.map((file) => {
643
+ const { data, content } = matter6.read(file);
644
+ return {
645
+ ...data,
646
+ id: data.id,
647
+ name: data.name,
648
+ avatarUrl: data.avatarUrl,
649
+ markdown: content.trim()
650
+ };
651
+ });
652
+ };
653
+ var writeUser = (catalogDir) => async (user, options = {}) => {
654
+ const resource = { ...user };
655
+ const currentUser = await getUser(catalogDir)(resource.id);
656
+ const exists = currentUser !== void 0;
657
+ if (exists && !options.override) {
658
+ throw new Error(`Failed to write ${resource.id} (user) as it already exists`);
659
+ }
660
+ const { markdown, ...frontmatter } = resource;
661
+ const document = matter6.stringify(markdown, frontmatter);
662
+ fsSync6.mkdirSync(join11(catalogDir, ""), { recursive: true });
663
+ fsSync6.writeFileSync(join11(catalogDir, "", `${resource.id}.mdx`), document);
664
+ };
665
+ var rmUserById = (catalogDir) => async (id) => {
666
+ fsSync6.rmSync(join11(catalogDir, `${id}.mdx`), { recursive: true });
667
+ };
668
+
669
+ // src/index.ts
670
+ var index_default = (path4) => {
671
+ return {
672
+ /**
673
+ * Returns an events from EventCatalog
674
+ * @param id - The id of the event to retrieve
675
+ * @param version - Optional id of the version to get (supports semver)
676
+ * @returns Event|Undefined
677
+ */
678
+ getEvent: getEvent(join12(path4)),
679
+ /**
680
+ * Returns all events from EventCatalog
681
+ * @param latestOnly - optional boolean, set to true to get only latest versions
682
+ * @returns Event[]|Undefined
683
+ */
684
+ getEvents: getEvents(join12(path4)),
685
+ /**
686
+ * Adds an event to EventCatalog
687
+ *
688
+ * @param event - The event to write
689
+ * @param options - Optional options to write the event
690
+ *
691
+ */
692
+ writeEvent: writeEvent(join12(path4, "events")),
693
+ /**
694
+ * Adds an event to a service in EventCatalog
695
+ *
696
+ * @param event - The event to write to the service
697
+ * @param service - The service and it's id to write to the event to
698
+ * @param options - Optional options to write the event
699
+ *
700
+ */
701
+ writeEventToService: writeEventToService(join12(path4)),
702
+ /**
703
+ * Remove an event to EventCatalog (modeled on the standard POSIX rm utility)
704
+ *
705
+ * @param path - The path to your event, e.g. `/Inventory/InventoryAdjusted`
706
+ *
707
+ */
708
+ rmEvent: rmEvent(join12(path4, "events")),
709
+ /**
710
+ * Remove an event by an Event id
711
+ *
712
+ * @param id - The id of the event you want to remove
713
+ *
714
+ */
715
+ rmEventById: rmEventById(join12(path4)),
716
+ /**
717
+ * Moves a given event id to the version directory
718
+ * @param directory
719
+ */
720
+ versionEvent: versionEvent(join12(path4)),
721
+ /**
722
+ * Adds a file to the given event
723
+ * @param id - The id of the event to add the file to
724
+ * @param file - File contents to add including the content and the file name
725
+ * @param version - Optional version of the event to add the file to
726
+ * @returns
727
+ */
728
+ addFileToEvent: addFileToEvent(join12(path4)),
729
+ /**
730
+ * Adds a schema to the given event
731
+ * @param id - The id of the event to add the schema to
732
+ * @param schema - Schema contents to add including the content and the file name
733
+ * @param version - Optional version of the event to add the schema to
734
+ * @returns
735
+ */
736
+ addSchemaToEvent: addSchemaToEvent(join12(path4)),
737
+ /**
738
+ * Check to see if an event version exists
739
+ * @param id - The id of the event
740
+ * @param version - The version of the event (supports semver)
741
+ * @returns
742
+ */
743
+ eventHasVersion: eventHasVersion(join12(path4)),
744
+ /**
745
+ * ================================
746
+ * Commands
747
+ * ================================
748
+ */
749
+ /**
750
+ * Returns a command from EventCatalog
751
+ * @param id - The id of the command to retrieve
752
+ * @param version - Optional id of the version to get (supports semver)
753
+ * @returns Command|Undefined
754
+ */
755
+ getCommand: getCommand(join12(path4)),
756
+ /**
757
+ * Returns all commands from EventCatalog
758
+ * @param latestOnly - optional boolean, set to true to get only latest versions
759
+ * @returns Command[]|Undefined
760
+ */
761
+ getCommands: getCommands(join12(path4)),
762
+ /**
763
+ * Adds an command to EventCatalog
764
+ *
765
+ * @param command - The command to write
766
+ * @param options - Optional options to write the command
767
+ *
768
+ */
769
+ writeCommand: writeCommand(join12(path4, "commands")),
770
+ /**
771
+ * Adds a command to a service in EventCatalog
772
+ *
773
+ * @param command - The command to write to the service
774
+ * @param service - The service and it's id to write to the command to
775
+ * @param options - Optional options to write the command
776
+ *
777
+ */
778
+ writeCommandToService: writeCommandToService(join12(path4)),
779
+ /**
780
+ * Remove an command to EventCatalog (modeled on the standard POSIX rm utility)
781
+ *
782
+ * @param path - The path to your command, e.g. `/Inventory/InventoryAdjusted`
783
+ *
784
+ */
785
+ rmCommand: rmCommand(join12(path4, "commands")),
786
+ /**
787
+ * Remove an command by an Event id
788
+ *
789
+ * @param id - The id of the command you want to remove
790
+ *
791
+ */
792
+ rmCommandById: rmCommandById(join12(path4)),
793
+ /**
794
+ * Moves a given command id to the version directory
795
+ * @param directory
796
+ */
797
+ versionCommand: versionCommand(join12(path4)),
798
+ /**
799
+ * Adds a file to the given command
800
+ * @param id - The id of the command to add the file to
801
+ * @param file - File contents to add including the content and the file name
802
+ * @param version - Optional version of the command to add the file to
803
+ * @returns
804
+ */
805
+ addFileToCommand: addFileToCommand(join12(path4)),
806
+ /**
807
+ * Adds a schema to the given command
808
+ * @param id - The id of the command to add the schema to
809
+ * @param schema - Schema contents to add including the content and the file name
810
+ * @param version - Optional version of the command to add the schema to
811
+ * @returns
812
+ */
813
+ addSchemaToCommand: addSchemaToCommand(join12(path4)),
814
+ /**
815
+ * Check to see if a command version exists
816
+ * @param id - The id of the command
817
+ * @param version - The version of the command (supports semver)
818
+ * @returns
819
+ */
820
+ commandHasVersion: commandHasVersion(join12(path4)),
821
+ /**
822
+ * ================================
823
+ * Queries
824
+ * ================================
825
+ */
826
+ /**
827
+ * Returns a query from EventCatalog
828
+ * @param id - The id of the query to retrieve
829
+ * @param version - Optional id of the version to get (supports semver)
830
+ * @returns Query|Undefined
831
+ */
832
+ getQuery: getQuery(join12(path4)),
833
+ /**
834
+ * Returns all queries from EventCatalog
835
+ * @param latestOnly - optional boolean, set to true to get only latest versions
836
+ * @returns Query[]|Undefined
837
+ */
838
+ getQueries: getQueries(join12(path4)),
839
+ /**
840
+ * Adds a query to EventCatalog
841
+ *
842
+ * @param query - The query to write
843
+ * @param options - Optional options to write the event
844
+ *
845
+ */
846
+ writeQuery: writeQuery(join12(path4, "queries")),
847
+ /**
848
+ * Adds a query to a service in EventCatalog
849
+ *
850
+ * @param query - The query to write to the service
851
+ * @param service - The service and it's id to write to the query to
852
+ * @param options - Optional options to write the query
853
+ *
854
+ */
855
+ writeQueryToService: writeQueryToService(join12(path4)),
856
+ /**
857
+ * Remove an query to EventCatalog (modeled on the standard POSIX rm utility)
858
+ *
859
+ * @param path - The path to your query, e.g. `/Orders/GetOrder`
860
+ *
861
+ */
862
+ rmQuery: rmQuery(join12(path4, "queries")),
863
+ /**
864
+ * Remove a query by a Query id
865
+ *
866
+ * @param id - The id of the query you want to remove
867
+ *
868
+ */
869
+ rmQueryById: rmQueryById(join12(path4)),
870
+ /**
871
+ * Moves a given query id to the version directory
872
+ * @param directory
873
+ */
874
+ versionQuery: versionQuery(join12(path4)),
875
+ /**
876
+ * Adds a file to the given query
877
+ * @param id - The id of the query to add the file to
878
+ * @param file - File contents to add including the content and the file name
879
+ * @param version - Optional version of the query to add the file to
880
+ * @returns
881
+ */
882
+ addFileToQuery: addFileToQuery(join12(path4)),
883
+ /**
884
+ * Adds a schema to the given query
885
+ * @param id - The id of the query to add the schema to
886
+ * @param schema - Schema contents to add including the content and the file name
887
+ * @param version - Optional version of the query to add the schema to
888
+ * @returns
889
+ */
890
+ addSchemaToQuery: addSchemaToQuery(join12(path4)),
891
+ /**
892
+ * Check to see if an query version exists
893
+ * @param id - The id of the query
894
+ * @param version - The version of the query (supports semver)
895
+ * @returns
896
+ */
897
+ queryHasVersion: queryHasVersion(join12(path4)),
898
+ /**
899
+ * ================================
900
+ * Channels
901
+ * ================================
902
+ */
903
+ /**
904
+ * Returns a channel from EventCatalog
905
+ * @param id - The id of the channel to retrieve
906
+ * @param version - Optional id of the version to get (supports semver)
907
+ * @returns Channel|Undefined
908
+ */
909
+ getChannel: getChannel(join12(path4)),
910
+ /**
911
+ * Returns all channels from EventCatalog
912
+ * @param latestOnly - optional boolean, set to true to get only latest versions
913
+ * @returns Channel[]|Undefined
914
+ */
915
+ getChannels: getChannels(join12(path4)),
916
+ /**
917
+ * Adds an channel to EventCatalog
918
+ *
919
+ * @param command - The channel to write
920
+ * @param options - Optional options to write the channel
921
+ *
922
+ */
923
+ writeChannel: writeChannel(join12(path4, "channels")),
924
+ /**
925
+ * Remove an channel to EventCatalog (modeled on the standard POSIX rm utility)
926
+ *
927
+ * @param path - The path to your channel, e.g. `/Inventory/InventoryAdjusted`
928
+ *
929
+ */
930
+ rmChannel: rmChannel(join12(path4, "channels")),
931
+ /**
932
+ * Remove an channel by an Event id
933
+ *
934
+ * @param id - The id of the channel you want to remove
935
+ *
936
+ */
937
+ rmChannelById: rmChannelById(join12(path4)),
938
+ /**
939
+ * Moves a given channel id to the version directory
940
+ * @param directory
941
+ */
942
+ versionChannel: versionChannel(join12(path4)),
943
+ /**
944
+ * Check to see if a channel version exists
945
+ * @param id - The id of the channel
946
+ * @param version - The version of the channel (supports semver)
947
+ * @returns
948
+ */
949
+ channelHasVersion: channelHasVersion(join12(path4)),
950
+ /**
951
+ * Add a channel to an event
952
+ *
953
+ * Optionally specify a version to add the channel to a specific version of the event.
954
+ *
955
+ * @example
956
+ * ```ts
957
+ * import utils from '@eventcatalog/utils';
958
+ *
959
+ * const { addEventToChannel } = utils('/path/to/eventcatalog');
960
+ *
961
+ * // adds a new event (InventoryUpdatedEvent) to the inventory.{env}.events channel
962
+ * await addEventToChannel('inventory.{env}.events channel', { id: 'InventoryUpdatedEvent', version: '2.0.0', parameters: { env: 'dev' } });
963
+ *
964
+ * ```
965
+ */
966
+ addEventToChannel: addMessageToChannel(join12(path4), "events"),
967
+ /**
968
+ * Add a channel to an command
969
+ *
970
+ * Optionally specify a version to add the channel to a specific version of the command.
971
+ *
972
+ * @example
973
+ * ```ts
974
+ * import utils from '@eventcatalog/utils';
975
+ *
976
+ * const { addCommandToChannel } = utils('/path/to/eventcatalog');
977
+ *
978
+ * // adds a new command (UpdateInventory) to the inventory.{env}.events channel
979
+ * await addCommandToChannel('inventory.{env}.events channel', { id: 'UpdateInventory', version: '2.0.0', parameters: { env: 'dev' } });
980
+ *
981
+ * ```
982
+ */
983
+ addCommandToChannel: addMessageToChannel(join12(path4), "commands"),
984
+ /**
985
+ * Add a channel to an query
986
+ *
987
+ * Optionally specify a version to add the channel to a specific version of the query.
988
+ *
989
+ * @example
990
+ * ```ts
991
+ * import utils from '@eventcatalog/utils';
992
+ *
993
+ * const { addQueryToChannel } = utils('/path/to/eventcatalog');
994
+ *
995
+ * // adds a new query (GetInventory) to the inventory.{env}.events channel
996
+ * await addQueryToChannel('inventory.{env}.events channel', { id: 'GetInventory', version: '2.0.0', parameters: { env: 'dev' } });
997
+ *
998
+ * ```
999
+ */
1000
+ addQueryToChannel: addMessageToChannel(join12(path4), "queries"),
1001
+ /**
1002
+ * ================================
1003
+ * SERVICES
1004
+ * ================================
1005
+ */
1006
+ /**
1007
+ * Adds a service to EventCatalog
1008
+ *
1009
+ * @param service - The service to write
1010
+ * @param options - Optional options to write the event
1011
+ *
1012
+ */
1013
+ writeService: writeService(join12(path4, "services")),
1014
+ /**
1015
+ * Adds a versioned service to EventCatalog
1016
+ *
1017
+ * @param service - The service to write
1018
+ *
1019
+ */
1020
+ writeVersionedService: writeVersionedService(join12(path4, "services")),
1021
+ /**
1022
+ * Adds a service to a domain in EventCatalog
1023
+ *
1024
+ * @param service - The service to write
1025
+ * @param domain - The domain to add the service to
1026
+ * @param options - Optional options to write the event
1027
+ *
1028
+ */
1029
+ writeServiceToDomain: writeServiceToDomain(join12(path4, "domains")),
1030
+ /**
1031
+ * Returns a service from EventCatalog
1032
+ * @param id - The id of the service to retrieve
1033
+ * @param version - Optional id of the version to get (supports semver)
1034
+ * @returns Service|Undefined
1035
+ */
1036
+ getService: getService(join12(path4)),
1037
+ /**
1038
+ * Returns all services from EventCatalog
1039
+ * @param latestOnly - optional boolean, set to true to get only latest versions
1040
+ * @returns Service[]|Undefined
1041
+ */
1042
+ getServices: getServices(join12(path4)),
1043
+ /**
1044
+ * Moves a given service id to the version directory
1045
+ * @param directory
1046
+ */
1047
+ versionService: versionService(join12(path4)),
1048
+ /**
1049
+ * Remove a service from EventCatalog (modeled on the standard POSIX rm utility)
1050
+ *
1051
+ * @param path - The path to your service, e.g. `/InventoryService`
1052
+ *
1053
+ */
1054
+ rmService: rmService(join12(path4, "services")),
1055
+ /**
1056
+ * Remove an service by an service id
1057
+ *
1058
+ * @param id - The id of the service you want to remove
1059
+ *
1060
+ */
1061
+ rmServiceById: rmServiceById(join12(path4)),
1062
+ /**
1063
+ * Adds a file to the given service
1064
+ * @param id - The id of the service to add the file to
1065
+ * @param file - File contents to add including the content and the file name
1066
+ * @param version - Optional version of the service to add the file to
1067
+ * @returns
1068
+ */
1069
+ addFileToService: addFileToService(join12(path4)),
1070
+ /**
1071
+ * Returns the specifications for a given service
1072
+ * @param id - The id of the service to retrieve the specifications for
1073
+ * @param version - Optional version of the service
1074
+ * @returns
1075
+ */
1076
+ getSpecificationFilesForService: getSpecificationFilesForService(join12(path4)),
1077
+ /**
1078
+ * Check to see if a service version exists
1079
+ * @param id - The id of the service
1080
+ * @param version - The version of the service (supports semver)
1081
+ * @returns
1082
+ */
1083
+ serviceHasVersion: serviceHasVersion(join12(path4)),
1084
+ /**
1085
+ * Add an event to a service by it's id.
1086
+ *
1087
+ * Optionally specify a version to add the event to a specific version of the service.
1088
+ *
1089
+ * @example
1090
+ * ```ts
1091
+ * import utils from '@eventcatalog/utils';
1092
+ *
1093
+ * const { addEventToService } = utils('/path/to/eventcatalog');
1094
+ *
1095
+ * // adds a new event (InventoryUpdatedEvent) that the InventoryService will send
1096
+ * await addEventToService('InventoryService', 'sends', { event: 'InventoryUpdatedEvent', version: '2.0.0' });
1097
+ *
1098
+ * // adds a new event (OrderComplete) that the InventoryService will receive
1099
+ * await addEventToService('InventoryService', 'receives', { event: 'OrderComplete', version: '2.0.0' });
1100
+ *
1101
+ * ```
1102
+ */
1103
+ addEventToService: addMessageToService(join12(path4)),
1104
+ /**
1105
+ * Add a command to a service by it's id.
1106
+ *
1107
+ * Optionally specify a version to add the event to a specific version of the service.
1108
+ *
1109
+ * @example
1110
+ * ```ts
1111
+ * import utils from '@eventcatalog/utils';
1112
+ *
1113
+ * const { addCommandToService } = utils('/path/to/eventcatalog');
1114
+ *
1115
+ * // adds a new command (UpdateInventoryCommand) that the InventoryService will send
1116
+ * await addCommandToService('InventoryService', 'sends', { command: 'UpdateInventoryCommand', version: '2.0.0' });
1117
+ *
1118
+ * // adds a new command (VerifyInventory) that the InventoryService will receive
1119
+ * await addCommandToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '2.0.0' });
1120
+ *
1121
+ * ```
1122
+ */
1123
+ addCommandToService: addMessageToService(join12(path4)),
1124
+ /**
1125
+ * Add a query to a service by it's id.
1126
+ *
1127
+ * Optionally specify a version to add the event to a specific version of the service.
1128
+ *
1129
+ * @example
1130
+ * ```ts
1131
+ * import utils from '@eventcatalog/utils';
1132
+ *
1133
+ * const { addQueryToService } = utils('/path/to/eventcatalog');
1134
+ *
1135
+ * // adds a new query (UpdateInventory) that the InventoryService will send
1136
+ * await addQueryToService('InventoryService', 'sends', { command: 'UpdateInventory', version: '2.0.0' });
1137
+ *
1138
+ * // adds a new command (VerifyInventory) that the InventoryService will receive
1139
+ * await addQueryToService('InventoryService', 'receives', { command: 'VerifyInventory', version: '2.0.0' });
1140
+ *
1141
+ * ```
1142
+ */
1143
+ addQueryToService: addMessageToService(join12(path4)),
1144
+ /**
1145
+ * ================================
1146
+ * Domains
1147
+ * ================================
1148
+ */
1149
+ /**
1150
+ * Adds a domain to EventCatalog
1151
+ *
1152
+ * @param domain - The domain to write
1153
+ * @param options - Optional options to write the event
1154
+ *
1155
+ */
1156
+ writeDomain: writeDomain(join12(path4, "domains")),
1157
+ /**
1158
+ * Returns a domain from EventCatalog
1159
+ * @param id - The id of the domain to retrieve
1160
+ * @param version - Optional id of the version to get (supports semver)
1161
+ * @returns Domain|Undefined
1162
+ */
1163
+ getDomain: getDomain(join12(path4, "domains")),
1164
+ /**
1165
+ * Returns all domains from EventCatalog
1166
+ * @param latestOnly - optional boolean, set to true to get only latest versions
1167
+ * @returns Domain[]|Undefined
1168
+ */
1169
+ getDomains: getDomains(join12(path4)),
1170
+ /**
1171
+ * Moves a given domain id to the version directory
1172
+ * @param directory
1173
+ */
1174
+ versionDomain: versionDomain(join12(path4, "domains")),
1175
+ /**
1176
+ * Remove a domain from EventCatalog (modeled on the standard POSIX rm utility)
1177
+ *
1178
+ * @param path - The path to your domain, e.g. `/Payment`
1179
+ *
1180
+ */
1181
+ rmDomain: rmDomain(join12(path4, "domains")),
1182
+ /**
1183
+ * Remove an service by an domain id
1184
+ *
1185
+ * @param id - The id of the domain you want to remove
1186
+ *
1187
+ */
1188
+ rmDomainById: rmDomainById(join12(path4, "domains")),
1189
+ /**
1190
+ * Adds a file to the given domain
1191
+ * @param id - The id of the domain to add the file to
1192
+ * @param file - File contents to add including the content and the file name
1193
+ * @param version - Optional version of the domain to add the file to
1194
+ * @returns
1195
+ */
1196
+ addFileToDomain: addFileToDomain(join12(path4, "domains")),
1197
+ /**
1198
+ * Adds an ubiquitous language dictionary to a domain
1199
+ * @param id - The id of the domain to add the ubiquitous language to
1200
+ * @param ubiquitousLanguageDictionary - The ubiquitous language dictionary to add
1201
+ * @param version - Optional version of the domain to add the ubiquitous language to
1202
+ */
1203
+ addUbiquitousLanguageToDomain: addUbiquitousLanguageToDomain(join12(path4, "domains")),
1204
+ /**
1205
+ * Get the ubiquitous language dictionary from a domain
1206
+ * @param id - The id of the domain to get the ubiquitous language from
1207
+ * @param version - Optional version of the domain to get the ubiquitous language from
1208
+ * @returns
1209
+ */
1210
+ getUbiquitousLanguageFromDomain: getUbiquitousLanguageFromDomain(join12(path4, "domains")),
1211
+ /**
1212
+ * Check to see if a domain version exists
1213
+ * @param id - The id of the domain
1214
+ * @param version - The version of the domain (supports semver)
1215
+ * @returns
1216
+ */
1217
+ domainHasVersion: domainHasVersion(join12(path4)),
1218
+ /**
1219
+ * Adds a given service to a domain
1220
+ * @param id - The id of the domain
1221
+ * @param service - The id and version of the service to add
1222
+ * @param version - (Optional) The version of the domain to add the service to
1223
+ * @returns
1224
+ */
1225
+ addServiceToDomain: addServiceToDomain(join12(path4, "domains")),
1226
+ /**
1227
+ * ================================
1228
+ * Teams
1229
+ * ================================
1230
+ */
1231
+ /**
1232
+ * Adds a team to EventCatalog
1233
+ *
1234
+ * @param team - The team to write
1235
+ * @param options - Optional options to write the team
1236
+ *
1237
+ */
1238
+ writeTeam: writeTeam(join12(path4, "teams")),
1239
+ /**
1240
+ * Returns a team from EventCatalog
1241
+ * @param id - The id of the team to retrieve
1242
+ * @returns Team|Undefined
1243
+ */
1244
+ getTeam: getTeam(join12(path4, "teams")),
1245
+ /**
1246
+ * Returns all teams from EventCatalog
1247
+ * @returns Team[]|Undefined
1248
+ */
1249
+ getTeams: getTeams(join12(path4)),
1250
+ /**
1251
+ * Remove a team by the team id
1252
+ *
1253
+ * @param id - The id of the team you want to remove
1254
+ *
1255
+ */
1256
+ rmTeamById: rmTeamById(join12(path4, "teams")),
1257
+ /**
1258
+ * ================================
1259
+ * Users
1260
+ * ================================
1261
+ */
1262
+ /**
1263
+ * Adds a user to EventCatalog
1264
+ *
1265
+ * @param user - The user to write
1266
+ * @param options - Optional options to write the user
1267
+ *
1268
+ */
1269
+ writeUser: writeUser(join12(path4, "users")),
1270
+ /**
1271
+ * Returns a user from EventCatalog
1272
+ * @param id - The id of the user to retrieve
1273
+ * @returns User|Undefined
1274
+ */
1275
+ getUser: getUser(join12(path4, "users")),
1276
+ /**
1277
+ * Returns all user from EventCatalog
1278
+ * @returns User[]|Undefined
1279
+ */
1280
+ getUsers: getUsers(join12(path4)),
1281
+ /**
1282
+ * Remove a user by the user id
1283
+ *
1284
+ * @param id - The id of the user you want to remove
1285
+ *
1286
+ */
1287
+ rmUserById: rmUserById(join12(path4, "users")),
1288
+ /**
1289
+ * ================================
1290
+ * Custom Docs
1291
+ * ================================
1292
+ */
1293
+ /**
1294
+ * Returns a custom doc from EventCatalog
1295
+ * @param path - The path to the custom doc to retrieve
1296
+ * @returns CustomDoc|Undefined
1297
+ */
1298
+ getCustomDoc: getCustomDoc(join12(path4, "docs")),
1299
+ /**
1300
+ * Returns all custom docs from EventCatalog
1301
+ * @param options - Optional options to get custom docs from a specific path
1302
+ * @returns CustomDoc[]|Undefined
1303
+ */
1304
+ getCustomDocs: getCustomDocs(join12(path4, "docs")),
1305
+ /**
1306
+ * Writes a custom doc to EventCatalog
1307
+ * @param customDoc - The custom doc to write
1308
+ * @param options - Optional options to write the custom doc
1309
+ *
1310
+ */
1311
+ writeCustomDoc: writeCustomDoc(join12(path4, "docs")),
1312
+ /**
1313
+ * Removes a custom doc from EventCatalog
1314
+ * @param path - The path to the custom doc to remove
1315
+ *
1316
+ */
1317
+ rmCustomDoc: rmCustomDoc(join12(path4, "docs")),
1318
+ /**
1319
+ * Dumps the catalog to a JSON file.
1320
+ * @param directory - The directory to dump the catalog to
1321
+ * @returns A JSON file with the catalog
1322
+ */
1323
+ dumpCatalog: dumpCatalog(join12(path4))
1324
+ };
1325
+ };
1326
+
1327
+ // src/eventcatalog.ts
1328
+ var DUMP_VERSION = "0.0.1";
1329
+ var getEventCatalogVersion = async (catalogDir) => {
1330
+ try {
1331
+ const packageJson = fs10.readFileSync(join13(catalogDir, "package.json"), "utf8");
1332
+ const packageJsonObject = JSON.parse(packageJson);
1333
+ return packageJsonObject["dependencies"]["@eventcatalog/core"];
1334
+ } catch (error) {
1335
+ return "unknown";
1336
+ }
1337
+ };
1338
+ var hydrateResource = async (catalogDir, resources, { attachSchema = false } = {}) => {
1339
+ return await Promise.all(
1340
+ resources.map(async (resource) => {
1341
+ const resourcePath = await getResourcePath(catalogDir, resource.id, resource.version);
1342
+ let schema = "";
1343
+ if (resource.schemaPath && resourcePath?.fullPath) {
1344
+ const pathToSchema = path3.join(path3.dirname(resourcePath?.fullPath), resource.schemaPath);
1345
+ if (fs10.existsSync(pathToSchema)) {
1346
+ schema = fs10.readFileSync(pathToSchema, "utf8");
1347
+ }
1348
+ }
1349
+ const eventcatalog = schema ? { directory: resourcePath?.directory, schema } : { directory: resourcePath?.directory };
1350
+ return {
1351
+ ...resource,
1352
+ _eventcatalog: eventcatalog
1353
+ };
1354
+ })
1355
+ );
1356
+ };
1357
+ var filterCollection = (collection, options) => {
1358
+ return collection.map((item) => ({
1359
+ ...item,
1360
+ markdown: options?.includeMarkdown ? item.markdown : void 0
1361
+ }));
1362
+ };
1363
+ var dumpCatalog = (directory) => async (options) => {
1364
+ const { getDomains: getDomains2, getServices: getServices2, getEvents: getEvents2, getQueries: getQueries2, getCommands: getCommands2, getChannels: getChannels2, getTeams: getTeams2, getUsers: getUsers2 } = index_default(directory);
1365
+ const { includeMarkdown = true } = options || {};
1366
+ const domains = await getDomains2();
1367
+ const services = await getServices2();
1368
+ const events = await getEvents2();
1369
+ const commands = await getCommands2();
1370
+ const queries = await getQueries2();
1371
+ const teams = await getTeams2();
1372
+ const users = await getUsers2();
1373
+ const channels = await getChannels2();
1374
+ const [
1375
+ hydratedDomains,
1376
+ hydratedServices,
1377
+ hydratedEvents,
1378
+ hydratedQueries,
1379
+ hydratedCommands,
1380
+ hydratedTeams,
1381
+ hydratedUsers,
1382
+ hydratedChannels
1383
+ ] = await Promise.all([
1384
+ hydrateResource(directory, domains),
1385
+ hydrateResource(directory, services),
1386
+ hydrateResource(directory, events),
1387
+ hydrateResource(directory, queries),
1388
+ hydrateResource(directory, commands),
1389
+ hydrateResource(directory, teams),
1390
+ hydrateResource(directory, users),
1391
+ hydrateResource(directory, channels)
1392
+ ]);
1393
+ return {
1394
+ version: DUMP_VERSION,
1395
+ catalogVersion: await getEventCatalogVersion(directory),
1396
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1397
+ resources: {
1398
+ domains: filterCollection(hydratedDomains, { includeMarkdown }),
1399
+ services: filterCollection(hydratedServices, { includeMarkdown }),
1400
+ messages: {
1401
+ events: filterCollection(hydratedEvents, { includeMarkdown }),
1402
+ queries: filterCollection(hydratedQueries, { includeMarkdown }),
1403
+ commands: filterCollection(hydratedCommands, { includeMarkdown })
1404
+ },
1405
+ teams: filterCollection(hydratedTeams, { includeMarkdown }),
1406
+ users: filterCollection(hydratedUsers, { includeMarkdown }),
1407
+ channels: filterCollection(hydratedChannels, { includeMarkdown })
1408
+ }
1409
+ };
1410
+ };
1411
+ export {
1412
+ dumpCatalog
1413
+ };
1414
+ //# sourceMappingURL=eventcatalog.mjs.map