@eventcatalog/core 4.10.4 → 4.10.5

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.
@@ -29,10 +29,10 @@ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
29
29
  // src/eventcatalog.ts
30
30
  var import_commander = require("commander");
31
31
  var import_node_child_process2 = require("child_process");
32
- var import_node_path17 = require("path");
32
+ var import_node_path18 = require("path");
33
33
  var import_node_http = __toESM(require("http"), 1);
34
34
  var import_fs3 = __toESM(require("fs"), 1);
35
- var import_node_path18 = __toESM(require("path"), 1);
35
+ var import_node_path19 = __toESM(require("path"), 1);
36
36
  var import_node_url = require("url");
37
37
 
38
38
  // src/generate.js
@@ -144,7 +144,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
144
144
  var import_picocolors = __toESM(require("picocolors"), 1);
145
145
 
146
146
  // package.json
147
- var version = "4.10.4";
147
+ var version = "4.10.5";
148
148
 
149
149
  // src/constants.ts
150
150
  var VERSION = version;
@@ -299,6 +299,9 @@ async function raiseEvent(eventData) {
299
299
 
300
300
  // src/analytics/count-resources.js
301
301
  var import_glob = require("glob");
302
+ var import_node_crypto = require("crypto");
303
+ var import_promises2 = require("fs/promises");
304
+ var import_node_path3 = __toESM(require("path"), 1);
302
305
  var RESOURCE_PATTERNS = {
303
306
  adrs: ["**/adrs/*/index.@(md|mdx)"],
304
307
  agents: ["**/agents/*/index.@(md|mdx)"],
@@ -339,6 +342,23 @@ async function countResources(projectDir) {
339
342
  }
340
343
  return counts;
341
344
  }
345
+ async function hashCatalogContent(projectDir) {
346
+ const hash = (0, import_node_crypto.createHash)("sha256");
347
+ const files = /* @__PURE__ */ new Set();
348
+ for (const pattern of Object.values(RESOURCE_PATTERNS).flat()) {
349
+ for (const file of await (0, import_glob.glob)(pattern, { cwd: projectDir, ignore: DEFAULT_IGNORES })) {
350
+ files.add(file);
351
+ }
352
+ }
353
+ for (const file of [...files].sort()) {
354
+ try {
355
+ hash.update(file);
356
+ hash.update(await (0, import_promises2.readFile)(import_node_path3.default.join(projectDir, file)));
357
+ } catch {
358
+ }
359
+ }
360
+ return hash.digest("hex").slice(0, 16);
361
+ }
342
362
  function serializeCounts(counts) {
343
363
  return Object.entries(counts).map(([k, v]) => `${k}:${v}`).join(",");
344
364
  }
@@ -412,7 +432,7 @@ var reportCloudResourceInventory = async (configFile, resourceCounts) => {
412
432
  })
413
433
  });
414
434
  };
