@salesforce/graphiti 10.13.0 → 10.14.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/CHANGELOG.md +10 -0
- package/dist/intent/types.d.ts +1 -1
- package/dist/mcp/tools/sf-gql-aggregate.js +3 -5
- package/dist/mcp/tools/sf-gql-aggregate.js.map +1 -1
- package/dist/mcp/tools/sf-gql-create.js +3 -5
- package/dist/mcp/tools/sf-gql-create.js.map +1 -1
- package/dist/mcp/tools/sf-gql-delete.js +3 -5
- package/dist/mcp/tools/sf-gql-delete.js.map +1 -1
- package/dist/mcp/tools/sf-gql-list.js +3 -6
- package/dist/mcp/tools/sf-gql-list.js.map +1 -1
- package/dist/mcp/tools/sf-gql-raw.js +2 -4
- package/dist/mcp/tools/sf-gql-raw.js.map +1 -1
- package/dist/mcp/tools/sf-gql-update.js +3 -5
- package/dist/mcp/tools/sf-gql-update.js.map +1 -1
- package/package.json +1 -1
- package/src/intent/types.ts +1 -1
- package/src/mcp/tools/__tests__/sf-gql-aggregate.spec.ts +23 -0
- package/src/mcp/tools/__tests__/sf-gql-create.spec.ts +23 -0
- package/src/mcp/tools/__tests__/sf-gql-delete.spec.ts +24 -1
- package/src/mcp/tools/__tests__/sf-gql-list.spec.ts +23 -0
- package/src/mcp/tools/__tests__/sf-gql-raw.spec.ts +19 -0
- package/src/mcp/tools/__tests__/sf-gql-update.spec.ts +23 -0
- package/src/mcp/tools/sf-gql-aggregate.ts +5 -5
- package/src/mcp/tools/sf-gql-create.ts +5 -5
- package/src/mcp/tools/sf-gql-delete.ts +5 -5
- package/src/mcp/tools/sf-gql-list.ts +5 -6
- package/src/mcp/tools/sf-gql-raw.ts +4 -4
- package/src/mcp/tools/sf-gql-update.ts +5 -5
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.14.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v10.13.1...v10.14.0) (2026-06-17)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @salesforce/graphiti
|
|
9
|
+
|
|
10
|
+
## [10.13.1](https://github.com/salesforce-experience-platform-emu/webapps/compare/v10.13.0...v10.13.1) (2026-06-16)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- @W-22899736 MCP GraphQL Name Parity ([#630](https://github.com/salesforce-experience-platform-emu/webapps/issues/630)) ([67e035d](https://github.com/salesforce-experience-platform-emu/webapps/commit/67e035d0c7b7640bc3a26cf37b7f3a18e7b07ee1))
|
|
15
|
+
|
|
6
16
|
## [10.13.0](https://github.com/salesforce-experience-platform-emu/webapps/compare/v10.12.4...v10.13.0) (2026-06-16)
|
|
7
17
|
|
|
8
18
|
**Note:** Version bump only for package @salesforce/graphiti
|
package/dist/intent/types.d.ts
CHANGED
|
@@ -177,6 +177,6 @@ export interface RawSpec {
|
|
|
177
177
|
commands: string[];
|
|
178
178
|
/** Operation root; default `"query"`. Sets the `createSession` operation. */
|
|
179
179
|
operation?: RawOperation;
|
|
180
|
-
/**
|
|
180
|
+
/** GraphQL operation name override. Defaults to Raw<Operation> (FR-12.3). */
|
|
181
181
|
typeName?: string;
|
|
182
182
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
7
8
|
import { buildAggregate } from "../../intent/build-aggregate.js";
|
|
8
9
|
import { GROUP_BY_FUNCTIONS } from "../../intent/types.js";
|
|
9
10
|
const aliasField = z
|
|
@@ -33,7 +34,7 @@ const groupByElementSchema = z.union([
|
|
|
33
34
|
]);
|
|
34
35
|
const inputSchema = {
|
|
35
36
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
36
|
-
object:
|
|
37
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
37
38
|
groupBy: z
|
|
38
39
|
.array(groupByElementSchema)
|
|
39
40
|
.optional()
|
|
@@ -56,10 +57,7 @@ const inputSchema = {
|
|
|
56
57
|
.positive()
|
|
57
58
|
.optional()
|
|
58
59
|
.describe("Connection page size (top-N pattern). No default — omit for all buckets."),
|
|
59
|
-
operationName:
|
|
60
|
-
.string()
|
|
61
|
-
.optional()
|
|
62
|
-
.describe("Override the GraphQL operation name. Defaults to <Object>Aggregate."),
|
|
60
|
+
operationName: graphqlName("Override the GraphQL operation name. Defaults to <Object>Aggregate.").optional(),
|
|
63
61
|
};
|
|
64
62
|
export function registerSfGqlAggregateTool(server, opts = {}) {
|
|
65
63
|
server.registerTool("sf_gql_aggregate", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sf-gql-aggregate.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-aggregate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAO3D,MAAM,UAAU,GAAG,CAAC;KAClB,MAAM,EAAE;KACR,QAAQ,EAAE;KACV,QAAQ,CAAC,kDAAkD,CAAC,CAAC;AAE/D,MAAM,iBAAiB,GAAG,CAAC,CAAC,kBAAkB,CAAC,UAAU,EAAE;IAC1D,CAAC,CAAC,MAAM,CAAC;QACR,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;QAC/F,KAAK,EAAE,UAAU;KACjB,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACR,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC9C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;QACnF,KAAK,EAAE,UAAU;KACjB,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,MAAM,EAAE;IACV,CAAC,CAAC,MAAM,CAAC;QACR,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QAC3E,QAAQ,EAAE,CAAC;aACT,IAAI,CAAC,kBAAkB,CAAC;aACxB,QAAQ,CAAC,0DAA0D,CAAC;KACtE,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"sf-gql-aggregate.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-aggregate.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
7
8
|
import { buildCreate } from "../../intent/build-create.js";
|
|
8
9
|
const inputSchema = {
|
|
9
10
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
10
|
-
object:
|
|
11
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
11
12
|
returnFields: z
|
|
12
13
|
.array(z.string())
|
|
13
14
|
.optional()
|
|
@@ -16,10 +17,7 @@ const inputSchema = {
|
|
|
16
17
|
.string()
|
|
17
18
|
.optional()
|
|
18
19
|
.describe('Variable name (without "$") for the create input. Defaults to "input". Declared as $<name>: <Object>CreateInput!.'),
|
|
19
|
-
operationName:
|
|
20
|
-
.string()
|
|
21
|
-
.optional()
|
|
22
|
-
.describe("Override the GraphQL operation name. Defaults to Create<Object>."),
|
|
20
|
+
operationName: graphqlName("Override the GraphQL operation name. Defaults to Create<Object>.").optional(),
|
|
23
21
|
};
|
|
24
22
|
export function registerSfGqlCreateTool(server, opts = {}) {
|
|
25
23
|
server.registerTool("sf_gql_create", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sf-gql-create.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-create.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"sf-gql-create.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-create.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,WAAW,CAAC,0EAA0E,CAAC;IAC/F,YAAY,EAAE,CAAC;SACb,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CACR,2MAA2M,CAC3M;IACF,aAAa,EAAE,CAAC;SACd,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACR,mHAAmH,CACnH;IACF,aAAa,EAAE,WAAW,CACzB,kEAAkE,CAClE,CAAC,QAAQ,EAAE;CACZ,CAAC;AAEF,MAAM,UAAU,uBAAuB,CACtC,MAAiB,EACjB,OAA+B,EAAE;IAEjC,MAAM,CAAC,YAAY,CAClB,eAAe,EACf;QACC,WAAW,EACV,4QAA4Q;QAC7Q,WAAW;KACX,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;SACzD,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -4,18 +4,16 @@
|
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
7
8
|
import { buildDelete } from "../../intent/build-delete.js";
|
|
8
9
|
const inputSchema = {
|
|
9
10
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
10
|
-
object:
|
|
11
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
11
12
|
inputVariable: z
|
|
12
13
|
.string()
|
|
13
14
|
.optional()
|
|
14
15
|
.describe('Variable name (without "$") for the delete input. Defaults to "input". Declared as $<name>: RecordDeleteInput! — the schema-wide delete input carrying the record Id, not an <Object>-specific type.'),
|
|
15
|
-
operationName:
|
|
16
|
-
.string()
|
|
17
|
-
.optional()
|
|
18
|
-
.describe("Override the GraphQL operation name. Defaults to Delete<Object>."),
|
|
16
|
+
operationName: graphqlName("Override the GraphQL operation name. Defaults to Delete<Object>.").optional(),
|
|
19
17
|
};
|
|
20
18
|
export function registerSfGqlDeleteTool(server, opts = {}) {
|
|
21
19
|
server.registerTool("sf_gql_delete", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sf-gql-delete.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-delete.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"sf-gql-delete.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-delete.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,WAAW,CAAC,0EAA0E,CAAC;IAC/F,aAAa,EAAE,CAAC;SACd,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACR,sMAAsM,CACtM;IACF,aAAa,EAAE,WAAW,CACzB,kEAAkE,CAClE,CAAC,QAAQ,EAAE;CACZ,CAAC;AAEF,MAAM,UAAU,uBAAuB,CACtC,MAAiB,EACjB,OAA+B,EAAE;IAEjC,MAAM,CAAC,YAAY,CAClB,eAAe,EACf;QACC,WAAW,EACV,gVAAgV;QACjV,WAAW;KACX,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;SACzD,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import { childRelationshipSchema, orderByObject } from "./shared/zod-schemas.js";
|
|
7
|
+
import { childRelationshipSchema, graphqlName, orderByObject } from "./shared/zod-schemas.js";
|
|
8
8
|
import { buildList } from "../../intent/build-list.js";
|
|
9
9
|
// `sf_gql_list` advertises both shapes (singleton + array) for backward
|
|
10
10
|
// compatibility with early MCP clients that learned the array form.
|
|
11
11
|
const orderBySchema = z.union([orderByObject, z.array(orderByObject)]);
|
|
12
12
|
const inputSchema = {
|
|
13
13
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
14
|
-
object:
|
|
14
|
+
object: graphqlName('SObject API name, e.g. "Account", "Case". Must be a valid GraphQL Name.'),
|
|
15
15
|
fields: z
|
|
16
16
|
.array(z.string())
|
|
17
17
|
.describe('Scalar field API names to select on the node. Dot-paths like "Owner.Name" are allowed.'),
|
|
@@ -34,10 +34,7 @@ const inputSchema = {
|
|
|
34
34
|
.optional()
|
|
35
35
|
.describe("Top-level connection page size; defaults to 10."),
|
|
36
36
|
scope: z.string().optional().describe('Scope enum (e.g. "MINE", "EVERYTHING") or $varName.'),
|
|
37
|
-
operationName:
|
|
38
|
-
.string()
|
|
39
|
-
.optional()
|
|
40
|
-
.describe("Override the GraphQL operation name. Defaults to <Object>List."),
|
|
37
|
+
operationName: graphqlName("Override the GraphQL operation name. Defaults to <Object>List.").optional(),
|
|
41
38
|
};
|
|
42
39
|
export function registerSfGqlListTool(server, opts = {}) {
|
|
43
40
|
server.registerTool("sf_gql_list", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sf-gql-list.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"sf-gql-list.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAOvD,wEAAwE;AACxE,oEAAoE;AACpE,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAEvE,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,WAAW,CAAC,yEAAyE,CAAC;IAC9F,MAAM,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,CACR,wFAAwF,CACxF;IACF,YAAY,EAAE,CAAC;SACb,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,wDAAwD,CAAC;IACpE,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC9E,MAAM,EAAE,CAAC;SACP,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACnB,QAAQ,EAAE;SACV,QAAQ,CACR,0FAA0F,CAC1F;IACF,OAAO,EAAE,aAAa;SACpB,QAAQ,EAAE;SACV,QAAQ,CACR,wFAAwF,CACxF;IACF,KAAK,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,QAAQ,CAAC,iDAAiD,CAAC;IAC7D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;IAC5F,aAAa,EAAE,WAAW,CACzB,gEAAgE,CAChE,CAAC,QAAQ,EAAE;CACZ,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,OAA6B,EAAE;IACvF,MAAM,CAAC,YAAY,CAClB,aAAa,EACb;QACC,WAAW,EACV,uJAAuJ;QACxJ,WAAW;KACX,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;SACzD,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
7
8
|
import { buildRaw } from "../../intent/build-raw.js";
|
|
8
9
|
const inputSchema = {
|
|
9
10
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
@@ -20,10 +21,7 @@ const inputSchema = {
|
|
|
20
21
|
.enum(["query", "mutation", "aggregate"])
|
|
21
22
|
.optional()
|
|
22
23
|
.describe('Operation root. "query" (default) → uiapi.query; "mutation" → mutation root; "aggregate" → uiapi.aggregate.'),
|
|
23
|
-
typeName:
|
|
24
|
-
.string()
|
|
25
|
-
.optional()
|
|
26
|
-
.describe("Codegen type prefix / operation name override. Defaults to Raw<Operation>."),
|
|
24
|
+
typeName: graphqlName("Override the GraphQL operation name. Defaults to Raw<Operation>.").optional(),
|
|
27
25
|
};
|
|
28
26
|
export function registerSfGqlRawTool(server, opts = {}) {
|
|
29
27
|
server.registerTool("sf_gql_raw", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sf-gql-raw.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-raw.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAOrD,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,QAAQ,EAAE,CAAC;SACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACR,gFAAgF;QAC/E,sFAAsF;QACtF,6GAA6G;QAC7G,0GAA0G;QAC1G,2VAA2V;QAC3V,8HAA8H,CAC/H;IACF,SAAS,EAAE,CAAC;SACV,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;SACxC,QAAQ,EAAE;SACV,QAAQ,CACR,6GAA6G,CAC7G;IACF,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"sf-gql-raw.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-raw.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAOrD,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,QAAQ,EAAE,CAAC;SACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CACR,gFAAgF;QAC/E,sFAAsF;QACtF,6GAA6G;QAC7G,0GAA0G;QAC1G,2VAA2V;QAC3V,8HAA8H,CAC/H;IACF,SAAS,EAAE,CAAC;SACV,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;SACxC,QAAQ,EAAE;SACV,QAAQ,CACR,6GAA6G,CAC7G;IACF,QAAQ,EAAE,WAAW,CACpB,kEAAkE,CAClE,CAAC,QAAQ,EAAE;CACZ,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,OAA4B,EAAE;IACrF,MAAM,CAAC,YAAY,CAClB,YAAY,EACZ;QACC,WAAW,EACV,+UAA+U;QAChV,WAAW;KACX,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;SACzD,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* For full license text, see the LICENSE.txt file
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
7
8
|
import { buildUpdate } from "../../intent/build-update.js";
|
|
8
9
|
const inputSchema = {
|
|
9
10
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
10
|
-
object:
|
|
11
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
11
12
|
returnFields: z
|
|
12
13
|
.array(z.string())
|
|
13
14
|
.optional()
|
|
@@ -16,10 +17,7 @@ const inputSchema = {
|
|
|
16
17
|
.string()
|
|
17
18
|
.optional()
|
|
18
19
|
.describe('Variable name (without "$") for the update input. Defaults to "input". Declared as $<name>: <Object>UpdateInput!.'),
|
|
19
|
-
operationName:
|
|
20
|
-
.string()
|
|
21
|
-
.optional()
|
|
22
|
-
.describe("Override the GraphQL operation name. Defaults to Update<Object>."),
|
|
20
|
+
operationName: graphqlName("Override the GraphQL operation name. Defaults to Update<Object>.").optional(),
|
|
23
21
|
};
|
|
24
22
|
export function registerSfGqlUpdateTool(server, opts = {}) {
|
|
25
23
|
server.registerTool("sf_gql_update", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sf-gql-update.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-update.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"sf-gql-update.js","sourceRoot":"","sources":["../../../src/mcp/tools/sf-gql-update.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAO3D,MAAM,WAAW,GAAG;IACnB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oEAAoE,CAAC;IAC9F,MAAM,EAAE,WAAW,CAAC,0EAA0E,CAAC;IAC/F,YAAY,EAAE,CAAC;SACb,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CACR,2MAA2M,CAC3M;IACF,aAAa,EAAE,CAAC;SACd,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACR,mHAAmH,CACnH;IACF,aAAa,EAAE,WAAW,CACzB,kEAAkE,CAClE,CAAC,QAAQ,EAAE;CACZ,CAAC;AAEF,MAAM,UAAU,uBAAuB,CACtC,MAAiB,EACjB,OAA+B,EAAE;IAEjC,MAAM,CAAC,YAAY,CAClB,eAAe,EACf;QACC,WAAW,EACV,4QAA4Q;QAC7Q,WAAW;KACX,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO;YACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;SACzD,CAAC;IACH,CAAC,CACD,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/intent/types.ts
CHANGED
|
@@ -201,6 +201,6 @@ export interface RawSpec {
|
|
|
201
201
|
commands: string[];
|
|
202
202
|
/** Operation root; default `"query"`. Sets the `createSession` operation. */
|
|
203
203
|
operation?: RawOperation;
|
|
204
|
-
/**
|
|
204
|
+
/** GraphQL operation name override. Defaults to Raw<Operation> (FR-12.3). */
|
|
205
205
|
typeName?: string;
|
|
206
206
|
}
|
|
@@ -96,6 +96,11 @@ describe("mcp/tools/sf-gql-aggregate", () => {
|
|
|
96
96
|
expect(props.object).toBeDefined();
|
|
97
97
|
expect(props.groupBy).toBeDefined();
|
|
98
98
|
expect(props.aggregations).toBeDefined();
|
|
99
|
+
// W-22899736: object + operationName advertise the GraphQL Name pattern in tools/list.
|
|
100
|
+
expect((props.object as { pattern?: string }).pattern).toBe("^[A-Za-z_][A-Za-z0-9_]*$");
|
|
101
|
+
expect((props.operationName as { pattern?: string }).pattern).toBe(
|
|
102
|
+
"^[A-Za-z_][A-Za-z0-9_]*$",
|
|
103
|
+
);
|
|
99
104
|
} finally {
|
|
100
105
|
await client.close();
|
|
101
106
|
await server.close();
|
|
@@ -170,4 +175,22 @@ describe("mcp/tools/sf-gql-aggregate", () => {
|
|
|
170
175
|
await server.close();
|
|
171
176
|
}
|
|
172
177
|
});
|
|
178
|
+
|
|
179
|
+
it("tools/call rejects invalid GraphQL Names in object/operationName", async () => {
|
|
180
|
+
const { client, server } = await connect();
|
|
181
|
+
try {
|
|
182
|
+
for (const args of [
|
|
183
|
+
{ org: ORG, object: "1Bad" },
|
|
184
|
+
{ org: ORG, object: "Account", operationName: "1Bad" },
|
|
185
|
+
]) {
|
|
186
|
+
const result = await client.callTool({ name: "sf_gql_aggregate", arguments: args });
|
|
187
|
+
expect(result.isError).toBe(true);
|
|
188
|
+
const content = result.content as { type: string; text?: string }[];
|
|
189
|
+
expect(content[0]?.text ?? "").toMatch(/GraphQL Name/);
|
|
190
|
+
}
|
|
191
|
+
} finally {
|
|
192
|
+
await client.close();
|
|
193
|
+
await server.close();
|
|
194
|
+
}
|
|
195
|
+
});
|
|
173
196
|
});
|
|
@@ -83,6 +83,11 @@ describe("mcp/tools/sf-gql-create", () => {
|
|
|
83
83
|
expect(props.org).toBeDefined();
|
|
84
84
|
expect(props.object).toBeDefined();
|
|
85
85
|
expect(props.returnFields).toBeDefined();
|
|
86
|
+
// W-22899736: object + operationName advertise the GraphQL Name pattern in tools/list.
|
|
87
|
+
expect((props.object as { pattern?: string }).pattern).toBe("^[A-Za-z_][A-Za-z0-9_]*$");
|
|
88
|
+
expect((props.operationName as { pattern?: string }).pattern).toBe(
|
|
89
|
+
"^[A-Za-z_][A-Za-z0-9_]*$",
|
|
90
|
+
);
|
|
86
91
|
} finally {
|
|
87
92
|
await client.close();
|
|
88
93
|
await server.close();
|
|
@@ -232,4 +237,22 @@ describe("mcp/tools/sf-gql-create", () => {
|
|
|
232
237
|
await server.close();
|
|
233
238
|
}
|
|
234
239
|
});
|
|
240
|
+
|
|
241
|
+
it("tools/call rejects invalid GraphQL Names in object/operationName", async () => {
|
|
242
|
+
const { client, server } = await connect();
|
|
243
|
+
try {
|
|
244
|
+
for (const args of [
|
|
245
|
+
{ org: ORG, object: "1Bad" },
|
|
246
|
+
{ org: ORG, object: "Account", operationName: "1Bad" },
|
|
247
|
+
]) {
|
|
248
|
+
const result = await client.callTool({ name: "sf_gql_create", arguments: args });
|
|
249
|
+
expect(result.isError).toBe(true);
|
|
250
|
+
const content = result.content as { type: string; text?: string }[];
|
|
251
|
+
expect(content[0]?.text ?? "").toMatch(/GraphQL Name/);
|
|
252
|
+
}
|
|
253
|
+
} finally {
|
|
254
|
+
await client.close();
|
|
255
|
+
await server.close();
|
|
256
|
+
}
|
|
257
|
+
});
|
|
235
258
|
});
|
|
@@ -82,6 +82,11 @@ describe("mcp/tools/sf-gql-delete", () => {
|
|
|
82
82
|
expect(props.object).toBeDefined();
|
|
83
83
|
expect(props.inputVariable).toBeDefined();
|
|
84
84
|
expect(props.operationName).toBeDefined();
|
|
85
|
+
// W-22899736: object + operationName advertise the GraphQL Name pattern in tools/list.
|
|
86
|
+
expect((props.object as { pattern?: string }).pattern).toBe("^[A-Za-z_][A-Za-z0-9_]*$");
|
|
87
|
+
expect((props.operationName as { pattern?: string }).pattern).toBe(
|
|
88
|
+
"^[A-Za-z_][A-Za-z0-9_]*$",
|
|
89
|
+
);
|
|
85
90
|
// Delete has no returnFields — result is always Id only.
|
|
86
91
|
expect(props.returnFields).toBeUndefined();
|
|
87
92
|
} finally {
|
|
@@ -176,6 +181,24 @@ describe("mcp/tools/sf-gql-delete", () => {
|
|
|
176
181
|
}
|
|
177
182
|
});
|
|
178
183
|
|
|
184
|
+
it("tools/call rejects invalid GraphQL Names in object/operationName", async () => {
|
|
185
|
+
const { client, server } = await connect();
|
|
186
|
+
try {
|
|
187
|
+
for (const args of [
|
|
188
|
+
{ org: ORG, object: "1Bad" },
|
|
189
|
+
{ org: ORG, object: "Account", operationName: "1Bad" },
|
|
190
|
+
]) {
|
|
191
|
+
const result = await client.callTool({ name: "sf_gql_delete", arguments: args });
|
|
192
|
+
expect(result.isError).toBe(true);
|
|
193
|
+
const content = result.content as { type: string; text?: string }[];
|
|
194
|
+
expect(content[0]?.text ?? "").toMatch(/GraphQL Name/);
|
|
195
|
+
}
|
|
196
|
+
} finally {
|
|
197
|
+
await client.close();
|
|
198
|
+
await server.close();
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
179
202
|
it("tools/call sf_gql_delete with an invalid object name returns error", async () => {
|
|
180
203
|
const { client, server } = await connect();
|
|
181
204
|
try {
|
|
@@ -185,7 +208,7 @@ describe("mcp/tools/sf-gql-delete", () => {
|
|
|
185
208
|
});
|
|
186
209
|
expect(result.isError).toBe(true);
|
|
187
210
|
const content = result.content as { type: string; text?: string }[];
|
|
188
|
-
expect(content[0]?.text).toMatch(/
|
|
211
|
+
expect(content[0]?.text).toMatch(/GraphQL Name/);
|
|
189
212
|
} finally {
|
|
190
213
|
await client.close();
|
|
191
214
|
await server.close();
|
|
@@ -79,6 +79,11 @@ describe("mcp/tools/sf-gql-list", () => {
|
|
|
79
79
|
expect(props.org).toBeDefined();
|
|
80
80
|
expect(props.object).toBeDefined();
|
|
81
81
|
expect(props.fields).toBeDefined();
|
|
82
|
+
// W-22899736: object + operationName advertise the GraphQL Name pattern in tools/list.
|
|
83
|
+
expect((props.object as { pattern?: string }).pattern).toBe("^[A-Za-z_][A-Za-z0-9_]*$");
|
|
84
|
+
expect((props.operationName as { pattern?: string }).pattern).toBe(
|
|
85
|
+
"^[A-Za-z_][A-Za-z0-9_]*$",
|
|
86
|
+
);
|
|
82
87
|
} finally {
|
|
83
88
|
await client.close();
|
|
84
89
|
await server.close();
|
|
@@ -125,4 +130,22 @@ describe("mcp/tools/sf-gql-list", () => {
|
|
|
125
130
|
await server.close();
|
|
126
131
|
}
|
|
127
132
|
});
|
|
133
|
+
|
|
134
|
+
it("tools/call rejects invalid GraphQL Names in object/operationName", async () => {
|
|
135
|
+
const { client, server } = await connect();
|
|
136
|
+
try {
|
|
137
|
+
for (const args of [
|
|
138
|
+
{ org: ORG, object: "1Bad", fields: ["Id", "Name"] },
|
|
139
|
+
{ org: ORG, object: "Account", fields: ["Id", "Name"], operationName: "1Bad" },
|
|
140
|
+
]) {
|
|
141
|
+
const result = await client.callTool({ name: "sf_gql_list", arguments: args });
|
|
142
|
+
expect(result.isError).toBe(true);
|
|
143
|
+
const content = result.content as { type: string; text?: string }[];
|
|
144
|
+
expect(content[0]?.text ?? "").toMatch(/GraphQL Name/);
|
|
145
|
+
}
|
|
146
|
+
} finally {
|
|
147
|
+
await client.close();
|
|
148
|
+
await server.close();
|
|
149
|
+
}
|
|
150
|
+
});
|
|
128
151
|
});
|
|
@@ -81,6 +81,8 @@ describe("mcp/tools/sf-gql-raw", () => {
|
|
|
81
81
|
(tool!.inputSchema as { properties?: Record<string, unknown> }).properties ?? {};
|
|
82
82
|
expect(props.org).toBeDefined();
|
|
83
83
|
expect(props.commands).toBeDefined();
|
|
84
|
+
// W-22899736: typeName advertises the GraphQL Name pattern in tools/list.
|
|
85
|
+
expect((props.typeName as { pattern?: string }).pattern).toBe("^[A-Za-z_][A-Za-z0-9_]*$");
|
|
84
86
|
} finally {
|
|
85
87
|
await client.close();
|
|
86
88
|
await server.close();
|
|
@@ -122,6 +124,23 @@ describe("mcp/tools/sf-gql-raw", () => {
|
|
|
122
124
|
await server.close();
|
|
123
125
|
}
|
|
124
126
|
});
|
|
127
|
+
|
|
128
|
+
it("tools/call rejects invalid GraphQL Names in typeName", async () => {
|
|
129
|
+
const { client, server } = await connect();
|
|
130
|
+
try {
|
|
131
|
+
for (const args of [
|
|
132
|
+
{ org: ORG, commands: ["select uiapi/query/Case/edges/node/Id"], typeName: "1Bad" },
|
|
133
|
+
]) {
|
|
134
|
+
const result = await client.callTool({ name: "sf_gql_raw", arguments: args });
|
|
135
|
+
expect(result.isError).toBe(true);
|
|
136
|
+
const content = result.content as { type: string; text?: string }[];
|
|
137
|
+
expect(content[0]?.text ?? "").toMatch(/GraphQL Name/);
|
|
138
|
+
}
|
|
139
|
+
} finally {
|
|
140
|
+
await client.close();
|
|
141
|
+
await server.close();
|
|
142
|
+
}
|
|
143
|
+
});
|
|
125
144
|
});
|
|
126
145
|
|
|
127
146
|
describe("mcp/server registers sf_gql_raw", () => {
|
|
@@ -55,6 +55,11 @@ describe("mcp/tools/sf-gql-update", () => {
|
|
|
55
55
|
expect(props.org).toBeDefined();
|
|
56
56
|
expect(props.object).toBeDefined();
|
|
57
57
|
expect(props.returnFields).toBeDefined();
|
|
58
|
+
// W-22899736: object + operationName advertise the GraphQL Name pattern in tools/list.
|
|
59
|
+
expect((props.object as { pattern?: string }).pattern).toBe("^[A-Za-z_][A-Za-z0-9_]*$");
|
|
60
|
+
expect((props.operationName as { pattern?: string }).pattern).toBe(
|
|
61
|
+
"^[A-Za-z_][A-Za-z0-9_]*$",
|
|
62
|
+
);
|
|
58
63
|
} finally {
|
|
59
64
|
await client.close();
|
|
60
65
|
await server.close();
|
|
@@ -204,4 +209,22 @@ describe("mcp/tools/sf-gql-update", () => {
|
|
|
204
209
|
await server.close();
|
|
205
210
|
}
|
|
206
211
|
});
|
|
212
|
+
|
|
213
|
+
it("tools/call rejects invalid GraphQL Names in object/operationName", async () => {
|
|
214
|
+
const { client, server } = await connect();
|
|
215
|
+
try {
|
|
216
|
+
for (const args of [
|
|
217
|
+
{ org: ORG, object: "1Bad" },
|
|
218
|
+
{ org: ORG, object: "Account", operationName: "1Bad" },
|
|
219
|
+
]) {
|
|
220
|
+
const result = await client.callTool({ name: "sf_gql_update", arguments: args });
|
|
221
|
+
expect(result.isError).toBe(true);
|
|
222
|
+
const content = result.content as { type: string; text?: string }[];
|
|
223
|
+
expect(content[0]?.text ?? "").toMatch(/GraphQL Name/);
|
|
224
|
+
}
|
|
225
|
+
} finally {
|
|
226
|
+
await client.close();
|
|
227
|
+
await server.close();
|
|
228
|
+
}
|
|
229
|
+
});
|
|
207
230
|
});
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
9
10
|
import { buildAggregate } from "../../intent/build-aggregate.js";
|
|
10
11
|
import { GROUP_BY_FUNCTIONS } from "../../intent/types.js";
|
|
11
12
|
import { type PrimeDeps } from "../../lib/prime-schema.js";
|
|
@@ -44,7 +45,7 @@ const groupByElementSchema = z.union([
|
|
|
44
45
|
|
|
45
46
|
const inputSchema = {
|
|
46
47
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
47
|
-
object:
|
|
48
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
48
49
|
groupBy: z
|
|
49
50
|
.array(groupByElementSchema)
|
|
50
51
|
.optional()
|
|
@@ -75,10 +76,9 @@ const inputSchema = {
|
|
|
75
76
|
.positive()
|
|
76
77
|
.optional()
|
|
77
78
|
.describe("Connection page size (top-N pattern). No default — omit for all buckets."),
|
|
78
|
-
operationName:
|
|
79
|
-
.
|
|
80
|
-
|
|
81
|
-
.describe("Override the GraphQL operation name. Defaults to <Object>Aggregate."),
|
|
79
|
+
operationName: graphqlName(
|
|
80
|
+
"Override the GraphQL operation name. Defaults to <Object>Aggregate.",
|
|
81
|
+
).optional(),
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
export function registerSfGqlAggregateTool(
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
9
10
|
import { buildCreate } from "../../intent/build-create.js";
|
|
10
11
|
import { type PrimeDeps } from "../../lib/prime-schema.js";
|
|
11
12
|
|
|
@@ -15,7 +16,7 @@ export interface SfGqlCreateToolOptions {
|
|
|
15
16
|
|
|
16
17
|
const inputSchema = {
|
|
17
18
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
18
|
-
object:
|
|
19
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
19
20
|
returnFields: z
|
|
20
21
|
.array(z.string())
|
|
21
22
|
.optional()
|
|
@@ -28,10 +29,9 @@ const inputSchema = {
|
|
|
28
29
|
.describe(
|
|
29
30
|
'Variable name (without "$") for the create input. Defaults to "input". Declared as $<name>: <Object>CreateInput!.',
|
|
30
31
|
),
|
|
31
|
-
operationName:
|
|
32
|
-
.
|
|
33
|
-
|
|
34
|
-
.describe("Override the GraphQL operation name. Defaults to Create<Object>."),
|
|
32
|
+
operationName: graphqlName(
|
|
33
|
+
"Override the GraphQL operation name. Defaults to Create<Object>.",
|
|
34
|
+
).optional(),
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
export function registerSfGqlCreateTool(
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
9
10
|
import { buildDelete } from "../../intent/build-delete.js";
|
|
10
11
|
import { type PrimeDeps } from "../../lib/prime-schema.js";
|
|
11
12
|
|
|
@@ -15,17 +16,16 @@ export interface SfGqlDeleteToolOptions {
|
|
|
15
16
|
|
|
16
17
|
const inputSchema = {
|
|
17
18
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
18
|
-
object:
|
|
19
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
19
20
|
inputVariable: z
|
|
20
21
|
.string()
|
|
21
22
|
.optional()
|
|
22
23
|
.describe(
|
|
23
24
|
'Variable name (without "$") for the delete input. Defaults to "input". Declared as $<name>: RecordDeleteInput! — the schema-wide delete input carrying the record Id, not an <Object>-specific type.',
|
|
24
25
|
),
|
|
25
|
-
operationName:
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
.describe("Override the GraphQL operation name. Defaults to Delete<Object>."),
|
|
26
|
+
operationName: graphqlName(
|
|
27
|
+
"Override the GraphQL operation name. Defaults to Delete<Object>.",
|
|
28
|
+
).optional(),
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export function registerSfGqlDeleteTool(
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
-
import { childRelationshipSchema, orderByObject } from "./shared/zod-schemas.js";
|
|
9
|
+
import { childRelationshipSchema, graphqlName, orderByObject } from "./shared/zod-schemas.js";
|
|
10
10
|
import { buildList } from "../../intent/build-list.js";
|
|
11
11
|
import { type PrimeDeps } from "../../lib/prime-schema.js";
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ const orderBySchema = z.union([orderByObject, z.array(orderByObject)]);
|
|
|
20
20
|
|
|
21
21
|
const inputSchema = {
|
|
22
22
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
23
|
-
object:
|
|
23
|
+
object: graphqlName('SObject API name, e.g. "Account", "Case". Must be a valid GraphQL Name.'),
|
|
24
24
|
fields: z
|
|
25
25
|
.array(z.string())
|
|
26
26
|
.describe(
|
|
@@ -49,10 +49,9 @@ const inputSchema = {
|
|
|
49
49
|
.optional()
|
|
50
50
|
.describe("Top-level connection page size; defaults to 10."),
|
|
51
51
|
scope: z.string().optional().describe('Scope enum (e.g. "MINE", "EVERYTHING") or $varName.'),
|
|
52
|
-
operationName:
|
|
53
|
-
.
|
|
54
|
-
|
|
55
|
-
.describe("Override the GraphQL operation name. Defaults to <Object>List."),
|
|
52
|
+
operationName: graphqlName(
|
|
53
|
+
"Override the GraphQL operation name. Defaults to <Object>List.",
|
|
54
|
+
).optional(),
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
export function registerSfGqlListTool(server: McpServer, opts: SfGqlListToolOptions = {}): void {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
9
10
|
import { buildRaw } from "../../intent/build-raw.js";
|
|
10
11
|
import { type PrimeDeps } from "../../lib/prime-schema.js";
|
|
11
12
|
|
|
@@ -32,10 +33,9 @@ const inputSchema = {
|
|
|
32
33
|
.describe(
|
|
33
34
|
'Operation root. "query" (default) → uiapi.query; "mutation" → mutation root; "aggregate" → uiapi.aggregate.',
|
|
34
35
|
),
|
|
35
|
-
typeName:
|
|
36
|
-
.
|
|
37
|
-
|
|
38
|
-
.describe("Codegen type prefix / operation name override. Defaults to Raw<Operation>."),
|
|
36
|
+
typeName: graphqlName(
|
|
37
|
+
"Override the GraphQL operation name. Defaults to Raw<Operation>.",
|
|
38
|
+
).optional(),
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export function registerSfGqlRawTool(server: McpServer, opts: SfGqlRawToolOptions = {}): void {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
+
import { graphqlName } from "./shared/zod-schemas.js";
|
|
9
10
|
import { buildUpdate } from "../../intent/build-update.js";
|
|
10
11
|
import { type PrimeDeps } from "../../lib/prime-schema.js";
|
|
11
12
|
|
|
@@ -15,7 +16,7 @@ export interface SfGqlUpdateToolOptions {
|
|
|
15
16
|
|
|
16
17
|
const inputSchema = {
|
|
17
18
|
org: z.string().describe("Org alias resolved via local Salesforce CLI auth (~/.sf, ~/.sfdx)."),
|
|
18
|
-
object:
|
|
19
|
+
object: graphqlName('SObject API name, e.g. "Account", "Order". Must be a valid GraphQL Name.'),
|
|
19
20
|
returnFields: z
|
|
20
21
|
.array(z.string())
|
|
21
22
|
.optional()
|
|
@@ -28,10 +29,9 @@ const inputSchema = {
|
|
|
28
29
|
.describe(
|
|
29
30
|
'Variable name (without "$") for the update input. Defaults to "input". Declared as $<name>: <Object>UpdateInput!.',
|
|
30
31
|
),
|
|
31
|
-
operationName:
|
|
32
|
-
.
|
|
33
|
-
|
|
34
|
-
.describe("Override the GraphQL operation name. Defaults to Update<Object>."),
|
|
32
|
+
operationName: graphqlName(
|
|
33
|
+
"Override the GraphQL operation name. Defaults to Update<Object>.",
|
|
34
|
+
).optional(),
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
export function registerSfGqlUpdateTool(
|