@ryanstark24/sfgraph-cli 1.2.1 → 1.6.0

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.
Files changed (78) hide show
  1. package/dist/commands/audit.d.ts.map +1 -1
  2. package/dist/commands/audit.js +8 -3
  3. package/dist/commands/audit.js.map +1 -1
  4. package/dist/commands/diagnose.d.ts +139 -0
  5. package/dist/commands/diagnose.d.ts.map +1 -0
  6. package/dist/commands/diagnose.js +508 -0
  7. package/dist/commands/diagnose.js.map +1 -0
  8. package/dist/commands/doctor.d.ts.map +1 -1
  9. package/dist/commands/doctor.js +1 -1
  10. package/dist/commands/doctor.js.map +1 -1
  11. package/dist/commands/ingest.d.ts +73 -0
  12. package/dist/commands/ingest.d.ts.map +1 -1
  13. package/dist/commands/ingest.js +362 -19
  14. package/dist/commands/ingest.js.map +1 -1
  15. package/dist/commands/rebuild-bindings.d.ts.map +1 -1
  16. package/dist/commands/rebuild-bindings.js +2 -2
  17. package/dist/commands/rebuild-bindings.js.map +1 -1
  18. package/dist/commands/reset-elemid-map.d.ts.map +1 -1
  19. package/dist/commands/reset-elemid-map.js.map +1 -1
  20. package/dist/commands/serve.d.ts +7 -0
  21. package/dist/commands/serve.d.ts.map +1 -1
  22. package/dist/commands/serve.js +59 -1
  23. package/dist/commands/serve.js.map +1 -1
  24. package/dist/commands/skip-labels.d.ts +11 -0
  25. package/dist/commands/skip-labels.d.ts.map +1 -0
  26. package/dist/commands/skip-labels.js +15 -0
  27. package/dist/commands/skip-labels.js.map +1 -0
  28. package/dist/commands/telemetry.js +1 -1
  29. package/dist/commands/telemetry.js.map +1 -1
  30. package/dist/heap.d.ts +24 -0
  31. package/dist/heap.d.ts.map +1 -0
  32. package/dist/heap.js +45 -0
  33. package/dist/heap.js.map +1 -0
  34. package/dist/index.d.ts +13 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +43 -2
  37. package/dist/index.js.map +1 -1
  38. package/package.json +8 -7
  39. package/dist/__tests__/doctor.test.d.ts +0 -2
  40. package/dist/__tests__/doctor.test.d.ts.map +0 -1
  41. package/dist/__tests__/doctor.test.js +0 -64
  42. package/dist/__tests__/doctor.test.js.map +0 -1
  43. package/dist/__tests__/ingest-db-guard.test.d.ts +0 -2
  44. package/dist/__tests__/ingest-db-guard.test.d.ts.map +0 -1
  45. package/dist/__tests__/ingest-db-guard.test.js +0 -110
  46. package/dist/__tests__/ingest-db-guard.test.js.map +0 -1
  47. package/dist/__tests__/ingest-multi.test.d.ts +0 -2
  48. package/dist/__tests__/ingest-multi.test.d.ts.map +0 -1
  49. package/dist/__tests__/ingest-multi.test.js +0 -51
  50. package/dist/__tests__/ingest-multi.test.js.map +0 -1
  51. package/dist/__tests__/install-dry-run.test.d.ts +0 -2
  52. package/dist/__tests__/install-dry-run.test.d.ts.map +0 -1
  53. package/dist/__tests__/install-dry-run.test.js +0 -29
  54. package/dist/__tests__/install-dry-run.test.js.map +0 -1
  55. package/dist/__tests__/install-e2e.test.d.ts +0 -2
  56. package/dist/__tests__/install-e2e.test.d.ts.map +0 -1
  57. package/dist/__tests__/install-e2e.test.js +0 -33
  58. package/dist/__tests__/install-e2e.test.js.map +0 -1
  59. package/dist/__tests__/mcp-config.test.d.ts +0 -2
  60. package/dist/__tests__/mcp-config.test.d.ts.map +0 -1
  61. package/dist/__tests__/mcp-config.test.js +0 -104
  62. package/dist/__tests__/mcp-config.test.js.map +0 -1
  63. package/dist/__tests__/rebuild.test.d.ts +0 -2
  64. package/dist/__tests__/rebuild.test.d.ts.map +0 -1
  65. package/dist/__tests__/rebuild.test.js +0 -180
  66. package/dist/__tests__/rebuild.test.js.map +0 -1
  67. package/dist/__tests__/serve-guard.test.d.ts +0 -2
  68. package/dist/__tests__/serve-guard.test.d.ts.map +0 -1
  69. package/dist/__tests__/serve-guard.test.js +0 -82
  70. package/dist/__tests__/serve-guard.test.js.map +0 -1
  71. package/dist/__tests__/snapshot.test.d.ts +0 -2
  72. package/dist/__tests__/snapshot.test.d.ts.map +0 -1
  73. package/dist/__tests__/snapshot.test.js +0 -139
  74. package/dist/__tests__/snapshot.test.js.map +0 -1
  75. package/dist/__tests__/telemetry.test.d.ts +0 -2
  76. package/dist/__tests__/telemetry.test.d.ts.map +0 -1
  77. package/dist/__tests__/telemetry.test.js +0 -53
  78. package/dist/__tests__/telemetry.test.js.map +0 -1
