@salesforce/graphiti 10.10.2 → 10.11.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.
- package/AGENT_GUIDE.md +23 -0
- package/CHANGELOG.md +10 -0
- package/README.md +17 -6
- package/dist/commands/connect.d.ts +2 -1
- package/dist/commands/connect.js +28 -7
- package/dist/commands/connect.js.map +1 -1
- package/dist/intent/build-connect.d.ts +24 -0
- package/dist/intent/build-connect.js +47 -0
- package/dist/intent/build-connect.js.map +1 -0
- package/dist/intent/types.d.ts +23 -0
- package/dist/lib/fs-utils.d.ts +3 -1
- package/dist/lib/fs-utils.js +7 -3
- package/dist/lib/fs-utils.js.map +1 -1
- package/dist/lib/introspect.js +20 -1
- package/dist/lib/introspect.js.map +1 -1
- package/dist/lib/prime-schema.d.ts +70 -16
- package/dist/lib/prime-schema.js +166 -33
- package/dist/lib/prime-schema.js.map +1 -1
- package/dist/lib/walker.d.ts +10 -0
- package/dist/lib/walker.js +26 -2
- package/dist/lib/walker.js.map +1 -1
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/sf-gql-connect.d.ts +9 -0
- package/dist/mcp/tools/sf-gql-connect.js +27 -0
- package/dist/mcp/tools/sf-gql-connect.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/helpers/object-info.ts +37 -0
- package/src/commands/__tests__/connect.spec.ts +92 -0
- package/src/commands/connect.ts +28 -6
- package/src/intent/__tests__/build-connect.spec.ts +103 -0
- package/src/intent/build-connect.ts +55 -0
- package/src/intent/types.ts +25 -0
- package/src/lib/__tests__/introspect.spec.ts +34 -0
- package/src/lib/__tests__/prime-schema.spec.ts +341 -0
- package/src/lib/__tests__/walker.spec.ts +13 -0
- package/src/lib/fs-utils.ts +8 -3
- package/src/lib/introspect.ts +29 -6
- package/src/lib/prime-schema.ts +184 -32
- package/src/lib/walker.ts +26 -2
- package/src/mcp/__tests__/server.spec.ts +1 -0
- package/src/mcp/server.ts +2 -0
- package/src/mcp/tools/__tests__/sf-gql-connect.spec.ts +202 -0
- package/src/mcp/tools/sf-gql-connect.ts +42 -0
package/AGENT_GUIDE.md
CHANGED
|
@@ -7,6 +7,7 @@ Graphiti is a CLI for building and executing Salesforce GraphQL queries by navig
|
|
|
7
7
|
```bash
|
|
8
8
|
graphiti agent-guide # print this guide (for agents)
|
|
9
9
|
graphiti connect <org> # download schema (one-time per org)
|
|
10
|
+
graphiti connect <org> --refresh # re-download after deploying new metadata
|
|
10
11
|
graphiti new <org> --name myQuery # create a session
|
|
11
12
|
graphiti use myQuery # set it as active (persists)
|
|
12
13
|
graphiti cd uiapi/query/Case/edges/node
|
|
@@ -16,6 +17,28 @@ graphiti check # validate
|
|
|
16
17
|
graphiti run # execute
|
|
17
18
|
```
|
|
18
19
|
|
|
20
|
+
## Refreshing after a deploy
|
|
21
|
+
|
|
22
|
+
graphiti caches an org's schema on first connect. After you deploy new metadata (fields, picklist values, objects), force a refresh so graphiti stops serving the stale cache — this invalidates all three caches coherently (on-disk introspection JSON, in-memory parsed schema, and the ObjectInfo cache that backs picklists / filterable / sortable / required-on-create):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
graphiti connect <org> --refresh # CLI: re-download + clear all caches
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
When driving the **MCP server**, use the `sf_gql_connect` tool — the long-lived server holds an in-memory schema that no query tool can refresh on its own:
|
|
29
|
+
|
|
30
|
+
```jsonc
|
|
31
|
+
// sf_gql_connect
|
|
32
|
+
{ "org": "<org>", "forceRefresh": true }
|
|
33
|
+
// → { org, instanceUrl, refreshed, cached, durationMs, warnings? }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Notes:
|
|
37
|
+
|
|
38
|
+
- Concurrent refreshes (CLI + MCP) **coalesce** into a single introspection.
|
|
39
|
+
- If the refresh fails (network/5xx) it is retried once. On terminal failure the **old cache is kept** and `sf_gql_connect` returns `refreshed: false` with a staleness `warnings[]` entry instead of erroring — keep working on the still-valid cached schema and retry the refresh shortly.
|
|
40
|
+
- ObjectInfo is keyed by org alias: refreshing alias `A` does not invalidate ObjectInfo cached under a different alias `B` for the same org (its 1-hour TTL heals it).
|
|
41
|
+
|
|
19
42
|
## Session Resolution
|
|
20
43
|
|
|
21
44
|
All session commands target the **active session** implicitly. Resolution order:
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [10.11.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v10.10.3...v10.11.0) (2026-06-11)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- W-22845606 add graphiti schema refresh cli functionality ([#618](https://github.com/salesforce-experience-platform-emu/webapps/issues/618)) ([f68d3ce](https://github.com/salesforce-experience-platform-emu/webapps/commit/f68d3cef2992e33c1fa2379a2a4059500b7ca46f))
|
|
11
|
+
|
|
12
|
+
## [10.10.3](https://github.com/salesforce-experience-platform-emu/webapps/compare/v10.10.2...v10.10.3) (2026-06-11)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package @salesforce/graphiti
|
|
15
|
+
|
|
6
16
|
## [10.10.2](https://github.com/salesforce-experience-platform-emu/webapps/compare/v10.10.1...v10.10.2) (2026-06-11)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package @salesforce/graphiti
|
package/README.md
CHANGED
|
@@ -90,11 +90,12 @@ Inside the REPL:
|
|
|
90
90
|
|
|
91
91
|
### Setup
|
|
92
92
|
|
|
93
|
-
| Command | Description
|
|
94
|
-
| ------------------------------------------- |
|
|
95
|
-
| `graphiti connect <org>` | Connect to a Salesforce org and download its GraphQL schema
|
|
96
|
-
| `graphiti
|
|
97
|
-
| `graphiti
|
|
93
|
+
| Command | Description |
|
|
94
|
+
| ------------------------------------------- | ---------------------------------------------------------------------- |
|
|
95
|
+
| `graphiti connect <org>` | Connect to a Salesforce org and download its GraphQL schema |
|
|
96
|
+
| `graphiti connect <org> --refresh` | Re-download the schema and clear all caches (after deploying metadata) |
|
|
97
|
+
| `graphiti type <org> <TypeName>` | Inspect a named GraphQL type |
|
|
98
|
+
| `graphiti validate <org> <TypeName> <json>` | Validate a JSON value against an input type |
|
|
98
99
|
|
|
99
100
|
### Session lifecycle
|
|
100
101
|
|
|
@@ -193,9 +194,19 @@ Schema and auth data are cached aggressively to minimize cold-start overhead:
|
|
|
193
194
|
Schemas are stored in `~/.graphiti/schemas/` keyed by a hash of the normalized Salesforce instance URL. This means:
|
|
194
195
|
|
|
195
196
|
- Reusing an org alias for a different org will always pick up the correct schema.
|
|
196
|
-
- `graphiti connect <org>` re-downloads and refreshes the cache for that org.
|
|
197
197
|
- The companion SDL file (`<cacheKey>.graphql`) is regenerated automatically whenever the introspection JSON is updated.
|
|
198
198
|
|
|
199
|
+
### Refreshing after a deploy
|
|
200
|
+
|
|
201
|
+
graphiti caches three things per org: the on-disk introspection JSON, the in-memory parsed schema, and an ObjectInfo cache (picklists, filterable/sortable flags, required-on-create; 1-hour TTL on disk). When you deploy new metadata (fields, picklist values, objects), run a refresh to invalidate **all three** coherently:
|
|
202
|
+
|
|
203
|
+
- `graphiti connect <org> --refresh` re-downloads the schema and clears all three caches.
|
|
204
|
+
- In the MCP server, call the `sf_gql_connect` tool with `forceRefresh: true` — the long-lived server cannot otherwise pick up new metadata, since its in-memory caches outlive a single request.
|
|
205
|
+
- Concurrent refreshes (a CLI `--refresh` and an MCP `sf_gql_connect` firing at once) **coalesce** into a single introspection via the on-disk schema lock, so you normally never pay for the (large, multi-second) introspection twice. Coalescing is best-effort: it keys off the cache file's modification time, so on filesystems with coarse mtime resolution two refreshes landing in the same tick may each download — never incorrect, just occasionally redundant.
|
|
206
|
+
- If a refresh fails (network/5xx) it is retried once; on terminal failure the previously cached schema is **kept** and a staleness-aware message is surfaced — the cache stays usable.
|
|
207
|
+
|
|
208
|
+
> **ObjectInfo is keyed by org alias, not instance URL.** Refreshing alias `A` does not invalidate ObjectInfo cached under a different alias `B` that points at the same org; refresh each alias you actively use, or let ObjectInfo's 1-hour TTL heal it.
|
|
209
|
+
|
|
199
210
|
## Development
|
|
200
211
|
|
|
201
212
|
```bash
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
|
+
import { type PrimeDeps } from "../lib/prime-schema.js";
|
|
6
7
|
export declare function connectCommand(orgAlias: string, opts?: {
|
|
7
8
|
refresh?: boolean;
|
|
8
|
-
}): Promise<void>;
|
|
9
|
+
}, deps?: PrimeDeps): Promise<void>;
|
package/dist/commands/connect.js
CHANGED
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
6
|
import { getOrgAuth } from "../lib/auth.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import { getSchemaMetadata } from "../lib/introspect.js";
|
|
8
|
+
import { primeSchemaWithLock } from "../lib/prime-schema.js";
|
|
9
|
+
export async function connectCommand(orgAlias, opts = {}, deps) {
|
|
10
|
+
const getAuth = deps?.getOrgAuth ?? getOrgAuth;
|
|
9
11
|
console.log(`Connecting to ${orgAlias}...`);
|
|
10
|
-
const auth = await
|
|
12
|
+
const auth = await getAuth(orgAlias);
|
|
11
13
|
console.log(`Authenticated as ${auth.username} on ${auth.instanceUrl}`);
|
|
12
14
|
if (!opts.refresh) {
|
|
15
|
+
// Resolve via the already-resolved instance URL (not the alias) so we
|
|
16
|
+
// don't trigger a second org resolution, and so injected deps stay honored.
|
|
13
17
|
const existing = getSchemaMetadata(auth.instanceUrl);
|
|
14
18
|
if (existing) {
|
|
15
19
|
const age = formatSchemaAge(new Date(existing.downloadedAt));
|
|
@@ -18,20 +22,37 @@ export async function connectCommand(orgAlias, opts = {}) {
|
|
|
18
22
|
return;
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
|
-
|
|
25
|
+
const verb = opts.refresh ? "Refreshing" : "Downloading";
|
|
26
|
+
console.log(`${verb} GraphQL schema via introspection...`);
|
|
22
27
|
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
23
28
|
let i = 0;
|
|
24
29
|
const startTime = Date.now();
|
|
25
30
|
const spinner = setInterval(() => {
|
|
26
31
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(0);
|
|
27
|
-
process.stderr.write(`\r${frames[i++ % frames.length]}
|
|
32
|
+
process.stderr.write(`\r${frames[i++ % frames.length]} ${verb} schema... (${elapsed}s)`);
|
|
28
33
|
}, 100);
|
|
29
34
|
try {
|
|
30
|
-
|
|
35
|
+
// Route through the shared priming layer so a refresh coherently clears
|
|
36
|
+
// all three caches (introspection JSON, in-memory schema, ObjectInfo) and
|
|
37
|
+
// coalesces with any concurrent CLI/MCP refresh. A failed refresh throws
|
|
38
|
+
// SchemaRefreshError (kept caches + staleness message), surfaced by cli.ts.
|
|
39
|
+
const result = await primeSchemaWithLock(orgAlias, deps, { forceRefresh: !!opts.refresh });
|
|
31
40
|
clearInterval(spinner);
|
|
32
41
|
process.stderr.write("\r");
|
|
33
42
|
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
34
|
-
|
|
43
|
+
// `result.typeCount` is set on the download path; a coalesced refresh
|
|
44
|
+
// (no download performed here) falls back to a one-time metadata read.
|
|
45
|
+
const typeCount = result.typeCount ?? getSchemaMetadata(auth.instanceUrl)?.typeCount ?? 0;
|
|
46
|
+
if (opts.refresh && !result.refreshed) {
|
|
47
|
+
// A concurrent refresh produced the new schema while we waited.
|
|
48
|
+
console.log(`Schema for ${orgAlias} was just refreshed by a concurrent process: ${typeCount} types.`);
|
|
49
|
+
}
|
|
50
|
+
else if (opts.refresh) {
|
|
51
|
+
console.log(`Refreshed ${orgAlias}. Schema cached: ${typeCount} types (${elapsed}s).`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(`Connected to ${orgAlias}. Schema cached: ${typeCount} types (${elapsed}s).`);
|
|
55
|
+
}
|
|
35
56
|
}
|
|
36
57
|
catch (err) {
|
|
37
58
|
clearInterval(spinner);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { type ConnectOutput, type ConnectSpec } from "./types.js";
|
|
7
|
+
import { type PrimeDeps } from "../lib/prime-schema.js";
|
|
8
|
+
export interface ConnectDeps {
|
|
9
|
+
primeDeps?: PrimeDeps;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build the `sf_gql_connect` payload (W-22845606). Primes the schema cache for
|
|
13
|
+
* `spec.org`, or — with `spec.forceRefresh` — re-downloads it and coherently
|
|
14
|
+
* clears all three caches (on-disk introspection JSON, in-memory parsed schema,
|
|
15
|
+
* ObjectInfo).
|
|
16
|
+
*
|
|
17
|
+
* Failure policy (Q6 of the plan): a failed *refresh* that leaves a usable
|
|
18
|
+
* cached schema behind is recoverable, so we return a soft `ConnectOutput`
|
|
19
|
+
* (`refreshed: false`, `cached: true`) carrying a staleness-aware `warnings[]`
|
|
20
|
+
* entry — the agent can keep working on the still-valid schema. A failure with
|
|
21
|
+
* no prior cache (or any non-refresh failure such as missing auth) propagates,
|
|
22
|
+
* so the MCP SDK surfaces it as a hard tool error.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildConnect(spec: ConnectSpec, deps?: ConnectDeps): Promise<ConnectOutput>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { primeSchemaWithLock, SchemaRefreshError } from "../lib/prime-schema.js";
|
|
7
|
+
/**
|
|
8
|
+
* Build the `sf_gql_connect` payload (W-22845606). Primes the schema cache for
|
|
9
|
+
* `spec.org`, or — with `spec.forceRefresh` — re-downloads it and coherently
|
|
10
|
+
* clears all three caches (on-disk introspection JSON, in-memory parsed schema,
|
|
11
|
+
* ObjectInfo).
|
|
12
|
+
*
|
|
13
|
+
* Failure policy (Q6 of the plan): a failed *refresh* that leaves a usable
|
|
14
|
+
* cached schema behind is recoverable, so we return a soft `ConnectOutput`
|
|
15
|
+
* (`refreshed: false`, `cached: true`) carrying a staleness-aware `warnings[]`
|
|
16
|
+
* entry — the agent can keep working on the still-valid schema. A failure with
|
|
17
|
+
* no prior cache (or any non-refresh failure such as missing auth) propagates,
|
|
18
|
+
* so the MCP SDK surfaces it as a hard tool error.
|
|
19
|
+
*/
|
|
20
|
+
export async function buildConnect(spec, deps = {}) {
|
|
21
|
+
try {
|
|
22
|
+
const prime = await primeSchemaWithLock(spec.org, deps.primeDeps, {
|
|
23
|
+
forceRefresh: spec.forceRefresh,
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
org: spec.org,
|
|
27
|
+
instanceUrl: prime.instanceUrl,
|
|
28
|
+
refreshed: prime.refreshed,
|
|
29
|
+
cached: prime.cached,
|
|
30
|
+
durationMs: prime.durationMs,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
if (e instanceof SchemaRefreshError && e.staleSince) {
|
|
35
|
+
return {
|
|
36
|
+
org: spec.org,
|
|
37
|
+
instanceUrl: e.instanceUrl,
|
|
38
|
+
refreshed: false,
|
|
39
|
+
cached: true,
|
|
40
|
+
durationMs: 0,
|
|
41
|
+
warnings: [e.message],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
throw e;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=build-connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-connect.js","sourceRoot":"","sources":["../../src/intent/build-connect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAkB,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAMjG;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CACjC,IAAiB,EACjB,OAAoB,EAAE;IAEtB,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE;YACjE,YAAY,EAAE,IAAI,CAAC,YAAY;SAC/B,CAAC,CAAC;QACH,OAAO;YACN,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;SAC5B,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,IAAI,CAAC,YAAY,kBAAkB,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YACrD,OAAO;gBACN,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,SAAS,EAAE,KAAK;gBAChB,MAAM,EAAE,IAAI;gBACZ,UAAU,EAAE,CAAC;gBACb,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACrB,CAAC;QACH,CAAC;QACD,MAAM,CAAC,CAAC;IACT,CAAC;AACF,CAAC"}
|
package/dist/intent/types.d.ts
CHANGED
|
@@ -143,6 +143,29 @@ export interface DeleteSpec {
|
|
|
143
143
|
inputVariable?: string;
|
|
144
144
|
operationName?: string;
|
|
145
145
|
}
|
|
146
|
+
export interface ConnectSpec {
|
|
147
|
+
org: string;
|
|
148
|
+
/**
|
|
149
|
+
* Re-download the schema even if it is already cached, coherently clearing
|
|
150
|
+
* all three caches (on-disk introspection JSON, in-memory parsed schema, and
|
|
151
|
+
* ObjectInfo). Defaults to false — a plain connect lazily primes on miss.
|
|
152
|
+
*/
|
|
153
|
+
forceRefresh?: boolean;
|
|
154
|
+
}
|
|
155
|
+
export interface ConnectOutput {
|
|
156
|
+
org: string;
|
|
157
|
+
instanceUrl: string;
|
|
158
|
+
/** True when this call performed a forced re-download. */
|
|
159
|
+
refreshed: boolean;
|
|
160
|
+
/** True when an existing cache satisfied the request (no download performed). */
|
|
161
|
+
cached: boolean;
|
|
162
|
+
durationMs: number;
|
|
163
|
+
/**
|
|
164
|
+
* Populated when a refresh failed but a usable cached schema survived — the
|
|
165
|
+
* staleness-aware message tells the caller the cache is still valid.
|
|
166
|
+
*/
|
|
167
|
+
warnings?: string[];
|
|
168
|
+
}
|
|
146
169
|
export type RawOperation = "query" | "mutation" | "aggregate";
|
|
147
170
|
export interface RawSpec {
|
|
148
171
|
org: string;
|
package/dist/lib/fs-utils.d.ts
CHANGED
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function graphitiHome(): string;
|
|
16
16
|
/**
|
|
17
|
-
* Write
|
|
17
|
+
* Write `text` to `finalPath` atomically. Writes to a sibling
|
|
18
18
|
* `<base>.tmp.<pid>.<timestamp>.<rand>` file, then renames over the final
|
|
19
19
|
* path. Concurrent readers see either the old contents or the fully-written
|
|
20
20
|
* new contents — never a partial. The temp file is unlinked if the rename
|
|
21
21
|
* fails, so failure paths do not leak partial files.
|
|
22
22
|
*/
|
|
23
|
+
export declare function atomicWriteText(finalPath: string, text: string): void;
|
|
24
|
+
/** Write JSON to `finalPath` atomically (pretty-printed). See {@link atomicWriteText}. */
|
|
23
25
|
export declare function atomicWriteJson(finalPath: string, payload: unknown): void;
|
package/dist/lib/fs-utils.js
CHANGED
|
@@ -20,16 +20,16 @@ export function graphitiHome() {
|
|
|
20
20
|
return process.env.GRAPHITI_HOME ?? path.join(os.homedir(), ".graphiti");
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
* Write
|
|
23
|
+
* Write `text` to `finalPath` atomically. Writes to a sibling
|
|
24
24
|
* `<base>.tmp.<pid>.<timestamp>.<rand>` file, then renames over the final
|
|
25
25
|
* path. Concurrent readers see either the old contents or the fully-written
|
|
26
26
|
* new contents — never a partial. The temp file is unlinked if the rename
|
|
27
27
|
* fails, so failure paths do not leak partial files.
|
|
28
28
|
*/
|
|
29
|
-
export function
|
|
29
|
+
export function atomicWriteText(finalPath, text) {
|
|
30
30
|
fs.mkdirSync(path.dirname(finalPath), { recursive: true });
|
|
31
31
|
const tmp = `${finalPath}.tmp.${process.pid}.${Date.now()}.${crypto.randomBytes(4).toString("hex")}`;
|
|
32
|
-
fs.writeFileSync(tmp,
|
|
32
|
+
fs.writeFileSync(tmp, text, "utf-8");
|
|
33
33
|
try {
|
|
34
34
|
fs.renameSync(tmp, finalPath);
|
|
35
35
|
}
|
|
@@ -43,4 +43,8 @@ export function atomicWriteJson(finalPath, payload) {
|
|
|
43
43
|
throw e;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
+
/** Write JSON to `finalPath` atomically (pretty-printed). See {@link atomicWriteText}. */
|
|
47
|
+
export function atomicWriteJson(finalPath, payload) {
|
|
48
|
+
atomicWriteText(finalPath, JSON.stringify(payload, null, 2));
|
|
49
|
+
}
|
|
46
50
|
//# sourceMappingURL=fs-utils.js.map
|
package/dist/lib/fs-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../../src/lib/fs-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../../src/lib/fs-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,IAAY;IAC9D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,GAAG,SAAS,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;IACrG,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC;QACJ,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,IAAI,CAAC;YACJ,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACR,sBAAsB;QACvB,CAAC;QACD,MAAM,CAAC,CAAC;IACT,CAAC;AACF,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,OAAgB;IAClE,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|
package/dist/lib/introspect.js
CHANGED
|
@@ -18,6 +18,25 @@ async function getConnection(auth) {
|
|
|
18
18
|
const org = await Org.create({ aliasOrUsername: auth.alias });
|
|
19
19
|
return org.getConnection();
|
|
20
20
|
}
|
|
21
|
+
// Per-request options for the introspection POST (W-22845606). `@salesforce/core`
|
|
22
|
+
// passes these straight through to jsforce:
|
|
23
|
+
// - `timeout` bounds EACH attempt (jsforce defaults to 30 min) so a wedged gateway
|
|
24
|
+
// can't hang the schema-lock holder indefinitely. A single attempt (5 min) aborts
|
|
25
|
+
// before prime-schema's 7-min STALE_LOCK_MS, so the holder normally releases the
|
|
26
|
+
// lock before any waiter reclaims it. A timeout *plus* the retry below can run
|
|
27
|
+
// ~2x the timeout and exceed STALE_LOCK_MS — a waiter may then reclaim mid-retry
|
|
28
|
+
// and run a second introspection: benign, it degrades to the redundant-download
|
|
29
|
+
// case coalescing already tolerates (atomic writes keep the cache correct). A
|
|
30
|
+
// strict bound would require timeout × (maxRetries + 1) < STALE_LOCK_MS.
|
|
31
|
+
// - jsforce does NOT retry POST by default, so we opt this idempotent introspection
|
|
32
|
+
// read into one retry on transient HTTP/network failures (with jsforce's built-in
|
|
33
|
+
// exponential backoff). Network errnos (ECONNRESET/ETIMEDOUT/…) are covered by
|
|
34
|
+
// jsforce's default `errorCodes`.
|
|
35
|
+
const INTROSPECTION_TIMEOUT_MS = 5 * 60_000;
|
|
36
|
+
const INTROSPECTION_REQUEST_OPTIONS = {
|
|
37
|
+
timeout: INTROSPECTION_TIMEOUT_MS,
|
|
38
|
+
retry: { methods: ["POST"], maxRetries: 1, statusCodes: [420, 429, 500, 502, 503, 504] },
|
|
39
|
+
};
|
|
21
40
|
/** Resolves the directory holding cached introspection JSON files. */
|
|
22
41
|
export function schemaDir() {
|
|
23
42
|
return path.join(graphitiHome(), "schemas");
|
|
@@ -220,7 +239,7 @@ export async function downloadSchema(auth) {
|
|
|
220
239
|
url,
|
|
221
240
|
body: JSON.stringify({ query: INTROSPECTION_QUERY }),
|
|
222
241
|
headers: { "Content-Type": "application/json", "X-Chatter-Entity-Encoding": "false" },
|
|
223
|
-
}));
|
|
242
|
+
}, INTROSPECTION_REQUEST_OPTIONS));
|
|
224
243
|
if (rawResult?.errors?.length) {
|
|
225
244
|
const messages = rawResult.errors
|
|
226
245
|
.map((e) => e.message ?? JSON.stringify(e))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"introspect.js","sourceRoot":"","sources":["../../src/lib/introspect.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"introspect.js","sourceRoot":"","sources":["../../src/lib/introspect.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,26 +10,61 @@ import { type SchemaMetadata } from "./introspect.js";
|
|
|
10
10
|
* since `mkdir` is atomic on POSIX), run `work`, then release the lock.
|
|
11
11
|
*
|
|
12
12
|
* If another process holds the lock, this polls every 100ms for the lock
|
|
13
|
-
* to be released. On release, if
|
|
14
|
-
* is skipped (the other process already did it).
|
|
15
|
-
*
|
|
16
|
-
* lock and runs `work`.
|
|
13
|
+
* to be released. On release, if the work is already satisfied (per `skipIf`),
|
|
14
|
+
* the work function is skipped (the other process already did it). Otherwise
|
|
15
|
+
* this acquires the lock and runs `work`.
|
|
17
16
|
*
|
|
18
|
-
* Contract: `work` will NOT run when `
|
|
17
|
+
* Contract: `work` will NOT run when `skipIf()` is true at any point during
|
|
19
18
|
* the lock dance — including immediately after we acquire the lock (a holder
|
|
20
19
|
* may have finished and released the lock between our last EEXIST poll and
|
|
21
20
|
* our successful `mkdir`). In that case the lock is released and the
|
|
22
21
|
* function returns `undefined`.
|
|
23
22
|
*
|
|
23
|
+
* `skipIf` defaults to "`finalPath` exists" — the lazy-prime contract (any
|
|
24
|
+
* cached schema is good enough). A forced refresh passes a predicate that is
|
|
25
|
+
* true only once the file has been *replaced* since the refresh was requested,
|
|
26
|
+
* which coalesces concurrent refreshes onto a single introspection.
|
|
27
|
+
*
|
|
24
28
|
* Stale locks (older than STALE_LOCK_MS) are reclaimed.
|
|
25
29
|
*/
|
|
26
|
-
export declare function withSchemaLock<T>(finalPath: string, work: () => Promise<T
|
|
30
|
+
export declare function withSchemaLock<T>(finalPath: string, work: () => Promise<T>, opts?: {
|
|
31
|
+
skipIf?: () => boolean;
|
|
32
|
+
}): Promise<T | undefined>;
|
|
27
33
|
export interface PrimeResult {
|
|
28
34
|
cached: boolean;
|
|
35
|
+
/** True only when this call performed a forced re-download (forceRefresh). */
|
|
36
|
+
refreshed: boolean;
|
|
29
37
|
filePath: string;
|
|
30
38
|
durationMs: number;
|
|
31
39
|
/** Resolved instance URL (already auth-resolved). */
|
|
32
40
|
instanceUrl: string;
|
|
41
|
+
/**
|
|
42
|
+
* Non-`__` type count from the just-downloaded schema. Present only when this
|
|
43
|
+
* call performed a download (`cached: false`); a cache hit or coalesced
|
|
44
|
+
* refresh leaves it undefined to avoid re-parsing the (large) introspection
|
|
45
|
+
* JSON just to count types.
|
|
46
|
+
*/
|
|
47
|
+
typeCount?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Thrown when a forced refresh fails to download a new schema. The previously
|
|
51
|
+
* cached schema (if any) is left intact on disk and in memory — we only clear
|
|
52
|
+
* the caches *after* a successful download. `staleSince` is the surviving
|
|
53
|
+
* cache's download timestamp (ISO) so callers can render a staleness-aware
|
|
54
|
+
* message; it is undefined when no prior cache existed (a true hard failure) —
|
|
55
|
+
* or when a cache file is present but unparseable, since `getSchemaMetadata`
|
|
56
|
+
* returns null for a corrupt file, which correctly degrades to a hard failure
|
|
57
|
+
* (a corrupt cache is not usable). `instanceUrl` is always the resolved org URL
|
|
58
|
+
* (known before the download).
|
|
59
|
+
*/
|
|
60
|
+
export declare class SchemaRefreshError extends Error {
|
|
61
|
+
staleSince?: string;
|
|
62
|
+
instanceUrl: string;
|
|
63
|
+
constructor(message: string, opts: {
|
|
64
|
+
instanceUrl: string;
|
|
65
|
+
staleSince?: string;
|
|
66
|
+
cause?: unknown;
|
|
67
|
+
});
|
|
33
68
|
}
|
|
34
69
|
/**
|
|
35
70
|
* Dependencies that `primeSchemaWithLock` calls. Defaulted to the real
|
|
@@ -40,20 +75,39 @@ export interface PrimeDeps {
|
|
|
40
75
|
downloadSchema: (auth: OrgAuth) => Promise<SchemaMetadata>;
|
|
41
76
|
}
|
|
42
77
|
/**
|
|
43
|
-
* Lazily prime the on-disk schema
|
|
78
|
+
* Lazily prime — or, with `forceRefresh`, re-download — the on-disk schema
|
|
79
|
+
* cache for `orgAlias`.
|
|
44
80
|
*
|
|
81
|
+
* Lazy prime (`forceRefresh` falsy):
|
|
45
82
|
* - If `<HOME>/.graphiti/schemas/<hash>.json` already exists, returns
|
|
46
|
-
* `{cached: true}` immediately.
|
|
83
|
+
* `{cached: true, refreshed: false}` immediately.
|
|
47
84
|
* - Otherwise: resolves auth via `deps.getOrgAuth` (throws verbatim if the
|
|
48
85
|
* alias is not authenticated, per FR-13.5), acquires the schema lock via
|
|
49
86
|
* `withSchemaLock`, calls `deps.downloadSchema(auth)` (which writes the
|
|
50
|
-
* cache atomically
|
|
51
|
-
*
|
|
52
|
-
* `
|
|
53
|
-
*
|
|
87
|
+
* cache atomically), releases the lock, and returns `{cached: false}`. Per
|
|
88
|
+
* FR-13.6, partial caches never reach disk because writes are atomic.
|
|
89
|
+
* `downloadSchema` bounds the request with a timeout and retries transient
|
|
90
|
+
* failures (network / 5xx) once at the connection layer; deterministic
|
|
91
|
+
* failures (4xx, GraphQL errors in a 200 body, missing `__schema`) and missing
|
|
92
|
+
* auth surface immediately. Unlike a forced refresh, a lazy-prime failure is
|
|
93
|
+
* re-thrown verbatim (there is no prior cache to keep, so no `SchemaRefreshError`).
|
|
94
|
+
*
|
|
95
|
+
* Forced refresh (`forceRefresh: true`) — W-22845606:
|
|
96
|
+
* - Re-downloads even though the file exists, then clears all three caches
|
|
97
|
+
* coherently: the on-disk introspection JSON (overwritten atomically), this
|
|
98
|
+
* process's in-memory parsed-schema cache, and the ObjectInfo cache (memory
|
|
99
|
+
* + disk). Clearing happens only AFTER a successful download, so a failed
|
|
100
|
+
* refresh leaves every cache intact.
|
|
101
|
+
* - Coalesces concurrent refreshes (CLI + MCP) into a single introspection via
|
|
102
|
+
* a request-time mtime snapshot: a peer that replaced the file since this
|
|
103
|
+
* refresh was requested satisfies us, and we skip the redundant download.
|
|
104
|
+
* - The download retries transient failures (network / 5xx) once at the
|
|
105
|
+
* connection layer. On terminal failure throws {@link SchemaRefreshError}
|
|
106
|
+
* carrying the surviving cache's age; the old caches are kept.
|
|
54
107
|
*
|
|
55
|
-
* Concurrent callers in the same or different processes serialize on the
|
|
56
|
-
*
|
|
57
|
-
* the primed cache and short-circuit (FR-13.4).
|
|
108
|
+
* Concurrent callers in the same or different processes serialize on the lock
|
|
109
|
+
* dir; only one performs introspection.
|
|
58
110
|
*/
|
|
59
|
-
export declare function primeSchemaWithLock(orgAlias: string, deps?: PrimeDeps
|
|
111
|
+
export declare function primeSchemaWithLock(orgAlias: string, deps?: PrimeDeps, opts?: {
|
|
112
|
+
forceRefresh?: boolean;
|
|
113
|
+
}): Promise<PrimeResult>;
|