@salesforce/graphiti 10.10.3 → 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.
Files changed (44) hide show
  1. package/AGENT_GUIDE.md +23 -0
  2. package/CHANGELOG.md +6 -0
  3. package/README.md +17 -6
  4. package/dist/commands/connect.d.ts +2 -1
  5. package/dist/commands/connect.js +28 -7
  6. package/dist/commands/connect.js.map +1 -1
  7. package/dist/intent/build-connect.d.ts +24 -0
  8. package/dist/intent/build-connect.js +47 -0
  9. package/dist/intent/build-connect.js.map +1 -0
  10. package/dist/intent/types.d.ts +23 -0
  11. package/dist/lib/fs-utils.d.ts +3 -1
  12. package/dist/lib/fs-utils.js +7 -3
  13. package/dist/lib/fs-utils.js.map +1 -1
  14. package/dist/lib/introspect.js +20 -1
  15. package/dist/lib/introspect.js.map +1 -1
  16. package/dist/lib/prime-schema.d.ts +70 -16
  17. package/dist/lib/prime-schema.js +166 -33
  18. package/dist/lib/prime-schema.js.map +1 -1
  19. package/dist/lib/walker.d.ts +10 -0
  20. package/dist/lib/walker.js +26 -2
  21. package/dist/lib/walker.js.map +1 -1
  22. package/dist/mcp/server.js +2 -0
  23. package/dist/mcp/server.js.map +1 -1
  24. package/dist/mcp/tools/sf-gql-connect.d.ts +9 -0
  25. package/dist/mcp/tools/sf-gql-connect.js +27 -0
  26. package/dist/mcp/tools/sf-gql-connect.js.map +1 -0
  27. package/package.json +1 -1
  28. package/src/__tests__/helpers/object-info.ts +37 -0
  29. package/src/commands/__tests__/connect.spec.ts +92 -0
  30. package/src/commands/connect.ts +28 -6
  31. package/src/intent/__tests__/build-connect.spec.ts +103 -0
  32. package/src/intent/build-connect.ts +55 -0
  33. package/src/intent/types.ts +25 -0
  34. package/src/lib/__tests__/introspect.spec.ts +34 -0
  35. package/src/lib/__tests__/prime-schema.spec.ts +341 -0
  36. package/src/lib/__tests__/walker.spec.ts +13 -0
  37. package/src/lib/fs-utils.ts +8 -3
  38. package/src/lib/introspect.ts +29 -6
  39. package/src/lib/prime-schema.ts +184 -32
  40. package/src/lib/walker.ts +26 -2
  41. package/src/mcp/__tests__/server.spec.ts +1 -0
  42. package/src/mcp/server.ts +2 -0
  43. package/src/mcp/tools/__tests__/sf-gql-connect.spec.ts +202 -0
  44. 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,12 @@
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
+
6
12
  ## [10.10.3](https://github.com/salesforce-experience-platform-emu/webapps/compare/v10.10.2...v10.10.3) (2026-06-11)
7
13
 
8
14
  **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 type <org> <TypeName>` | Inspect a named GraphQL type |
97
- | `graphiti validate <org> <TypeName> <json>` | Validate a JSON value against an input type |
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>;
@@ -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 { downloadSchema, getSchemaMetadata } from "../lib/introspect.js";
8
- export async function connectCommand(orgAlias, opts = {}) {
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 getOrgAuth(orgAlias);
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
- console.log("Downloading GraphQL schema via introspection...");
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]} Downloading schema... (${elapsed}s)`);
32
+ process.stderr.write(`\r${frames[i++ % frames.length]} ${verb} schema... (${elapsed}s)`);
28
33
  }, 100);
