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