@@ -1,180 +0,0 @@
1
- import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
- /**
6
- * --rebuild moves an existing graph file to `<dataDir>/backups/`. We exercise
7
- * the real `applyRebuild` path by feeding the CLI a `--db` override (so the
8
- * computation of the dbPath is fully under our control) and stubbing
9
- * `liveIngest` so we don't open a Salesforce connection.
10
- *
11
- * Note: --rebuild's backupDir computation in CLI uses `getSfgraphPaths().data`,
12
- * not the dir of --db. So we additionally stub that.
13
- */
14
- let tmpDataDir;
15
- let tmpDbDir;
16
- let prevAllowAnyDb;
17
- beforeEach(() => {
18
- tmpDataDir = mkdtempSync(join(tmpdir(), "sfgraph-rebuild-data-"));
19
- tmpDbDir = mkdtempSync(join(tmpdir(), "sfgraph-rebuild-db-"));
20
- // The CLI rebuild path validates that `--db` resolves inside the data dir
21
- // unless `SFGRAPH_ALLOW_ANY_DB=1`. These tests deliberately point `--db`
22
- // outside the data dir to verify backup-dir computation stays anchored
23
- // to the data dir, so opt in to the cross-dir mode for this suite.
24
- prevAllowAnyDb = process.env.SFGRAPH_ALLOW_ANY_DB;
25
- process.env.SFGRAPH_ALLOW_ANY_DB = "1";
26
- });
27
- afterEach(() => {
28
- rmSync(tmpDataDir, { recursive: true, force: true });
29
- rmSync(tmpDbDir, { recursive: true, force: true });
30
- if (prevAllowAnyDb === undefined) {
31
- // biome-ignore lint/performance/noDelete: cleanest reset of an env var override
32
- delete process.env.SFGRAPH_ALLOW_ANY_DB;
33
- }
34
- else {
35
- process.env.SFGRAPH_ALLOW_ANY_DB = prevAllowAnyDb;
36
- }
37
- vi.restoreAllMocks();
38
- vi.resetModules();
39
- });
40
- async function stubModulesForRebuild(orgId) {
41
- vi.doMock("@ryanstark24/sfgraph-core", async () => {
42
- const actual = await vi.importActual("@ryanstark24/sfgraph-core");
43
- return {
44
- ...actual,
45
- liveIngest: async () => ({
46
- orgId,
47
- capabilities: {},
48
- mode: "full",
49
- membersProcessed: 0,
50
- parseErrors: 0,
51
- deletions: 0,
52
- durationMs: 0,
53
- }),
54
- resolveOrg: async (alias) => ({
55
- orgId,
56
- alias,
57
- username: "u@example.com",
58
- instanceUrl: "https://x.test",
59
- apiVersion: "60.0",
60
- conn: {},
61
- }),
62
- };
63
- });
64
- vi.doMock("@ryanstark24/sfgraph-shared", async () => {
65
- const actual = await vi.importActual("@ryanstark24/sfgraph-shared");
66
- return {
67
- ...actual,
68
- getSfgraphPaths: () => ({
69
- data: tmpDataDir,
70
- cache: tmpDataDir,
71
- log: tmpDataDir,
72
- config: tmpDataDir,
73
- temp: tmpDataDir,
74
- }),
75
- };
76
- });
77
- }
78
- describe("ingest --rebuild file handling", () => {
79
- it("moves an existing graph file to backups/", async () => {
80
- const orgId = "00Dxxfakeorg00";
81
- const dbPath = join(tmpDbDir, `${orgId}.sqlite`);
82
- writeFileSync(dbPath, "stub");
83
- await stubModulesForRebuild(orgId);
84
- const { ingestCmd } = await import("../commands/ingest.js");
85
- await ingestCmd({ org: "fake", rebuild: true, db: dbPath });
86
- // After rebuild, a NEW empty DB exists at dbPath (created by SqliteGraphStore).
87
- // The OLD stub bytes must live in backups/.
88
- const backupDir = join(tmpDataDir, "backups");
89
- expect(existsSync(backupDir)).toBe(true);
90
- const files = readdirSync(backupDir);
91
- const backupFile = files.find((f) => f.startsWith(`${orgId}.rebuild-`) && f.endsWith(".sqlite"));
92
- expect(backupFile).toBeDefined();
93
- // Confirm the backup is the original stub content (not a fresh SQLite DB).
94
- expect(readFileSync(join(backupDir, backupFile ?? ""), "utf8")).toBe("stub");
95
- });
96
- it("--no-backup deletes the file instead", async () => {
97
- const orgId = "00Dxxnobak00";
98
- const dbPath = join(tmpDbDir, `${orgId}.sqlite`);
99
- writeFileSync(dbPath, "stub");
100
- await stubModulesForRebuild(orgId);
101
- const { ingestCmd } = await import("../commands/ingest.js");
102
- await ingestCmd({ org: "fake", rebuild: true, noBackup: true, db: dbPath });
103
- // dbPath was unlinked, then SqliteGraphStore re-created a fresh DB there.
104
- // Confirm no backup was made for this org.
105
- const backupDir = join(tmpDataDir, "backups");
106
- if (existsSync(backupDir)) {
107
- const files = readdirSync(backupDir);
108
- expect(files.some((f) => f.startsWith(`${orgId}.rebuild-`))).toBe(false);
109
- }
110
- // The recreated DB at dbPath is NOT the stub content.
111
- if (existsSync(dbPath)) {
112
- expect(readFileSync(dbPath, "utf8")).not.toBe("stub");
113
- }
114
- });
115
- it("moves WAL/SHM sidecars alongside the main DB to backups/", async () => {
116
- const orgId = "00Dxxsidecar01";
117
- const dbPath = join(tmpDbDir, `${orgId}.sqlite`);
118
- writeFileSync(dbPath, "stub");
119
- writeFileSync(`${dbPath}-wal`, "stubwal");
120
- writeFileSync(`${dbPath}-shm`, "stubshm");
121
- await stubModulesForRebuild(orgId);
122
- const { ingestCmd } = await import("../commands/ingest.js");
123
- await ingestCmd({ org: "fake", rebuild: true, db: dbPath });
124
- const backupDir = join(tmpDataDir, "backups");
125
- const files = readdirSync(backupDir);
126
- const mainBackup = files.find((f) => f.startsWith(`${orgId}.rebuild-`) && f.endsWith(".sqlite"));
127
- expect(mainBackup).toBeDefined();
128
- // Sidecars must have moved alongside the main file.
129
- const walBackup = files.find((f) => f === `${mainBackup}-wal`);
130
- const shmBackup = files.find((f) => f === `${mainBackup}-shm`);
131
- expect(walBackup).toBeDefined();
132
- expect(shmBackup).toBeDefined();
133
- expect(readFileSync(join(backupDir, walBackup ?? ""), "utf8")).toBe("stubwal");
134
- expect(readFileSync(join(backupDir, shmBackup ?? ""), "utf8")).toBe("stubshm");
135
- // No orphan sidecars left next to the (fresh) main DB.
136
- expect(existsSync(`${dbPath}-wal`)).toBeDefined();
137
- // The fresh sidecars from the reopened DB are SQLite's own; what
138
- // matters is the stub contents are gone — assert by absence of "stubwal".
139
- if (existsSync(`${dbPath}-wal`)) {
140
- expect(readFileSync(`${dbPath}-wal`, "utf8")).not.toBe("stubwal");
141
- }
142
- });
143
- it("--no-backup deletes sidecars too", async () => {
144
- const orgId = "00Dxxsidecar02";
145
- const dbPath = join(tmpDbDir, `${orgId}.sqlite`);
146
- writeFileSync(dbPath, "stub");
147
- writeFileSync(`${dbPath}-wal`, "stubwal");
148
- writeFileSync(`${dbPath}-shm`, "stubshm");
149
- writeFileSync(`${dbPath}-journal`, "stubjournal");
150
- await stubModulesForRebuild(orgId);
151
- const { ingestCmd } = await import("../commands/ingest.js");
152
- await ingestCmd({ org: "fake", rebuild: true, noBackup: true, db: dbPath });
153
- // After rebuild + no-backup, the stub sidecars must not exist (a fresh
154
- // DB may have created new WAL/SHM with different content, which is fine).
155
- if (existsSync(`${dbPath}-wal`)) {
156
- expect(readFileSync(`${dbPath}-wal`, "utf8")).not.toBe("stubwal");
157
- }
158
- if (existsSync(`${dbPath}-shm`)) {
159
- expect(readFileSync(`${dbPath}-shm`, "utf8")).not.toBe("stubshm");
160
- }
161
- // -journal isn't created in WAL mode, so it shouldn't reappear.
162
- expect(existsSync(`${dbPath}-journal`)).toBe(false);
163
- });
164
- it("is a no-op when no existing DB file is present", async () => {
165
- const orgId = "00Dxxnewbuild";
166
- const dbPath = join(tmpDbDir, `${orgId}.sqlite`);
167
- expect(existsSync(dbPath)).toBe(false);
168
- await stubModulesForRebuild(orgId);
169
- const { ingestCmd } = await import("../commands/ingest.js");
170
- // Should not throw.
171
- await ingestCmd({ org: "fake", rebuild: true, db: dbPath });
172
- // No backup created.
173
- const backupDir = join(tmpDataDir, "backups");
174
- if (existsSync(backupDir)) {
175
- const files = readdirSync(backupDir);
176
- expect(files.some((f) => f.startsWith(`${orgId}.rebuild-`))).toBe(false);
177
- }
178
- });
179
- });
180
- //# sourceMappingURL=rebuild.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rebuild.test.js","sourceRoot":"","sources":["../../src/__tests__/rebuild.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=serve-guard.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-guard.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/serve-guard.test.ts"],"names":[],"mappings":""}
@@ -1,82 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
- import { serveCmd } from "../commands/serve.js";
3
- /**
4
- * The web API has no authentication — binding to a non-loopback host leaks
5
- * the full ingested org graph to anyone reachable on that interface. The
6
- * CLI refuses to do that without an explicit `--i-understand-public-bind`
7
- * acknowledgement.
8
- */
9
- let prevExitCode;
10
- let errSpy;
11
- let warnSpy;
12
- beforeEach(() => {
13
- prevExitCode = process.exitCode;
14
- process.exitCode = 0;
15
- errSpy = vi.spyOn(console, "error").mockImplementation(() => { });
16
- warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
17
- });
18
- afterEach(() => {
19
- process.exitCode = prevExitCode;
20
- errSpy.mockRestore();
21
- warnSpy.mockRestore();
22
- vi.restoreAllMocks();
23
- });
24
- describe("serveCmd public-bind guard", () => {
25
- it("refuses to start on 0.0.0.0 without --i-understand-public-bind", async () => {
26
- await serveCmd({ port: 0, host: "0.0.0.0", open: false });
27
- expect(process.exitCode).toBe(1);
28
- expect(errSpy).toHaveBeenCalled();
29
- const calls = errSpy.mock.calls.map((c) => String(c[0]));
30
- expect(calls.some((s) => s.includes("refusing to bind"))).toBe(true);
31
- });
32
- it("refuses to start on a LAN IP without acknowledgement", async () => {
33
- await serveCmd({ port: 0, host: "192.168.1.10", open: false });
34
- expect(process.exitCode).toBe(1);
35
- const calls = errSpy.mock.calls.map((c) => String(c[0]));
36
- expect(calls.some((s) => s.includes("192.168.1.10"))).toBe(true);
37
- });
38
- it("accepts 127.0.0.1 without acknowledgement (default)", async () => {
39
- // Stub the actual server import so we don't open a socket.
40
- vi.doMock("@ryanstark24/sfgraph-web", () => ({
41
- startWebServer: async () => ({
42
- port: 7777,
43
- url: "http://127.0.0.1:7777",
44
- stop: async () => { },
45
- }),
46
- }));
47
- // Race serveCmd against a microtask — it blocks on a never-resolving
48
- // promise, so we just verify it doesn't early-exit.
49
- let earlyExit = false;
50
- const p = serveCmd({ port: 0, host: "127.0.0.1", open: false }).then(() => {
51
- earlyExit = true;
52
- });
53
- await new Promise((r) => setTimeout(r, 50));
54
- expect(earlyExit).toBe(false);
55
- expect(process.exitCode).toBe(0);
56
- void p;
57
- });
58
- it("accepts public host when --i-understand-public-bind is set (warns loudly)", async () => {
59
- vi.doMock("@ryanstark24/sfgraph-web", () => ({
60
- startWebServer: async () => ({
61
- port: 7777,
62
- url: "http://0.0.0.0:7777",
63
- stop: async () => { },
64
- }),
65
- }));
66
- let earlyExit = false;
67
- const p = serveCmd({
68
- port: 0,
69
- host: "0.0.0.0",
70
- open: false,
71
- iUnderstandPublicBind: true,
72
- }).then(() => {
73
- earlyExit = true;
74
- });
75
- await new Promise((r) => setTimeout(r, 50));
76
- expect(earlyExit).toBe(false);
77
- expect(process.exitCode).toBe(0);
78
- expect(warnSpy).toHaveBeenCalled();
79
- void p;
80
- });
81
- });
82
- //# sourceMappingURL=serve-guard.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-guard.test.js","sourceRoot":"","sources":["../../src/__tests__/serve-guard.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD;;;;;GAKG;AAEH,IAAI,YAAqC,CAAC;AAC1C,IAAI,MAAmC,CAAC;AACxC,IAAI,OAAoC,CAAC;AAEzC,UAAU,CAAC,GAAG,EAAE;IACd,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;IAChC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACrB,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACjE,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,OAAO,CAAC,QAAQ,GAAG,YAAY,CAAC;IAChC,MAAM,CAAC,WAAW,EAAE,CAAC;IACrB,OAAO,CAAC,WAAW,EAAE,CAAC;IACtB,EAAE,CAAC,eAAe,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,2DAA2D;QAC3D,EAAE,CAAC,MAAM,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3C,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;gBAC3B,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,uBAAuB;gBAC5B,IAAI,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;aACrB,CAAC;SACH,CAAC,CAAC,CAAC;QACJ,qEAAqE;QACrE,oDAAoD;QACpD,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACxE,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,KAAK,CAAC,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,EAAE,CAAC,MAAM,CAAC,0BAA0B,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3C,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;gBAC3B,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,qBAAqB;gBAC1B,IAAI,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;aACrB,CAAC;SACH,CAAC,CAAC,CAAC;QACJ,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,GAAG,QAAQ,CAAC;YACjB,IAAI,EAAE,CAAC;YACP,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,KAAK;YACX,qBAAqB,EAAE,IAAI;SAC5B,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;YACX,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACnC,KAAK,CAAC,CAAC;IACT,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=snapshot.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"snapshot.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/snapshot.test.ts"],"names":[],"mappings":""}
@@ -1,139 +0,0 @@
1
- import { mkdtempSync, rmSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
- /**
6
- * End-to-end snapshot CLI tests. We:
7
- * - Stub @salesforce/core so resolveOrg returns a fake orgId
8
- * - Stub getSfgraphPaths to point to a temp dir
9
- * - Call the snapshot subcommand wrappers directly
10
- * - Inspect the resulting SQLite store through a second `SqliteSnapshotStore`
11
- * instance (or via the same command's read paths).
12
- */
13
- let tmpDataDir;
14
- const orgId = "00DTestSnap0001";
15
- beforeEach(() => {
16
- tmpDataDir = mkdtempSync(join(tmpdir(), "sfgraph-snap-"));
17
- });
18
- afterEach(() => {
19
- rmSync(tmpDataDir, { recursive: true, force: true });
20
- vi.restoreAllMocks();
21
- vi.resetModules();
22
- });
23
- async function stubModules() {
24
- vi.doMock("@ryanstark24/sfgraph-core", async () => {
25
- const actual = await vi.importActual("@ryanstark24/sfgraph-core");
26
- return {
27
- ...actual,
28
- resolveOrg: async (alias) => ({
29
- orgId,
30
- alias,
31
- username: "u@example.com",
32
- instanceUrl: "https://x.test",
33
- apiVersion: "60.0",
34
- conn: {},
35
- }),
36
- resolveDefaultOrgAlias: async () => "fake",
37
- };
38
- });
39
- vi.doMock("@ryanstark24/sfgraph-shared", async () => {
40
- const actual = await vi.importActual("@ryanstark24/sfgraph-shared");
41
- return {
42
- ...actual,
43
- getSfgraphPaths: () => ({
44
- data: tmpDataDir,
45
- cache: tmpDataDir,
46
- log: tmpDataDir,
47
- config: tmpDataDir,
48
- temp: tmpDataDir,
49
- }),
50
- };
51
- });
52
- }
53
- describe("sfgraph snapshot CLI", () => {
54
- it("list reports 'no snapshots' for a fresh org", async () => {
55
- await stubModules();
56
- const { snapshotListCmd } = await import("../commands/snapshot.js");
57
- const logs = [];
58
- const spy = vi.spyOn(console, "log").mockImplementation((m) => {
59
- logs.push(String(m));
60
- });
61
- await snapshotListCmd({ org: "fake" });
62
- spy.mockRestore();
63
- expect(logs.join("\n")).toMatch(/No snapshots/);
64
- });
65
- it("create + list shows the new snapshot in the table", async () => {
66
- await stubModules();
67
- const { snapshotCreateCmd, snapshotListCmd } = await import("../commands/snapshot.js");
68
- const logs = [];
69
- const spy = vi.spyOn(console, "log").mockImplementation((m) => {
70
- logs.push(String(m));
71
- });
72
- await snapshotCreateCmd({ org: "fake", label: "before-deploy" });
73
- await snapshotListCmd({ org: "fake" });
74
- spy.mockRestore();
75
- const out = logs.join("\n");
76
- expect(out).toMatch(/Created snapshot snap_/);
77
- expect(out).toMatch(/manual:before-deploy/);
78
- expect(out).toMatch(/\| ID \| Label \| Created \| Auto \|/);
79
- });
80
- it("diff against 'current' produces a markdown summary", async () => {
81
- await stubModules();
82
- const { snapshotCreateCmd, snapshotDiffCmd } = await import("../commands/snapshot.js");
83
- let snapId = "";
84
- const captureCreate = vi.spyOn(console, "log").mockImplementation((m) => {
85
- const match = /(snap_[a-f0-9-]+)/.exec(String(m));
86
- if (match)
87
- snapId = match[1] ?? "";
88
- });
89
- await snapshotCreateCmd({ org: "fake", label: "baseline" });
90
- captureCreate.mockRestore();
91
- expect(snapId).toMatch(/^snap_/);
92
- const logs = [];
93
- const spy = vi.spyOn(console, "log").mockImplementation((m) => {
94
- logs.push(String(m));
95
- });
96
- await snapshotDiffCmd({ org: "fake", fromId: snapId, toId: "current" });
97
- spy.mockRestore();
98
- const out = logs.join("\n");
99
- expect(out).toMatch(/Snapshot diff/);
100
- expect(out).toMatch(/Nodes/);
101
- expect(out).toMatch(/Edges/);
102
- });
103
- it("prune --retain-days 0 returns a count", async () => {
104
- await stubModules();
105
- const { snapshotCreateCmd, snapshotPruneCmd } = await import("../commands/snapshot.js");
106
- // Prune only touches auto-snapshots, and CLI creates manual ones → 0 is fine.
107
- await snapshotCreateCmd({ org: "fake", label: "x" });
108
- const logs = [];
109
- const spy = vi.spyOn(console, "log").mockImplementation((m) => {
110
- logs.push(String(m));
111
- });
112
- await snapshotPruneCmd({ org: "fake", retainDays: 0 });
113
- spy.mockRestore();
114
- expect(logs.join("\n")).toMatch(/Pruned \d+ auto-snapshot/);
115
- });
116
- it("delete removes a specific snapshot id", async () => {
117
- await stubModules();
118
- const { snapshotCreateCmd, snapshotDeleteCmd, snapshotListCmd } = await import("../commands/snapshot.js");
119
- let snapId = "";
120
- const captureCreate = vi.spyOn(console, "log").mockImplementation((m) => {
121
- const match = /(snap_[a-f0-9-]+)/.exec(String(m));
122
- if (match)
123
- snapId = match[1] ?? "";
124
- });
125
- await snapshotCreateCmd({ org: "fake", label: "del-me" });
126
- captureCreate.mockRestore();
127
- expect(snapId).toMatch(/^snap_/);
128
- await snapshotDeleteCmd({ org: "fake", snapshotId: snapId });
129
- const logs = [];
130
- const spy = vi.spyOn(console, "log").mockImplementation((m) => {
131
- logs.push(String(m));
132
- });
133
- await snapshotListCmd({ org: "fake" });
134
- spy.mockRestore();
135
- // The label was unique to that snap; should be gone.
136
- expect(logs.join("\n")).not.toMatch(/del-me/);
137
- });
138
- });
139
- //# sourceMappingURL=snapshot.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"snapshot.test.js","sourceRoot":"","sources":["../../src/__tests__/snapshot.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=telemetry.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"telemetry.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/telemetry.test.ts"],"names":[],"mappings":""}
@@ -1,53 +0,0 @@
1
- import { mkdtempSync, readFileSync, rmSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
- import { disableCmd, enableLocalCmd, previewCmd, resetIdCmd, statusCmd, } from "../commands/telemetry.js";
6
- import { readConfig } from "../config.js";
7
- let configDir;
8
- let dataDir;
9
- let logs;
10
- const env = () => ({ configDir, dataDir, log: (s) => logs.push(s) });
11
- beforeEach(() => {
12
- configDir = mkdtempSync(join(tmpdir(), "sfgraph-cfg-"));
13
- dataDir = mkdtempSync(join(tmpdir(), "sfgraph-data-"));
14
- logs = [];
15
- });
16
- afterEach(() => {
17
- rmSync(configDir, { recursive: true, force: true });
18
- rmSync(dataDir, { recursive: true, force: true });
19
- });
20
- describe("telemetry commands", () => {
21
- it("round-trips enable then status", async () => {
22
- await enableLocalCmd(env());
23
- await statusCmd(env());
24
- expect(logs.join("\n")).toMatch(/telemetry: enabled/);
25
- const cfg = readConfig(configDir);
26
- expect(cfg.telemetry.enabled).toBe(true);
27
- expect(cfg.telemetry.sink).toBe("local");
28
- });
29
- it("disable flips enabled false", async () => {
30
- await enableLocalCmd(env());
31
- await disableCmd(env());
32
- const cfg = readConfig(configDir);
33
- expect(cfg.telemetry.enabled).toBe(false);
34
- });
35
- it("preview sanitizes a sample event", async () => {
36
- await previewCmd(env());
37
- const out = logs.join("\n");
38
- expect(out).toMatch(/<path>/);
39
- expect(out).not.toMatch(/\/Users\/alice/);
40
- });
41
- it("reset-id changes the machine id when enabled", async () => {
42
- await enableLocalCmd(env());
43
- const id1 = readFileSync(join(configDir, "machine-id"), "utf8");
44
- await resetIdCmd(env());
45
- const id2 = readFileSync(join(configDir, "machine-id"), "utf8");
46
- expect(id1).not.toBe(id2);
47
- });
48
- it("reset-id is a no-op when disabled", async () => {
49
- await resetIdCmd(env());
50
- expect(logs.join("\n")).toMatch(/disabled/);
51
- });
52
- });
53
- //# sourceMappingURL=telemetry.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"telemetry.test.js","sourceRoot":"","sources":["../../src/__tests__/telemetry.test.ts"],"names":[],"mappings":"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"}