415
- var main = async (projectDir, { isEventCatalogStarterEnabled: isEventCatalogStarterEnabled2, isEventCatalogScaleEnabled: isEventCatalogScaleEnabled2, isBackstagePluginEnabled }) => {
435
+ var main = async (projectDir, { isEventCatalogStarterEnabled: isEventCatalogStarterEnabled2, isEventCatalogScaleEnabled: isEventCatalogScaleEnabled2, isBackstagePluginEnabled, command = "build" }) => {
416
436
  try {
417
437
  await verifyRequiredFieldsAreInCatalogConfigFile(projectDir);
418
438
  const configFile = await getEventCatalogConfigFile(projectDir);
@@ -429,11 +449,18 @@ var main = async (projectDir, { isEventCatalogStarterEnabled: isEventCatalogStar
429
449
  }
430
450
  const features = await getFeatures(configFile);
431
451
  const resourceCounts = await countResources(projectDir);
452
+ const contentHash = await hashCatalogContent(projectDir);
432
453
  await reportCloudResourceInventory(configFile, resourceCounts);
433
454
  await raiseEvent({
434
- command: "build",
455
+ command,
435
456
  org: organizationName,
436
457
  cId,
458
+ // CI redeploys and human-run builds are different signals; tag rather than suppress
459
+ ci: process.env.CI ? "true" : "false",
460
+ // The commercial plan, separate from the generators list, so telemetry joins cleanly to licensing
461
+ plan: isEventCatalogScaleEnabled2 ? "scale" : isEventCatalogStarterEnabled2 ? "starter" : "none",
462
+ backstage: isBackstagePluginEnabled ? "true" : "false",
463
+ contentHash,
437
464
  generators: generatorNames.toString(),
438
465
  features: Object.keys(features).map((feature) => `${feature}:${features[feature]}`).join(","),
439
466
  directorySources: serializeDirectorySources(configFile),
@@ -449,7 +476,7 @@ var import_watcher = __toESM(require("@parcel/watcher"), 1);
449
476
  var import_node_fs2 = __toESM(require("fs"), 1);
450
477
 
451
478
  // src/map-catalog-to-astro.js
452
- var import_node_path3 = __toESM(require("path"), 1);
479
+ var import_node_path4 = __toESM(require("path"), 1);
453
480
  var CUSTOM_PAGE_EXTENSIONS = [".astro", ".ts", ".js", ".mjs"];
454
481
  var COLLECTION_KEYS = [
455
482
  "agents",
@@ -479,10 +506,10 @@ function mapCatalogToAstro({ filePath, astroDir, projectDir }) {
479
506
  }
480
507
  const baseTargetPaths = getBaseTargetPaths(relativeFilePath);
481
508
  const relativeTargetPath = getRelativeTargetPath(relativeFilePath);
482
- return baseTargetPaths.map((base) => import_node_path3.default.join(astroDir, base, relativeTargetPath));
509
+ return baseTargetPaths.map((base) => import_node_path4.default.join(astroDir, base, relativeTargetPath));
483
510
  }
484
511
  function removeBasePath(fullPath, basePath) {
485
- const relativePath = import_node_path3.default.relative(basePath, fullPath);
512
+ const relativePath = import_node_path4.default.relative(basePath, fullPath);
486
513
  return relativePath.startsWith("..") ? fullPath : relativePath;
487
514
  }
488
515
  function isCollectionKey(key) {
@@ -493,21 +520,21 @@ function isLikeC4Source(filePath) {
493
520
  }
494
521
  var hasExtension = (str) => /\.[a-zA-Z0-9]{2,}$/.test(str);
495
522
  function getCustomPageTargetPaths(filePath, astroDir) {
496
- const filePathArr = filePath.split(import_node_path3.default.sep).filter(Boolean);
523
+ const filePathArr = filePath.split(import_node_path4.default.sep).filter(Boolean);
497
524
  if (filePathArr[0] !== "pages") {
498
525
  return null;
499
526
  }
500
- const customPagePath = import_node_path3.default.join(astroDir, "src", "custom-pages", ...filePathArr.slice(1));
501
- if (CUSTOM_PAGE_EXTENSIONS.includes(import_node_path3.default.extname(filePath).toLowerCase())) {
527
+ const customPagePath = import_node_path4.default.join(astroDir, "src", "custom-pages", ...filePathArr.slice(1));
528
+ if (CUSTOM_PAGE_EXTENSIONS.includes(import_node_path4.default.extname(filePath).toLowerCase())) {
502
529
  return [customPagePath];
503
530
  }
504
531
  if (!hasExtension(filePath)) {
505
- return [customPagePath, import_node_path3.default.join(astroDir, "public", "generated", ...filePathArr)];
532
+ return [customPagePath, import_node_path4.default.join(astroDir, "public", "generated", ...filePathArr)];
506
533
  }
507
- return [import_node_path3.default.join(astroDir, "public", "generated", ...filePathArr)];
534
+ return [import_node_path4.default.join(astroDir, "public", "generated", ...filePathArr)];
508
535
  }
509
536
  function isCatalogRelated(filePath) {
510
- const filePathArr = filePath.split(import_node_path3.default.sep).filter(Boolean);
537
+ const filePathArr = filePath.split(import_node_path4.default.sep).filter(Boolean);
511
538
  if ([
512
539
  "eventcatalog.config.js",
513
540
  // config file at root
@@ -528,38 +555,38 @@ function isCatalogRelated(filePath) {
528
555
  return false;
529
556
  }
530
557
  function getBaseTargetPaths(filePath) {
531
- const filePathArr = filePath.split(import_node_path3.default.sep).filter(Boolean);
558
+ const filePathArr = filePath.split(import_node_path4.default.sep).filter(Boolean);
532
559
  if (isCollectionKey(filePathArr[0])) {
533
560
  if (hasExtension(filePath)) {
534
- return [import_node_path3.default.join("public", "generated")];
561
+ return [import_node_path4.default.join("public", "generated")];
535
562
  }
536
- return [import_node_path3.default.join("public", "generated")];
563
+ return [import_node_path4.default.join("public", "generated")];
537
564
  }
538
565
  if (filePathArr[0] == "components") {
539
- return [import_node_path3.default.join("src", "custom-defined-components")];
566
+ return [import_node_path4.default.join("src", "custom-defined-components")];
540
567
  }
541
568
  if (filePathArr[0] == "snippets") {
542
- return [import_node_path3.default.join("src")];
569
+ return [import_node_path4.default.join("src")];
543
570
  }
544
571
  if (filePathArr[0] == "public") {
545
- return [import_node_path3.default.join("public")];
572
+ return [import_node_path4.default.join("public")];
546
573
  }
547
- return [import_node_path3.default.join("/")];
574
+ return [import_node_path4.default.join("/")];
548
575
  }
549
576
  function getRelativeTargetPath(filePath) {
550
- const filePathArr = filePath.split(import_node_path3.default.sep).filter(Boolean);
577
+ const filePathArr = filePath.split(import_node_path4.default.sep).filter(Boolean);
551
578
  if (filePathArr[0] == "public" || filePathArr[0] == "components") {
552
579
  filePathArr.shift();
553
580
  }
554
581
  if (filePathArr[0] == "snippets") {
555
- return import_node_path3.default.join("snippets", ...filePathArr.slice(1));
582
+ return import_node_path4.default.join("snippets", ...filePathArr.slice(1));
556
583
  }
557
584
  const relativePath = [];
558
585
  for (let i = filePathArr.length - 1; i >= 0; i--) {
559
586
  relativePath.unshift(filePathArr[i]);
560
587
  if (isCollectionKey(filePathArr[i]) && filePathArr[i] != "snippets") break;
561
588
  }
562
- return import_node_path3.default.join(...relativePath);
589
+ return import_node_path4.default.join(...relativePath);
563
590
  }
564
591
 
565
592
  // src/watcher.js
@@ -656,21 +683,21 @@ function retryEPERM(fn) {
656
683
 
657
684
  // src/catalog-to-astro-content-directory.js
658
685
  var import_glob2 = require("glob");
659
- var path5 = __toESM(require("path"), 1);
686
+ var path6 = __toESM(require("path"), 1);
660
687
  var import_fs = __toESM(require("fs"), 1);
661
688
  var import_url2 = require("url");
662
689
  var import_node_os2 = __toESM(require("os"), 1);
663
690
 
664
691
  // src/custom-components.js
665
- var import_promises2 = __toESM(require("fs/promises"), 1);
666
- var import_node_path4 = __toESM(require("path"), 1);
692
+ var import_promises3 = __toESM(require("fs/promises"), 1);
693
+ var import_node_path5 = __toESM(require("path"), 1);
667
694
  var isCustomComponentPath = (projectDirectory, filePath) => {
668
- const [rootDirectory, childDirectory] = import_node_path4.default.relative(projectDirectory, filePath).split(import_node_path4.default.sep);
695
+ const [rootDirectory, childDirectory] = import_node_path5.default.relative(projectDirectory, filePath).split(import_node_path5.default.sep);
669
696
  return rootDirectory === "components" || rootDirectory === "federated" && childDirectory === "components";
670
697
  };
671
698
  var readDirectory = async (directory) => {
672
699
  try {
673
- return await import_promises2.default.readdir(directory, { withFileTypes: true });
700
+ return await import_promises3.default.readdir(directory, { withFileTypes: true });
674
701
  } catch (error) {
675
702
  if (error.code === "ENOENT") return [];
676
703
  throw error;
@@ -678,57 +705,57 @@ var readDirectory = async (directory) => {
678
705
  };
679
706
  var mergeDirectory = async (sourceDirectory, destinationDirectory) => {
680
707
  for (const entry of await readDirectory(sourceDirectory)) {
681
- const sourcePath = import_node_path4.default.join(sourceDirectory, entry.name);
682
- const destinationPath = import_node_path4.default.join(destinationDirectory, entry.name);
708
+ const sourcePath = import_node_path5.default.join(sourceDirectory, entry.name);
709
+ const destinationPath = import_node_path5.default.join(destinationDirectory, entry.name);
683
710
  if (entry.isDirectory()) {
684
- const destinationEntry = await import_promises2.default.stat(destinationPath).catch((error) => {
711
+ const destinationEntry = await import_promises3.default.stat(destinationPath).catch((error) => {
685
712
  if (error.code === "ENOENT") return void 0;
686
713
  throw error;
687
714
  });
688
715
  if (destinationEntry && !destinationEntry.isDirectory()) {
689
- await import_promises2.default.rm(destinationPath, { recursive: true, force: true });
716
+ await import_promises3.default.rm(destinationPath, { recursive: true, force: true });
690
717
  }
691
- await import_promises2.default.mkdir(destinationPath, { recursive: true });
718
+ await import_promises3.default.mkdir(destinationPath, { recursive: true });
692
719
  await mergeDirectory(sourcePath, destinationPath);
693
720
  continue;
694
721
  }
695
- await import_promises2.default.rm(destinationPath, { recursive: true, force: true });
696
- await import_promises2.default.copyFile(sourcePath, destinationPath);
722
+ await import_promises3.default.rm(destinationPath, { recursive: true, force: true });
723
+ await import_promises3.default.copyFile(sourcePath, destinationPath);
697
724
  }
698
725
  };
699
726
  var syncCustomComponents = async (projectDirectory, catalogDirectory) => {
700
- const destinationDirectory = import_node_path4.default.join(catalogDirectory, "src", "custom-defined-components");
701
- const destinationParent = import_node_path4.default.dirname(destinationDirectory);
702
- await import_promises2.default.mkdir(destinationParent, { recursive: true });
703
- const stagingDirectory = await import_promises2.default.mkdtemp(import_node_path4.default.join(destinationParent, ".custom-defined-components.staging-"));
727
+ const destinationDirectory = import_node_path5.default.join(catalogDirectory, "src", "custom-defined-components");
728
+ const destinationParent = import_node_path5.default.dirname(destinationDirectory);
729
+ await import_promises3.default.mkdir(destinationParent, { recursive: true });
730
+ const stagingDirectory = await import_promises3.default.mkdtemp(import_node_path5.default.join(destinationParent, ".custom-defined-components.staging-"));
704
731
  try {
705
- await mergeDirectory(import_node_path4.default.join(projectDirectory, "federated", "components"), stagingDirectory);
706
- await mergeDirectory(import_node_path4.default.join(projectDirectory, "components"), stagingDirectory);
707
- await import_promises2.default.rm(destinationDirectory, { recursive: true, force: true });
708
- await import_promises2.default.rename(stagingDirectory, destinationDirectory);
732
+ await mergeDirectory(import_node_path5.default.join(projectDirectory, "federated", "components"), stagingDirectory);
733
+ await mergeDirectory(import_node_path5.default.join(projectDirectory, "components"), stagingDirectory);
734
+ await import_promises3.default.rm(destinationDirectory, { recursive: true, force: true });
735
+ await import_promises3.default.rename(stagingDirectory, destinationDirectory);
709
736
  } finally {
710
- await import_promises2.default.rm(stagingDirectory, { recursive: true, force: true });
737
+ await import_promises3.default.rm(stagingDirectory, { recursive: true, force: true });
711
738
  }
712
739
  };
713
740
 
714
741
  // src/catalog-to-astro-content-directory.js
715
742
  var __filename2 = (0, import_url2.fileURLToPath)(importMetaUrl);
716
- var rootPkg = path5.resolve(path5.dirname(__filename2), "../");
743
+ var rootPkg = path6.resolve(path6.dirname(__filename2), "../");
717
744
  var copyFiles = async (source, target) => {
718
- const files = await (0, import_glob2.glob)(path5.join(source, "**"), {
745
+ const files = await (0, import_glob2.glob)(path6.join(source, "**"), {
719
746
  nodir: true,
720
747
  windowsPathsNoEscape: import_node_os2.default.platform() == "win32",
721
748
  ignore: ["node_modules/**", "**/dist/**", "**/teams", "**/users", "**/*.mdx", "**/*.md", "**/package.json", "**/Dockerfile"]
722
749
  });
723
- const snippets = await (0, import_glob2.glob)(path5.join(source, "snippets/**/*.mdx"), {
750
+ const snippets = await (0, import_glob2.glob)(path6.join(source, "snippets/**/*.mdx"), {
724
751
  nodir: true,
725
752
  windowsPathsNoEscape: import_node_os2.default.platform() == "win32"
726
753
  });
727
754
  if (snippets.length > 0) {
728
755
  files.push(...snippets);
729
756
  }
730
- if (import_fs.default.existsSync(path5.join(source, ".env"))) {
731
- files.push(path5.join(source, ".env"));
757
+ if (import_fs.default.existsSync(path6.join(source, ".env"))) {
758
+ files.push(path6.join(source, ".env"));
732
759
  }
733
760
  for (const file of files) {
734
761
  if (isCustomComponentPath(source, file)) continue;
@@ -743,9 +770,9 @@ var copyFiles = async (source, target) => {
743
770
  }
744
771
  };
745
772
  var clearCustomPages = async (target) => {
746
- const customPagesDir = path5.join(target, "src", "custom-pages");
773
+ const customPagesDir = path6.join(target, "src", "custom-pages");
747
774
  if (import_fs.default.existsSync(customPagesDir)) import_fs.default.rmSync(customPagesDir, { recursive: true });
748
- const staleCodeFiles = await (0, import_glob2.glob)(path5.join(target, "public", "generated", "pages", "**/*.{astro,ts,js,mjs}"), {
775
+ const staleCodeFiles = await (0, import_glob2.glob)(path6.join(target, "public", "generated", "pages", "**/*.{astro,ts,js,mjs}"), {
749
776
  nodir: true,
750
777
  windowsPathsNoEscape: import_node_os2.default.platform() == "win32"
751
778
  });
@@ -754,8 +781,8 @@ var clearCustomPages = async (target) => {
754
781
  }
755
782
  };
756
783
  var removeGeneratedLikeC4Sources = async (target) => {
757
- const generatedDir = path5.join(target, "public", "generated");
758
- const files = await (0, import_glob2.glob)(path5.join(generatedDir, "**/*.{c4,likec4}"), {
784
+ const generatedDir = path6.join(target, "public", "generated");
785
+ const files = await (0, import_glob2.glob)(path6.join(generatedDir, "**/*.{c4,likec4}"), {
759
786
  nodir: true,
760
787
  windowsPathsNoEscape: import_node_os2.default.platform() == "win32"
761
788
  });
@@ -764,12 +791,12 @@ var removeGeneratedLikeC4Sources = async (target) => {
764
791
  }
765
792
  };
766
793
  var catalogToAstro = async (source, astroDir) => {
767
- const astroContentDir = path5.join(astroDir, "src/content/");
794
+ const astroContentDir = path6.join(astroDir, "src/content/");
768
795
  if (import_fs.default.existsSync(astroContentDir)) import_fs.default.rmSync(astroContentDir, { recursive: true });
769
796
  import_fs.default.mkdirSync(astroContentDir);
770
797
  await verifyRequiredFieldsAreInCatalogConfigFile(source);
771
- if (!import_fs.default.existsSync(path5.join(source, "eventcatalog.styles.css"))) {
772
- import_fs.default.writeFileSync(path5.join(source, "eventcatalog.styles.css"), "");
798
+ if (!import_fs.default.existsSync(path6.join(source, "eventcatalog.styles.css"))) {
799
+ import_fs.default.writeFileSync(path6.join(source, "eventcatalog.styles.css"), "");
773
800
  }
774
801
  await clearCustomPages(astroDir);
775
802
  await removeGeneratedLikeC4Sources(astroDir);
@@ -778,7 +805,7 @@ var catalogToAstro = async (source, astroDir) => {
778
805
  };
779
806
 
780
807
  // src/resolve-catalog-dependencies.js
781
- var import_node_path5 = __toESM(require("path"), 1);
808
+ var import_node_path6 = __toESM(require("path"), 1);
782
809
  var import_node_fs3 = __toESM(require("fs"), 1);
783
810
  var import_gray_matter2 = __toESM(require("gray-matter"), 1);
784
811
  var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
@@ -787,7 +814,7 @@ var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
787
814
  if (!dependencies) {
788
815
  return;
789
816
  }
790
- const dependenciesDir = import_node_path5.default.join(catalogDir, "dependencies");
817
+ const dependenciesDir = import_node_path6.default.join(catalogDir, "dependencies");
791
818
  if (import_node_fs3.default.existsSync(dependenciesDir)) {
792
819
  import_node_fs3.default.rmSync(dependenciesDir, { recursive: true, force: true });
793
820
  }
@@ -811,8 +838,8 @@ var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
811
838
  },
812
839
  frontmatter
813
840
  );
814
- const resourceFile = import_node_path5.default.join(dependenciesDir, resourceType, dependency.id, `index.md`);
815
- import_node_fs3.default.mkdirSync(import_node_path5.default.dirname(resourceFile), { recursive: true });
841
+ const resourceFile = import_node_path6.default.join(dependenciesDir, resourceType, dependency.id, `index.md`);
842
+ import_node_fs3.default.mkdirSync(import_node_path6.default.dirname(resourceFile), { recursive: true });
816
843
  import_node_fs3.default.writeFileSync(resourceFile, markdown);
817
844
  }
818
845
  }
@@ -823,7 +850,7 @@ var resolve_catalog_dependencies_default = async (catalogDir, core2) => {
823
850
  var import_boxen = __toESM(require("boxen"), 1);
824
851
 
825
852
  // src/features.ts
826
- var import_node_path6 = require("path");
853
+ var import_node_path7 = require("path");
827
854
  var import_node_fs4 = __toESM(require("fs"), 1);
828
855
  var getProjectOutDir = async () => {
829
856
  const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
@@ -839,7 +866,7 @@ var isIndexedSearchEnabled = async () => {
839
866
  };
840
867
  var isAuthEnabled = async () => {
841
868
  const directory = process.env.PROJECT_DIR || process.cwd();
842
- const hasAuthConfig = import_node_fs4.default.existsSync((0, import_node_path6.join)(directory, "eventcatalog.auth.js"));
869
+ const hasAuthConfig = import_node_fs4.default.existsSync((0, import_node_path7.join)(directory, "eventcatalog.auth.js"));
843
870
  return hasAuthConfig;
844
871
  };
845
872
 
@@ -852,7 +879,7 @@ var import_node_fs5 = __toESM(require("fs"), 1);
852
879
  var import_glob3 = require("glob");
853
880
  var import_node_os3 = __toESM(require("os"), 1);
854
881
  var import_gray_matter3 = __toESM(require("gray-matter"), 1);
855
- var import_node_path7 = __toESM(require("path"), 1);
882
+ var import_node_path8 = __toESM(require("path"), 1);
856
883
  var DISABLE_CHANNEL_MIGRATION_ENV = "EVENTCATALOG_DISABLE_CHANNEL_MIGRATION";
857
884
  var isChannelMigrationDisabled = () => {
858
885
  return ["true", "1", "yes"].includes((process.env[DISABLE_CHANNEL_MIGRATION_ENV] ?? "").toLowerCase());
@@ -861,7 +888,7 @@ var message_channels_to_service_channels_default = async (dir2) => {
861
888
  if (isChannelMigrationDisabled()) {
862
889
  return { status: "skipped", message: `Channel migration disabled by ${DISABLE_CHANNEL_MIGRATION_ENV}` };
863
890
  }
864
- const PROJECT_DIR = import_node_path7.default.join(dir2 || process.env.PROJECT_DIR);
891
+ const PROJECT_DIR = import_node_path8.default.join(dir2 || process.env.PROJECT_DIR);
865
892
  const messages = await (0, import_glob3.glob)(
866
893
  [
867
894
  "**/events/*/index.mdx",
@@ -968,7 +995,7 @@ var runMigrations = async (dir2) => {
968
995
  };
969
996
 
970
997
  // eventcatalog/src/enterprise/fields/field-indexer.ts
971
- var import_node_path8 = __toESM(require("path"), 1);
998
+ var import_node_path9 = __toESM(require("path"), 1);
972
999
  var import_node_fs7 = __toESM(require("fs"), 1);
973
1000
 
974
1001
  // eventcatalog/src/enterprise/fields/fields-db.ts
@@ -1334,22 +1361,22 @@ function getAvroTypeName(type) {
1334
1361
  function walkAvroRecord(schema, prefix, fields) {
1335
1362
  if (!schema.fields || !Array.isArray(schema.fields)) return;
1336
1363
  for (const field of schema.fields) {
1337
- const path18 = prefix ? `${prefix}.${field.name}` : field.name;
1364
+ const path19 = prefix ? `${prefix}.${field.name}` : field.name;
1338
1365
  const isOptional = Array.isArray(field.type) && field.type.includes("null");
1339
1366
  const typeName = getAvroTypeName(field.type);
1340
1367
  fields.push({
1341
- path: path18,
1368
+ path: path19,
1342
1369
  type: typeName,
1343
1370
  description: field.doc || "",
1344
1371
  required: !isOptional
1345
1372
  });
1346
1373
  const innerType = Array.isArray(field.type) ? field.type.find((t) => typeof t === "object" && t.type === "record") : typeof field.type === "object" && field.type.type === "record" ? field.type : null;
1347
1374
  if (innerType) {
1348
- walkAvroRecord(innerType, path18, fields);
1375
+ walkAvroRecord(innerType, path19, fields);
1349
1376
  }
1350
1377
  const arrayType = Array.isArray(field.type) ? field.type.find((t) => typeof t === "object" && t.type === "array") : typeof field.type === "object" && field.type.type === "array" ? field.type : null;
1351
1378
  if (arrayType && typeof arrayType.items === "object" && arrayType.items.type === "record") {
1352
- walkAvroRecord(arrayType.items, `${path18}[]`, fields);
1379
+ walkAvroRecord(arrayType.items, `${path19}[]`, fields);
1353
1380
  }
1354
1381
  }
1355
1382
  }
@@ -1380,32 +1407,32 @@ function walkJsonSchema(node, prefix, requiredList, rootSchema, fields) {
1380
1407
  }
1381
1408
  if (!node.properties) return;
1382
1409
  for (const [name, prop] of Object.entries(node.properties)) {
1383
- const path18 = prefix ? `${prefix}.${name}` : name;
1410
+ const path19 = prefix ? `${prefix}.${name}` : name;
1384
1411
  const isRequired = requiredList.includes(name);
1385
1412
  if (prop.$ref) {
1386
1413
  const resolved = resolveLocalRef(prop.$ref, rootSchema);
1387
1414
  if (resolved) {
1388
1415
  const rawRefType = resolved.type || "object";
1389
1416
  const type2 = Array.isArray(rawRefType) ? [...rawRefType].sort().join(" | ") : rawRefType;
1390
- fields.push({ path: path18, type: type2, description: resolved.description || "", required: isRequired });
1417
+ fields.push({ path: path19, type: type2, description: resolved.description || "", required: isRequired });
1391
1418
  if (resolved.properties) {
1392
- walkJsonSchema(resolved, path18, resolved.required || [], rootSchema, fields);
1419
+ walkJsonSchema(resolved, path19, resolved.required || [], rootSchema, fields);
1393
1420
  }
1394
1421
  } else {
1395
- fields.push({ path: path18, type: "$ref", description: "", required: isRequired });
1422
+ fields.push({ path: path19, type: "$ref", description: "", required: isRequired });
1396
1423
  }
1397
1424
  continue;
1398
1425
  }
1399
1426
  const rawType = prop.type || (prop.enum ? "enum" : prop.$ref ? "$ref" : "object");
1400
1427
  const typeList = Array.isArray(rawType) ? rawType : [rawType];
1401
1428
  const type = Array.isArray(rawType) ? [...rawType].sort().join(" | ") : rawType;
1402
- fields.push({ path: path18, type, description: prop.description || "", required: isRequired });
1429
+ fields.push({ path: path19, type, description: prop.description || "", required: isRequired });
1403
1430
  if (typeList.includes("object") && prop.properties) {
1404
- walkJsonSchema(prop, path18, prop.required || [], rootSchema, fields);
1431
+ walkJsonSchema(prop, path19, prop.required || [], rootSchema, fields);
1405
1432
  }
1406
1433
  if (typeList.includes("array") && prop.items) {
1407
1434
  if (prop.items.type === "object" && prop.items.properties) {
1408
- walkJsonSchema(prop.items, `${path18}[]`, prop.items.required || [], rootSchema, fields);
1435
+ walkJsonSchema(prop.items, `${path19}[]`, prop.items.required || [], rootSchema, fields);
1409
1436
  }
1410
1437
  }
1411
1438
  }
@@ -1423,7 +1450,7 @@ function resolveLocalRef(ref, rootSchema) {
1423
1450
 
1424
1451
  // eventcatalog/src/enterprise/fields/field-indexer.ts
1425
1452
  function detectFormat(fileName) {
1426
- const ext = import_node_path8.default.extname(fileName).toLowerCase();
1453
+ const ext = import_node_path9.default.extname(fileName).toLowerCase();
1427
1454
  if (ext === ".proto") return "proto";
1428
1455
  if (ext === ".avro" || ext === ".avsc") return "avro";
1429
1456
  return "json-schema";
@@ -1431,8 +1458,8 @@ function detectFormat(fileName) {
1431
1458
  async function buildFieldsIndex(catalogDir, outputDir) {
1432
1459
  const sdkModule = await import("@eventcatalog/sdk");
1433
1460
  const sdk = sdkModule.default(catalogDir);
1434
- const dbDir = import_node_path8.default.join(outputDir || catalogDir, ".eventcatalog");
1435
- const dbPath = import_node_path8.default.join(dbDir, "fields.db");
1461
+ const dbDir = import_node_path9.default.join(outputDir || catalogDir, ".eventcatalog");
1462
+ const dbPath = import_node_path9.default.join(dbDir, "fields.db");
1436
1463
  if (!import_node_fs7.default.existsSync(dbDir)) {
1437
1464
  import_node_fs7.default.mkdirSync(dbDir, { recursive: true });
1438
1465
  }
@@ -1517,8 +1544,8 @@ async function buildFieldsIndex(catalogDir, outputDir) {
1517
1544
  }
1518
1545
 
1519
1546
  // src/search-indexer.ts
1520
- var import_promises3 = __toESM(require("fs/promises"), 1);
1521
- var import_node_path9 = __toESM(require("path"), 1);
1547
+ var import_promises4 = __toESM(require("fs/promises"), 1);
1548
+ var import_node_path10 = __toESM(require("path"), 1);
1522
1549
  var import_glob4 = require("glob");
1523
1550
  var import_gray_matter4 = __toESM(require("gray-matter"), 1);
1524
1551
  var RESOURCE_COLLECTIONS = {
@@ -1581,9 +1608,9 @@ var markdownToSearchText = (content) => {
1581
1608
  };
1582
1609
  var inferDocIdFromFile = (relativePath, frontmatterId) => {
1583
1610
  if (frontmatterId) return frontmatterId;
1584
- const fileName = import_node_path9.default.posix.basename(removeExtension(relativePath));
1611
+ const fileName = import_node_path10.default.posix.basename(removeExtension(relativePath));
1585
1612
  if (fileName.toLowerCase() === "index") {
1586
- return import_node_path9.default.posix.basename(import_node_path9.default.posix.dirname(relativePath));
1613
+ return import_node_path10.default.posix.basename(import_node_path10.default.posix.dirname(relativePath));
1587
1614
  }
1588
1615
  return stripNumericPrefix(fileName);
1589
1616
  };
@@ -1601,10 +1628,10 @@ var findResourceSegment = (segments) => {
1601
1628
  return match;
1602
1629
  };
1603
1630
  var readResourceFrontmatter = async (projectDir, resourcePath) => {
1604
- const candidates = [import_node_path9.default.join(projectDir, resourcePath, "index.mdx"), import_node_path9.default.join(projectDir, resourcePath, "index.md")];
1631
+ const candidates = [import_node_path10.default.join(projectDir, resourcePath, "index.mdx"), import_node_path10.default.join(projectDir, resourcePath, "index.md")];
1605
1632
  for (const candidate of candidates) {
1606
1633
  try {
1607
- const file = await import_promises3.default.readFile(candidate, "utf8");
1634
+ const file = await import_promises4.default.readFile(candidate, "utf8");
1608
1635
  return (0, import_gray_matter4.default)(file).data;
1609
1636
  } catch {
1610
1637
  }
@@ -1626,7 +1653,7 @@ var deriveRecordFromPath = async ({
1626
1653
  }
1627
1654
  if (segments[0] === "docs") {
1628
1655
  const customPath = normalizeUrlPath(removeExtension(segments.slice(1).join("/")));
1629
- const title = data.title || data.label || import_node_path9.default.posix.basename(customPath) || "Custom docs";
1656
+ const title = data.title || data.label || import_node_path10.default.posix.basename(customPath) || "Custom docs";
1630
1657
  return {
1631
1658
  url: buildUrl(`/docs/custom/${customPath}`, config),
1632
1659
  title,
@@ -1742,9 +1769,9 @@ var collectSearchRecords = async ({
1742
1769
  });
1743
1770
  const records = await Promise.all(
1744
1771
  files.map(async (file) => {
1745
- const raw = await import_promises3.default.readFile(file, "utf8");
1772
+ const raw = await import_promises4.default.readFile(file, "utf8");
1746
1773
  const parsed = (0, import_gray_matter4.default)(raw);
1747
- const relativePath = normalizePath(import_node_path9.default.relative(projectDir, file));
1774
+ const relativePath = normalizePath(import_node_path10.default.relative(projectDir, file));
1748
1775
  const baseRecord = await deriveRecordFromPath({
1749
1776
  projectDir,
1750
1777
  relativePath,
@@ -1792,7 +1819,7 @@ var getSearchOutputPath = ({
1792
1819
  if (searchOutputPath) {
1793
1820
  return searchOutputPath;
1794
1821
  }
1795
- return import_node_path9.default.join(outDir, isServer ? "client" : "", "pagefind");
1822
+ return import_node_path10.default.join(outDir, isServer ? "client" : "", "pagefind");
1796
1823
  };
1797
1824
  var buildSearchIndex = async ({ projectDir, outDir, config, isServer, searchOutputPath }) => {
1798
1825
  const records = await collectSearchRecords({ projectDir, config });
@@ -1828,7 +1855,7 @@ var buildSearchIndex = async ({ projectDir, outDir, config, isServer, searchOutp
1828
1855
  }
1829
1856
  }
1830
1857
  const outputPath = getSearchOutputPath({ outDir, isServer, searchOutputPath });
1831
- await import_promises3.default.rm(outputPath, { recursive: true, force: true });
1858
+ await import_promises4.default.rm(outputPath, { recursive: true, force: true });
1832
1859
  const writeResult = await index.writeFiles({ outputPath });
1833
1860
  if (writeResult.errors?.length) {
1834
1861
  errors.push(...writeResult.errors.map((error) => error.message || String(error)));
@@ -1847,7 +1874,7 @@ ${errors.join("\n")}`);
1847
1874
 
1848
1875
  // src/core-node-modules.ts
1849
1876
  var import_fs2 = __toESM(require("fs"), 1);
1850
- var import_node_path10 = __toESM(require("path"), 1);
1877
+ var import_node_path11 = __toESM(require("path"), 1);
1851
1878
  var isDirectory = (directory) => {
1852
1879
  try {
1853
1880
  return import_fs2.default.statSync(directory).isDirectory();
@@ -1857,7 +1884,7 @@ var isDirectory = (directory) => {
1857
1884
  };
1858
1885
  var hasAstroDependency = (nodeModulesDirectory) => {
1859
1886
  const astroBin = process.platform === "win32" ? "astro.cmd" : "astro";
1860
- return import_fs2.default.existsSync(import_node_path10.default.join(nodeModulesDirectory, "astro", "package.json")) || import_fs2.default.existsSync(import_node_path10.default.join(nodeModulesDirectory, ".bin", astroBin));
1887
+ return import_fs2.default.existsSync(import_node_path11.default.join(nodeModulesDirectory, "astro", "package.json")) || import_fs2.default.existsSync(import_node_path11.default.join(nodeModulesDirectory, ".bin", astroBin));
1861
1888
  };
1862
1889
  var isSymbolicLink = (targetPath) => {
1863
1890
  try {
@@ -1877,20 +1904,20 @@ var resolveInstalledCoreNodeModules = (currentDir2) => {
1877
1904
  const candidates = [];
1878
1905
  const seen = /* @__PURE__ */ new Set();
1879
1906
  const addCandidate = (candidate) => {
1880
- const resolvedCandidate = import_node_path10.default.resolve(candidate);
1907
+ const resolvedCandidate = import_node_path11.default.resolve(candidate);
1881
1908
  if (!seen.has(resolvedCandidate)) {
1882
1909
  candidates.push(resolvedCandidate);
1883
1910
  seen.add(resolvedCandidate);
1884
1911
  }
1885
1912
  };
1886
- addCandidate(import_node_path10.default.resolve(currentDir2, "..", "node_modules"));
1887
- let directory = import_node_path10.default.resolve(currentDir2);
1913
+ addCandidate(import_node_path11.default.resolve(currentDir2, "..", "node_modules"));
1914
+ let directory = import_node_path11.default.resolve(currentDir2);
1888
1915
  while (true) {
1889
- if (import_node_path10.default.basename(directory) === "node_modules") {
1916
+ if (import_node_path11.default.basename(directory) === "node_modules") {
1890
1917
  addCandidate(directory);
1891
1918
  }
1892
- addCandidate(import_node_path10.default.join(directory, "node_modules"));
1893
- const parentDirectory = import_node_path10.default.dirname(directory);
1919
+ addCandidate(import_node_path11.default.join(directory, "node_modules"));
1920
+ const parentDirectory = import_node_path11.default.dirname(directory);
1894
1921
  if (parentDirectory === directory) {
1895
1922
  break;
1896
1923
  }
@@ -1929,28 +1956,28 @@ var createAstroDevLineFilter = () => {
1929
1956
  };
1930
1957
 
1931
1958
  // src/federation/federate.ts
1932
- var import_node_crypto4 = require("crypto");
1933
- var import_promises9 = __toESM(require("fs/promises"), 1);
1934
- var import_node_path16 = __toESM(require("path"), 1);
1959
+ var import_node_crypto5 = require("crypto");
1960
+ var import_promises10 = __toESM(require("fs/promises"), 1);
1961
+ var import_node_path17 = __toESM(require("path"), 1);
1935
1962
  var import_sdk3 = __toESM(require("@eventcatalog/sdk"), 1);
1936
1963
 
1937
1964
  // src/federation/content-cache.ts
1938
- var import_node_crypto = require("crypto");
1939
- var import_promises4 = __toESM(require("fs/promises"), 1);
1940
- var import_node_path11 = __toESM(require("path"), 1);
1941
- var getContentHash = (content) => `sha256:${(0, import_node_crypto.createHash)("sha256").update(content).digest("hex")}`;
1965
+ var import_node_crypto2 = require("crypto");
1966
+ var import_promises5 = __toESM(require("fs/promises"), 1);
1967
+ var import_node_path12 = __toESM(require("path"), 1);
1968
+ var getContentHash = (content) => `sha256:${(0, import_node_crypto2.createHash)("sha256").update(content).digest("hex")}`;
1942
1969
  var isContentHash = (key) => /^sha256:[a-f0-9]{64}$/i.test(key);
1943
1970
  var createFederationContentCache = (projectDirectory, options = {}) => {
1944
- const cacheDirectory = import_node_path11.default.join(projectDirectory, ".eventcatalog-cache", "federation", "content");
1945
- const getCachePath = (key) => import_node_path11.default.join(cacheDirectory, encodeURIComponent(key));
1971
+ const cacheDirectory = import_node_path12.default.join(projectDirectory, ".eventcatalog-cache", "federation", "content");
1972
+ const getCachePath = (key) => import_node_path12.default.join(cacheDirectory, encodeURIComponent(key));
1946
1973
  return {
1947
1974
  async get(key) {
1948
1975
  if (options.read === false || !isContentHash(key)) return void 0;
1949
1976
  const cachePath = getCachePath(key);
1950
1977
  try {
1951
- const content = await import_promises4.default.readFile(cachePath);
1978
+ const content = await import_promises5.default.readFile(cachePath);
1952
1979
  if (getContentHash(content) !== key) {
1953
- await import_promises4.default.rm(cachePath, { force: true });
1980
+ await import_promises5.default.rm(cachePath, { force: true });
1954
1981
  return void 0;
1955
1982
  }
1956
1983
  options.onHit?.(key);
@@ -1962,14 +1989,14 @@ var createFederationContentCache = (projectDirectory, options = {}) => {
1962
1989
  },
1963
1990
  async set(key, content) {
1964
1991
  if (!isContentHash(key) || getContentHash(content) !== key) return;
1965
- await import_promises4.default.mkdir(cacheDirectory, { recursive: true });
1992
+ await import_promises5.default.mkdir(cacheDirectory, { recursive: true });
1966
1993
  const cachePath = getCachePath(key);
1967
- const temporaryPath = `${cachePath}.tmp-${process.pid}-${(0, import_node_crypto.randomUUID)()}`;
1994
+ const temporaryPath = `${cachePath}.tmp-${process.pid}-${(0, import_node_crypto2.randomUUID)()}`;
1968
1995
  try {
1969
- await import_promises4.default.writeFile(temporaryPath, content);
1970
- await import_promises4.default.rename(temporaryPath, cachePath);
1996
+ await import_promises5.default.writeFile(temporaryPath, content);
1997
+ await import_promises5.default.rename(temporaryPath, cachePath);
1971
1998
  } finally {
1972
- await import_promises4.default.rm(temporaryPath, { force: true });
1999
+ await import_promises5.default.rm(temporaryPath, { force: true });
1973
2000
  }
1974
2001
  }
1975
2002
  };
@@ -2132,21 +2159,21 @@ var import_license = require("@eventcatalog/license");
2132
2159
  var isFederationEnabled = () => (0, import_license.isEventCatalogEnterpriseEnabled)();
2133
2160
 
2134
2161
  // src/federation/output-transaction.ts
2135
- var import_promises5 = __toESM(require("fs/promises"), 1);
2136
- var import_node_path12 = __toESM(require("path"), 1);
2162
+ var import_promises6 = __toESM(require("fs/promises"), 1);
2163
+ var import_node_path13 = __toESM(require("path"), 1);
2137
2164
  var getSafePublicPath = (publicDirectory, relativePath) => {
2138
- const normalizedPath = import_node_path12.default.posix.normalize(relativePath);
2139
- const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path12.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2165
+ const normalizedPath = import_node_path13.default.posix.normalize(relativePath);
2166
+ const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path13.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2140
2167
  if (unsafe) return void 0;
2141
- const destinationPath = import_node_path12.default.resolve(publicDirectory, relativePath);
2142
- const relativeDestinationPath = import_node_path12.default.relative(publicDirectory, destinationPath);
2143
- return relativeDestinationPath !== "" && relativeDestinationPath !== ".." && !relativeDestinationPath.startsWith(`..${import_node_path12.default.sep}`) && !import_node_path12.default.isAbsolute(relativeDestinationPath) ? destinationPath : void 0;
2168
+ const destinationPath = import_node_path13.default.resolve(publicDirectory, relativePath);
2169
+ const relativeDestinationPath = import_node_path13.default.relative(publicDirectory, destinationPath);
2170
+ return relativeDestinationPath !== "" && relativeDestinationPath !== ".." && !relativeDestinationPath.startsWith(`..${import_node_path13.default.sep}`) && !import_node_path13.default.isAbsolute(relativeDestinationPath) ? destinationPath : void 0;
2144
2171
  };
2145
2172
  var beginFederationOutputTransaction = async (projectDirectory, outDir, relativePublicPaths) => {
2146
- const transactionDirectory = await import_promises5.default.mkdtemp(import_node_path12.default.join(projectDirectory, ".eventcatalog-federation-transaction-"));
2147
- const previousOutDir = import_node_path12.default.join(transactionDirectory, "federated");
2148
- const publicBackupDirectory = import_node_path12.default.join(transactionDirectory, "public");
2149
- const publicDirectory = import_node_path12.default.resolve(projectDirectory, "public");
2173
+ const transactionDirectory = await import_promises6.default.mkdtemp(import_node_path13.default.join(projectDirectory, ".eventcatalog-federation-transaction-"));
2174
+ const previousOutDir = import_node_path13.default.join(transactionDirectory, "federated");
2175
+ const publicBackupDirectory = import_node_path13.default.join(transactionDirectory, "public");
2176
+ const publicDirectory = import_node_path13.default.resolve(projectDirectory, "public");
2150
2177
  const publicSnapshots = [];
2151
2178
  const missingPublicDirectories = /* @__PURE__ */ new Set();
2152
2179
  let hadPreviousOutDir = false;
@@ -2155,45 +2182,45 @@ var beginFederationOutputTransaction = async (projectDirectory, outDir, relative
2155
2182
  const destinationPath = getSafePublicPath(publicDirectory, relativePath);
2156
2183
  if (!destinationPath) continue;
2157
2184
  try {
2158
- const stat = await import_promises5.default.lstat(destinationPath);
2185
+ const stat = await import_promises6.default.lstat(destinationPath);
2159
2186
  if (!stat.isFile()) continue;
2160
- const backupPath = import_node_path12.default.join(publicBackupDirectory, `${publicSnapshots.length}`);
2161
- await import_promises5.default.mkdir(import_node_path12.default.dirname(backupPath), { recursive: true });
2162
- await import_promises5.default.copyFile(destinationPath, backupPath);
2187
+ const backupPath = import_node_path13.default.join(publicBackupDirectory, `${publicSnapshots.length}`);
2188
+ await import_promises6.default.mkdir(import_node_path13.default.dirname(backupPath), { recursive: true });
2189
+ await import_promises6.default.copyFile(destinationPath, backupPath);
2163
2190
  publicSnapshots.push({ backupPath, destinationPath, state: "file" });
2164
2191
  } catch (error) {
2165
2192
  const code = error.code;
2166
2193
  if (code === "ENOTDIR") continue;
2167
2194
  if (code !== "ENOENT") throw error;
2168
2195
  publicSnapshots.push({ destinationPath, state: "missing" });
2169
- let directory = import_node_path12.default.dirname(destinationPath);
2196
+ let directory = import_node_path13.default.dirname(destinationPath);
2170
2197
  while (directory !== publicDirectory) {
2171
2198
  try {
2172
- await import_promises5.default.lstat(directory);
2199
+ await import_promises6.default.lstat(directory);
2173
2200
  break;
2174
2201
  } catch (directoryError) {
2175
2202
  const directoryCode = directoryError.code;
2176
2203
  if (directoryCode === "ENOTDIR") break;
2177
2204
  if (directoryCode !== "ENOENT") throw directoryError;
2178
2205
  missingPublicDirectories.add(directory);
2179
- directory = import_node_path12.default.dirname(directory);
2206
+ directory = import_node_path13.default.dirname(directory);
2180
2207
  }
2181
2208
  }
2182
2209
  }
2183
2210
  }
2184
2211
  try {
2185
- await import_promises5.default.rename(outDir, previousOutDir);
2212
+ await import_promises6.default.rename(outDir, previousOutDir);
2186
2213
  hadPreviousOutDir = true;
2187
2214
  } catch (error) {
2188
2215
  if (error.code !== "ENOENT") throw error;
2189
2216
  }
2190
2217
  } catch (error) {
2191
- await import_promises5.default.rm(transactionDirectory, { recursive: true, force: true });
2218
+ await import_promises6.default.rm(transactionDirectory, { recursive: true, force: true });
2192
2219
  throw error;
2193
2220
  }
2194
2221
  return {
2195
2222
  commit: async () => {
2196
- await import_promises5.default.rm(transactionDirectory, { recursive: true, force: true }).catch(() => void 0);
2223
+ await import_promises6.default.rm(transactionDirectory, { recursive: true, force: true }).catch(() => void 0);
2197
2224
  },
2198
2225
  rollback: async () => {
2199
2226
  const rollbackErrors = [];
@@ -2204,28 +2231,28 @@ var beginFederationOutputTransaction = async (projectDirectory, outDir, relative
2204
2231
  rollbackErrors.push(error);
2205
2232
  }
2206
2233
  };
2207
- await attempt(() => import_promises5.default.rm(outDir, { recursive: true, force: true }));
2208
- if (hadPreviousOutDir) await attempt(() => import_promises5.default.rename(previousOutDir, outDir));
2234
+ await attempt(() => import_promises6.default.rm(outDir, { recursive: true, force: true }));
2235
+ if (hadPreviousOutDir) await attempt(() => import_promises6.default.rename(previousOutDir, outDir));
2209
2236
  for (const snapshot of publicSnapshots) {
2210
2237
  if (snapshot.state === "missing") {
2211
- await attempt(() => import_promises5.default.rm(snapshot.destinationPath, { force: true }));
2238
+ await attempt(() => import_promises6.default.rm(snapshot.destinationPath, { force: true }));
2212
2239
  continue;
2213
2240
  }
2214
2241
  await attempt(async () => {
2215
- await import_promises5.default.mkdir(import_node_path12.default.dirname(snapshot.destinationPath), { recursive: true });
2216
- await import_promises5.default.copyFile(snapshot.backupPath, snapshot.destinationPath);
2242
+ await import_promises6.default.mkdir(import_node_path13.default.dirname(snapshot.destinationPath), { recursive: true });
2243
+ await import_promises6.default.copyFile(snapshot.backupPath, snapshot.destinationPath);
2217
2244
  });
2218
2245
  }
2219
2246
  for (const directory of [...missingPublicDirectories].sort((left, right) => right.length - left.length)) {
2220
2247
  await attempt(async () => {
2221
2248
  try {
2222
- await import_promises5.default.rmdir(directory);
2249
+ await import_promises6.default.rmdir(directory);
2223
2250
  } catch (error) {
2224
2251
  if (!["ENOENT", "ENOTEMPTY"].includes(error.code ?? "")) throw error;
2225
2252
  }
2226
2253
  });
2227
2254
  }
2228
- await attempt(() => import_promises5.default.rm(transactionDirectory, { recursive: true, force: true }));
2255
+ await attempt(() => import_promises6.default.rm(transactionDirectory, { recursive: true, force: true }));
2229
2256
  if (rollbackErrors.length > 0) throw new AggregateError(rollbackErrors, "Failed to restore the previous federation output");
2230
2257
  }
2231
2258
  };
@@ -2247,27 +2274,27 @@ var withFederationOutputTransaction = async (projectDirectory, outDir, relativeP
2247
2274
  };
2248
2275
 
2249
2276
  // src/federation/public-assets.ts
2250
- var import_node_crypto2 = require("crypto");
2251
- var import_promises6 = __toESM(require("fs/promises"), 1);
2252
- var import_node_path13 = __toESM(require("path"), 1);
2253
- var getContentHash2 = (content) => `sha256:${(0, import_node_crypto2.createHash)("sha256").update(content).digest("hex")}`;
2277
+ var import_node_crypto3 = require("crypto");
2278
+ var import_promises7 = __toESM(require("fs/promises"), 1);
2279
+ var import_node_path14 = __toESM(require("path"), 1);
2280
+ var getContentHash2 = (content) => `sha256:${(0, import_node_crypto3.createHash)("sha256").update(content).digest("hex")}`;
2254
2281
  var getFileHash = async (filePath) => {
2255
2282
  try {
2256
- const stat = await import_promises6.default.lstat(filePath);
2257
- return stat.isFile() ? getContentHash2(await import_promises6.default.readFile(filePath)) : void 0;
2283
+ const stat = await import_promises7.default.lstat(filePath);
2284
+ return stat.isFile() ? getContentHash2(await import_promises7.default.readFile(filePath)) : void 0;
2258
2285
  } catch (error) {
2259
2286
  if (error.code === "ENOENT") return void 0;
2260
2287
  throw error;
2261
2288
  }
2262
2289
  };
2263
2290
  var getSafePath = (directory, relativePath) => {
2264
- const normalizedPath = import_node_path13.default.posix.normalize(relativePath);
2265
- const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path13.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2291
+ const normalizedPath = import_node_path14.default.posix.normalize(relativePath);
2292
+ const unsafe = relativePath.length === 0 || relativePath.includes("\0") || relativePath.includes("\\") || import_node_path14.default.posix.isAbsolute(relativePath) || /^[a-zA-Z]:\//.test(relativePath) || normalizedPath !== relativePath || normalizedPath === ".." || normalizedPath.startsWith("../");
2266
2293
  if (unsafe) return void 0;
2267
- const resolvedDirectory = import_node_path13.default.resolve(directory);
2268
- const resolvedPath = import_node_path13.default.resolve(resolvedDirectory, relativePath);
2269
- const relativeResolvedPath = import_node_path13.default.relative(resolvedDirectory, resolvedPath);
2270
- if (relativeResolvedPath === "" || relativeResolvedPath === ".." || relativeResolvedPath.startsWith(`..${import_node_path13.default.sep}`) || import_node_path13.default.isAbsolute(relativeResolvedPath)) {
2294
+ const resolvedDirectory = import_node_path14.default.resolve(directory);
2295
+ const resolvedPath = import_node_path14.default.resolve(resolvedDirectory, relativePath);
2296
+ const relativeResolvedPath = import_node_path14.default.relative(resolvedDirectory, resolvedPath);
2297
+ if (relativeResolvedPath === "" || relativeResolvedPath === ".." || relativeResolvedPath.startsWith(`..${import_node_path14.default.sep}`) || import_node_path14.default.isAbsolute(relativeResolvedPath)) {
2271
2298
  return void 0;
2272
2299
  }
2273
2300
  return resolvedPath;
@@ -2275,23 +2302,23 @@ var getSafePath = (directory, relativePath) => {
2275
2302
  var listFiles = async (directory, relativeDirectory = "") => {
2276
2303
  let entries;
2277
2304
  try {
2278
- entries = await import_promises6.default.readdir(import_node_path13.default.join(directory, relativeDirectory), { withFileTypes: true });
2305
+ entries = await import_promises7.default.readdir(import_node_path14.default.join(directory, relativeDirectory), { withFileTypes: true });
2279
2306
  } catch (error) {
2280
2307
  if (error.code === "ENOENT") return [];
2281
2308
  throw error;
2282
2309
  }
2283
2310
  const files = await Promise.all(
2284
2311
  entries.map(async (entry) => {
2285
- const relativePath = import_node_path13.default.join(relativeDirectory, entry.name);
2312
+ const relativePath = import_node_path14.default.join(relativeDirectory, entry.name);
2286
2313
  if (entry.isDirectory()) return listFiles(directory, relativePath);
2287
- return entry.isFile() ? [relativePath.split(import_node_path13.default.sep).join("/")] : [];
2314
+ return entry.isFile() ? [relativePath.split(import_node_path14.default.sep).join("/")] : [];
2288
2315
  })
2289
2316
  );
2290
2317
  return files.flat().sort();
2291
2318
  };
2292
2319
  var pathExists = async (filePath) => {
2293
2320
  try {
2294
- await import_promises6.default.lstat(filePath);
2321
+ await import_promises7.default.lstat(filePath);
2295
2322
  return true;
2296
2323
  } catch (error) {
2297
2324
  if (error.code === "ENOENT") return false;
@@ -2299,27 +2326,27 @@ var pathExists = async (filePath) => {
2299
2326
  }
2300
2327
  };
2301
2328
  var hasBlockingParent = async (publicDirectory, destinationPath) => {
2302
- let currentPath = import_node_path13.default.dirname(destinationPath);
2329
+ let currentPath = import_node_path14.default.dirname(destinationPath);
2303
2330
  while (currentPath !== publicDirectory) {
2304
2331
  try {
2305
- if (!(await import_promises6.default.lstat(currentPath)).isDirectory()) return true;
2332
+ if (!(await import_promises7.default.lstat(currentPath)).isDirectory()) return true;
2306
2333
  } catch (error) {
2307
2334
  if (error.code !== "ENOENT") throw error;
2308
2335
  }
2309
- currentPath = import_node_path13.default.dirname(currentPath);
2336
+ currentPath = import_node_path14.default.dirname(currentPath);
2310
2337
  }
2311
2338
  return false;
2312
2339
  };
2313
2340
  var pruneEmptyDirectories = async (publicDirectory, filePath) => {
2314
- let currentPath = import_node_path13.default.dirname(filePath);
2341
+ let currentPath = import_node_path14.default.dirname(filePath);
2315
2342
  while (currentPath !== publicDirectory) {
2316
2343
  try {
2317
- await import_promises6.default.rmdir(currentPath);
2344
+ await import_promises7.default.rmdir(currentPath);
2318
2345
  } catch (error) {
2319
2346
  if (!["ENOENT", "ENOTEMPTY"].includes(error.code ?? "")) throw error;
2320
2347
  if (error.code === "ENOTEMPTY") return;
2321
2348
  }
2322
- currentPath = import_node_path13.default.dirname(currentPath);
2349
+ currentPath = import_node_path14.default.dirname(currentPath);
2323
2350
  }
2324
2351
  };
2325
2352
  var composePublicAssets = async ({
@@ -2329,8 +2356,8 @@ var composePublicAssets = async ({
2329
2356
  previousFiles = {},
2330
2357
  collisionPaths = /* @__PURE__ */ new Set()
2331
2358
  }) => {
2332
- const publicDirectory = import_node_path13.default.resolve(projectDirectory, "public");
2333
- const federatedPublicDirectory = import_node_path13.default.resolve(federatedDirectory, "public");
2359
+ const publicDirectory = import_node_path14.default.resolve(projectDirectory, "public");
2360
+ const federatedPublicDirectory = import_node_path14.default.resolve(federatedDirectory, "public");
2334
2361
  const sourceFiles = await listFiles(federatedPublicDirectory);
2335
2362
  const sourceFileSet = new Set(sourceFiles);
2336
2363
  const managedFiles = /* @__PURE__ */ new Set();
@@ -2343,7 +2370,7 @@ var composePublicAssets = async ({
2343
2370
  if (sourceFileSet.has(relativePath)) continue;
2344
2371
  const destinationPath = getSafePath(publicDirectory, relativePath);
2345
2372
  if (!destinationPath) continue;
2346
- await import_promises6.default.rm(destinationPath, { force: true });
2373
+ await import_promises7.default.rm(destinationPath, { force: true });
2347
2374
  await pruneEmptyDirectories(publicDirectory, destinationPath);
2348
2375
  removed += 1;
2349
2376
  }
@@ -2365,31 +2392,31 @@ var composePublicAssets = async ({
2365
2392
  }
2366
2393
  const asset = publicAssetsByPath.get(relativePath);
2367
2394
  if (!asset) throw new Error(`Cannot identify the source of federated public asset "${relativePath}"`);
2368
- const content = await import_promises6.default.readFile(sourcePath);
2369
- await import_promises6.default.mkdir(import_node_path13.default.dirname(destinationPath), { recursive: true });
2370
- await import_promises6.default.writeFile(destinationPath, content);
2395
+ const content = await import_promises7.default.readFile(sourcePath);
2396
+ await import_promises7.default.mkdir(import_node_path14.default.dirname(destinationPath), { recursive: true });
2397
+ await import_promises7.default.writeFile(destinationPath, content);
2371
2398
  files[relativePath] = { source: asset.resolvedFrom.source, hash: getContentHash2(content) };
2372
2399
  copied += 1;
2373
2400
  if (collisionPaths.has(`public/${relativePath}`)) overwritten += 1;
2374
2401
  }
2375
- await import_promises6.default.rm(federatedPublicDirectory, { recursive: true, force: true });
2402
+ await import_promises7.default.rm(federatedPublicDirectory, { recursive: true, force: true });
2376
2403
  return { files, copied, skipped, overwritten, removed };
2377
2404
  };
2378
2405
 
2379
2406
  // src/federation/filesystem-source-provider.ts
2380
- var import_node_crypto3 = require("crypto");
2381
- var import_promises7 = __toESM(require("fs/promises"), 1);
2382
- var import_node_path14 = __toESM(require("path"), 1);
2407
+ var import_node_crypto4 = require("crypto");
2408
+ var import_promises8 = __toESM(require("fs/promises"), 1);
2409
+ var import_node_path15 = __toESM(require("path"), 1);
2383
2410
  var import_sdk = __toESM(require("@eventcatalog/sdk"), 1);
2384
2411
  var FILESYSTEM_SOURCE_PREFIX = "file:";
2385
2412
  var isWithinDirectory = (directory, target) => {
2386
- const relativePath = import_node_path14.default.relative(directory, target);
2387
- return relativePath === "" || !relativePath.startsWith(`..${import_node_path14.default.sep}`) && relativePath !== ".." && !import_node_path14.default.isAbsolute(relativePath);
2413
+ const relativePath = import_node_path15.default.relative(directory, target);
2414
+ return relativePath === "" || !relativePath.startsWith(`..${import_node_path15.default.sep}`) && relativePath !== ".." && !import_node_path15.default.isAbsolute(relativePath);
2388
2415
  };
2389
2416
  var assertPortableRelativePath = (filePath, label, allowRoot = true) => {
2390
2417
  const portablePath = filePath.replaceAll("\\", "/");
2391
- const normalizedPath = import_node_path14.default.posix.normalize(portablePath);
2392
- const isUnsafe = filePath.includes("\\") || filePath.includes("\0") || import_node_path14.default.posix.isAbsolute(normalizedPath) || /^[a-zA-Z]:\//.test(normalizedPath) || normalizedPath === ".." || normalizedPath.startsWith("../") || !allowRoot && (normalizedPath === "." || normalizedPath === "");
2418
+ const normalizedPath = import_node_path15.default.posix.normalize(portablePath);
2419
+ const isUnsafe = filePath.includes("\\") || filePath.includes("\0") || import_node_path15.default.posix.isAbsolute(normalizedPath) || /^[a-zA-Z]:\//.test(normalizedPath) || normalizedPath === ".." || normalizedPath.startsWith("../") || !allowRoot && (normalizedPath === "." || normalizedPath === "");
2393
2420
  if (isUnsafe) throw new Error(`${label} "${filePath}" escapes its filesystem source`);
2394
2421
  return normalizedPath;
2395
2422
  };
@@ -2399,22 +2426,22 @@ var getSourceRoot = (projectDirectory, source) => {
2399
2426
  }
2400
2427
  const locator = source.source.slice(FILESYSTEM_SOURCE_PREFIX.length);
2401
2428
  if (!locator.trim()) throw new Error(`Filesystem federation source "${source.id}" requires a path after "file:".`);
2402
- return import_node_path14.default.resolve(projectDirectory, locator);
2429
+ return import_node_path15.default.resolve(projectDirectory, locator);
2403
2430
  };
2404
2431
  var getCatalogDirectory = async (projectDirectory, source) => {
2405
2432
  if (source.ref) throw new Error(`Filesystem federation source "${source.id}" does not support "ref".`);
2406
2433
  const sourceRoot = getSourceRoot(projectDirectory, source);
2407
2434
  const catalogPath = assertPortableRelativePath(source.path ?? ".", "Catalog path");
2408
- const catalogDirectory = import_node_path14.default.resolve(sourceRoot, ...catalogPath.split("/"));
2435
+ const catalogDirectory = import_node_path15.default.resolve(sourceRoot, ...catalogPath.split("/"));
2409
2436
  if (!isWithinDirectory(sourceRoot, catalogDirectory)) {
2410
2437
  throw new Error(`Catalog path "${source.path}" escapes source "${source.id}"`);
2411
2438
  }
2412
2439
  try {
2413
- const [realSourceRoot, realCatalogDirectory] = await Promise.all([import_promises7.default.realpath(sourceRoot), import_promises7.default.realpath(catalogDirectory)]);
2440
+ const [realSourceRoot, realCatalogDirectory] = await Promise.all([import_promises8.default.realpath(sourceRoot), import_promises8.default.realpath(catalogDirectory)]);
2414
2441
  if (!isWithinDirectory(realSourceRoot, realCatalogDirectory)) {
2415
2442
  throw new Error(`Catalog path "${source.path}" escapes source "${source.id}"`);
2416
2443
  }
2417
- if (!(await import_promises7.default.stat(realCatalogDirectory)).isDirectory()) {
2444
+ if (!(await import_promises8.default.stat(realCatalogDirectory)).isDirectory()) {
2418
2445
  throw new Error(`Filesystem federation source "${source.id}" is not a directory: ${catalogDirectory}`);
2419
2446
  }
2420
2447
  return realCatalogDirectory;
@@ -2427,12 +2454,12 @@ var getCatalogDirectory = async (projectDirectory, source) => {
2427
2454
  };
2428
2455
  var getArtifactPath = async (catalogDirectory, source, artifactPath) => {
2429
2456
  const normalizedPath = assertPortableRelativePath(artifactPath, "Federated artifact path", false);
2430
- const filePath = import_node_path14.default.resolve(catalogDirectory, ...normalizedPath.split("/"));
2457
+ const filePath = import_node_path15.default.resolve(catalogDirectory, ...normalizedPath.split("/"));
2431
2458
  if (!isWithinDirectory(catalogDirectory, filePath)) {
2432
2459
  throw new Error(`Federated artifact path "${artifactPath}" escapes source "${source.id}"`);
2433
2460
  }
2434
2461
  try {
2435
- const realFilePath = await import_promises7.default.realpath(filePath);
2462
+ const realFilePath = await import_promises8.default.realpath(filePath);
2436
2463
  if (!isWithinDirectory(catalogDirectory, realFilePath)) {
2437
2464
  throw new Error(`Federated artifact path "${artifactPath}" escapes source "${source.id}"`);
2438
2465
  }
@@ -2452,22 +2479,22 @@ var createFileSystemSourceProvider = (projectDirectory) => ({
2452
2479
  commit: "local",
2453
2480
  includeFederated: false
2454
2481
  });
2455
- const snapshot = (0, import_node_crypto3.createHash)("sha256").update(JSON.stringify(localIndex)).digest("hex").slice(0, 12);
2482
+ const snapshot = (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(localIndex)).digest("hex").slice(0, 12);
2456
2483
  const index = { ...localIndex, commit: `local:${snapshot}` };
2457
2484
  const bytes = Buffer.from(JSON.stringify(index));
2458
2485
  return { bytes, index, commit: index.commit, generated: true };
2459
2486
  },
2460
2487
  async fetchContent({ source, path: artifactPath }) {
2461
2488
  const catalogDirectory = await getCatalogDirectory(projectDirectory, source);
2462
- return import_promises7.default.readFile(await getArtifactPath(catalogDirectory, source, artifactPath));
2489
+ return import_promises8.default.readFile(await getArtifactPath(catalogDirectory, source, artifactPath));
2463
2490
  }
2464
2491
  });
2465
2492
 
2466
2493
  // src/federation/github-source-provider.ts
2467
2494
  var import_node_child_process = require("child_process");
2468
- var import_promises8 = __toESM(require("fs/promises"), 1);
2495
+ var import_promises9 = __toESM(require("fs/promises"), 1);
2469
2496
  var import_node_os4 = __toESM(require("os"), 1);
2470
- var import_node_path15 = __toESM(require("path"), 1);
2497
+ var import_node_path16 = __toESM(require("path"), 1);
2471
2498
  var import_node_util = require("util");
2472
2499
  var import_sdk2 = __toESM(require("@eventcatalog/sdk"), 1);
2473
2500
  var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
@@ -2478,8 +2505,8 @@ var parseGitHubSource = (source) => {
2478
2505
  };
2479
2506
  var assertSafeCatalogPath = (source) => {
2480
2507
  const catalogPath = source.path ?? ".";
2481
- const normalized = import_node_path15.default.posix.normalize(catalogPath.replaceAll("\\", "/"));
2482
- if (catalogPath.includes("\\") || import_node_path15.default.posix.isAbsolute(normalized) || normalized === ".." || normalized.startsWith("../")) {
2508
+ const normalized = import_node_path16.default.posix.normalize(catalogPath.replaceAll("\\", "/"));
2509
+ if (catalogPath.includes("\\") || import_node_path16.default.posix.isAbsolute(normalized) || normalized === ".." || normalized.startsWith("../")) {
2483
2510
  throw new Error(`Catalog path "${catalogPath}" escapes source "${source.id}"`);
2484
2511
  }
2485
2512
  };
@@ -2522,8 +2549,8 @@ var getGitEnvironment = (token) => {
2522
2549
  };
2523
2550
  var createCheckout = (executeFile, token) => async (source, ref, callback) => {
2524
2551
  const { owner, repository } = parseGitHubSource(source);
2525
- const catalogPath = import_node_path15.default.posix.normalize(source.path ?? ".");
2526
- const directory = await import_promises8.default.mkdtemp(import_node_path15.default.join(import_node_os4.default.tmpdir(), "eventcatalog-federation-"));
2552
+ const catalogPath = import_node_path16.default.posix.normalize(source.path ?? ".");
2553
+ const directory = await import_promises9.default.mkdtemp(import_node_path16.default.join(import_node_os4.default.tmpdir(), "eventcatalog-federation-"));
2527
2554
  const env = getGitEnvironment(token);
2528
2555
  try {
2529
2556
  const git = (args) => executeFile("git", args, { cwd: directory, env, encoding: "utf8" });
@@ -2537,22 +2564,22 @@ var createCheckout = (executeFile, token) => async (source, ref, callback) => {
2537
2564
  await git(["checkout", "--quiet", "--detach", "FETCH_HEAD"]);
2538
2565
  return await callback(directory);
2539
2566
  } finally {
2540
- await import_promises8.default.rm(directory, { recursive: true, force: true });
2567
+ await import_promises9.default.rm(directory, { recursive: true, force: true });
2541
2568
  }
2542
2569
  };
2543
2570
  var generateIndex = async (source, ref, checkout, executeFile) => checkout(source, ref, async (directory) => {
2544
2571
  const { stdout } = await executeFile("git", ["rev-parse", "HEAD"], { cwd: directory, encoding: "utf8" });
2545
2572
  const commit = stdout.trim();
2546
- const catalogDirectory = import_node_path15.default.resolve(directory, source.path ?? ".");
2547
- const relativeCatalogDirectory = import_node_path15.default.relative(directory, catalogDirectory);
2548
- if (relativeCatalogDirectory.startsWith("..") || import_node_path15.default.isAbsolute(relativeCatalogDirectory)) {
2573
+ const catalogDirectory = import_node_path16.default.resolve(directory, source.path ?? ".");
2574
+ const relativeCatalogDirectory = import_node_path16.default.relative(directory, catalogDirectory);
2575
+ if (relativeCatalogDirectory.startsWith("..") || import_node_path16.default.isAbsolute(relativeCatalogDirectory)) {
2549
2576
  throw new Error(`Catalog path "${source.path}" escapes source "${source.id}"`);
2550
2577
  }
2551
2578
  const index = await (0, import_sdk2.default)(catalogDirectory).buildIndex({ source: source.id, commit });
2552
2579
  return { bytes: Buffer.from(JSON.stringify(index)), index, commit, generated: true };
2553
2580
  });
2554
2581
  var fetchPublishedIndex = async (source, ref, fetcher, token) => {
2555
- const indexPath = import_node_path15.default.posix.join(source.path ?? ".", "catalog.index.json");
2582
+ const indexPath = import_node_path16.default.posix.join(source.path ?? ".", "catalog.index.json");
2556
2583
  const bytes = await fetchBytes(source, ref, indexPath, fetcher, token);
2557
2584
  if (!bytes) return void 0;
2558
2585
  const index = (0, import_sdk2.parseIndex)(JSON.parse(bytes.toString("utf8")));
@@ -2575,7 +2602,7 @@ var createGitHubSourceProvider = (options = {}) => {
2575
2602
  },
2576
2603
  async fetchContent({ source, commit, path: artifactPath }) {
2577
2604
  assertSafeCatalogPath(source);
2578
- const catalogPath = import_node_path15.default.posix.join(source.path ?? ".", artifactPath);
2605
+ const catalogPath = import_node_path16.default.posix.join(source.path ?? ".", artifactPath);
2579
2606
  const content = await fetchBytes(source, commit, catalogPath, fetcher, token);
2580
2607
  if (!content) throw new Error(`Federated artifact not found for "${source.id}": ${artifactPath}`);
2581
2608
  return content;
@@ -2661,16 +2688,16 @@ var createDiagnosticGraph = (graph, ownershipGraph, remoteSourceIds, localSource
2661
2688
  var writeLock = async (lockPath, lock) => {
2662
2689
  const temporaryPath = `${lockPath}.tmp-${process.pid}`;
2663
2690
  try {
2664
- await import_promises9.default.writeFile(temporaryPath, `${JSON.stringify(lock, null, 2)}
2691
+ await import_promises10.default.writeFile(temporaryPath, `${JSON.stringify(lock, null, 2)}
2665
2692
  `, "utf8");
2666
- await import_promises9.default.rename(temporaryPath, lockPath);
2693
+ await import_promises10.default.rename(temporaryPath, lockPath);
2667
2694
  } finally {
2668
- await import_promises9.default.rm(temporaryPath, { force: true });
2695
+ await import_promises10.default.rm(temporaryPath, { force: true });
2669
2696
  }
2670
2697
  };
2671
2698
  var readLock = async (lockPath) => {
2672
2699
  try {
2673
- return JSON.parse(await import_promises9.default.readFile(lockPath, "utf8"));
2700
+ return JSON.parse(await import_promises10.default.readFile(lockPath, "utf8"));
2674
2701
  } catch (error) {
2675
2702
  if (error.code === "ENOENT") return void 0;
2676
2703
  throw new Error(`Cannot read federation lock at "${lockPath}"`, { cause: error });
@@ -2678,7 +2705,7 @@ var readLock = async (lockPath) => {
2678
2705
  };
2679
2706
  var pathExists2 = async (filePath) => {
2680
2707
  try {
2681
- await import_promises9.default.access(filePath);
2708
+ await import_promises10.default.access(filePath);
2682
2709
  return true;
2683
2710
  } catch (error) {
2684
2711
  if (error.code === "ENOENT") return false;
@@ -2686,8 +2713,8 @@ var pathExists2 = async (filePath) => {
2686
2713
  }
2687
2714
  };
2688
2715
  var cleanupPreviousFederation = async (projectDirectory, onProgress) => {
2689
- const outDir = import_node_path16.default.join(projectDirectory, "federated");
2690
- const lockPath = import_node_path16.default.join(projectDirectory, "eventcatalog.lock");
2716
+ const outDir = import_node_path17.default.join(projectDirectory, "federated");
2717
+ const lockPath = import_node_path17.default.join(projectDirectory, "eventcatalog.lock");
2691
2718
  const previousLock = await readLock(lockPath);
2692
2719
  const hadFederatedOutput = await pathExists2(outDir);
2693
2720
  const hadLock = previousLock !== void 0;
@@ -2703,7 +2730,7 @@ var cleanupPreviousFederation = async (projectDirectory, onProgress) => {
2703
2730
  assets: [],
2704
2731
  previousFiles: previousLock?.publicFiles
2705
2732
  });
2706
- await import_promises9.default.rm(lockPath, { force: true });
2733
+ await import_promises10.default.rm(lockPath, { force: true });
2707
2734
  return result;
2708
2735
  }
2709
2736
  );
@@ -2752,8 +2779,8 @@ var federateCatalog = async (projectDirectory, options = {}) => {
2752
2779
  throw new Error(`Failed to federate source "${source.id}": ${message}`, { cause: error });
2753
2780
  }
2754
2781
  }
2755
- const outDir = import_node_path16.default.join(projectDirectory, "federated");
2756
- const lockPath = import_node_path16.default.join(projectDirectory, "eventcatalog.lock");
2782
+ const outDir = import_node_path17.default.join(projectDirectory, "federated");
2783
+ const lockPath = import_node_path17.default.join(projectDirectory, "eventcatalog.lock");
2757
2784
  const previousLock = await readLock(lockPath);
2758
2785
  const resources = resolvedSources.reduce((total, source) => total + source.resolved.index.resources.length, 0);
2759
2786
  const remoteIndexes = resolvedSources.map(({ resolved }) => resolved.index);
@@ -2826,7 +2853,7 @@ var federateCatalog = async (projectDirectory, options = {}) => {
2826
2853
  lockVersion: 1,
2827
2854
  sources: resolvedSources.map(({ config: source, resolved }) => ({
2828
2855
  id: source.id,
2829
- digest: `sha256:${(0, import_node_crypto4.createHash)("sha256").update(resolved.bytes).digest("hex")}`,
2856
+ digest: `sha256:${(0, import_node_crypto5.createHash)("sha256").update(resolved.bytes).digest("hex")}`,
2830
2857
  commit: resolved.commit,
2831
2858
  resolvedAt
2832
2859
  })).sort((left, right) => left.id.localeCompare(right.id)),
@@ -2851,14 +2878,14 @@ var federateCatalog = async (projectDirectory, options = {}) => {
2851
2878
 
2852
2879
  // src/eventcatalog.ts
2853
2880
  var import_license2 = require("@eventcatalog/license");
2854
- var currentDir = import_node_path18.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
2881
+ var currentDir = import_node_path19.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
2855
2882
  var program = new import_commander.Command().version(VERSION);
2856
- var dir = import_node_path18.default.resolve(process.env.PROJECT_DIR || process.cwd());
2857
- var core = import_node_path18.default.resolve(process.env.CATALOG_DIR || (0, import_node_path17.join)(dir, ".eventcatalog-core"));
2858
- var eventCatalogDir = import_node_path18.default.resolve((0, import_node_path17.join)(currentDir, "../eventcatalog/"));
2883
+ var dir = import_node_path19.default.resolve(process.env.PROJECT_DIR || process.cwd());
2884
+ var core = import_node_path19.default.resolve(process.env.CATALOG_DIR || (0, import_node_path18.join)(dir, ".eventcatalog-core"));
2885
+ var eventCatalogDir = import_node_path19.default.resolve((0, import_node_path18.join)(currentDir, "../eventcatalog/"));
2859
2886
  var getInstalledEventCatalogVersion = () => {
2860
2887
  try {
2861
- const pkg = import_fs3.default.readFileSync((0, import_node_path17.join)(dir, "package.json"), "utf8");
2888
+ const pkg = import_fs3.default.readFileSync((0, import_node_path18.join)(dir, "package.json"), "utf8");
2862
2889
  const json = JSON.parse(pkg);
2863
2890
  return json.dependencies["@eventcatalog/core"];
2864
2891
  } catch (error) {
@@ -2924,12 +2951,12 @@ var startDevPrewarm = ({
2924
2951
  var buildDevSearchIndex = async ({ config }) => {
2925
2952
  const result = await buildSearchIndex({
2926
2953
  projectDir: dir,
2927
- outDir: import_node_path18.default.join(core, "public"),
2928
- searchOutputPath: import_node_path18.default.join(core, "public", "pagefind"),
2954
+ outDir: import_node_path19.default.join(core, "public"),
2955
+ searchOutputPath: import_node_path19.default.join(core, "public", "pagefind"),
2929
2956
  config,
2930
2957
  isServer: false
2931
2958
  });
2932
- logger.info(`Indexed ${result.records} page(s) into ${import_node_path18.default.relative(core, result.outputPath)}`, "search");
2959
+ logger.info(`Indexed ${result.records} page(s) into ${import_node_path19.default.relative(core, result.outputPath)}`, "search");
2933
2960
  };
2934
2961
  var warnIfIndexedSearchUsesAuth = async () => {
2935
2962
  if (!await isAuthEnabled()) {
@@ -3044,12 +3071,12 @@ var copyCore = () => {
3044
3071
  import_fs3.default.cpSync(eventCatalogDir, core, {
3045
3072
  recursive: true,
3046
3073
  filter: (src) => {
3047
- const relativePath = import_node_path18.default.relative(eventCatalogDir, src);
3048
- const pathParts = relativePath.split(import_node_path18.default.sep);
3074
+ const relativePath = import_node_path19.default.relative(eventCatalogDir, src);
3075
+ const pathParts = relativePath.split(import_node_path19.default.sep);
3049
3076
  return !pathParts.some((part) => [".astro", "dist", "node_modules"].includes(part));
3050
3077
  }
3051
3078
  });
3052
- const coreNodeModules = import_node_path18.default.join(core, "node_modules");
3079
+ const coreNodeModules = import_node_path19.default.join(core, "node_modules");
3053
3080
  const installedCoreNodeModules = resolveInstalledCoreNodeModules(currentDir);
3054
3081
  linkCoreNodeModules({ coreNodeModules, installedCoreNodeModules });
3055
3082
  };
@@ -3108,8 +3135,8 @@ program.command("dev").description("Run development server of EventCatalog").opt
3108
3135
  logger.info("Setting up EventCatalog...", "eventcatalog");
3109
3136
  const isServer = await isOutputServer();
3110
3137
  logger.info(isServer ? "EventCatalog is running in Server Mode" : "EventCatalog is running in Static Mode", "config");
3111
- if (import_fs3.default.existsSync(import_node_path18.default.join(dir, ".env"))) {
3112
- import_dotenv.default.config({ path: import_node_path18.default.join(dir, ".env") });
3138
+ if (import_fs3.default.existsSync(import_node_path19.default.join(dir, ".env"))) {
3139
+ import_dotenv.default.config({ path: import_node_path19.default.join(dir, ".env") });
3113
3140
  }
3114
3141
  if (options.debug) {
3115
3142
  logger.info("Debug mode enabled", "debug");
@@ -3129,6 +3156,12 @@ program.command("dev").description("Run development server of EventCatalog").opt
3129
3156
  );
3130
3157
  const isEventCatalogStarter = await (0, import_license2.isEventCatalogStarterEnabled)();
3131
3158
  const isEventCatalogScale = await (0, import_license2.isEventCatalogScaleEnabled)();
3159
+ void log_build_default(dir, {
3160
+ isEventCatalogStarterEnabled: isEventCatalogStarter,
3161
+ isEventCatalogScaleEnabled: isEventCatalogScale,
3162
+ isBackstagePluginEnabled: canEmbedPages || isEventCatalogScale,
3163
+ command: "dev"
3164
+ });
3132
3165
  if (isServer) {
3133
3166
  try {
3134
3167
  logger.info("Building fields index...", "fields");
@@ -3189,8 +3222,8 @@ program.command("build").description("Run build of EventCatalog").action(async (
3189
3222
  logger.info("Building EventCatalog...", "build");
3190
3223
  const isServer = await isOutputServer();
3191
3224
  logger.info(isServer ? "EventCatalog is running in Server Mode" : "EventCatalog is running in Static Mode", "config");
3192
- if (import_fs3.default.existsSync(import_node_path18.default.join(dir, ".env"))) {
3193
- import_dotenv.default.config({ path: import_node_path18.default.join(dir, ".env") });
3225
+ if (import_fs3.default.existsSync(import_node_path19.default.join(dir, ".env"))) {
3226
+ import_dotenv.default.config({ path: import_node_path19.default.join(dir, ".env") });
3194
3227
  }
3195
3228
  await verifyRequiredFieldsAreInCatalogConfigFile(dir);
3196
3229
  copyCore();
@@ -3204,7 +3237,8 @@ program.command("build").description("Run build of EventCatalog").action(async (
3204
3237
  await log_build_default(dir, {
3205
3238
  isEventCatalogStarterEnabled: isEventCatalogStarter,
3206
3239
  isEventCatalogScaleEnabled: isEventCatalogScale,
3207
- isBackstagePluginEnabled: canEmbedPages || isEventCatalogScale
3240
+ isBackstagePluginEnabled: canEmbedPages || isEventCatalogScale,
3241
+ command: "build"
3208
3242
  });
3209
3243
  await resolve_catalog_dependencies_default(dir, core);
3210
3244
  await runMigrations(dir);
@@ -3240,7 +3274,7 @@ program.command("build").description("Run build of EventCatalog").action(async (
3240
3274
  if (await isIndexedSearchEnabled()) {
3241
3275
  await warnIfIndexedSearchUsesAuth();
3242
3276
  const config = await getEventCatalogConfigFile(dir);
3243
- const outDir = import_node_path18.default.resolve(dir, await getProjectOutDir());
3277
+ const outDir = import_node_path19.default.resolve(dir, await getProjectOutDir());
3244
3278
  logger.info("Building indexed search...", "search");
3245
3279
  const result = await buildSearchIndex({
3246
3280
  projectDir: dir,
@@ -3248,7 +3282,7 @@ program.command("build").description("Run build of EventCatalog").action(async (
3248
3282
  config,
3249
3283
  isServer
3250
3284
  });
3251
- logger.info(`Indexed ${result.records} page(s) into ${import_node_path18.default.relative(dir, result.outputPath)}`, "search");
3285
+ logger.info(`Indexed ${result.records} page(s) into ${import_node_path19.default.relative(dir, result.outputPath)}`, "search");
3252
3286
  }
3253
3287
  });
3254
3288
  var previewCatalog = async ({
@@ -3275,7 +3309,7 @@ var startServerCatalog = async ({
3275
3309
  isEventCatalogStarter = false,
3276
3310
  isEventCatalogScale = false
3277
3311
  }) => {
3278
- const serverEntryPath = import_node_path18.default.join(dir, "dist", "server", "entry.mjs");
3312
+ const serverEntryPath = import_node_path19.default.join(dir, "dist", "server", "entry.mjs");
3279
3313
  await runCommandWithFilteredOutput({
3280
3314
  command: `node "${serverEntryPath}"`,
3281
3315
  cwd: core,
@@ -3292,8 +3326,8 @@ var startServerCatalog = async ({
3292
3326
  program.command("preview").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
3293
3327
  logger.welcome();
3294
3328
  logger.info("Starting preview of your build...", "preview");
3295
- if (import_fs3.default.existsSync(import_node_path18.default.join(dir, ".env"))) {
3296
- import_dotenv.default.config({ path: import_node_path18.default.join(dir, ".env") });
3329
+ if (import_fs3.default.existsSync(import_node_path19.default.join(dir, ".env"))) {
3330
+ import_dotenv.default.config({ path: import_node_path19.default.join(dir, ".env") });
3297
3331
  }
3298
3332
  const canEmbedPages = await (0, import_license2.isFeatureEnabled)(
3299
3333
  "@eventcatalog/backstage-plugin-eventcatalog",
@@ -3311,8 +3345,8 @@ program.command("preview").description("Serves the contents of your eventcatalog
3311
3345
  program.command("start").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
3312
3346
  logger.welcome();
3313
3347
  logger.info("Starting preview of your build...", "preview");
3314
- if (import_fs3.default.existsSync(import_node_path18.default.join(dir, ".env"))) {
3315
- import_dotenv.default.config({ path: import_node_path18.default.join(dir, ".env") });
3348
+ if (import_fs3.default.existsSync(import_node_path19.default.join(dir, ".env"))) {
3349
+ import_dotenv.default.config({ path: import_node_path19.default.join(dir, ".env") });
3316
3350
  }
3317
3351
  const canEmbedPages = await (0, import_license2.isFeatureEnabled)(
3318
3352
  "@eventcatalog/backstage-plugin-eventcatalog",
@@ -3339,22 +3373,22 @@ program.command("start").description("Serves the contents of your eventcatalog b
3339
3373
  program.command("export").description("Export your EventCatalog using the SDK dumpCatalog function").option("--include-markdown", "Include markdown content in the export", false).action(async (options) => {
3340
3374
  logger.welcome();
3341
3375
  logger.info("Exporting EventCatalog...", "export");
3342
- if (import_fs3.default.existsSync(import_node_path18.default.join(dir, ".env"))) {
3343
- import_dotenv.default.config({ path: import_node_path18.default.join(dir, ".env") });
3376
+ if (import_fs3.default.existsSync(import_node_path19.default.join(dir, ".env"))) {
3377
+ import_dotenv.default.config({ path: import_node_path19.default.join(dir, ".env") });
3344
3378
  }
3345
3379
  const { default: initSDK } = await import("@eventcatalog/sdk");
3346
3380
  const sdk = initSDK(dir);
3347
3381
  const catalog = await sdk.dumpCatalog({ includeMarkdown: options.includeMarkdown });
3348
- const exportsDir = import_node_path18.default.join(dir, "exports");
3382
+ const exportsDir = import_node_path19.default.join(dir, "exports");
3349
3383
  ensureDir(exportsDir);
3350
3384
  const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
3351
- const exportFile = import_node_path18.default.join(exportsDir, `catalog-${date}.json`);
3385
+ const exportFile = import_node_path19.default.join(exportsDir, `catalog-${date}.json`);
3352
3386
  import_fs3.default.writeFileSync(exportFile, JSON.stringify(catalog, null, 2), "utf-8");
3353
3387
  logger.info(`Catalog exported to ${exportFile}`, "export");
3354
3388
  });
3355
3389
  program.command("generate [siteDir]").description("Start the generator scripts.").action(async () => {
3356
- if (import_fs3.default.existsSync(import_node_path18.default.join(dir, ".env"))) {
3357
- import_dotenv.default.config({ path: import_node_path18.default.join(dir, ".env") });
3390
+ if (import_fs3.default.existsSync(import_node_path19.default.join(dir, ".env"))) {
3391
+ import_dotenv.default.config({ path: import_node_path19.default.join(dir, ".env") });
3358
3392
  }
3359
3393
  await generate(dir);
3360
3394
  });
@@ -3427,7 +3461,7 @@ var reportFederationProgress = (event, verbose = false) => {
3427
3461
  }
3428
3462
  return;
3429
3463
  case "hydrating":
3430
- logger.info(`Hydrating federated content into ${import_node_path18.default.relative(dir, event.outDir)}/...`, "federation");
3464
+ logger.info(`Hydrating federated content into ${import_node_path19.default.relative(dir, event.outDir)}/...`, "federation");
3431
3465
  return;
3432
3466
  case "hydrate:cache":
3433
3467
  if (event.files === 1 || event.files % 25 === 0) {
@@ -3450,13 +3484,13 @@ var reportFederationProgress = (event, verbose = false) => {
3450
3484
  `Federation complete: ${event.result.sources} sources, ${event.result.resources} remote resources, ${event.result.hydrate.written} files written (${event.result.hydrate.fetched} downloaded, ${event.result.hydrate.written - event.result.hydrate.fetched} cached)`,
3451
3485
  "federation"
3452
3486
  );
3453
- logger.info(`Recorded resolved source state in ${import_node_path18.default.relative(dir, event.result.lockPath)}`, "federation");
3487
+ logger.info(`Recorded resolved source state in ${import_node_path19.default.relative(dir, event.result.lockPath)}`, "federation");
3454
3488
  }
3455
3489
  };
3456
3490
  program.command("federate").description("Fetch, resolve, and hydrate the catalogs configured in federation.sources.").option("--no-cache", "Download all federation content and refresh the cache.").option("-v, --verbose", "Show detailed federation diagnostics.").action(async (commandOptions) => {
3457
3491
  logger.welcome();
3458
- if (import_fs3.default.existsSync(import_node_path18.default.join(dir, ".env"))) {
3459
- import_dotenv.default.config({ path: import_node_path18.default.join(dir, ".env") });
3492
+ if (import_fs3.default.existsSync(import_node_path19.default.join(dir, ".env"))) {
3493
+ import_dotenv.default.config({ path: import_node_path19.default.join(dir, ".env") });
3460
3494
  }
3461
3495
  logger.info("Starting federation...", "federation");
3462
3496
  let cleanedPreviousOutput = false;