@eventcatalog/sdk 2.26.1 → 2.26.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.
- package/dist/index.d.mts +104 -37
- package/dist/index.d.ts +104 -37
- package/dist/index.js +897 -555
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +898 -556
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2466,430 +2466,118 @@ var dumpCatalog = (directory) => async (options) => {
|
|
|
2466
2466
|
};
|
|
2467
2467
|
};
|
|
2468
2468
|
|
|
2469
|
-
// src/
|
|
2470
|
-
var import_node_fs9 = __toESM(require("fs"));
|
|
2471
|
-
var import_node_path19 = __toESM(require("path"));
|
|
2472
|
-
var import_node_crypto = require("crypto");
|
|
2473
|
-
var import_node_child_process = require("child_process");
|
|
2469
|
+
// src/graph.ts
|
|
2474
2470
|
var import_semver6 = require("semver");
|
|
2475
2471
|
|
|
2476
|
-
// src/
|
|
2477
|
-
var
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
const addResources = (items, type) => {
|
|
2490
|
-
for (const item of items) {
|
|
2491
|
-
resources.push({
|
|
2492
|
-
resourceId: item.id,
|
|
2493
|
-
version: item.version,
|
|
2494
|
-
type,
|
|
2495
|
-
data: item
|
|
2496
|
-
});
|
|
2497
|
-
}
|
|
2498
|
-
};
|
|
2499
|
-
addResources(snapshot.resources.domains, "domain");
|
|
2500
|
-
addResources(snapshot.resources.services, "service");
|
|
2501
|
-
addResources(snapshot.resources.agents || [], "agent");
|
|
2502
|
-
addResources(snapshot.resources.messages.events, "event");
|
|
2503
|
-
addResources(snapshot.resources.messages.commands, "command");
|
|
2504
|
-
addResources(snapshot.resources.messages.queries, "query");
|
|
2505
|
-
addResources(snapshot.resources.channels, "channel");
|
|
2506
|
-
return resources;
|
|
2472
|
+
// src/adrs.ts
|
|
2473
|
+
var import_promises12 = __toESM(require("fs/promises"));
|
|
2474
|
+
var import_node_path19 = require("path");
|
|
2475
|
+
var getAdr = (directory) => async (id, version) => getResource(directory, id, version, { type: "adr" });
|
|
2476
|
+
var getAdrs = (directory) => async (options) => getResources(directory, { type: "adrs", latestOnly: options?.latestOnly });
|
|
2477
|
+
var writeAdr = (directory) => async (adr, options = {
|
|
2478
|
+
path: "",
|
|
2479
|
+
override: false,
|
|
2480
|
+
format: "mdx"
|
|
2481
|
+
}) => writeResource(directory, { ...adr }, { ...options, type: "adr" });
|
|
2482
|
+
var rmAdr = (directory) => async (path9) => {
|
|
2483
|
+
await import_promises12.default.rm((0, import_node_path19.join)(directory, path9), { recursive: true });
|
|
2484
|
+
invalidateFileCache();
|
|
2507
2485
|
};
|
|
2508
|
-
var
|
|
2509
|
-
|
|
2510
|
-
const result = {};
|
|
2511
|
-
for (const [key, value] of Object.entries(data)) {
|
|
2512
|
-
if (!EXCLUDED_FIELDS.has(key)) {
|
|
2513
|
-
result[key] = value;
|
|
2514
|
-
}
|
|
2515
|
-
}
|
|
2516
|
-
return result;
|
|
2486
|
+
var rmAdrById = (directory) => async (id, version, persistFiles) => {
|
|
2487
|
+
await rmResourceById(directory, id, version, { type: "adr", persistFiles });
|
|
2517
2488
|
};
|
|
2518
|
-
var
|
|
2519
|
-
|
|
2520
|
-
const
|
|
2521
|
-
|
|
2522
|
-
const changed = [];
|
|
2523
|
-
for (const key of allKeys) {
|
|
2524
|
-
if (stableStringify(fieldsA[key] ?? null) !== stableStringify(fieldsB[key] ?? null)) {
|
|
2525
|
-
changed.push(key);
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2528
|
-
return changed;
|
|
2489
|
+
var versionAdr = (directory) => async (id) => versionResource(directory, id);
|
|
2490
|
+
var adrHasVersion = (directory) => async (id, version) => {
|
|
2491
|
+
const file = await findFileById(directory, id, version);
|
|
2492
|
+
return !!file;
|
|
2529
2493
|
};
|
|
2530
|
-
var
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
}
|
|
2547
|
-
const changes = [];
|
|
2548
|
-
const handledIds = /* @__PURE__ */ new Set();
|
|
2549
|
-
for (const resource of resourcesB) {
|
|
2550
|
-
const key = resourceKey(resource);
|
|
2551
|
-
if (!mapA.has(key)) {
|
|
2552
|
-
const idKey = idTypeKey(resource);
|
|
2553
|
-
const oldResource = byIdA.get(idKey);
|
|
2554
|
-
if (oldResource && oldResource.version !== resource.version && !handledIds.has(idKey)) {
|
|
2555
|
-
const changedFields = findChangedFields(oldResource.data, resource.data);
|
|
2556
|
-
changes.push({
|
|
2557
|
-
resourceId: resource.resourceId,
|
|
2558
|
-
version: resource.version,
|
|
2559
|
-
type: resource.type,
|
|
2560
|
-
changeType: "versioned",
|
|
2561
|
-
previousVersion: oldResource.version,
|
|
2562
|
-
newVersion: resource.version,
|
|
2563
|
-
changedFields: changedFields.length > 0 ? changedFields : void 0
|
|
2564
|
-
});
|
|
2565
|
-
handledIds.add(idKey);
|
|
2566
|
-
} else if (!handledIds.has(idKey)) {
|
|
2567
|
-
changes.push({
|
|
2568
|
-
resourceId: resource.resourceId,
|
|
2569
|
-
version: resource.version,
|
|
2570
|
-
type: resource.type,
|
|
2571
|
-
changeType: "added"
|
|
2572
|
-
});
|
|
2573
|
-
}
|
|
2574
|
-
}
|
|
2575
|
-
}
|
|
2576
|
-
for (const resource of resourcesA) {
|
|
2577
|
-
const key = resourceKey(resource);
|
|
2578
|
-
if (!mapB.has(key)) {
|
|
2579
|
-
const idKey = idTypeKey(resource);
|
|
2580
|
-
if (!handledIds.has(idKey)) {
|
|
2581
|
-
changes.push({
|
|
2582
|
-
resourceId: resource.resourceId,
|
|
2583
|
-
version: resource.version,
|
|
2584
|
-
type: resource.type,
|
|
2585
|
-
changeType: "removed"
|
|
2586
|
-
});
|
|
2587
|
-
}
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
for (const resourceB of resourcesB) {
|
|
2591
|
-
const key = resourceKey(resourceB);
|
|
2592
|
-
const resourceA = mapA.get(key);
|
|
2593
|
-
if (resourceA) {
|
|
2594
|
-
const changedFields = findChangedFields(resourceA.data, resourceB.data);
|
|
2595
|
-
if (changedFields.length > 0) {
|
|
2596
|
-
changes.push({
|
|
2597
|
-
resourceId: resourceB.resourceId,
|
|
2598
|
-
version: resourceB.version,
|
|
2599
|
-
type: resourceB.type,
|
|
2600
|
-
changeType: "modified",
|
|
2601
|
-
changedFields
|
|
2602
|
-
});
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
}
|
|
2606
|
-
return changes;
|
|
2494
|
+
var addFileToAdr = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version, { type: "adr" });
|
|
2495
|
+
|
|
2496
|
+
// src/data-products.ts
|
|
2497
|
+
var import_promises13 = __toESM(require("fs/promises"));
|
|
2498
|
+
var import_node_path20 = require("path");
|
|
2499
|
+
var getDataProduct = (directory) => async (id, version) => getResource(directory, id, version, { type: "data-product" });
|
|
2500
|
+
var getDataProducts = (directory) => async (options) => getResources(directory, { type: "data-products", latestOnly: options?.latestOnly });
|
|
2501
|
+
var writeDataProduct = (directory) => async (dataProduct, options = {
|
|
2502
|
+
path: "",
|
|
2503
|
+
override: false,
|
|
2504
|
+
format: "mdx"
|
|
2505
|
+
}) => writeResource(directory, { ...dataProduct }, { ...options, type: "data-product" });
|
|
2506
|
+
var writeDataProductToDomain = (directory) => async (dataProduct, domain, options = { path: "", format: "mdx", override: false }) => {
|
|
2507
|
+
let pathForDataProduct = domain.version && domain.version !== "latest" ? `/${domain.id}/versioned/${domain.version}/data-products` : `/${domain.id}/data-products`;
|
|
2508
|
+
pathForDataProduct = (0, import_node_path20.join)(pathForDataProduct, dataProduct.id);
|
|
2509
|
+
await writeResource(directory, { ...dataProduct }, { ...options, path: pathForDataProduct, type: "data-product" });
|
|
2607
2510
|
};
|
|
2608
|
-
var
|
|
2609
|
-
|
|
2511
|
+
var rmDataProduct = (directory) => async (path9) => {
|
|
2512
|
+
await import_promises13.default.rm((0, import_node_path20.join)(directory, path9), { recursive: true });
|
|
2513
|
+
invalidateFileCache();
|
|
2610
2514
|
};
|
|
2611
|
-
var
|
|
2612
|
-
|
|
2613
|
-
for (const service of [...snapshot.resources.services, ...snapshot.resources.agents || []]) {
|
|
2614
|
-
for (const direction of ["sends", "receives"]) {
|
|
2615
|
-
const pointers = service[direction] || [];
|
|
2616
|
-
for (const pointer of pointers) {
|
|
2617
|
-
const key = getRelationshipKey(service.id, pointer.id, pointer.version, direction);
|
|
2618
|
-
relationships.set(key, {
|
|
2619
|
-
serviceId: service.id,
|
|
2620
|
-
serviceVersion: service.version,
|
|
2621
|
-
resourceId: pointer.id,
|
|
2622
|
-
resourceVersion: pointer.version,
|
|
2623
|
-
direction
|
|
2624
|
-
});
|
|
2625
|
-
}
|
|
2626
|
-
}
|
|
2627
|
-
}
|
|
2628
|
-
return relationships;
|
|
2515
|
+
var rmDataProductById = (directory) => async (id, version, persistFiles) => {
|
|
2516
|
+
await rmResourceById(directory, id, version, { type: "data-product", persistFiles });
|
|
2629
2517
|
};
|
|
2630
|
-
var
|
|
2631
|
-
|
|
2632
|
-
const
|
|
2633
|
-
|
|
2634
|
-
for (const [key, rel] of relsB) {
|
|
2635
|
-
if (!relsA.has(key)) {
|
|
2636
|
-
changes.push({ ...rel, changeType: "added" });
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
for (const [key, rel] of relsA) {
|
|
2640
|
-
if (!relsB.has(key)) {
|
|
2641
|
-
changes.push({ ...rel, changeType: "removed" });
|
|
2642
|
-
}
|
|
2643
|
-
}
|
|
2644
|
-
return changes;
|
|
2518
|
+
var versionDataProduct = (directory) => async (id) => versionResource(directory, id);
|
|
2519
|
+
var dataProductHasVersion = (directory) => async (id, version) => {
|
|
2520
|
+
const file = await findFileById(directory, id, version);
|
|
2521
|
+
return !!file;
|
|
2645
2522
|
};
|
|
2523
|
+
var addFileToDataProduct = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
|
|
2646
2524
|
|
|
2647
|
-
// src/
|
|
2648
|
-
var
|
|
2649
|
-
var
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2525
|
+
// src/containers.ts
|
|
2526
|
+
var import_promises14 = __toESM(require("fs/promises"));
|
|
2527
|
+
var import_node_path21 = require("path");
|
|
2528
|
+
var getContainer = (directory) => async (id, version) => getResource(directory, id, version, { type: "container" });
|
|
2529
|
+
var getContainers = (directory) => async (options) => getResources(directory, { type: "containers", latestOnly: options?.latestOnly });
|
|
2530
|
+
var writeContainer = (directory) => async (data, options = {
|
|
2531
|
+
path: "",
|
|
2532
|
+
override: false,
|
|
2533
|
+
format: "mdx"
|
|
2534
|
+
}) => writeResource(directory, { ...data }, { ...options, type: "container" });
|
|
2535
|
+
var versionContainer = (directory) => async (id) => versionResource(directory, id);
|
|
2536
|
+
var rmContainer = (directory) => async (path9) => {
|
|
2537
|
+
await import_promises14.default.rm((0, import_node_path21.join)(directory, path9), { recursive: true });
|
|
2538
|
+
invalidateFileCache();
|
|
2657
2539
|
};
|
|
2658
|
-
var
|
|
2659
|
-
|
|
2660
|
-
if (resource.sends) picked.sends = resource.sends;
|
|
2661
|
-
if (resource.receives) picked.receives = resource.receives;
|
|
2662
|
-
if (resource.deprecated) picked.deprecated = resource.deprecated;
|
|
2663
|
-
if (resource.owners) picked.owners = resource.owners;
|
|
2664
|
-
if (resource.schemaPath) picked.schemaPath = resource.schemaPath;
|
|
2665
|
-
if (resource.schemaHash) picked.schemaHash = resource.schemaHash;
|
|
2666
|
-
return picked;
|
|
2540
|
+
var rmContainerById = (directory) => async (id, version, persistFiles) => {
|
|
2541
|
+
await rmResourceById(directory, id, version, { type: "container", persistFiles });
|
|
2667
2542
|
};
|
|
2668
|
-
var
|
|
2669
|
-
const
|
|
2670
|
-
|
|
2671
|
-
const existing = seen.get(r.id);
|
|
2672
|
-
if (!existing || (0, import_semver6.compare)(r.version, existing.version) > 0) {
|
|
2673
|
-
seen.set(r.id, r);
|
|
2674
|
-
}
|
|
2675
|
-
}
|
|
2676
|
-
return Array.from(seen.values());
|
|
2543
|
+
var containerHasVersion = (directory) => async (id, version) => {
|
|
2544
|
+
const file = await findFileById(directory, id, version);
|
|
2545
|
+
return !!file;
|
|
2677
2546
|
};
|
|
2678
|
-
var
|
|
2679
|
-
|
|
2680
|
-
|
|
2547
|
+
var addFileToContainer = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
|
|
2548
|
+
var writeContainerToService = (directory) => async (container, service, options = { path: "", format: "mdx", override: false }) => {
|
|
2549
|
+
const resourcePath = await getResourcePath(directory, service.id, service.version);
|
|
2550
|
+
if (!resourcePath) {
|
|
2551
|
+
throw new Error("Service not found");
|
|
2552
|
+
}
|
|
2553
|
+
let pathForContainer = service.version && service.version !== "latest" ? `${resourcePath.directory}/versioned/${service.version}/containers` : `${resourcePath.directory}/containers`;
|
|
2554
|
+
pathForContainer = (0, import_node_path21.join)(pathForContainer, container.id);
|
|
2555
|
+
await writeResource(directory, { ...container }, { ...options, path: pathForContainer, type: "container" });
|
|
2681
2556
|
};
|
|
2682
|
-
var
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
const commit = (0, import_node_child_process.execSync)("git rev-parse --short HEAD", opts).trim();
|
|
2687
|
-
const status = (0, import_node_child_process.execSync)("git status --porcelain", opts).trim();
|
|
2688
|
-
return { branch, commit, dirty: status.length > 0 };
|
|
2689
|
-
} catch {
|
|
2690
|
-
return void 0;
|
|
2691
|
-
}
|
|
2692
|
-
};
|
|
2693
|
-
var enrichWithSchemaHashes = async (getSchemaForMessage2, resources) => {
|
|
2694
|
-
await Promise.all(
|
|
2695
|
-
resources.map(async (resource) => {
|
|
2696
|
-
if (!resource.schemaPath) return;
|
|
2697
|
-
const schema = await getSchemaForMessage2(resource.id, resource.version);
|
|
2698
|
-
if (!schema) return;
|
|
2699
|
-
resource.schemaHash = (0, import_node_crypto.createHash)("sha256").update(schema.schema).digest("hex");
|
|
2700
|
-
})
|
|
2701
|
-
);
|
|
2702
|
-
};
|
|
2703
|
-
var createSnapshot = (directory) => {
|
|
2704
|
-
return async (options) => {
|
|
2705
|
-
const { label, outputDir, git } = options || {};
|
|
2706
|
-
const sdk = src_default(directory);
|
|
2707
|
-
const [domains, services, agents, events, commands, queries, channels] = await Promise.all([
|
|
2708
|
-
sdk.getDomains(),
|
|
2709
|
-
sdk.getServices(),
|
|
2710
|
-
sdk.getAgents(),
|
|
2711
|
-
sdk.getEvents(),
|
|
2712
|
-
sdk.getCommands(),
|
|
2713
|
-
sdk.getQueries(),
|
|
2714
|
-
sdk.getChannels()
|
|
2715
|
-
]);
|
|
2716
|
-
await Promise.all([
|
|
2717
|
-
enrichWithSchemaHashes(sdk.getSchemaForMessage, events || []),
|
|
2718
|
-
enrichWithSchemaHashes(sdk.getSchemaForMessage, commands || []),
|
|
2719
|
-
enrichWithSchemaHashes(sdk.getSchemaForMessage, queries || [])
|
|
2720
|
-
]);
|
|
2721
|
-
const snapshotDomains = stripToCore(domains);
|
|
2722
|
-
const snapshotServices = stripToCore(services);
|
|
2723
|
-
const snapshotAgents = stripToCore(agents);
|
|
2724
|
-
const snapshotEvents = stripToCore(events);
|
|
2725
|
-
const snapshotCommands = stripToCore(commands);
|
|
2726
|
-
const snapshotQueries = stripToCore(queries);
|
|
2727
|
-
const snapshotChannels = stripToCore(channels);
|
|
2728
|
-
const snapshotLabel = label || (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2729
|
-
const gitInfo = git || detectGitInfo(directory);
|
|
2730
|
-
const snapshot = {
|
|
2731
|
-
snapshotVersion: SNAPSHOT_VERSION,
|
|
2732
|
-
catalogVersion: getEventCatalogVersion2(directory),
|
|
2733
|
-
label: snapshotLabel,
|
|
2734
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2735
|
-
...gitInfo ? { git: gitInfo } : {},
|
|
2736
|
-
resources: {
|
|
2737
|
-
domains: snapshotDomains,
|
|
2738
|
-
services: snapshotServices,
|
|
2739
|
-
agents: snapshotAgents,
|
|
2740
|
-
messages: {
|
|
2741
|
-
events: snapshotEvents,
|
|
2742
|
-
commands: snapshotCommands,
|
|
2743
|
-
queries: snapshotQueries
|
|
2744
|
-
},
|
|
2745
|
-
channels: snapshotChannels
|
|
2746
|
-
}
|
|
2747
|
-
};
|
|
2748
|
-
const snapshotsDir = outputDir || import_node_path19.default.join(directory, ".snapshots");
|
|
2749
|
-
import_node_fs9.default.mkdirSync(snapshotsDir, { recursive: true });
|
|
2750
|
-
const fileName = `${snapshotLabel}.snapshot.json`;
|
|
2751
|
-
const filePath = import_node_path19.default.join(snapshotsDir, fileName);
|
|
2752
|
-
import_node_fs9.default.writeFileSync(filePath, JSON.stringify(snapshot));
|
|
2753
|
-
return { filePath, snapshot };
|
|
2754
|
-
};
|
|
2755
|
-
};
|
|
2756
|
-
var diffSnapshots = (directory) => async (snapshotAPath, snapshotBPath) => {
|
|
2757
|
-
const snapshotA = JSON.parse(import_node_fs9.default.readFileSync(snapshotAPath, "utf-8"));
|
|
2758
|
-
const snapshotB = JSON.parse(import_node_fs9.default.readFileSync(snapshotBPath, "utf-8"));
|
|
2759
|
-
const resourceChanges = computeResourceDiff(snapshotA, snapshotB);
|
|
2760
|
-
const relationshipChanges = computeRelationshipDiff(snapshotA, snapshotB);
|
|
2761
|
-
const resourceCounts = { added: 0, removed: 0, modified: 0, versioned: 0 };
|
|
2762
|
-
for (const r of resourceChanges) resourceCounts[r.changeType]++;
|
|
2763
|
-
const relCounts = { added: 0, removed: 0 };
|
|
2764
|
-
for (const r of relationshipChanges) relCounts[r.changeType]++;
|
|
2765
|
-
return {
|
|
2766
|
-
snapshotA: { label: snapshotA.label, createdAt: snapshotA.createdAt },
|
|
2767
|
-
snapshotB: { label: snapshotB.label, createdAt: snapshotB.createdAt },
|
|
2768
|
-
summary: {
|
|
2769
|
-
totalChanges: resourceChanges.length + relationshipChanges.length,
|
|
2770
|
-
resourcesAdded: resourceCounts.added,
|
|
2771
|
-
resourcesRemoved: resourceCounts.removed,
|
|
2772
|
-
resourcesModified: resourceCounts.modified,
|
|
2773
|
-
resourcesVersioned: resourceCounts.versioned,
|
|
2774
|
-
relationshipsAdded: relCounts.added,
|
|
2775
|
-
relationshipsRemoved: relCounts.removed
|
|
2776
|
-
},
|
|
2777
|
-
resources: resourceChanges,
|
|
2778
|
-
relationships: relationshipChanges
|
|
2779
|
-
};
|
|
2780
|
-
};
|
|
2781
|
-
var listSnapshots = (directory) => async () => {
|
|
2782
|
-
const snapshotsDir = import_node_path19.default.join(directory, ".snapshots");
|
|
2783
|
-
if (!import_node_fs9.default.existsSync(snapshotsDir)) return [];
|
|
2784
|
-
const files = import_node_fs9.default.readdirSync(snapshotsDir).filter((f) => f.endsWith(".snapshot.json"));
|
|
2785
|
-
const snapshots = [];
|
|
2786
|
-
for (const file of files) {
|
|
2787
|
-
try {
|
|
2788
|
-
const filePath = import_node_path19.default.join(snapshotsDir, file);
|
|
2789
|
-
const content = JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf-8"));
|
|
2790
|
-
snapshots.push({
|
|
2791
|
-
label: content.label,
|
|
2792
|
-
createdAt: content.createdAt,
|
|
2793
|
-
filePath,
|
|
2794
|
-
...content.git ? { git: content.git } : {}
|
|
2795
|
-
});
|
|
2796
|
-
} catch {
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
return snapshots.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
2800
|
-
};
|
|
2801
|
-
|
|
2802
|
-
// src/changelogs.ts
|
|
2803
|
-
var import_node_path20 = __toESM(require("path"));
|
|
2804
|
-
var import_node_fs10 = __toESM(require("fs"));
|
|
2805
|
-
var import_promises12 = __toESM(require("fs/promises"));
|
|
2806
|
-
var import_gray_matter8 = __toESM(require("gray-matter"));
|
|
2807
|
-
var writeChangelog = (catalogDir) => async (id, changelog, options = {}) => {
|
|
2808
|
-
const { version, format = "mdx" } = options;
|
|
2809
|
-
const resourceFile = await findFileById(catalogDir, id, version);
|
|
2810
|
-
if (!resourceFile) {
|
|
2811
|
-
throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ""}`);
|
|
2812
|
-
}
|
|
2813
|
-
const resourceDir = (0, import_node_path20.dirname)(resourceFile);
|
|
2814
|
-
const changelogPath = import_node_path20.default.join(resourceDir, `changelog.${format}`);
|
|
2815
|
-
const { markdown, ...frontmatter } = changelog;
|
|
2816
|
-
const fm = { ...frontmatter };
|
|
2817
|
-
if (fm.createdAt instanceof Date) {
|
|
2818
|
-
fm.createdAt = fm.createdAt;
|
|
2819
|
-
}
|
|
2820
|
-
if (!fm.badges || fm.badges.length === 0) {
|
|
2821
|
-
delete fm.badges;
|
|
2557
|
+
var writeContainerToSystem = (directory) => async (container, system, options = { path: "", format: "mdx", override: false }) => {
|
|
2558
|
+
const resourcePath = await getResourcePath(directory, system.id, system.version);
|
|
2559
|
+
if (!resourcePath) {
|
|
2560
|
+
throw new Error("System not found");
|
|
2822
2561
|
}
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
import_node_fs10.default.writeFileSync(changelogPath, document);
|
|
2826
|
-
invalidateFileCache();
|
|
2562
|
+
const pathForContainer = (0, import_node_path21.join)(resourcePath.directory, "containers", container.id);
|
|
2563
|
+
await writeResource(directory, { ...container }, { ...options, path: pathForContainer, type: "container" });
|
|
2827
2564
|
};
|
|
2828
|
-
var appendChangelog = (catalogDir) => async (id, changelog, options = {}) => {
|
|
2829
|
-
const { version, format = "mdx" } = options;
|
|
2830
|
-
const resourceFile = await findFileById(catalogDir, id, version);
|
|
2831
|
-
if (!resourceFile) {
|
|
2832
|
-
throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ""}`);
|
|
2833
|
-
}
|
|
2834
|
-
const resourceDir = (0, import_node_path20.dirname)(resourceFile);
|
|
2835
|
-
const mdxPath = import_node_path20.default.join(resourceDir, "changelog.mdx");
|
|
2836
|
-
const mdPath = import_node_path20.default.join(resourceDir, "changelog.md");
|
|
2837
|
-
const existingPath = import_node_fs10.default.existsSync(mdxPath) ? mdxPath : import_node_fs10.default.existsSync(mdPath) ? mdPath : void 0;
|
|
2838
|
-
if (!existingPath) {
|
|
2839
|
-
return writeChangelog(catalogDir)(id, changelog, options);
|
|
2840
|
-
}
|
|
2841
|
-
const existing = import_gray_matter8.default.read(existingPath);
|
|
2842
|
-
const existingContent = existing.content.trim();
|
|
2843
|
-
const newEntry = changelog.markdown.trim();
|
|
2844
|
-
const combined = `${newEntry}
|
|
2845
2565
|
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
import_node_fs10.default.writeFileSync(existingPath, document);
|
|
2858
|
-
invalidateFileCache();
|
|
2859
|
-
};
|
|
2860
|
-
var getChangelog = (catalogDir) => async (id, options = {}) => {
|
|
2861
|
-
const { version } = options;
|
|
2862
|
-
const resourceFile = await findFileById(catalogDir, id, version);
|
|
2863
|
-
if (!resourceFile) return void 0;
|
|
2864
|
-
const resourceDir = (0, import_node_path20.dirname)(resourceFile);
|
|
2865
|
-
const mdxPath = import_node_path20.default.join(resourceDir, "changelog.mdx");
|
|
2866
|
-
const mdPath = import_node_path20.default.join(resourceDir, "changelog.md");
|
|
2867
|
-
const changelogPath = import_node_fs10.default.existsSync(mdxPath) ? mdxPath : import_node_fs10.default.existsSync(mdPath) ? mdPath : void 0;
|
|
2868
|
-
if (!changelogPath) return void 0;
|
|
2869
|
-
const { data, content } = import_gray_matter8.default.read(changelogPath);
|
|
2870
|
-
return { ...data, markdown: content.trim() };
|
|
2871
|
-
};
|
|
2872
|
-
var rmChangelog = (catalogDir) => async (id, options = {}) => {
|
|
2873
|
-
const { version } = options;
|
|
2874
|
-
const resourceFile = await findFileById(catalogDir, id, version);
|
|
2875
|
-
if (!resourceFile) {
|
|
2876
|
-
throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ""}`);
|
|
2877
|
-
}
|
|
2878
|
-
const resourceDir = (0, import_node_path20.dirname)(resourceFile);
|
|
2879
|
-
const mdxPath = import_node_path20.default.join(resourceDir, "changelog.mdx");
|
|
2880
|
-
const mdPath = import_node_path20.default.join(resourceDir, "changelog.md");
|
|
2881
|
-
if (import_node_fs10.default.existsSync(mdxPath)) {
|
|
2882
|
-
await import_promises12.default.rm(mdxPath);
|
|
2883
|
-
}
|
|
2884
|
-
if (import_node_fs10.default.existsSync(mdPath)) {
|
|
2885
|
-
await import_promises12.default.rm(mdPath);
|
|
2886
|
-
}
|
|
2887
|
-
invalidateFileCache();
|
|
2888
|
-
};
|
|
2566
|
+
// src/data-stores.ts
|
|
2567
|
+
var getDataStore = getContainer;
|
|
2568
|
+
var getDataStores = getContainers;
|
|
2569
|
+
var writeDataStore = writeContainer;
|
|
2570
|
+
var versionDataStore = versionContainer;
|
|
2571
|
+
var rmDataStore = rmContainer;
|
|
2572
|
+
var rmDataStoreById = rmContainerById;
|
|
2573
|
+
var dataStoreHasVersion = containerHasVersion;
|
|
2574
|
+
var addFileToDataStore = addFileToContainer;
|
|
2575
|
+
var writeDataStoreToService = writeContainerToService;
|
|
2576
|
+
var writeDataStoreToSystem = writeContainerToSystem;
|
|
2889
2577
|
|
|
2890
2578
|
// src/entities.ts
|
|
2891
|
-
var
|
|
2892
|
-
var
|
|
2579
|
+
var import_promises15 = __toESM(require("fs/promises"));
|
|
2580
|
+
var import_node_path22 = require("path");
|
|
2893
2581
|
var getEntity = (directory) => async (id, version) => getResource(directory, id, version, { type: "entity" });
|
|
2894
2582
|
var getEntities = (directory) => async (options) => getResources(directory, { type: "entities", latestOnly: options?.latestOnly });
|
|
2895
2583
|
var writeEntity = (directory) => async (entity, options = {
|
|
@@ -2902,11 +2590,11 @@ var writeEntityToSystem = (directory) => async (entity, system, options = { path
|
|
|
2902
2590
|
if (!resourcePath) {
|
|
2903
2591
|
throw new Error("System not found");
|
|
2904
2592
|
}
|
|
2905
|
-
const pathForEntity = (0,
|
|
2593
|
+
const pathForEntity = (0, import_node_path22.join)(resourcePath.directory, "entities", entity.id);
|
|
2906
2594
|
await writeResource(directory, { ...entity }, { ...options, path: pathForEntity, type: "entity" });
|
|
2907
2595
|
};
|
|
2908
2596
|
var rmEntity = (directory) => async (path9) => {
|
|
2909
|
-
await
|
|
2597
|
+
await import_promises15.default.rm((0, import_node_path22.join)(directory, path9), { recursive: true });
|
|
2910
2598
|
invalidateFileCache();
|
|
2911
2599
|
};
|
|
2912
2600
|
var rmEntityById = (directory) => async (id, version, persistFiles) => {
|
|
@@ -2919,8 +2607,8 @@ var entityHasVersion = (directory) => async (id, version) => {
|
|
|
2919
2607
|
};
|
|
2920
2608
|
|
|
2921
2609
|
// src/flows.ts
|
|
2922
|
-
var
|
|
2923
|
-
var
|
|
2610
|
+
var import_promises16 = __toESM(require("fs/promises"));
|
|
2611
|
+
var import_node_path23 = require("path");
|
|
2924
2612
|
|
|
2925
2613
|
// src/flow-builder.ts
|
|
2926
2614
|
var cloneStep = (step) => ({
|
|
@@ -3384,144 +3072,815 @@ var FlowBuilder = class _FlowBuilder {
|
|
|
3384
3072
|
throw new Error(`Flow step "${step.id}" references missing next step "${nextStepId}"`);
|
|
3385
3073
|
}
|
|
3386
3074
|
}
|
|
3387
|
-
}
|
|
3388
|
-
}
|
|
3389
|
-
};
|
|
3390
|
-
|
|
3391
|
-
// src/flows.ts
|
|
3392
|
-
var getFlow = (directory) => async (id, version) => getResource(directory, id, version, { type: "flow" });
|
|
3393
|
-
var getFlows = (directory) => async (options) => getResources(directory, { type: "flows", latestOnly: options?.latestOnly });
|
|
3394
|
-
var writeFlow = (directory) => async (flow, options = {
|
|
3395
|
-
path: "",
|
|
3396
|
-
override: false,
|
|
3397
|
-
format: "mdx"
|
|
3398
|
-
}) => writeResource(directory, { ...flow }, { ...options, type: "flow" });
|
|
3399
|
-
var writeVersionedFlow = (directory) => async (flow) => {
|
|
3400
|
-
const path9 = getVersionedDirectory(flow.id, flow.version);
|
|
3401
|
-
return await writeFlow(directory)({ ...flow }, { path: path9 });
|
|
3402
|
-
};
|
|
3403
|
-
var writeFlowToDomain = (directory) => async (flow, domain, options = { path: "", format: "mdx", override: false }) => {
|
|
3404
|
-
let pathForFlow = domain.version && domain.version !== "latest" ? `/${domain.id}/versioned/${domain.version}/flows` : `/${domain.id}/flows`;
|
|
3405
|
-
pathForFlow = (0,
|
|
3406
|
-
await writeResource(directory, { ...flow }, { ...options, path: pathForFlow, type: "flow" });
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
};
|
|
3078
|
+
|
|
3079
|
+
// src/flows.ts
|
|
3080
|
+
var getFlow = (directory) => async (id, version) => getResource(directory, id, version, { type: "flow" });
|
|
3081
|
+
var getFlows = (directory) => async (options) => getResources(directory, { type: "flows", latestOnly: options?.latestOnly });
|
|
3082
|
+
var writeFlow = (directory) => async (flow, options = {
|
|
3083
|
+
path: "",
|
|
3084
|
+
override: false,
|
|
3085
|
+
format: "mdx"
|
|
3086
|
+
}) => writeResource(directory, { ...flow }, { ...options, type: "flow" });
|
|
3087
|
+
var writeVersionedFlow = (directory) => async (flow) => {
|
|
3088
|
+
const path9 = getVersionedDirectory(flow.id, flow.version);
|
|
3089
|
+
return await writeFlow(directory)({ ...flow }, { path: path9 });
|
|
3090
|
+
};
|
|
3091
|
+
var writeFlowToDomain = (directory) => async (flow, domain, options = { path: "", format: "mdx", override: false }) => {
|
|
3092
|
+
let pathForFlow = domain.version && domain.version !== "latest" ? `/${domain.id}/versioned/${domain.version}/flows` : `/${domain.id}/flows`;
|
|
3093
|
+
pathForFlow = (0, import_node_path23.join)(pathForFlow, flow.id);
|
|
3094
|
+
await writeResource(directory, { ...flow }, { ...options, path: pathForFlow, type: "flow" });
|
|
3095
|
+
};
|
|
3096
|
+
var writeFlowToService = (directory) => async (flow, service, options = { path: "", format: "mdx", override: false }) => {
|
|
3097
|
+
let pathForFlow = service.version && service.version !== "latest" ? `/${service.id}/versioned/${service.version}/flows` : `/${service.id}/flows`;
|
|
3098
|
+
pathForFlow = (0, import_node_path23.join)(pathForFlow, flow.id);
|
|
3099
|
+
await writeResource(directory, { ...flow }, { ...options, path: pathForFlow, type: "flow" });
|
|
3100
|
+
};
|
|
3101
|
+
var writeFlowToSystem = (directory) => async (flow, system, options = { path: "", format: "mdx", override: false }) => {
|
|
3102
|
+
const resourcePath = await getResourcePath(directory, system.id, system.version);
|
|
3103
|
+
if (!resourcePath) {
|
|
3104
|
+
throw new Error("System not found");
|
|
3105
|
+
}
|
|
3106
|
+
const pathForFlow = (0, import_node_path23.join)(resourcePath.directory, "flows", flow.id);
|
|
3107
|
+
await writeResource(directory, { ...flow }, { ...options, path: pathForFlow, type: "flow" });
|
|
3108
|
+
};
|
|
3109
|
+
var writeFlowToAgent = (directory) => async (flow, agent, options = { path: "", format: "mdx", override: false }) => {
|
|
3110
|
+
let pathForFlow = agent.version && agent.version !== "latest" ? `/${agent.id}/versioned/${agent.version}/flows` : `/${agent.id}/flows`;
|
|
3111
|
+
pathForFlow = (0, import_node_path23.join)(pathForFlow, flow.id);
|
|
3112
|
+
await writeResource(directory, { ...flow }, { ...options, path: pathForFlow, type: "flow" });
|
|
3113
|
+
};
|
|
3114
|
+
var rmFlow = (directory) => async (path9) => {
|
|
3115
|
+
await import_promises16.default.rm((0, import_node_path23.join)(directory, path9), { recursive: true });
|
|
3116
|
+
invalidateFileCache();
|
|
3117
|
+
};
|
|
3118
|
+
var rmFlowById = (directory) => async (id, version, persistFiles) => {
|
|
3119
|
+
await rmResourceById(directory, id, version, { type: "flow", persistFiles });
|
|
3120
|
+
};
|
|
3121
|
+
var versionFlow = (directory) => async (id) => versionResource(directory, id);
|
|
3122
|
+
var flowHasVersion = (directory) => async (id, version) => {
|
|
3123
|
+
const file = await findFileById(directory, id, version);
|
|
3124
|
+
return !!file;
|
|
3125
|
+
};
|
|
3126
|
+
var addFileToFlow = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version, { type: "flow" });
|
|
3127
|
+
|
|
3128
|
+
// src/graph.ts
|
|
3129
|
+
var DEFAULT_DEPTH = Number.POSITIVE_INFINITY;
|
|
3130
|
+
var RESOURCE_TYPE_ORDER = [
|
|
3131
|
+
"domain",
|
|
3132
|
+
"system",
|
|
3133
|
+
"service",
|
|
3134
|
+
"agent",
|
|
3135
|
+
"event",
|
|
3136
|
+
"command",
|
|
3137
|
+
"query",
|
|
3138
|
+
"channel",
|
|
3139
|
+
"entity",
|
|
3140
|
+
"container",
|
|
3141
|
+
"data-product",
|
|
3142
|
+
"flow",
|
|
3143
|
+
"adr"
|
|
3144
|
+
];
|
|
3145
|
+
var typeOrder = new Map(RESOURCE_TYPE_ORDER.map((type, index) => [type, index]));
|
|
3146
|
+
var NON_ADR_RESOURCE_TYPES = RESOURCE_TYPE_ORDER.filter((type) => type !== "adr");
|
|
3147
|
+
var NESTED_TRAVERSAL_CONCURRENCY = 16;
|
|
3148
|
+
var RESOURCE_TYPE_ALIASES = {
|
|
3149
|
+
domains: "domain",
|
|
3150
|
+
systems: "system",
|
|
3151
|
+
services: "service",
|
|
3152
|
+
agents: "agent",
|
|
3153
|
+
events: "event",
|
|
3154
|
+
commands: "command",
|
|
3155
|
+
queries: "query",
|
|
3156
|
+
channels: "channel",
|
|
3157
|
+
entities: "entity",
|
|
3158
|
+
containers: "container",
|
|
3159
|
+
"data-products": "data-product",
|
|
3160
|
+
flows: "flow",
|
|
3161
|
+
adrs: "adr"
|
|
3162
|
+
};
|
|
3163
|
+
var resourceKey = (resource) => `${resource.type}:${resource.id}:${resource.version}`;
|
|
3164
|
+
var toGraphResource = (type, resource) => ({
|
|
3165
|
+
type,
|
|
3166
|
+
id: resource.id,
|
|
3167
|
+
version: resource.version
|
|
3168
|
+
});
|
|
3169
|
+
var sortResources = (left, right) => {
|
|
3170
|
+
const typeComparison = (typeOrder.get(left.type) || 0) - (typeOrder.get(right.type) || 0);
|
|
3171
|
+
if (typeComparison !== 0) return typeComparison;
|
|
3172
|
+
const idComparison = left.id.localeCompare(right.id);
|
|
3173
|
+
return idComparison !== 0 ? idComparison : left.version.localeCompare(right.version);
|
|
3174
|
+
};
|
|
3175
|
+
var normalizeResourceType = (type) => {
|
|
3176
|
+
if (!type) return void 0;
|
|
3177
|
+
if (RESOURCE_TYPE_ORDER.includes(type)) return type;
|
|
3178
|
+
return RESOURCE_TYPE_ALIASES[type];
|
|
3179
|
+
};
|
|
3180
|
+
var indexResources = (resources) => {
|
|
3181
|
+
const byId = /* @__PURE__ */ new Map();
|
|
3182
|
+
const byVersion = /* @__PURE__ */ new Map();
|
|
3183
|
+
for (const resource of resources) {
|
|
3184
|
+
const versions = byId.get(resource.id);
|
|
3185
|
+
if (versions) versions.push(resource);
|
|
3186
|
+
else byId.set(resource.id, [resource]);
|
|
3187
|
+
byVersion.set(`${resource.id}:${resource.version}`, resource);
|
|
3188
|
+
}
|
|
3189
|
+
return { byId, byVersion };
|
|
3190
|
+
};
|
|
3191
|
+
var pathIncludes = (path9, key) => {
|
|
3192
|
+
let current = path9;
|
|
3193
|
+
while (current) {
|
|
3194
|
+
if (current.key === key) return true;
|
|
3195
|
+
current = current.parent;
|
|
3196
|
+
}
|
|
3197
|
+
return false;
|
|
3198
|
+
};
|
|
3199
|
+
var mapWithConcurrency = async (items, concurrency, transform) => {
|
|
3200
|
+
const results = new Array(items.length);
|
|
3201
|
+
let nextIndex = 0;
|
|
3202
|
+
const worker = async () => {
|
|
3203
|
+
while (nextIndex < items.length) {
|
|
3204
|
+
const index = nextIndex++;
|
|
3205
|
+
results[index] = await transform(items[index]);
|
|
3206
|
+
}
|
|
3207
|
+
};
|
|
3208
|
+
const workers = Array.from({ length: Math.min(concurrency, items.length) }, worker);
|
|
3209
|
+
await Promise.all(workers);
|
|
3210
|
+
return results;
|
|
3211
|
+
};
|
|
3212
|
+
var validateDepth = (depth) => {
|
|
3213
|
+
if (!Number.isInteger(depth) || depth < 0) {
|
|
3214
|
+
throw new Error("Graph depth must be a non-negative integer");
|
|
3215
|
+
}
|
|
3216
|
+
};
|
|
3217
|
+
var getGraph = (directory) => {
|
|
3218
|
+
const graph = async (root, options = {}) => {
|
|
3219
|
+
const depth = options.depth ?? DEFAULT_DEPTH;
|
|
3220
|
+
if (options.depth !== void 0) validateDepth(depth);
|
|
3221
|
+
const collectionLoaders = {
|
|
3222
|
+
domain: getDomains(directory),
|
|
3223
|
+
system: getSystems(directory),
|
|
3224
|
+
service: getServices(directory),
|
|
3225
|
+
agent: getAgents(directory),
|
|
3226
|
+
event: getEvents(directory),
|
|
3227
|
+
command: getCommands(directory),
|
|
3228
|
+
query: getQueries(directory),
|
|
3229
|
+
flow: getFlows(directory),
|
|
3230
|
+
channel: getChannels(directory),
|
|
3231
|
+
entity: getEntities(directory),
|
|
3232
|
+
container: getDataStores(directory),
|
|
3233
|
+
"data-product": getDataProducts(directory),
|
|
3234
|
+
adr: getAdrs(directory)
|
|
3235
|
+
};
|
|
3236
|
+
const latestIndexCache = /* @__PURE__ */ new Map();
|
|
3237
|
+
const allVersionsIndexCache = /* @__PURE__ */ new Map();
|
|
3238
|
+
const adjacencyCache = /* @__PURE__ */ new Map();
|
|
3239
|
+
const loadLatestIndex = (type) => {
|
|
3240
|
+
const cachedIndex = latestIndexCache.get(type);
|
|
3241
|
+
if (cachedIndex) return cachedIndex;
|
|
3242
|
+
const index = collectionLoaders[type]({ latestOnly: true }).then((resources2) => indexResources(resources2 || []));
|
|
3243
|
+
latestIndexCache.set(type, index);
|
|
3244
|
+
return index;
|
|
3245
|
+
};
|
|
3246
|
+
const loadAllVersionsIndex = (type) => {
|
|
3247
|
+
const cachedIndex = allVersionsIndexCache.get(type);
|
|
3248
|
+
if (cachedIndex) return cachedIndex;
|
|
3249
|
+
const latestIndex = latestIndexCache.get(type);
|
|
3250
|
+
const index = Promise.all([collectionLoaders[type](), latestIndex]).then(([resources2, loadedLatestIndex]) => {
|
|
3251
|
+
const allVersionsIndex = indexResources(resources2 || []);
|
|
3252
|
+
for (const [id, latestResources] of loadedLatestIndex?.byId || []) {
|
|
3253
|
+
const latestResource = latestResources[0];
|
|
3254
|
+
if (!latestResource) continue;
|
|
3255
|
+
const key = `${id}:${latestResource.version}`;
|
|
3256
|
+
if (!allVersionsIndex.byVersion.has(key)) continue;
|
|
3257
|
+
allVersionsIndex.byVersion.set(key, latestResource);
|
|
3258
|
+
const versions = allVersionsIndex.byId.get(id);
|
|
3259
|
+
const matchingVersion = versions?.findIndex((resource) => resource.version === latestResource.version) ?? -1;
|
|
3260
|
+
if (versions && matchingVersion !== -1) versions[matchingVersion] = latestResource;
|
|
3261
|
+
}
|
|
3262
|
+
return allVersionsIndex;
|
|
3263
|
+
});
|
|
3264
|
+
allVersionsIndexCache.set(type, index);
|
|
3265
|
+
return index;
|
|
3266
|
+
};
|
|
3267
|
+
const read = async (type, pointer) => {
|
|
3268
|
+
const latestIndex = await loadLatestIndex(type);
|
|
3269
|
+
const latestResource = latestIndex.byId.get(pointer.id)?.[0];
|
|
3270
|
+
if (!pointer.version || pointer.version === "latest") {
|
|
3271
|
+
return latestResource;
|
|
3272
|
+
}
|
|
3273
|
+
if (latestResource?.version === pointer.version) return latestResource;
|
|
3274
|
+
const allVersionsIndex = await loadAllVersionsIndex(type);
|
|
3275
|
+
const exactMatch = allVersionsIndex.byVersion.get(`${pointer.id}:${pointer.version}`);
|
|
3276
|
+
if (exactMatch) return exactMatch;
|
|
3277
|
+
const range = (0, import_semver6.validRange)(pointer.version);
|
|
3278
|
+
if (!range) return void 0;
|
|
3279
|
+
const candidates = allVersionsIndex.byId.get(pointer.id) || [];
|
|
3280
|
+
const version = (0, import_semver6.maxSatisfying)(
|
|
3281
|
+
candidates.map((resource) => resource.version),
|
|
3282
|
+
range
|
|
3283
|
+
);
|
|
3284
|
+
return candidates.find((resource) => resource.version === version);
|
|
3285
|
+
};
|
|
3286
|
+
const resolvePointer = async (pointer, candidateTypes) => {
|
|
3287
|
+
const explicitType = normalizeResourceType(pointer.type);
|
|
3288
|
+
if (pointer.type && !explicitType) return [];
|
|
3289
|
+
const types = explicitType ? [explicitType] : candidateTypes;
|
|
3290
|
+
const resolved = await Promise.all(
|
|
3291
|
+
types.map(async (type) => {
|
|
3292
|
+
const resource = await read(type, pointer);
|
|
3293
|
+
return resource && resource.hidden !== true ? { type, resource } : void 0;
|
|
3294
|
+
})
|
|
3295
|
+
);
|
|
3296
|
+
return resolved.filter((resource) => resource !== void 0);
|
|
3297
|
+
};
|
|
3298
|
+
const resolvePointers = async (pointers, candidateTypes) => {
|
|
3299
|
+
const resolved = await Promise.all(pointers.map((pointer) => resolvePointer(pointer, candidateTypes)));
|
|
3300
|
+
return resolved.flat();
|
|
3301
|
+
};
|
|
3302
|
+
let adrTargetIndex;
|
|
3303
|
+
const loadAdrTargetIndex = () => {
|
|
3304
|
+
if (adrTargetIndex) return adrTargetIndex;
|
|
3305
|
+
adrTargetIndex = loadAllVersionsIndex("adr").then((adrIndex) => {
|
|
3306
|
+
const targets = /* @__PURE__ */ new Map();
|
|
3307
|
+
for (const adr of adrIndex.byVersion.values()) {
|
|
3308
|
+
if (adr.hidden === true) continue;
|
|
3309
|
+
for (const pointer of adr.appliesTo || []) {
|
|
3310
|
+
const type = normalizeResourceType(pointer.type);
|
|
3311
|
+
if (!type || type === "adr") continue;
|
|
3312
|
+
const key = `${type}:${pointer.id}`;
|
|
3313
|
+
const entries = targets.get(key);
|
|
3314
|
+
const target = { pointer, resource: adr };
|
|
3315
|
+
if (entries) entries.push(target);
|
|
3316
|
+
else targets.set(key, [target]);
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
return targets;
|
|
3320
|
+
});
|
|
3321
|
+
return adrTargetIndex;
|
|
3322
|
+
};
|
|
3323
|
+
const pointerMatchesVersion = (pointer, version) => {
|
|
3324
|
+
if (!pointer.version || pointer.version === "latest") return true;
|
|
3325
|
+
if (pointer.version === version) return true;
|
|
3326
|
+
const range = (0, import_semver6.validRange)(pointer.version);
|
|
3327
|
+
return range ? (0, import_semver6.maxSatisfying)([version], range) === version : false;
|
|
3328
|
+
};
|
|
3329
|
+
const getAdrsForResource = async (type, resource) => {
|
|
3330
|
+
if (type === "adr") return [];
|
|
3331
|
+
const targets = (await loadAdrTargetIndex()).get(`${type}:${resource.id}`) || [];
|
|
3332
|
+
return targets.filter(({ pointer }) => pointerMatchesVersion(pointer, resource.version)).map(({ resource: resource2 }) => ({ type: "adr", resource: resource2 }));
|
|
3333
|
+
};
|
|
3334
|
+
const resolveChildren = async (type, resource) => {
|
|
3335
|
+
const children = [];
|
|
3336
|
+
const addPointers = async (pointers, candidateTypes) => {
|
|
3337
|
+
children.push(...await resolvePointers(pointers, candidateTypes));
|
|
3338
|
+
};
|
|
3339
|
+
if (type === "domain") {
|
|
3340
|
+
await addPointers(resource.domains || [], ["domain"]);
|
|
3341
|
+
await addPointers(resource.systems || [], ["system"]);
|
|
3342
|
+
await addPointers(resource.services || [], ["service"]);
|
|
3343
|
+
await addPointers(resource.agents || [], ["agent"]);
|
|
3344
|
+
await addPointers(resource.entities || [], ["entity"]);
|
|
3345
|
+
await addPointers(resource.flows || [], ["flow"]);
|
|
3346
|
+
await addPointers([...resource.dataProducts || [], ...resource["data-products"] || []], ["data-product"]);
|
|
3347
|
+
await addPointers([...resource.sends || [], ...resource.receives || []], ["event", "command", "query"]);
|
|
3348
|
+
} else if (type === "system") {
|
|
3349
|
+
await addPointers(resource.relationships || [], ["system"]);
|
|
3350
|
+
await addPointers(resource.services || [], ["service"]);
|
|
3351
|
+
await addPointers(resource.flows || [], ["flow"]);
|
|
3352
|
+
await addPointers(resource.entities || [], ["entity"]);
|
|
3353
|
+
await addPointers(resource.containers || [], ["container"]);
|
|
3354
|
+
} else if (type === "service" || type === "agent") {
|
|
3355
|
+
await addPointers([...resource.sends || [], ...resource.receives || []], ["event", "command", "query"]);
|
|
3356
|
+
await addPointers(resource.entities || [], ["entity"]);
|
|
3357
|
+
await addPointers(resource.flows || [], ["flow"]);
|
|
3358
|
+
await addPointers([...resource.writesTo || [], ...resource.readsFrom || []], ["container"]);
|
|
3359
|
+
} else if (type === "event" || type === "command" || type === "query") {
|
|
3360
|
+
await addPointers([...resource.channels || [], ...resource.messageChannels || []], ["channel"]);
|
|
3361
|
+
} else if (type === "channel") {
|
|
3362
|
+
await addPointers(resource.routes || [], ["channel"]);
|
|
3363
|
+
} else if (type === "data-product") {
|
|
3364
|
+
await addPointers(
|
|
3365
|
+
[...resource.inputs || [], ...resource.outputs || []],
|
|
3366
|
+
["event", "command", "query", "channel", "container", "service"]
|
|
3367
|
+
);
|
|
3368
|
+
} else if (type === "flow") {
|
|
3369
|
+
for (const step of resource.steps || []) {
|
|
3370
|
+
if (step.message) await addPointers([step.message], ["event", "command", "query"]);
|
|
3371
|
+
if (step.agent) await addPointers([step.agent], ["agent"]);
|
|
3372
|
+
if (step.service) await addPointers([step.service], ["service"]);
|
|
3373
|
+
if (step.flow) await addPointers([step.flow], ["flow"]);
|
|
3374
|
+
if (step.container) await addPointers([step.container], ["container"]);
|
|
3375
|
+
if (step.dataProduct) await addPointers([step.dataProduct], ["data-product"]);
|
|
3376
|
+
}
|
|
3377
|
+
} else if (type === "adr") {
|
|
3378
|
+
await addPointers(resource.appliesTo || [], NON_ADR_RESOURCE_TYPES);
|
|
3379
|
+
await addPointers(
|
|
3380
|
+
[
|
|
3381
|
+
...resource.supersedes || [],
|
|
3382
|
+
...resource.supersededBy || [],
|
|
3383
|
+
...resource.amends || [],
|
|
3384
|
+
...resource.amendedBy || [],
|
|
3385
|
+
...resource.related || []
|
|
3386
|
+
],
|
|
3387
|
+
["adr"]
|
|
3388
|
+
);
|
|
3389
|
+
}
|
|
3390
|
+
children.push(...await getAdrsForResource(type, resource));
|
|
3391
|
+
const uniqueChildren = /* @__PURE__ */ new Map();
|
|
3392
|
+
for (const child of children) {
|
|
3393
|
+
const graphResource = toGraphResource(child.type, child.resource);
|
|
3394
|
+
uniqueChildren.set(resourceKey(graphResource), child);
|
|
3395
|
+
}
|
|
3396
|
+
return Array.from(uniqueChildren.values()).sort(
|
|
3397
|
+
(left, right) => sortResources(toGraphResource(left.type, left.resource), toGraphResource(right.type, right.resource))
|
|
3398
|
+
);
|
|
3399
|
+
};
|
|
3400
|
+
const getChildren = (type, resource) => {
|
|
3401
|
+
const key = resourceKey(toGraphResource(type, resource));
|
|
3402
|
+
const cachedChildren = adjacencyCache.get(key);
|
|
3403
|
+
if (cachedChildren) return cachedChildren;
|
|
3404
|
+
const children = resolveChildren(type, resource);
|
|
3405
|
+
adjacencyCache.set(key, children);
|
|
3406
|
+
return children;
|
|
3407
|
+
};
|
|
3408
|
+
const buildNode = async (type, resource, remainingDepth, ancestors) => {
|
|
3409
|
+
const graphResource = toGraphResource(type, resource);
|
|
3410
|
+
const key = resourceKey(graphResource);
|
|
3411
|
+
if (remainingDepth === 0) return { ...graphResource, children: [] };
|
|
3412
|
+
const nextAncestors = { key, parent: ancestors };
|
|
3413
|
+
const resolvedChildren = await getChildren(type, resource);
|
|
3414
|
+
const children = await mapWithConcurrency(
|
|
3415
|
+
resolvedChildren,
|
|
3416
|
+
NESTED_TRAVERSAL_CONCURRENCY,
|
|
3417
|
+
({ type: childType, resource: childResource }) => {
|
|
3418
|
+
const child = toGraphResource(childType, childResource);
|
|
3419
|
+
if (pathIncludes(nextAncestors, resourceKey(child))) return Promise.resolve({ ...child, children: [] });
|
|
3420
|
+
return buildNode(childType, childResource, remainingDepth - 1, nextAncestors);
|
|
3421
|
+
}
|
|
3422
|
+
);
|
|
3423
|
+
return { ...graphResource, children };
|
|
3424
|
+
};
|
|
3425
|
+
const rootResource = await read(root.type, root);
|
|
3426
|
+
if (!rootResource || rootResource.hidden === true) return void 0;
|
|
3427
|
+
const flatRoot = toGraphResource(root.type, rootResource);
|
|
3428
|
+
if (!options.flat) {
|
|
3429
|
+
const nestedRoot = await buildNode(root.type, rootResource, depth);
|
|
3430
|
+
return { root: nestedRoot };
|
|
3431
|
+
}
|
|
3432
|
+
const flatRootKey = resourceKey(flatRoot);
|
|
3433
|
+
const resources = /* @__PURE__ */ new Map([[flatRootKey, flatRoot]]);
|
|
3434
|
+
const visited = /* @__PURE__ */ new Set([flatRootKey]);
|
|
3435
|
+
const queue = [
|
|
3436
|
+
{ type: root.type, resource: rootResource, remainingDepth: depth }
|
|
3437
|
+
];
|
|
3438
|
+
for (let index = 0; index < queue.length; index++) {
|
|
3439
|
+
const current = queue[index];
|
|
3440
|
+
if (current.remainingDepth === 0) continue;
|
|
3441
|
+
const children = await getChildren(current.type, current.resource);
|
|
3442
|
+
for (const child of children) {
|
|
3443
|
+
const graphResource = toGraphResource(child.type, child.resource);
|
|
3444
|
+
const key = resourceKey(graphResource);
|
|
3445
|
+
if (visited.has(key)) continue;
|
|
3446
|
+
visited.add(key);
|
|
3447
|
+
resources.set(key, graphResource);
|
|
3448
|
+
queue.push({ ...child, remainingDepth: current.remainingDepth - 1 });
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
const relatedResources = Array.from(resources.values()).filter((resource) => resourceKey(resource) !== flatRootKey).sort(sortResources);
|
|
3452
|
+
return {
|
|
3453
|
+
root: flatRoot,
|
|
3454
|
+
resources: [flatRoot, ...relatedResources]
|
|
3455
|
+
};
|
|
3456
|
+
};
|
|
3457
|
+
return graph;
|
|
3458
|
+
};
|
|
3459
|
+
|
|
3460
|
+
// src/snapshots.ts
|
|
3461
|
+
var import_node_fs9 = __toESM(require("fs"));
|
|
3462
|
+
var import_node_path24 = __toESM(require("path"));
|
|
3463
|
+
var import_node_crypto = require("crypto");
|
|
3464
|
+
var import_node_child_process = require("child_process");
|
|
3465
|
+
var import_semver7 = require("semver");
|
|
3466
|
+
|
|
3467
|
+
// src/snapshot-diff.ts
|
|
3468
|
+
var stableStringify = (value) => {
|
|
3469
|
+
if (value === null || value === void 0 || typeof value !== "object") {
|
|
3470
|
+
return JSON.stringify(value);
|
|
3471
|
+
}
|
|
3472
|
+
if (Array.isArray(value)) {
|
|
3473
|
+
return "[" + value.map(stableStringify).join(",") + "]";
|
|
3474
|
+
}
|
|
3475
|
+
const sorted = Object.keys(value).sort().map((key) => JSON.stringify(key) + ":" + stableStringify(value[key]));
|
|
3476
|
+
return "{" + sorted.join(",") + "}";
|
|
3477
|
+
};
|
|
3478
|
+
var flattenResources = (snapshot) => {
|
|
3479
|
+
const resources = [];
|
|
3480
|
+
const addResources = (items, type) => {
|
|
3481
|
+
for (const item of items) {
|
|
3482
|
+
resources.push({
|
|
3483
|
+
resourceId: item.id,
|
|
3484
|
+
version: item.version,
|
|
3485
|
+
type,
|
|
3486
|
+
data: item
|
|
3487
|
+
});
|
|
3488
|
+
}
|
|
3489
|
+
};
|
|
3490
|
+
addResources(snapshot.resources.domains, "domain");
|
|
3491
|
+
addResources(snapshot.resources.services, "service");
|
|
3492
|
+
addResources(snapshot.resources.agents || [], "agent");
|
|
3493
|
+
addResources(snapshot.resources.messages.events, "event");
|
|
3494
|
+
addResources(snapshot.resources.messages.commands, "command");
|
|
3495
|
+
addResources(snapshot.resources.messages.queries, "query");
|
|
3496
|
+
addResources(snapshot.resources.channels, "channel");
|
|
3497
|
+
return resources;
|
|
3498
|
+
};
|
|
3499
|
+
var EXCLUDED_FIELDS = /* @__PURE__ */ new Set(["markdown", "_eventcatalog"]);
|
|
3500
|
+
var getComparableFields = (data) => {
|
|
3501
|
+
const result = {};
|
|
3502
|
+
for (const [key, value] of Object.entries(data)) {
|
|
3503
|
+
if (!EXCLUDED_FIELDS.has(key)) {
|
|
3504
|
+
result[key] = value;
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
return result;
|
|
3508
|
+
};
|
|
3509
|
+
var findChangedFields = (dataA, dataB) => {
|
|
3510
|
+
const fieldsA = getComparableFields(dataA);
|
|
3511
|
+
const fieldsB = getComparableFields(dataB);
|
|
3512
|
+
const allKeys = /* @__PURE__ */ new Set([...Object.keys(fieldsA), ...Object.keys(fieldsB)]);
|
|
3513
|
+
const changed = [];
|
|
3514
|
+
for (const key of allKeys) {
|
|
3515
|
+
if (stableStringify(fieldsA[key] ?? null) !== stableStringify(fieldsB[key] ?? null)) {
|
|
3516
|
+
changed.push(key);
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
return changed;
|
|
3520
|
+
};
|
|
3521
|
+
var resourceKey2 = (r) => `${r.resourceId}@${r.version}`;
|
|
3522
|
+
var idTypeKey = (r) => `${r.resourceId}:${r.type}`;
|
|
3523
|
+
var computeResourceDiff = (snapshotA, snapshotB) => {
|
|
3524
|
+
const resourcesA = flattenResources(snapshotA);
|
|
3525
|
+
const resourcesB = flattenResources(snapshotB);
|
|
3526
|
+
const mapA = /* @__PURE__ */ new Map();
|
|
3527
|
+
const byIdA = /* @__PURE__ */ new Map();
|
|
3528
|
+
for (const r of resourcesA) {
|
|
3529
|
+
mapA.set(resourceKey2(r), r);
|
|
3530
|
+
byIdA.set(idTypeKey(r), r);
|
|
3531
|
+
}
|
|
3532
|
+
const mapB = /* @__PURE__ */ new Map();
|
|
3533
|
+
const byIdB = /* @__PURE__ */ new Map();
|
|
3534
|
+
for (const r of resourcesB) {
|
|
3535
|
+
mapB.set(resourceKey2(r), r);
|
|
3536
|
+
byIdB.set(idTypeKey(r), r);
|
|
3537
|
+
}
|
|
3538
|
+
const changes = [];
|
|
3539
|
+
const handledIds = /* @__PURE__ */ new Set();
|
|
3540
|
+
for (const resource of resourcesB) {
|
|
3541
|
+
const key = resourceKey2(resource);
|
|
3542
|
+
if (!mapA.has(key)) {
|
|
3543
|
+
const idKey = idTypeKey(resource);
|
|
3544
|
+
const oldResource = byIdA.get(idKey);
|
|
3545
|
+
if (oldResource && oldResource.version !== resource.version && !handledIds.has(idKey)) {
|
|
3546
|
+
const changedFields = findChangedFields(oldResource.data, resource.data);
|
|
3547
|
+
changes.push({
|
|
3548
|
+
resourceId: resource.resourceId,
|
|
3549
|
+
version: resource.version,
|
|
3550
|
+
type: resource.type,
|
|
3551
|
+
changeType: "versioned",
|
|
3552
|
+
previousVersion: oldResource.version,
|
|
3553
|
+
newVersion: resource.version,
|
|
3554
|
+
changedFields: changedFields.length > 0 ? changedFields : void 0
|
|
3555
|
+
});
|
|
3556
|
+
handledIds.add(idKey);
|
|
3557
|
+
} else if (!handledIds.has(idKey)) {
|
|
3558
|
+
changes.push({
|
|
3559
|
+
resourceId: resource.resourceId,
|
|
3560
|
+
version: resource.version,
|
|
3561
|
+
type: resource.type,
|
|
3562
|
+
changeType: "added"
|
|
3563
|
+
});
|
|
3564
|
+
}
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
for (const resource of resourcesA) {
|
|
3568
|
+
const key = resourceKey2(resource);
|
|
3569
|
+
if (!mapB.has(key)) {
|
|
3570
|
+
const idKey = idTypeKey(resource);
|
|
3571
|
+
if (!handledIds.has(idKey)) {
|
|
3572
|
+
changes.push({
|
|
3573
|
+
resourceId: resource.resourceId,
|
|
3574
|
+
version: resource.version,
|
|
3575
|
+
type: resource.type,
|
|
3576
|
+
changeType: "removed"
|
|
3577
|
+
});
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
for (const resourceB of resourcesB) {
|
|
3582
|
+
const key = resourceKey2(resourceB);
|
|
3583
|
+
const resourceA = mapA.get(key);
|
|
3584
|
+
if (resourceA) {
|
|
3585
|
+
const changedFields = findChangedFields(resourceA.data, resourceB.data);
|
|
3586
|
+
if (changedFields.length > 0) {
|
|
3587
|
+
changes.push({
|
|
3588
|
+
resourceId: resourceB.resourceId,
|
|
3589
|
+
version: resourceB.version,
|
|
3590
|
+
type: resourceB.type,
|
|
3591
|
+
changeType: "modified",
|
|
3592
|
+
changedFields
|
|
3593
|
+
});
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
return changes;
|
|
3598
|
+
};
|
|
3599
|
+
var getRelationshipKey = (serviceId, resourceId, resourceVersion, direction) => {
|
|
3600
|
+
return `${serviceId}:${direction}:${resourceId}@${resourceVersion || "latest"}`;
|
|
3601
|
+
};
|
|
3602
|
+
var extractRelationships = (snapshot) => {
|
|
3603
|
+
const relationships = /* @__PURE__ */ new Map();
|
|
3604
|
+
for (const service of [...snapshot.resources.services, ...snapshot.resources.agents || []]) {
|
|
3605
|
+
for (const direction of ["sends", "receives"]) {
|
|
3606
|
+
const pointers = service[direction] || [];
|
|
3607
|
+
for (const pointer of pointers) {
|
|
3608
|
+
const key = getRelationshipKey(service.id, pointer.id, pointer.version, direction);
|
|
3609
|
+
relationships.set(key, {
|
|
3610
|
+
serviceId: service.id,
|
|
3611
|
+
serviceVersion: service.version,
|
|
3612
|
+
resourceId: pointer.id,
|
|
3613
|
+
resourceVersion: pointer.version,
|
|
3614
|
+
direction
|
|
3615
|
+
});
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
return relationships;
|
|
3620
|
+
};
|
|
3621
|
+
var computeRelationshipDiff = (snapshotA, snapshotB) => {
|
|
3622
|
+
const relsA = extractRelationships(snapshotA);
|
|
3623
|
+
const relsB = extractRelationships(snapshotB);
|
|
3624
|
+
const changes = [];
|
|
3625
|
+
for (const [key, rel] of relsB) {
|
|
3626
|
+
if (!relsA.has(key)) {
|
|
3627
|
+
changes.push({ ...rel, changeType: "added" });
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
for (const [key, rel] of relsA) {
|
|
3631
|
+
if (!relsB.has(key)) {
|
|
3632
|
+
changes.push({ ...rel, changeType: "removed" });
|
|
3633
|
+
}
|
|
3634
|
+
}
|
|
3635
|
+
return changes;
|
|
3636
|
+
};
|
|
3637
|
+
|
|
3638
|
+
// src/snapshots.ts
|
|
3639
|
+
var SNAPSHOT_VERSION = "1.0.0";
|
|
3640
|
+
var getEventCatalogVersion2 = (catalogDir) => {
|
|
3641
|
+
try {
|
|
3642
|
+
const packageJson = import_node_fs9.default.readFileSync(import_node_path24.default.join(catalogDir, "package.json"), "utf8");
|
|
3643
|
+
const packageJsonObject = JSON.parse(packageJson);
|
|
3644
|
+
return packageJsonObject["dependencies"]?.["@eventcatalog/core"] ?? "unknown";
|
|
3645
|
+
} catch {
|
|
3646
|
+
return "unknown";
|
|
3647
|
+
}
|
|
3648
|
+
};
|
|
3649
|
+
var pickCoreFields = (resource) => {
|
|
3650
|
+
const picked = { id: resource.id, version: resource.version, name: resource.name };
|
|
3651
|
+
if (resource.sends) picked.sends = resource.sends;
|
|
3652
|
+
if (resource.receives) picked.receives = resource.receives;
|
|
3653
|
+
if (resource.deprecated) picked.deprecated = resource.deprecated;
|
|
3654
|
+
if (resource.owners) picked.owners = resource.owners;
|
|
3655
|
+
if (resource.schemaPath) picked.schemaPath = resource.schemaPath;
|
|
3656
|
+
if (resource.schemaHash) picked.schemaHash = resource.schemaHash;
|
|
3657
|
+
return picked;
|
|
3658
|
+
};
|
|
3659
|
+
var deduplicateByLatestVersion = (resources) => {
|
|
3660
|
+
const seen = /* @__PURE__ */ new Map();
|
|
3661
|
+
for (const r of resources) {
|
|
3662
|
+
const existing = seen.get(r.id);
|
|
3663
|
+
if (!existing || (0, import_semver7.compare)(r.version, existing.version) > 0) {
|
|
3664
|
+
seen.set(r.id, r);
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
return Array.from(seen.values());
|
|
3668
|
+
};
|
|
3669
|
+
var stripToCore = (resources) => {
|
|
3670
|
+
if (!resources || resources.length === 0) return [];
|
|
3671
|
+
return deduplicateByLatestVersion(resources).map(pickCoreFields);
|
|
3672
|
+
};
|
|
3673
|
+
var detectGitInfo = (catalogDir) => {
|
|
3674
|
+
try {
|
|
3675
|
+
const opts = { cwd: catalogDir, encoding: "utf8", stdio: "pipe" };
|
|
3676
|
+
const branch = (0, import_node_child_process.execSync)("git rev-parse --abbrev-ref HEAD", opts).trim();
|
|
3677
|
+
const commit = (0, import_node_child_process.execSync)("git rev-parse --short HEAD", opts).trim();
|
|
3678
|
+
const status = (0, import_node_child_process.execSync)("git status --porcelain", opts).trim();
|
|
3679
|
+
return { branch, commit, dirty: status.length > 0 };
|
|
3680
|
+
} catch {
|
|
3681
|
+
return void 0;
|
|
3682
|
+
}
|
|
3683
|
+
};
|
|
3684
|
+
var enrichWithSchemaHashes = async (getSchemaForMessage2, resources) => {
|
|
3685
|
+
await Promise.all(
|
|
3686
|
+
resources.map(async (resource) => {
|
|
3687
|
+
if (!resource.schemaPath) return;
|
|
3688
|
+
const schema = await getSchemaForMessage2(resource.id, resource.version);
|
|
3689
|
+
if (!schema) return;
|
|
3690
|
+
resource.schemaHash = (0, import_node_crypto.createHash)("sha256").update(schema.schema).digest("hex");
|
|
3691
|
+
})
|
|
3692
|
+
);
|
|
3693
|
+
};
|
|
3694
|
+
var createSnapshot = (directory) => {
|
|
3695
|
+
return async (options) => {
|
|
3696
|
+
const { label, outputDir, git } = options || {};
|
|
3697
|
+
const sdk = src_default(directory);
|
|
3698
|
+
const [domains, services, agents, events, commands, queries, channels] = await Promise.all([
|
|
3699
|
+
sdk.getDomains(),
|
|
3700
|
+
sdk.getServices(),
|
|
3701
|
+
sdk.getAgents(),
|
|
3702
|
+
sdk.getEvents(),
|
|
3703
|
+
sdk.getCommands(),
|
|
3704
|
+
sdk.getQueries(),
|
|
3705
|
+
sdk.getChannels()
|
|
3706
|
+
]);
|
|
3707
|
+
await Promise.all([
|
|
3708
|
+
enrichWithSchemaHashes(sdk.getSchemaForMessage, events || []),
|
|
3709
|
+
enrichWithSchemaHashes(sdk.getSchemaForMessage, commands || []),
|
|
3710
|
+
enrichWithSchemaHashes(sdk.getSchemaForMessage, queries || [])
|
|
3711
|
+
]);
|
|
3712
|
+
const snapshotDomains = stripToCore(domains);
|
|
3713
|
+
const snapshotServices = stripToCore(services);
|
|
3714
|
+
const snapshotAgents = stripToCore(agents);
|
|
3715
|
+
const snapshotEvents = stripToCore(events);
|
|
3716
|
+
const snapshotCommands = stripToCore(commands);
|
|
3717
|
+
const snapshotQueries = stripToCore(queries);
|
|
3718
|
+
const snapshotChannels = stripToCore(channels);
|
|
3719
|
+
const snapshotLabel = label || (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3720
|
+
const gitInfo = git || detectGitInfo(directory);
|
|
3721
|
+
const snapshot = {
|
|
3722
|
+
snapshotVersion: SNAPSHOT_VERSION,
|
|
3723
|
+
catalogVersion: getEventCatalogVersion2(directory),
|
|
3724
|
+
label: snapshotLabel,
|
|
3725
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3726
|
+
...gitInfo ? { git: gitInfo } : {},
|
|
3727
|
+
resources: {
|
|
3728
|
+
domains: snapshotDomains,
|
|
3729
|
+
services: snapshotServices,
|
|
3730
|
+
agents: snapshotAgents,
|
|
3731
|
+
messages: {
|
|
3732
|
+
events: snapshotEvents,
|
|
3733
|
+
commands: snapshotCommands,
|
|
3734
|
+
queries: snapshotQueries
|
|
3735
|
+
},
|
|
3736
|
+
channels: snapshotChannels
|
|
3737
|
+
}
|
|
3738
|
+
};
|
|
3739
|
+
const snapshotsDir = outputDir || import_node_path24.default.join(directory, ".snapshots");
|
|
3740
|
+
import_node_fs9.default.mkdirSync(snapshotsDir, { recursive: true });
|
|
3741
|
+
const fileName = `${snapshotLabel}.snapshot.json`;
|
|
3742
|
+
const filePath = import_node_path24.default.join(snapshotsDir, fileName);
|
|
3743
|
+
import_node_fs9.default.writeFileSync(filePath, JSON.stringify(snapshot));
|
|
3744
|
+
return { filePath, snapshot };
|
|
3745
|
+
};
|
|
3407
3746
|
};
|
|
3408
|
-
var
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3747
|
+
var diffSnapshots = (directory) => async (snapshotAPath, snapshotBPath) => {
|
|
3748
|
+
const snapshotA = JSON.parse(import_node_fs9.default.readFileSync(snapshotAPath, "utf-8"));
|
|
3749
|
+
const snapshotB = JSON.parse(import_node_fs9.default.readFileSync(snapshotBPath, "utf-8"));
|
|
3750
|
+
const resourceChanges = computeResourceDiff(snapshotA, snapshotB);
|
|
3751
|
+
const relationshipChanges = computeRelationshipDiff(snapshotA, snapshotB);
|
|
3752
|
+
const resourceCounts = { added: 0, removed: 0, modified: 0, versioned: 0 };
|
|
3753
|
+
for (const r of resourceChanges) resourceCounts[r.changeType]++;
|
|
3754
|
+
const relCounts = { added: 0, removed: 0 };
|
|
3755
|
+
for (const r of relationshipChanges) relCounts[r.changeType]++;
|
|
3756
|
+
return {
|
|
3757
|
+
snapshotA: { label: snapshotA.label, createdAt: snapshotA.createdAt },
|
|
3758
|
+
snapshotB: { label: snapshotB.label, createdAt: snapshotB.createdAt },
|
|
3759
|
+
summary: {
|
|
3760
|
+
totalChanges: resourceChanges.length + relationshipChanges.length,
|
|
3761
|
+
resourcesAdded: resourceCounts.added,
|
|
3762
|
+
resourcesRemoved: resourceCounts.removed,
|
|
3763
|
+
resourcesModified: resourceCounts.modified,
|
|
3764
|
+
resourcesVersioned: resourceCounts.versioned,
|
|
3765
|
+
relationshipsAdded: relCounts.added,
|
|
3766
|
+
relationshipsRemoved: relCounts.removed
|
|
3767
|
+
},
|
|
3768
|
+
resources: resourceChanges,
|
|
3769
|
+
relationships: relationshipChanges
|
|
3770
|
+
};
|
|
3412
3771
|
};
|
|
3413
|
-
var
|
|
3414
|
-
const
|
|
3415
|
-
if (!
|
|
3416
|
-
|
|
3772
|
+
var listSnapshots = (directory) => async () => {
|
|
3773
|
+
const snapshotsDir = import_node_path24.default.join(directory, ".snapshots");
|
|
3774
|
+
if (!import_node_fs9.default.existsSync(snapshotsDir)) return [];
|
|
3775
|
+
const files = import_node_fs9.default.readdirSync(snapshotsDir).filter((f) => f.endsWith(".snapshot.json"));
|
|
3776
|
+
const snapshots = [];
|
|
3777
|
+
for (const file of files) {
|
|
3778
|
+
try {
|
|
3779
|
+
const filePath = import_node_path24.default.join(snapshotsDir, file);
|
|
3780
|
+
const content = JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf-8"));
|
|
3781
|
+
snapshots.push({
|
|
3782
|
+
label: content.label,
|
|
3783
|
+
createdAt: content.createdAt,
|
|
3784
|
+
filePath,
|
|
3785
|
+
...content.git ? { git: content.git } : {}
|
|
3786
|
+
});
|
|
3787
|
+
} catch {
|
|
3788
|
+
}
|
|
3417
3789
|
}
|
|
3418
|
-
|
|
3419
|
-
await writeResource(directory, { ...flow }, { ...options, path: pathForFlow, type: "flow" });
|
|
3420
|
-
};
|
|
3421
|
-
var writeFlowToAgent = (directory) => async (flow, agent, options = { path: "", format: "mdx", override: false }) => {
|
|
3422
|
-
let pathForFlow = agent.version && agent.version !== "latest" ? `/${agent.id}/versioned/${agent.version}/flows` : `/${agent.id}/flows`;
|
|
3423
|
-
pathForFlow = (0, import_node_path22.join)(pathForFlow, flow.id);
|
|
3424
|
-
await writeResource(directory, { ...flow }, { ...options, path: pathForFlow, type: "flow" });
|
|
3425
|
-
};
|
|
3426
|
-
var rmFlow = (directory) => async (path9) => {
|
|
3427
|
-
await import_promises14.default.rm((0, import_node_path22.join)(directory, path9), { recursive: true });
|
|
3428
|
-
invalidateFileCache();
|
|
3429
|
-
};
|
|
3430
|
-
var rmFlowById = (directory) => async (id, version, persistFiles) => {
|
|
3431
|
-
await rmResourceById(directory, id, version, { type: "flow", persistFiles });
|
|
3432
|
-
};
|
|
3433
|
-
var versionFlow = (directory) => async (id) => versionResource(directory, id);
|
|
3434
|
-
var flowHasVersion = (directory) => async (id, version) => {
|
|
3435
|
-
const file = await findFileById(directory, id, version);
|
|
3436
|
-
return !!file;
|
|
3790
|
+
return snapshots.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
3437
3791
|
};
|
|
3438
|
-
var addFileToFlow = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version, { type: "flow" });
|
|
3439
3792
|
|
|
3440
|
-
// src/
|
|
3441
|
-
var
|
|
3442
|
-
var
|
|
3443
|
-
var
|
|
3444
|
-
var
|
|
3445
|
-
var
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3793
|
+
// src/changelogs.ts
|
|
3794
|
+
var import_node_path25 = __toESM(require("path"));
|
|
3795
|
+
var import_node_fs10 = __toESM(require("fs"));
|
|
3796
|
+
var import_promises17 = __toESM(require("fs/promises"));
|
|
3797
|
+
var import_gray_matter8 = __toESM(require("gray-matter"));
|
|
3798
|
+
var writeChangelog = (catalogDir) => async (id, changelog, options = {}) => {
|
|
3799
|
+
const { version, format = "mdx" } = options;
|
|
3800
|
+
const resourceFile = await findFileById(catalogDir, id, version);
|
|
3801
|
+
if (!resourceFile) {
|
|
3802
|
+
throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ""}`);
|
|
3803
|
+
}
|
|
3804
|
+
const resourceDir = (0, import_node_path25.dirname)(resourceFile);
|
|
3805
|
+
const changelogPath = import_node_path25.default.join(resourceDir, `changelog.${format}`);
|
|
3806
|
+
const { markdown, ...frontmatter } = changelog;
|
|
3807
|
+
const fm = { ...frontmatter };
|
|
3808
|
+
if (fm.createdAt instanceof Date) {
|
|
3809
|
+
fm.createdAt = fm.createdAt;
|
|
3810
|
+
}
|
|
3811
|
+
if (!fm.badges || fm.badges.length === 0) {
|
|
3812
|
+
delete fm.badges;
|
|
3813
|
+
}
|
|
3814
|
+
import_node_fs10.default.mkdirSync(resourceDir, { recursive: true });
|
|
3815
|
+
const document = import_gray_matter8.default.stringify(markdown.trim(), fm);
|
|
3816
|
+
import_node_fs10.default.writeFileSync(changelogPath, document);
|
|
3453
3817
|
invalidateFileCache();
|
|
3454
3818
|
};
|
|
3455
|
-
var
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
return !!file;
|
|
3461
|
-
};
|
|
3462
|
-
var addFileToContainer = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
|
|
3463
|
-
var writeContainerToService = (directory) => async (container, service, options = { path: "", format: "mdx", override: false }) => {
|
|
3464
|
-
const resourcePath = await getResourcePath(directory, service.id, service.version);
|
|
3465
|
-
if (!resourcePath) {
|
|
3466
|
-
throw new Error("Service not found");
|
|
3819
|
+
var appendChangelog = (catalogDir) => async (id, changelog, options = {}) => {
|
|
3820
|
+
const { version, format = "mdx" } = options;
|
|
3821
|
+
const resourceFile = await findFileById(catalogDir, id, version);
|
|
3822
|
+
if (!resourceFile) {
|
|
3823
|
+
throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ""}`);
|
|
3467
3824
|
}
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
if (!resourcePath) {
|
|
3475
|
-
throw new Error("System not found");
|
|
3825
|
+
const resourceDir = (0, import_node_path25.dirname)(resourceFile);
|
|
3826
|
+
const mdxPath = import_node_path25.default.join(resourceDir, "changelog.mdx");
|
|
3827
|
+
const mdPath = import_node_path25.default.join(resourceDir, "changelog.md");
|
|
3828
|
+
const existingPath = import_node_fs10.default.existsSync(mdxPath) ? mdxPath : import_node_fs10.default.existsSync(mdPath) ? mdPath : void 0;
|
|
3829
|
+
if (!existingPath) {
|
|
3830
|
+
return writeChangelog(catalogDir)(id, changelog, options);
|
|
3476
3831
|
}
|
|
3477
|
-
const
|
|
3478
|
-
|
|
3479
|
-
|
|
3832
|
+
const existing = import_gray_matter8.default.read(existingPath);
|
|
3833
|
+
const existingContent = existing.content.trim();
|
|
3834
|
+
const newEntry = changelog.markdown.trim();
|
|
3835
|
+
const combined = `${newEntry}
|
|
3480
3836
|
|
|
3481
|
-
|
|
3482
|
-
var getDataStore = getContainer;
|
|
3483
|
-
var getDataStores = getContainers;
|
|
3484
|
-
var writeDataStore = writeContainer;
|
|
3485
|
-
var versionDataStore = versionContainer;
|
|
3486
|
-
var rmDataStore = rmContainer;
|
|
3487
|
-
var rmDataStoreById = rmContainerById;
|
|
3488
|
-
var dataStoreHasVersion = containerHasVersion;
|
|
3489
|
-
var addFileToDataStore = addFileToContainer;
|
|
3490
|
-
var writeDataStoreToService = writeContainerToService;
|
|
3491
|
-
var writeDataStoreToSystem = writeContainerToSystem;
|
|
3837
|
+
---
|
|
3492
3838
|
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
var writeDataProductToDomain = (directory) => async (dataProduct, domain, options = { path: "", format: "mdx", override: false }) => {
|
|
3504
|
-
let pathForDataProduct = domain.version && domain.version !== "latest" ? `/${domain.id}/versioned/${domain.version}/data-products` : `/${domain.id}/data-products`;
|
|
3505
|
-
pathForDataProduct = (0, import_node_path24.join)(pathForDataProduct, dataProduct.id);
|
|
3506
|
-
await writeResource(directory, { ...dataProduct }, { ...options, path: pathForDataProduct, type: "data-product" });
|
|
3507
|
-
};
|
|
3508
|
-
var rmDataProduct = (directory) => async (path9) => {
|
|
3509
|
-
await import_promises16.default.rm((0, import_node_path24.join)(directory, path9), { recursive: true });
|
|
3839
|
+
${existingContent}`;
|
|
3840
|
+
const fm = { ...existing.data };
|
|
3841
|
+
fm.createdAt = changelog.createdAt;
|
|
3842
|
+
if (changelog.badges && changelog.badges.length > 0) {
|
|
3843
|
+
fm.badges = changelog.badges;
|
|
3844
|
+
} else {
|
|
3845
|
+
delete fm.badges;
|
|
3846
|
+
}
|
|
3847
|
+
const document = import_gray_matter8.default.stringify(combined, fm);
|
|
3848
|
+
import_node_fs10.default.writeFileSync(existingPath, document);
|
|
3510
3849
|
invalidateFileCache();
|
|
3511
3850
|
};
|
|
3512
|
-
var
|
|
3513
|
-
|
|
3851
|
+
var getChangelog = (catalogDir) => async (id, options = {}) => {
|
|
3852
|
+
const { version } = options;
|
|
3853
|
+
const resourceFile = await findFileById(catalogDir, id, version);
|
|
3854
|
+
if (!resourceFile) return void 0;
|
|
3855
|
+
const resourceDir = (0, import_node_path25.dirname)(resourceFile);
|
|
3856
|
+
const mdxPath = import_node_path25.default.join(resourceDir, "changelog.mdx");
|
|
3857
|
+
const mdPath = import_node_path25.default.join(resourceDir, "changelog.md");
|
|
3858
|
+
const changelogPath = import_node_fs10.default.existsSync(mdxPath) ? mdxPath : import_node_fs10.default.existsSync(mdPath) ? mdPath : void 0;
|
|
3859
|
+
if (!changelogPath) return void 0;
|
|
3860
|
+
const { data, content } = import_gray_matter8.default.read(changelogPath);
|
|
3861
|
+
return { ...data, markdown: content.trim() };
|
|
3514
3862
|
};
|
|
3515
|
-
var
|
|
3516
|
-
|
|
3517
|
-
const
|
|
3518
|
-
|
|
3863
|
+
var rmChangelog = (catalogDir) => async (id, options = {}) => {
|
|
3864
|
+
const { version } = options;
|
|
3865
|
+
const resourceFile = await findFileById(catalogDir, id, version);
|
|
3866
|
+
if (!resourceFile) {
|
|
3867
|
+
throw new Error(`No resource found with id: ${id}${version ? ` and version: ${version}` : ""}`);
|
|
3868
|
+
}
|
|
3869
|
+
const resourceDir = (0, import_node_path25.dirname)(resourceFile);
|
|
3870
|
+
const mdxPath = import_node_path25.default.join(resourceDir, "changelog.mdx");
|
|
3871
|
+
const mdPath = import_node_path25.default.join(resourceDir, "changelog.md");
|
|
3872
|
+
if (import_node_fs10.default.existsSync(mdxPath)) {
|
|
3873
|
+
await import_promises17.default.rm(mdxPath);
|
|
3874
|
+
}
|
|
3875
|
+
if (import_node_fs10.default.existsSync(mdPath)) {
|
|
3876
|
+
await import_promises17.default.rm(mdPath);
|
|
3877
|
+
}
|
|
3878
|
+
invalidateFileCache();
|
|
3519
3879
|
};
|
|
3520
|
-
var addFileToDataProduct = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version);
|
|
3521
3880
|
|
|
3522
3881
|
// src/diagrams.ts
|
|
3523
|
-
var
|
|
3524
|
-
var
|
|
3882
|
+
var import_promises18 = __toESM(require("fs/promises"));
|
|
3883
|
+
var import_node_path26 = require("path");
|
|
3525
3884
|
var getDiagram = (directory) => async (id, version) => getResource(directory, id, version, { type: "diagram" });
|
|
3526
3885
|
var getDiagrams = (directory) => async (options) => getResources(directory, { type: "diagrams", latestOnly: options?.latestOnly });
|
|
3527
3886
|
var writeDiagram = (directory) => async (diagram, options = {
|
|
@@ -3530,7 +3889,7 @@ var writeDiagram = (directory) => async (diagram, options = {
|
|
|
3530
3889
|
format: "mdx"
|
|
3531
3890
|
}) => writeResource(directory, { ...diagram }, { ...options, type: "diagram" });
|
|
3532
3891
|
var rmDiagram = (directory) => async (path9) => {
|
|
3533
|
-
await
|
|
3892
|
+
await import_promises18.default.rm((0, import_node_path26.join)(directory, path9), { recursive: true });
|
|
3534
3893
|
invalidateFileCache();
|
|
3535
3894
|
};
|
|
3536
3895
|
var rmDiagramById = (directory) => async (id, version, persistFiles) => {
|
|
@@ -3543,30 +3902,6 @@ var diagramHasVersion = (directory) => async (id, version) => {
|
|
|
3543
3902
|
};
|
|
3544
3903
|
var addFileToDiagram = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version, { type: "diagram" });
|
|
3545
3904
|
|
|
3546
|
-
// src/adrs.ts
|
|
3547
|
-
var import_promises18 = __toESM(require("fs/promises"));
|
|
3548
|
-
var import_node_path26 = require("path");
|
|
3549
|
-
var getAdr = (directory) => async (id, version) => getResource(directory, id, version, { type: "adr" });
|
|
3550
|
-
var getAdrs = (directory) => async (options) => getResources(directory, { type: "adrs", latestOnly: options?.latestOnly });
|
|
3551
|
-
var writeAdr = (directory) => async (adr, options = {
|
|
3552
|
-
path: "",
|
|
3553
|
-
override: false,
|
|
3554
|
-
format: "mdx"
|
|
3555
|
-
}) => writeResource(directory, { ...adr }, { ...options, type: "adr" });
|
|
3556
|
-
var rmAdr = (directory) => async (path9) => {
|
|
3557
|
-
await import_promises18.default.rm((0, import_node_path26.join)(directory, path9), { recursive: true });
|
|
3558
|
-
invalidateFileCache();
|
|
3559
|
-
};
|
|
3560
|
-
var rmAdrById = (directory) => async (id, version, persistFiles) => {
|
|
3561
|
-
await rmResourceById(directory, id, version, { type: "adr", persistFiles });
|
|
3562
|
-
};
|
|
3563
|
-
var versionAdr = (directory) => async (id) => versionResource(directory, id);
|
|
3564
|
-
var adrHasVersion = (directory) => async (id, version) => {
|
|
3565
|
-
const file = await findFileById(directory, id, version);
|
|
3566
|
-
return !!file;
|
|
3567
|
-
};
|
|
3568
|
-
var addFileToAdr = (directory) => async (id, file, version) => addFileToResource(directory, id, file, version, { type: "adr" });
|
|
3569
|
-
|
|
3570
3905
|
// src/index.ts
|
|
3571
3906
|
var src_default = (path9) => {
|
|
3572
3907
|
return {
|
|
@@ -4461,6 +4796,13 @@ var src_default = (path9) => {
|
|
|
4461
4796
|
* @returns A JSON file with the catalog
|
|
4462
4797
|
*/
|
|
4463
4798
|
dumpCatalog: dumpCatalog((0, import_node_path27.join)(path9)),
|
|
4799
|
+
/**
|
|
4800
|
+
* Returns the resources reachable from a catalog resource.
|
|
4801
|
+
* @param root - Resource to use as the root of the graph
|
|
4802
|
+
* @param options - Traversal depth and whether to return a flat resource list
|
|
4803
|
+
* @returns The resolved graph, or undefined when the root does not exist
|
|
4804
|
+
*/
|
|
4805
|
+
getGraph: getGraph((0, import_node_path27.join)(path9)),
|
|
4464
4806
|
/**
|
|
4465
4807
|
* Returns the event catalog configuration file.
|
|
4466
4808
|
* The event catalog configuration file is the file that contains the configuration for the event catalog.
|