@salesforce/graphiti 10.10.2
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 +424 -0
- package/CHANGELOG.md +448 -0
- package/LICENSE.txt +82 -0
- package/README.md +204 -0
- package/TASK.md +249 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +683 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/args.d.ts +13 -0
- package/dist/commands/args.js +207 -0
- package/dist/commands/args.js.map +1 -0
- package/dist/commands/build.d.ts +11 -0
- package/dist/commands/build.js +209 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/connect.d.ts +8 -0
- package/dist/commands/connect.js +55 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/describe.d.ts +6 -0
- package/dist/commands/describe.js +229 -0
- package/dist/commands/describe.js.map +1 -0
- package/dist/commands/meta.d.ts +9 -0
- package/dist/commands/meta.js +140 -0
- package/dist/commands/meta.js.map +1 -0
- package/dist/commands/navigate.d.ts +14 -0
- package/dist/commands/navigate.js +105 -0
- package/dist/commands/navigate.js.map +1 -0
- package/dist/commands/query-helpers.d.ts +80 -0
- package/dist/commands/query-helpers.js +865 -0
- package/dist/commands/query-helpers.js.map +1 -0
- package/dist/commands/query.d.ts +26 -0
- package/dist/commands/query.js +901 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/review.d.ts +18 -0
- package/dist/commands/review.js +533 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/session-mgmt.d.ts +25 -0
- package/dist/commands/session-mgmt.js +206 -0
- package/dist/commands/session-mgmt.js.map +1 -0
- package/dist/commands/type.d.ts +6 -0
- package/dist/commands/type.js +342 -0
- package/dist/commands/type.js.map +1 -0
- package/dist/commands/validate-input.d.ts +6 -0
- package/dist/commands/validate-input.js +32 -0
- package/dist/commands/validate-input.js.map +1 -0
- package/dist/intent/build-aggregate.d.ts +33 -0
- package/dist/intent/build-aggregate.js +134 -0
- package/dist/intent/build-aggregate.js.map +1 -0
- package/dist/intent/build-create.d.ts +14 -0
- package/dist/intent/build-create.js +16 -0
- package/dist/intent/build-create.js.map +1 -0
- package/dist/intent/build-delete.d.ts +30 -0
- package/dist/intent/build-delete.js +53 -0
- package/dist/intent/build-delete.js.map +1 -0
- package/dist/intent/build-detail.d.ts +32 -0
- package/dist/intent/build-detail.js +80 -0
- package/dist/intent/build-detail.js.map +1 -0
- package/dist/intent/build-discover.d.ts +30 -0
- package/dist/intent/build-discover.js +149 -0
- package/dist/intent/build-discover.js.map +1 -0
- package/dist/intent/build-list.d.ts +28 -0
- package/dist/intent/build-list.js +75 -0
- package/dist/intent/build-list.js.map +1 -0
- package/dist/intent/build-mutation.d.ts +23 -0
- package/dist/intent/build-mutation.js +54 -0
- package/dist/intent/build-mutation.js.map +1 -0
- package/dist/intent/build-output.d.ts +27 -0
- package/dist/intent/build-output.js +60 -0
- package/dist/intent/build-output.js.map +1 -0
- package/dist/intent/build-raw.d.ts +23 -0
- package/dist/intent/build-raw.js +54 -0
- package/dist/intent/build-raw.js.map +1 -0
- package/dist/intent/build-update.d.ts +14 -0
- package/dist/intent/build-update.js +16 -0
- package/dist/intent/build-update.js.map +1 -0
- package/dist/intent/get-schema-with-priming.d.ts +26 -0
- package/dist/intent/get-schema-with-priming.js +32 -0
- package/dist/intent/get-schema-with-priming.js.map +1 -0
- package/dist/intent/select-child-relationship.d.ts +19 -0
- package/dist/intent/select-child-relationship.js +38 -0
- package/dist/intent/select-child-relationship.js.map +1 -0
- package/dist/intent/types.d.ts +159 -0
- package/dist/intent/types.js +21 -0
- package/dist/intent/types.js.map +1 -0
- package/dist/lib/apply-command.d.ts +15 -0
- package/dist/lib/apply-command.js +238 -0
- package/dist/lib/apply-command.js.map +1 -0
- package/dist/lib/auth.d.ts +38 -0
- package/dist/lib/auth.js +113 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/codegen.d.ts +32 -0
- package/dist/lib/codegen.js +700 -0
- package/dist/lib/codegen.js.map +1 -0
- package/dist/lib/command-registry.d.ts +59 -0
- package/dist/lib/command-registry.js +366 -0
- package/dist/lib/command-registry.js.map +1 -0
- package/dist/lib/formatter.d.ts +76 -0
- package/dist/lib/formatter.js +419 -0
- package/dist/lib/formatter.js.map +1 -0
- package/dist/lib/fs-utils.d.ts +23 -0
- package/dist/lib/fs-utils.js +46 -0
- package/dist/lib/fs-utils.js.map +1 -0
- package/dist/lib/graphql-name.d.ts +27 -0
- package/dist/lib/graphql-name.js +32 -0
- package/dist/lib/graphql-name.js.map +1 -0
- package/dist/lib/interactive.d.ts +6 -0
- package/dist/lib/interactive.js +562 -0
- package/dist/lib/interactive.js.map +1 -0
- package/dist/lib/introspect.d.ts +40 -0
- package/dist/lib/introspect.js +280 -0
- package/dist/lib/introspect.js.map +1 -0
- package/dist/lib/object-info.d.ts +79 -0
- package/dist/lib/object-info.js +313 -0
- package/dist/lib/object-info.js.map +1 -0
- package/dist/lib/path-selection.d.ts +50 -0
- package/dist/lib/path-selection.js +146 -0
- package/dist/lib/path-selection.js.map +1 -0
- package/dist/lib/prime-schema.d.ts +59 -0
- package/dist/lib/prime-schema.js +158 -0
- package/dist/lib/prime-schema.js.map +1 -0
- package/dist/lib/query-builder.d.ts +10 -0
- package/dist/lib/query-builder.js +168 -0
- package/dist/lib/query-builder.js.map +1 -0
- package/dist/lib/query-commands.d.ts +19 -0
- package/dist/lib/query-commands.js +262 -0
- package/dist/lib/query-commands.js.map +1 -0
- package/dist/lib/session.d.ts +205 -0
- package/dist/lib/session.js +1075 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/lib/tokenize.d.ts +12 -0
- package/dist/lib/tokenize.js +48 -0
- package/dist/lib/tokenize.js.map +1 -0
- package/dist/lib/uiapi.d.ts +109 -0
- package/dist/lib/uiapi.js +159 -0
- package/dist/lib/uiapi.js.map +1 -0
- package/dist/lib/validator.d.ts +27 -0
- package/dist/lib/validator.js +100 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/lib/variable-promotion.d.ts +69 -0
- package/dist/lib/variable-promotion.js +95 -0
- package/dist/lib/variable-promotion.js.map +1 -0
- package/dist/lib/walker.d.ts +147 -0
- package/dist/lib/walker.js +723 -0
- package/dist/lib/walker.js.map +1 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +34 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +7 -0
- package/dist/mcp/stdio.js +25 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/mcp/tools/echo.d.ts +7 -0
- package/dist/mcp/tools/echo.js +17 -0
- package/dist/mcp/tools/echo.js.map +1 -0
- package/dist/mcp/tools/sf-gql-aggregate.d.ts +11 -0
- package/dist/mcp/tools/sf-gql-aggregate.js +75 -0
- package/dist/mcp/tools/sf-gql-aggregate.js.map +1 -0
- package/dist/mcp/tools/sf-gql-create.d.ts +11 -0
- package/dist/mcp/tools/sf-gql-create.js +35 -0
- package/dist/mcp/tools/sf-gql-create.js.map +1 -0
- package/dist/mcp/tools/sf-gql-delete.d.ts +11 -0
- package/dist/mcp/tools/sf-gql-delete.js +31 -0
- package/dist/mcp/tools/sf-gql-delete.js.map +1 -0
- package/dist/mcp/tools/sf-gql-detail.d.ts +11 -0
- package/dist/mcp/tools/sf-gql-detail.js +58 -0
- package/dist/mcp/tools/sf-gql-detail.js.map +1 -0
- package/dist/mcp/tools/sf-gql-discover.d.ts +9 -0
- package/dist/mcp/tools/sf-gql-discover.js +51 -0
- package/dist/mcp/tools/sf-gql-discover.js.map +1 -0
- package/dist/mcp/tools/sf-gql-list.d.ts +11 -0
- package/dist/mcp/tools/sf-gql-list.js +53 -0
- package/dist/mcp/tools/sf-gql-list.js.map +1 -0
- package/dist/mcp/tools/sf-gql-raw.d.ts +11 -0
- package/dist/mcp/tools/sf-gql-raw.js +39 -0
- package/dist/mcp/tools/sf-gql-raw.js.map +1 -0
- package/dist/mcp/tools/sf-gql-update.d.ts +11 -0
- package/dist/mcp/tools/sf-gql-update.js +35 -0
- package/dist/mcp/tools/sf-gql-update.js.map +1 -0
- package/dist/mcp/tools/shared/zod-schemas.d.ts +49 -0
- package/dist/mcp/tools/shared/zod-schemas.js +46 -0
- package/dist/mcp/tools/shared/zod-schemas.js.map +1 -0
- package/package.json +36 -0
- package/ralph-loop.sh +120 -0
- package/scripts/smoke-orderby.sh +190 -0
- package/src/__tests__/helpers/prime-deps.ts +46 -0
- package/src/__tests__/helpers/schema.ts +73 -0
- package/src/__tests__/helpers/stdout.ts +33 -0
- package/src/__tests__/setup.ts +19 -0
- package/src/cli.ts +764 -0
- package/src/commands/__tests__/query.spec.ts +137 -0
- package/src/commands/args.ts +306 -0
- package/src/commands/build.ts +288 -0
- package/src/commands/connect.ts +60 -0
- package/src/commands/describe.ts +246 -0
- package/src/commands/meta.ts +171 -0
- package/src/commands/navigate.ts +134 -0
- package/src/commands/query-helpers.ts +1202 -0
- package/src/commands/query.ts +1085 -0
- package/src/commands/review.ts +670 -0
- package/src/commands/session-mgmt.ts +256 -0
- package/src/commands/type.ts +437 -0
- package/src/commands/validate-input.ts +38 -0
- package/src/intent/__tests__/build-aggregate.spec.ts +931 -0
- package/src/intent/__tests__/build-create-validation.spec.ts +135 -0
- package/src/intent/__tests__/build-delete.spec.ts +121 -0
- package/src/intent/__tests__/build-detail.spec.ts +333 -0
- package/src/intent/__tests__/build-discover.spec.ts +432 -0
- package/src/intent/__tests__/build-list.spec.ts +284 -0
- package/src/intent/__tests__/build-mutation.spec.ts +108 -0
- package/src/intent/__tests__/build-output.spec.ts +55 -0
- package/src/intent/__tests__/build-raw.spec.ts +153 -0
- package/src/intent/__tests__/build-update-validation.spec.ts +134 -0
- package/src/intent/build-aggregate.ts +182 -0
- package/src/intent/build-create.ts +19 -0
- package/src/intent/build-delete.ts +62 -0
- package/src/intent/build-detail.ts +95 -0
- package/src/intent/build-discover.ts +199 -0
- package/src/intent/build-list.ts +91 -0
- package/src/intent/build-mutation.ts +75 -0
- package/src/intent/build-output.ts +72 -0
- package/src/intent/build-raw.ts +61 -0
- package/src/intent/build-update.ts +19 -0
- package/src/intent/get-schema-with-priming.ts +43 -0
- package/src/intent/select-child-relationship.ts +48 -0
- package/src/intent/types.ts +181 -0
- package/src/lib/__tests__/apply-command.parity.spec.ts +97 -0
- package/src/lib/__tests__/apply-command.spec.ts +171 -0
- package/src/lib/__tests__/auth.spec.ts +292 -0
- package/src/lib/__tests__/formatter.spec.ts +86 -0
- package/src/lib/__tests__/graphql-name.spec.ts +64 -0
- package/src/lib/__tests__/introspect.spec.ts +399 -0
- package/src/lib/__tests__/object-info.spec.ts +124 -0
- package/src/lib/__tests__/path-selection.spec.ts +219 -0
- package/src/lib/__tests__/prime-schema.spec.ts +269 -0
- package/src/lib/__tests__/query-builder.spec.ts +95 -0
- package/src/lib/__tests__/query-commands.spec.ts +74 -0
- package/src/lib/__tests__/session.spec.ts +292 -0
- package/src/lib/__tests__/tokenize.spec.ts +33 -0
- package/src/lib/__tests__/uiapi.spec.ts +192 -0
- package/src/lib/__tests__/variable-promotion.spec.ts +211 -0
- package/src/lib/__tests__/walker.spec.ts +250 -0
- package/src/lib/apply-command.ts +286 -0
- package/src/lib/auth.ts +157 -0
- package/src/lib/codegen.ts +899 -0
- package/src/lib/command-registry.ts +434 -0
- package/src/lib/formatter.ts +587 -0
- package/src/lib/fs-utils.ts +46 -0
- package/src/lib/graphql-name.ts +35 -0
- package/src/lib/interactive.ts +634 -0
- package/src/lib/introspect.ts +320 -0
- package/src/lib/object-info.ts +409 -0
- package/src/lib/path-selection.ts +162 -0
- package/src/lib/prime-schema.ts +195 -0
- package/src/lib/query-builder.ts +193 -0
- package/src/lib/query-commands.ts +290 -0
- package/src/lib/session.ts +1304 -0
- package/src/lib/tokenize.ts +43 -0
- package/src/lib/uiapi.ts +176 -0
- package/src/lib/validator.ts +143 -0
- package/src/lib/variable-promotion.ts +145 -0
- package/src/lib/walker.ts +975 -0
- package/src/mcp/__tests__/server.spec.ts +155 -0
- package/src/mcp/server.ts +38 -0
- package/src/mcp/stdio.ts +29 -0
- package/src/mcp/tools/__tests__/sf-gql-aggregate.spec.ts +173 -0
- package/src/mcp/tools/__tests__/sf-gql-create.spec.ts +235 -0
- package/src/mcp/tools/__tests__/sf-gql-delete.spec.ts +194 -0
- package/src/mcp/tools/__tests__/sf-gql-detail.spec.ts +246 -0
- package/src/mcp/tools/__tests__/sf-gql-discover.spec.ts +320 -0
- package/src/mcp/tools/__tests__/sf-gql-list.spec.ts +128 -0
- package/src/mcp/tools/__tests__/sf-gql-raw.spec.ts +141 -0
- package/src/mcp/tools/__tests__/sf-gql-update.spec.ts +207 -0
- package/src/mcp/tools/echo.ts +24 -0
- package/src/mcp/tools/sf-gql-aggregate.ts +102 -0
- package/src/mcp/tools/sf-gql-create.ts +55 -0
- package/src/mcp/tools/sf-gql-delete.ts +49 -0
- package/src/mcp/tools/sf-gql-detail.ts +85 -0
- package/src/mcp/tools/sf-gql-discover.ts +67 -0
- package/src/mcp/tools/sf-gql-list.ts +73 -0
- package/src/mcp/tools/sf-gql-raw.ts +56 -0
- package/src/mcp/tools/sf-gql-update.ts +55 -0
- package/src/mcp/tools/shared/zod-schemas.ts +55 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +14 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-info.js","sourceRoot":"","sources":["../../src/lib/object-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Library API for translating dotted parent-field paths into projection
|
|
8
|
+
* nodes. Encapsulates two UIAPI conventions that every caller would
|
|
9
|
+
* otherwise re-implement:
|
|
10
|
+
*
|
|
11
|
+
* 1. **Value-wrapper unwrapping.** UIAPI scalar fields are exposed as
|
|
12
|
+
* object types with a single `value` field (e.g. `Name { value }`).
|
|
13
|
+
* A caller asking for "Name" gets `Name { value }` — except for
|
|
14
|
+
* `Id`, which is a real scalar. The structural test for "is this
|
|
15
|
+
* a wrapper?" lives in `lib/uiapi.ts:isValueWrapperType` so every
|
|
16
|
+
* caller agrees on the rule.
|
|
17
|
+
*
|
|
18
|
+
* 2. **Polymorphic union expansion.** Relationship fields like `Owner`
|
|
19
|
+
* resolve to a union (`User | Group`). A path like "Owner.Name"
|
|
20
|
+
* cannot be selected directly; it must be expanded to inline
|
|
21
|
+
* fragments per union member that has the field. Members lacking
|
|
22
|
+
* the field are skipped silently — a partial selection is more
|
|
23
|
+
* useful than a hard failure.
|
|
24
|
+
*
|
|
25
|
+
* The MCP intent layer used to carry this logic locally, but it's a
|
|
26
|
+
* pure function of (schema, path) and other graphiti consumers (CLI
|
|
27
|
+
* helpers, future surfaces) need the same behavior.
|
|
28
|
+
*/
|
|
29
|
+
import { type GraphQLSchema } from "graphql";
|
|
30
|
+
import { type QuerySession } from "./session.js";
|
|
31
|
+
/**
|
|
32
|
+
* Selects a dotted field path (e.g. "Owner.Name") rooted at `basePath`,
|
|
33
|
+
* automatically expanding any segment that resolves to a polymorphic
|
|
34
|
+
* union into inline fragments on each member that has the field.
|
|
35
|
+
*
|
|
36
|
+
* Behavior contract:
|
|
37
|
+
* - "Name" (single segment) → calls `selectScalarOrValue`.
|
|
38
|
+
* - "Account.Name" (no union segments) → walks the dotted path, then
|
|
39
|
+
* selects the leaf with value-wrapper unwrapping.
|
|
40
|
+
* - "Owner.Name" where Owner is a union → emits
|
|
41
|
+
* `Owner { ... on User { Name { value } } ... on Group { Name { value } } }`.
|
|
42
|
+
* Members that don't have `Name` are skipped silently.
|
|
43
|
+
* - "Owner.BadField" where no union member has `BadField` → throws.
|
|
44
|
+
* A silent no-op would render an empty selection; failing loudly
|
|
45
|
+
* lets the caller correct the field name.
|
|
46
|
+
* - If the union segment is followed by more path components (e.g.
|
|
47
|
+
* `Owner.Account.Name`), the remaining path is appended to each
|
|
48
|
+
* member's inline fragment.
|
|
49
|
+
*/
|
|
50
|
+
export declare function selectDottedFieldPath(session: QuerySession, schema: GraphQLSchema, basePath: string[], dotField: string): void;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Library API for translating dotted parent-field paths into projection
|
|
8
|
+
* nodes. Encapsulates two UIAPI conventions that every caller would
|
|
9
|
+
* otherwise re-implement:
|
|
10
|
+
*
|
|
11
|
+
* 1. **Value-wrapper unwrapping.** UIAPI scalar fields are exposed as
|
|
12
|
+
* object types with a single `value` field (e.g. `Name { value }`).
|
|
13
|
+
* A caller asking for "Name" gets `Name { value }` — except for
|
|
14
|
+
* `Id`, which is a real scalar. The structural test for "is this
|
|
15
|
+
* a wrapper?" lives in `lib/uiapi.ts:isValueWrapperType` so every
|
|
16
|
+
* caller agrees on the rule.
|
|
17
|
+
*
|
|
18
|
+
* 2. **Polymorphic union expansion.** Relationship fields like `Owner`
|
|
19
|
+
* resolve to a union (`User | Group`). A path like "Owner.Name"
|
|
20
|
+
* cannot be selected directly; it must be expanded to inline
|
|
21
|
+
* fragments per union member that has the field. Members lacking
|
|
22
|
+
* the field are skipped silently — a partial selection is more
|
|
23
|
+
* useful than a hard failure.
|
|
24
|
+
*
|
|
25
|
+
* The MCP intent layer used to carry this logic locally, but it's a
|
|
26
|
+
* pure function of (schema, path) and other graphiti consumers (CLI
|
|
27
|
+
* helpers, future surfaces) need the same behavior.
|
|
28
|
+
*/
|
|
29
|
+
import { isUnionType } from "graphql";
|
|
30
|
+
import { selectLeaf } from "./session.js";
|
|
31
|
+
import { isValueWrapperType } from "./uiapi.js";
|
|
32
|
+
import { getFragmentTargets, MutationContextError, resolvePath } from "./walker.js";
|
|
33
|
+
/**
|
|
34
|
+
* Selects a scalar field at `basePath`, applying UIAPI value-wrapper
|
|
35
|
+
* unwrapping. `Id` is selected as a leaf directly; value-wrapper types
|
|
36
|
+
* are selected as `<field>/value`. Falls back to a direct selection
|
|
37
|
+
* when schema resolution fails — the downstream renderer/validator
|
|
38
|
+
* will surface a clearer error than we could here.
|
|
39
|
+
*/
|
|
40
|
+
function selectScalarOrValue(session, schema, basePath, fieldName) {
|
|
41
|
+
const fullPath = [...basePath, fieldName];
|
|
42
|
+
if (fieldName === "Id") {
|
|
43
|
+
selectLeaf(session, fullPath);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const wr = resolvePath(schema, session.operation, fullPath);
|
|
48
|
+
if (wr.isLeaf) {
|
|
49
|
+
selectLeaf(session, fullPath);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (isValueWrapperType(schema, wr.typeName)) {
|
|
53
|
+
selectLeaf(session, [...fullPath, "value"]);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
selectLeaf(session, fullPath);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
selectLeaf(session, fullPath);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Selects a dotted field path (e.g. "Owner.Name") rooted at `basePath`,
|
|
64
|
+
* automatically expanding any segment that resolves to a polymorphic
|
|
65
|
+
* union into inline fragments on each member that has the field.
|
|
66
|
+
*
|
|
67
|
+
* Behavior contract:
|
|
68
|
+
* - "Name" (single segment) → calls `selectScalarOrValue`.
|
|
69
|
+
* - "Account.Name" (no union segments) → walks the dotted path, then
|
|
70
|
+
* selects the leaf with value-wrapper unwrapping.
|
|
71
|
+
* - "Owner.Name" where Owner is a union → emits
|
|
72
|
+
* `Owner { ... on User { Name { value } } ... on Group { Name { value } } }`.
|
|
73
|
+
* Members that don't have `Name` are skipped silently.
|
|
74
|
+
* - "Owner.BadField" where no union member has `BadField` → throws.
|
|
75
|
+
* A silent no-op would render an empty selection; failing loudly
|
|
76
|
+
* lets the caller correct the field name.
|
|
77
|
+
* - If the union segment is followed by more path components (e.g.
|
|
78
|
+
* `Owner.Account.Name`), the remaining path is appended to each
|
|
79
|
+
* member's inline fragment.
|
|
80
|
+
*/
|
|
81
|
+
export function selectDottedFieldPath(session, schema, basePath, dotField) {
|
|
82
|
+
const parts = dotField.split(".");
|
|
83
|
+
const fieldName = parts.pop();
|
|
84
|
+
if (!fieldName) {
|
|
85
|
+
throw new Error(`Empty field name in dotted path "${dotField}"`);
|
|
86
|
+
}
|
|
87
|
+
// Walk parent segments looking for a union; expand the first one we hit.
|
|
88
|
+
const currentPath = [...basePath];
|
|
89
|
+
for (let i = 0; i < parts.length; i++) {
|
|
90
|
+
currentPath.push(parts[i]);
|
|
91
|
+
let resolved;
|
|
92
|
+
try {
|
|
93
|
+
resolved = resolvePath(schema, session.operation, currentPath);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
// Re-throw mutation-context errors — the walker produces a clear,
|
|
97
|
+
// actionable message that callers should see rather than a confusing
|
|
98
|
+
// downstream validation failure.
|
|
99
|
+
if (err instanceof MutationContextError) {
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
// Other path resolution failures (typo, unknown field) — bail out
|
|
103
|
+
// of union detection and fall back to a flat selection below.
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
if (!isUnionType(resolved.type))
|
|
107
|
+
continue;
|
|
108
|
+
const targets = getFragmentTargets(schema, resolved.type);
|
|
109
|
+
const remaining = parts.slice(i + 1);
|
|
110
|
+
let matchedAny = false;
|
|
111
|
+
for (const target of targets) {
|
|
112
|
+
const memberPath = [...currentPath, `[${target}]`, ...remaining, fieldName];
|
|
113
|
+
try {
|
|
114
|
+
const fieldResolved = resolvePath(schema, session.operation, memberPath);
|
|
115
|
+
if (fieldResolved.isLeaf) {
|
|
116
|
+
selectLeaf(session, memberPath);
|
|
117
|
+
}
|
|
118
|
+
else if (isValueWrapperType(schema, fieldResolved.typeName)) {
|
|
119
|
+
selectLeaf(session, [...memberPath, "value"]);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
selectLeaf(session, memberPath);
|
|
123
|
+
}
|
|
124
|
+
matchedAny = true;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Field doesn't exist on this union member — skip it. A
|
|
128
|
+
// partial selection across members that DO have the field
|
|
129
|
+
// is more useful than failing the whole call.
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!matchedAny) {
|
|
133
|
+
// No union member exposed the requested field. Unlike the
|
|
134
|
+
// per-member skip above, this means the caller asked for
|
|
135
|
+
// something nothing can resolve — a silent no-op would
|
|
136
|
+
// render an empty selection set. Fail loudly so the caller
|
|
137
|
+
// can correct the field name.
|
|
138
|
+
throw new Error(`Field "${[...remaining, fieldName].join(".")}" not found on any member of union ` +
|
|
139
|
+
`${resolved.type.name} (members: ${targets.join(", ")})`);
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const parentPath = [...basePath, ...parts];
|
|
144
|
+
selectScalarOrValue(session, schema, parentPath, fieldName);
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=path-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-selection.js","sourceRoot":"","sources":["../../src/lib/path-selection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
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 OrgAuth } from "./auth.js";
|
|
7
|
+
import { type SchemaMetadata } from "./introspect.js";
|
|
8
|
+
/**
|
|
9
|
+
* Acquire a filesystem advisory lock at `${finalPath}.lock` (a directory,
|
|
10
|
+
* since `mkdir` is atomic on POSIX), run `work`, then release the lock.
|
|
11
|
+
*
|
|
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`.
|
|
17
|
+
*
|
|
18
|
+
* Contract: `work` will NOT run when `finalPath` exists at any point during
|
|
19
|
+
* the lock dance — including immediately after we acquire the lock (a holder
|
|
20
|
+
* may have finished and released the lock between our last EEXIST poll and
|
|
21
|
+
* our successful `mkdir`). In that case the lock is released and the
|
|
22
|
+
* function returns `undefined`.
|
|
23
|
+
*
|
|
24
|
+
* Stale locks (older than STALE_LOCK_MS) are reclaimed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function withSchemaLock<T>(finalPath: string, work: () => Promise<T>): Promise<T | undefined>;
|
|
27
|
+
export interface PrimeResult {
|
|
28
|
+
cached: boolean;
|
|
29
|
+
filePath: string;
|
|
30
|
+
durationMs: number;
|
|
31
|
+
/** Resolved instance URL (already auth-resolved). */
|
|
32
|
+
instanceUrl: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Dependencies that `primeSchemaWithLock` calls. Defaulted to the real
|
|
36
|
+
* graphiti implementations; tests pass stubs.
|
|
37
|
+
*/
|
|
38
|
+
export interface PrimeDeps {
|
|
39
|
+
getOrgAuth: (orgAlias: string) => Promise<OrgAuth>;
|
|
40
|
+
downloadSchema: (auth: OrgAuth) => Promise<SchemaMetadata>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Lazily prime the on-disk schema cache for `orgAlias`.
|
|
44
|
+
*
|
|
45
|
+
* - If `<HOME>/.graphiti/schemas/<hash>.json` already exists, returns
|
|
46
|
+
* `{cached: true}` immediately.
|
|
47
|
+
* - Otherwise: resolves auth via `deps.getOrgAuth` (throws verbatim if the
|
|
48
|
+
* alias is not authenticated, per FR-13.5), acquires the schema lock via
|
|
49
|
+
* `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.
|
|
54
|
+
*
|
|
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).
|
|
58
|
+
*/
|
|
59
|
+
export declare function primeSchemaWithLock(orgAlias: string, deps?: PrimeDeps): Promise<PrimeResult>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { getOrgAuth as realGetOrgAuth } from "./auth.js";
|
|
9
|
+
import { downloadSchema as realDownloadSchema, normalizeInstanceUrl, schemaCacheKeyForInstanceUrl, schemaDir, } from "./introspect.js";
|
|
10
|
+
// FR-13.7 originally suggested a 10-30s introspection budget. Empirical
|
|
11
|
+
// smoke testing against real Salesforce UIAPI schemas measures ~135s for
|
|
12
|
+
// a ~40MB introspection. We size the stale-lock threshold and the waiter
|
|
13
|
+
// timeout for ~3× that observed worst case (~7 min): comfortable headroom
|
|
14
|
+
// for normal operation while keeping crashed-holder recovery within a few
|
|
15
|
+
// minutes. If introspection ever legitimately exceeds 5 min the design
|
|
16
|
+
// assumption ("priming completes in minutes, not tens of minutes") has
|
|
17
|
+
// changed and these constants should be revisited together (likely with
|
|
18
|
+
// a heartbeat that refreshes the lock dir's mtime while held).
|
|
19
|
+
const STALE_LOCK_MS = 7 * 60_000;
|
|
20
|
+
const POLL_MS = 100;
|
|
21
|
+
const MAX_WAIT_MS = 7 * 60_000;
|
|
22
|
+
/**
|
|
23
|
+
* Acquire a filesystem advisory lock at `${finalPath}.lock` (a directory,
|
|
24
|
+
* since `mkdir` is atomic on POSIX), run `work`, then release the lock.
|
|
25
|
+
*
|
|
26
|
+
* If another process holds the lock, this polls every 100ms for the lock
|
|
27
|
+
* to be released. On release, if `finalPath` now exists, the work function
|
|
28
|
+
* is skipped (the other process already did it). If `finalPath` still does
|
|
29
|
+
* not exist (the other process aborted without writing), this acquires the
|
|
30
|
+
* lock and runs `work`.
|
|
31
|
+
*
|
|
32
|
+
* Contract: `work` will NOT run when `finalPath` exists at any point during
|
|
33
|
+
* the lock dance — including immediately after we acquire the lock (a holder
|
|
34
|
+
* may have finished and released the lock between our last EEXIST poll and
|
|
35
|
+
* our successful `mkdir`). In that case the lock is released and the
|
|
36
|
+
* function returns `undefined`.
|
|
37
|
+
*
|
|
38
|
+
* Stale locks (older than STALE_LOCK_MS) are reclaimed.
|
|
39
|
+
*/
|
|
40
|
+
export async function withSchemaLock(finalPath, work) {
|
|
41
|
+
const lockPath = `${finalPath}.lock`;
|
|
42
|
+
fs.mkdirSync(path.dirname(finalPath), { recursive: true });
|
|
43
|
+
const startedWaitingAt = Date.now();
|
|
44
|
+
while (true) {
|
|
45
|
+
try {
|
|
46
|
+
fs.mkdirSync(lockPath); // atomic; throws EEXIST if held
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
const err = e;
|
|
51
|
+
if (err.code !== "EEXIST")
|
|
52
|
+
throw e;
|
|
53
|
+
// If the cache exists now, another holder finished — short-circuit.
|
|
54
|
+
if (fs.existsSync(finalPath))
|
|
55
|
+
return undefined;
|
|
56
|
+
// Stale-lock reclaim. Known TOCTOU: between this `statSync` and
|
|
57
|
+
// the `rmSync` below, another process may have already reclaimed
|
|
58
|
+
// the stale lock and re-created a fresh one — in which case we'd
|
|
59
|
+
// remove the fresh lock. Window is microseconds and the next
|
|
60
|
+
// `mkdirSync` retry self-heals (we'd re-acquire or re-block);
|
|
61
|
+
// not worth fcntl-level locking to close.
|
|
62
|
+
try {
|
|
63
|
+
const stat = fs.statSync(lockPath);
|
|
64
|
+
if (Date.now() - stat.mtimeMs > STALE_LOCK_MS) {
|
|
65
|
+
// Recursive removal: a stray file inside the lock dir
|
|
66
|
+
// (e.g. macOS `.DS_Store`) would make `rmdirSync` throw
|
|
67
|
+
// ENOTEMPTY, which the bare catch below would swallow,
|
|
68
|
+
// leaving the stale lock in place.
|
|
69
|
+
fs.rmSync(lockPath, { recursive: true });
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Lock vanished between EEXIST and stat — loop and retry mkdir.
|
|
75
|
+
}
|
|
76
|
+
if (Date.now() - startedWaitingAt > MAX_WAIT_MS) {
|
|
77
|
+
throw new Error(`Timed out waiting ${MAX_WAIT_MS}ms for schema priming lock at ${lockPath}`);
|
|
78
|
+
}
|
|
79
|
+
await new Promise((r) => setTimeout(r, POLL_MS));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// We now hold the lock. Re-check for the cache: a holder that finished
|
|
83
|
+
// between our last EEXIST poll and our successful mkdir may have just
|
|
84
|
+
// primed it. Avoid running `work` redundantly.
|
|
85
|
+
if (fs.existsSync(finalPath)) {
|
|
86
|
+
try {
|
|
87
|
+
fs.rmSync(lockPath, { recursive: true });
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// best-effort
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
return await work();
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
// Recursive remove tolerates stray files inside the lock dir (e.g.
|
|
99
|
+
// macOS `.DS_Store`) that would otherwise make `rmdirSync` throw
|
|
100
|
+
// ENOTEMPTY and leak the lock until the 7-min stale timeout.
|
|
101
|
+
try {
|
|
102
|
+
fs.rmSync(lockPath, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Already gone — fine.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const REAL_DEPS = {
|
|
110
|
+
getOrgAuth: realGetOrgAuth,
|
|
111
|
+
downloadSchema: realDownloadSchema,
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Lazily prime the on-disk schema cache for `orgAlias`.
|
|
115
|
+
*
|
|
116
|
+
* - If `<HOME>/.graphiti/schemas/<hash>.json` already exists, returns
|
|
117
|
+
* `{cached: true}` immediately.
|
|
118
|
+
* - Otherwise: resolves auth via `deps.getOrgAuth` (throws verbatim if the
|
|
119
|
+
* alias is not authenticated, per FR-13.5), acquires the schema lock via
|
|
120
|
+
* `withSchemaLock`, calls `deps.downloadSchema(auth)` (which writes the
|
|
121
|
+
* cache atomically via `downloadSchema`'s internal use of
|
|
122
|
+
* `atomicWriteJson`), releases the lock, and returns
|
|
123
|
+
* `{cached: false, durationMs}`. Per FR-13.6, partial caches never reach
|
|
124
|
+
* disk because writes are atomic.
|
|
125
|
+
*
|
|
126
|
+
* Concurrent callers in the same or different processes serialize on the
|
|
127
|
+
* lock dir; only one performs introspection. Subsequent waiters observe
|
|
128
|
+
* the primed cache and short-circuit (FR-13.4).
|
|
129
|
+
*/
|
|
130
|
+
export async function primeSchemaWithLock(orgAlias, deps = REAL_DEPS) {
|
|
131
|
+
// We must call `deps.getOrgAuth` first because it is the only injected
|
|
132
|
+
// source of the org's `instanceUrl`, which the cache key is derived from.
|
|
133
|
+
// In tests this returns a stub; in production it is memoized inside
|
|
134
|
+
// `auth.ts`'s in-process cache, so the org is resolved via `@salesforce/core`
|
|
135
|
+
// at most once per org alias per process.
|
|
136
|
+
const auth = await deps.getOrgAuth(orgAlias);
|
|
137
|
+
const instanceUrl = normalizeInstanceUrl(auth.instanceUrl);
|
|
138
|
+
const cacheKey = schemaCacheKeyForInstanceUrl(instanceUrl);
|
|
139
|
+
const filePath = path.join(schemaDir(), `${cacheKey}.json`);
|
|
140
|
+
if (fs.existsSync(filePath)) {
|
|
141
|
+
return { cached: true, filePath, durationMs: 0, instanceUrl };
|
|
142
|
+
}
|
|
143
|
+
const start = Date.now();
|
|
144
|
+
let primed = false;
|
|
145
|
+
await withSchemaLock(filePath, async () => {
|
|
146
|
+
// withSchemaLock re-checks `finalPath` after acquire and short-
|
|
147
|
+
// circuits if it now exists, so when our work runs we know we
|
|
148
|
+
// must do the introspection.
|
|
149
|
+
await deps.downloadSchema(auth);
|
|
150
|
+
primed = true;
|
|
151
|
+
});
|
|
152
|
+
if (!primed) {
|
|
153
|
+
// Another process primed while we were waiting.
|
|
154
|
+
return { cached: true, filePath, durationMs: Date.now() - start, instanceUrl };
|
|
155
|
+
}
|
|
156
|
+
return { cached: false, filePath, durationMs: Date.now() - start, instanceUrl };
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=prime-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prime-schema.js","sourceRoot":"","sources":["../../src/lib/prime-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
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 { QuerySession } from "./session.js";
|
|
7
|
+
/**
|
|
8
|
+
* Renders a QuerySession's selection tree into a properly formatted GraphQL query string.
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderQuery(session: QuerySession): string;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
import { getChildren, getEffectiveArgs } from "./session.js";
|
|
7
|
+
/**
|
|
8
|
+
* Renders a QuerySession's selection tree into a properly formatted GraphQL query string.
|
|
9
|
+
*/
|
|
10
|
+
export function renderQuery(session) {
|
|
11
|
+
const parts = [];
|
|
12
|
+
// Operation line with variables
|
|
13
|
+
const varDefs = session.variables.length > 0
|
|
14
|
+
? `(${session.variables
|
|
15
|
+
.map((v) => {
|
|
16
|
+
let def = `$${v.name}: ${v.type}`;
|
|
17
|
+
if (v.defaultValue !== undefined)
|
|
18
|
+
def += ` = ${v.defaultValue}`;
|
|
19
|
+
return def;
|
|
20
|
+
})
|
|
21
|
+
.join(", ")})`
|
|
22
|
+
: "";
|
|
23
|
+
const operationKeyword = session.operation === "aggregate" ? "query" : session.operation;
|
|
24
|
+
const operationName = session.operationName ? ` ${session.operationName}` : "";
|
|
25
|
+
const operationBody = renderChildren(session, null, 1);
|
|
26
|
+
if (operationBody) {
|
|
27
|
+
parts.push(`${operationKeyword}${operationName}${varDefs} {`);
|
|
28
|
+
parts.push(operationBody);
|
|
29
|
+
parts.push("}");
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
parts.push(`${operationKeyword}${operationName}${varDefs} { }`);
|
|
33
|
+
}
|
|
34
|
+
return parts.join("\n");
|
|
35
|
+
}
|
|
36
|
+
function renderChildren(session, parentId, depth) {
|
|
37
|
+
const _indent = " ".repeat(depth);
|
|
38
|
+
const lines = [];
|
|
39
|
+
for (const child of getChildren(session, parentId)) {
|
|
40
|
+
if (child.kind === "field") {
|
|
41
|
+
lines.push(renderField(session, child, depth));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
lines.push(renderInlineFragment(session, child, depth));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return lines.join("\n");
|
|
48
|
+
}
|
|
49
|
+
function renderField(session, node, depth) {
|
|
50
|
+
const indent = " ".repeat(depth);
|
|
51
|
+
let line = indent;
|
|
52
|
+
// Alias
|
|
53
|
+
if (node.alias) {
|
|
54
|
+
line += `${node.alias}: `;
|
|
55
|
+
}
|
|
56
|
+
line += node.fieldName;
|
|
57
|
+
// Arguments
|
|
58
|
+
const argEntries = Object.entries(getEffectiveArgs(session, node));
|
|
59
|
+
if (argEntries.length > 0) {
|
|
60
|
+
const argParts = argEntries.map(([name, value]) => {
|
|
61
|
+
return `${name}: ${formatArgValue(value)}`;
|
|
62
|
+
});
|
|
63
|
+
line += `(${argParts.join(", ")})`;
|
|
64
|
+
}
|
|
65
|
+
// Directives
|
|
66
|
+
for (const dir of node.directives) {
|
|
67
|
+
line += ` ${renderDirective(dir)}`;
|
|
68
|
+
}
|
|
69
|
+
// Sub-selections
|
|
70
|
+
const childNodes = getChildren(session, node.id);
|
|
71
|
+
const hasChildren = childNodes.length > 0;
|
|
72
|
+
if (hasChildren) {
|
|
73
|
+
const childContent = renderChildren(session, node.id, depth + 1);
|
|
74
|
+
line += ` {\n${childContent}\n${indent}}`;
|
|
75
|
+
}
|
|
76
|
+
return line;
|
|
77
|
+
}
|
|
78
|
+
function renderInlineFragment(session, frag, depth) {
|
|
79
|
+
const indent = " ".repeat(depth);
|
|
80
|
+
let line = `${indent}... on ${frag.onType}`;
|
|
81
|
+
for (const dir of frag.directives) {
|
|
82
|
+
line += ` ${renderDirective(dir)}`;
|
|
83
|
+
}
|
|
84
|
+
const childContent = renderChildren(session, frag.id, depth + 1);
|
|
85
|
+
if (childContent) {
|
|
86
|
+
line += ` {\n${childContent}\n${indent}}`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
line += " { }";
|
|
90
|
+
}
|
|
91
|
+
return line;
|
|
92
|
+
}
|
|
93
|
+
function renderDirective(dir) {
|
|
94
|
+
const argEntries = Object.entries(dir.args);
|
|
95
|
+
if (argEntries.length === 0) {
|
|
96
|
+
return `@${dir.name}`;
|
|
97
|
+
}
|
|
98
|
+
const argParts = argEntries.map(([name, value]) => `${name}: ${formatArgValue(value)}`);
|
|
99
|
+
return `@${dir.name}(${argParts.join(", ")})`;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Formats an argument value for rendering in GraphQL.
|
|
103
|
+
* Handles variable references ($varName), raw JSON objects, numbers, booleans, and strings.
|
|
104
|
+
*/
|
|
105
|
+
function formatArgValue(value) {
|
|
106
|
+
const trimmed = value.trim();
|
|
107
|
+
// Variable reference
|
|
108
|
+
if (trimmed.startsWith("$"))
|
|
109
|
+
return trimmed;
|
|
110
|
+
// Numeric
|
|
111
|
+
if (/^-?\d+(\.\d+)?$/.test(trimmed))
|
|
112
|
+
return trimmed;
|
|
113
|
+
// Boolean / null
|
|
114
|
+
if (trimmed === "true" || trimmed === "false" || trimmed === "null")
|
|
115
|
+
return trimmed;
|
|
116
|
+
// Enum value (unquoted identifier)
|
|
117
|
+
if (/^[A-Z_][A-Z0-9_]*$/i.test(trimmed) && trimmed === trimmed.toUpperCase())
|
|
118
|
+
return trimmed;
|
|
119
|
+
// JSON object or array — convert to GraphQL literal syntax
|
|
120
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
121
|
+
return jsonToGraphQL(trimmed);
|
|
122
|
+
}
|
|
123
|
+
// Quoted string — pass through
|
|
124
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"'))
|
|
125
|
+
return trimmed;
|
|
126
|
+
// Default: wrap in quotes
|
|
127
|
+
return `"${trimmed.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Converts a JSON string to GraphQL object literal syntax.
|
|
131
|
+
* GraphQL uses unquoted keys: { Status: { ne: "Closed" } }
|
|
132
|
+
*/
|
|
133
|
+
function jsonToGraphQL(jsonStr) {
|
|
134
|
+
try {
|
|
135
|
+
const parsed = JSON.parse(jsonStr);
|
|
136
|
+
return valueToGraphQL(parsed);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// If not valid JSON, return as-is (might already be in GraphQL format)
|
|
140
|
+
return jsonStr;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function valueToGraphQL(value) {
|
|
144
|
+
if (value === null || value === undefined)
|
|
145
|
+
return "null";
|
|
146
|
+
if (typeof value === "boolean")
|
|
147
|
+
return String(value);
|
|
148
|
+
if (typeof value === "number")
|
|
149
|
+
return String(value);
|
|
150
|
+
if (typeof value === "string") {
|
|
151
|
+
if (value.startsWith("$"))
|
|
152
|
+
return value;
|
|
153
|
+
// Emit uppercase identifiers as bare enum tokens (e.g. DESC, ASC, EVERYTHING)
|
|
154
|
+
if (/^[A-Z_][A-Z0-9_]*$/.test(value))
|
|
155
|
+
return value;
|
|
156
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
157
|
+
}
|
|
158
|
+
if (Array.isArray(value)) {
|
|
159
|
+
return `[${value.map(valueToGraphQL).join(", ")}]`;
|
|
160
|
+
}
|
|
161
|
+
if (typeof value === "object") {
|
|
162
|
+
const entries = Object.entries(value);
|
|
163
|
+
const parts = entries.map(([k, v]) => `${k}: ${valueToGraphQL(v)}`);
|
|
164
|
+
return `{ ${parts.join(", ")} }`;
|
|
165
|
+
}
|
|
166
|
+
return String(value);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=query-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-builder.js","sourceRoot":"","sources":["../../src/lib/query-builder.ts"],"names":[],"mappings":"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"}
|