29
34
  try {
30
- const meta = await downloadSchema(auth);
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
- console.log(`Connected to ${orgAlias}. Schema cached: ${meta.typeCount} types (${elapsed}s).`);
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":"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"}
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"}
@@ -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;
@@ -14,10 +14,12 @@
14
14
  */
15
15
  export declare function graphitiHome(): string;
16
16
  /**
17
- * Write JSON to `finalPath` atomically. Writes to a sibling
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;
@@ -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 JSON to `finalPath` atomically. Writes to a sibling
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 atomicWriteJson(finalPath, payload) {
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, JSON.stringify(payload, null, 2), "utf-8");
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
@@ -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,OAAgB;IAClE,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,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACjE,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"}
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"}
@@ -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":"AAAA;;;;GAIG;AACH,oKAAoK;AAEpK,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,GAAG,EAAmB,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE9D,yEAAyE;AACzE,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB;wFACwF;AACxF,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAE1C,KAAK,UAAU,aAAa,CAAC,IAAa;IACzC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9D,OAAO,GAAG,CAAC,aAAa,EAAE,CAAC;AAC5B,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,SAAS;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0E1B,CAAC;AAEH,gFAAgF;AAEhF,MAAM,WAAW,GAAG,QAAQ,CAAC;AAE7B,SAAS,uBAAuB,CAAC,OAAY;IAC5C,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IACtC,OAAO,uBAAuB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAQ;IAC3C,MAAM,MAAM,GAAG,GAAG,EAAE,IAAI,EAAE,QAAQ,IAAI,GAAG,EAAE,QAAQ,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,KAAK;QAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAE5D,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YAClF,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAErE,MAAM,SAAS,GAAG,CAAC,GAAQ,EAAE,EAAE;QAC9B,MAAM,IAAI,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC1C,OAAO,IAAI,IAAI,IAAI,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAE1E,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAC7C,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAChD,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5F,CAAC;IACF,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IACjC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACvD,OAAO,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,WAAmB;IAC/D,MAAM,UAAU,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,wBAAwB,CAAC,WAAmB;IACpD,MAAM,QAAQ,GAAG,4BAA4B,CAAC,WAAW,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,QAAQ,OAAO,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC/C,OAAO,EAAE,CAAC,UAAU,CAAC,wBAAwB,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAWD,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACpD,MAAM,UAAU,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,EAAE,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,IAAI,GAAG,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAU,CAAC;QAClF,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC7B,OAAO;YACN,QAAQ,EAAE,4BAA4B,CAAC,UAAU,CAAC;YAClD,WAAW,EAAE,UAAU;YACvB,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;YACpE,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YACtC,QAAQ,EAAE,EAAE;SACZ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB;IAChC,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,OAAO,EAAE;SACP,WAAW,CAAC,GAAG,CAAC;SAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QACjB,IAAI,CAAC;YACJ,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,IAAI,GAAG,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAU,CAAC;YAClF,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC7B,MAAM,WAAW,GAAG,GAAG,EAAE,UAAU,EAAE,WAAW,CAAC;YACjD,IAAI,OAAO,WAAW,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACjD,OAAO;gBACN,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBACvC,WAAW;gBACX,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;gBACpE,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBACtC,QAAQ,EAAE,EAAE;aACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAa;IACjD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,mBAAmB,UAAU,CAAC,aAAa,EAAE,UAAU,CAAC;IAEvF,MAAM,SAAS,GAAG,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC;QAC3C,MAAM,EAAE,MAAM;QACd,GAAG;QACH,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;QACpD,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,OAAO,EAAE;KACrF,CAAC,CAAQ,CAAC;IAEX,IAAI,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAI,SAAS,CAAC,MAAgB;aAC1C,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;aAC/C,IAAI,CAAC,MAAM,CAAC,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,QAAQ,IAAI,SAAS,EAAE,QAAQ,CAAC;IACnE,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,QAAQ,IAAI,MAAM,EAAE,QAAQ,CAAC;IAE1D,MAAM,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG;QACf,GAAG,MAAM;QACT,UAAU,EAAE;YACX,WAAW;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAClC,QAAQ,EAAE,4BAA4B,CAAC,WAAW,CAAC;YACnD,sBAAsB,EAAE,YAAY;SACpC;KACD,CAAC;IACF,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEnC,MAAM,SAAS,GAAI,MAAM,CAAC,KAAe,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IAE9F,OAAO;QACN,QAAQ,EAAE,4BAA4B,CAAC,WAAW,CAAC;QACnD,WAAW;QACX,SAAS;QACT,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACtC,QAAQ;QACR,sBAAsB,EAAE,YAAY,IAAI,SAAS;KACjD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IAC1D,MAAM,EAAE,GAAG,wBAAwB,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC;IACvE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,yBAAyB,WAAW,0CAA0C,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACpD,OAAO,wBAAwB,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,IAAa,EACb,KAAa,EACb,SAAmC;IAEnC,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,WAAW,mBAAmB,UAAU,CAAC,aAAa,EAAE,UAAU,CAAC;IACvF,OAAO,UAAU,CAAC,OAAO,CAAC;QACzB,MAAM,EAAE,MAAM;QACd,GAAG;QACH,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,OAAO,EAAE;KACrF,CAAC,CAAC;AACJ,CAAC"}
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 `finalPath` now exists, the work function
14
- * is skipped (the other process already did it). If `finalPath` still does
15
- * not exist (the other process aborted without writing), this acquires the
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 `finalPath` exists at any point during
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>): Promise<T | undefined>;
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 cache for `orgAlias`.
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 via `downloadSchema`'s internal use of
51
- * `atomicWriteJson`), releases the lock, and returns
52
- * `{cached: false, durationMs}`. Per FR-13.6, partial caches never reach
53
- * disk because writes are atomic.
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
- * lock dir; only one performs introspection. Subsequent waiters observe
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): Promise<PrimeResult>;
111
+ export declare function primeSchemaWithLock(orgAlias: string, deps?: PrimeDeps, opts?: {
112
+ forceRefresh?: boolean;
113
+ }): Promise<PrimeResult>;