@superblocksteam/sdk-api 2.0.119-next.0 → 2.0.119

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.
@@ -5,11 +5,8 @@
5
5
  * Handles proto message construction and response validation.
6
6
  */
7
7
 
8
- import type { PartialMessage } from "@bufbuild/protobuf";
9
8
  import { z } from "zod";
10
9
 
11
- import type { Property } from "@superblocksteam/types/dist/src/common/v1/plugin_pb";
12
-
13
10
  import { RestApiValidationError } from "../../errors.js";
14
11
  import type { QueryExecutor, TraceMetadata } from "../registry.js";
15
12
  import type { IntegrationConfig, IntegrationClientImpl } from "../types.js";
@@ -22,8 +19,6 @@ import type { IntegrationConfig, IntegrationClientImpl } from "../types.js";
22
19
  * - Executing queries and mutations through the orchestrator
23
20
  * - Required Zod schema validation on full GraphQL response
24
21
  * - Variables serialization for parameterized queries
25
- * - Optional per-request HTTP headers (in addition to any headers configured
26
- * on the integration)
27
22
  */
28
23
  export abstract class GraphQLIntegrationClient implements IntegrationClientImpl {
29
24
  readonly name: string;
@@ -45,7 +40,6 @@ export abstract class GraphQLIntegrationClient implements IntegrationClientImpl
45
40
  * @param schema - Zod schema for full response validation (REQUIRED)
46
41
  * @param variables - Optional variables for the query
47
42
  * @param metadata - Optional trace metadata for observability
48
- * @param headers - Optional HTTP headers to send with the request
49
43
  * @returns Validated query result
50
44
  */
51
45
  async query<TResponse>(
@@ -53,9 +47,8 @@ export abstract class GraphQLIntegrationClient implements IntegrationClientImpl
53
47
  schema: { response: z.ZodSchema<TResponse> },
54
48
  variables?: Record<string, unknown>,
55
49
  metadata?: TraceMetadata,
56
- headers?: Record<string, string>,
57
50
  ): Promise<TResponse> {
58
- return this.executeGraphQL(query, schema, variables, metadata, headers);
51
+ return this.executeGraphQL(query, schema, variables, metadata);
59
52
  }
60
53
 
61
54
  /**
@@ -65,7 +58,6 @@ export abstract class GraphQLIntegrationClient implements IntegrationClientImpl
65
58
  * @param schema - Zod schema for full response validation (REQUIRED)
66
59
  * @param variables - Optional variables for the mutation
67
60
  * @param metadata - Optional trace metadata for observability
68
- * @param headers - Optional HTTP headers to send with the request
69
61
  * @returns Validated mutation result
70
62
  */
71
63
  async mutation<TResponse>(
@@ -73,9 +65,8 @@ export abstract class GraphQLIntegrationClient implements IntegrationClientImpl
73
65
  schema: { response: z.ZodSchema<TResponse> },
74
66
  variables?: Record<string, unknown>,
75
67
  metadata?: TraceMetadata,
76
- headers?: Record<string, string>,
77
68
  ): Promise<TResponse> {
78
- return this.executeGraphQL(mutation, schema, variables, metadata, headers);
69
+ return this.executeGraphQL(mutation, schema, variables, metadata);
79
70
  }
80
71
 
81
72
  /**
@@ -89,17 +80,9 @@ export abstract class GraphQLIntegrationClient implements IntegrationClientImpl
89
80
  schema: { response: z.ZodSchema<TResponse> },
90
81
  variables?: Record<string, unknown>,
91
82
  metadata?: TraceMetadata,
92
- headers?: Record<string, string>,
93
83
  ): Promise<TResponse> {
94
- const headerProps: PartialMessage<Property>[] = [];
95
- if (headers) {
96
- for (const [key, value] of Object.entries(headers)) {
97
- headerProps.push({ key, value });
98
- }
99
- }
100
-
101
84
  // Build graphql.v1.Plugin proto message
102
- const request: Record<string, unknown> = {
85
+ const request = {
103
86
  body: queryString,
104
87
  custom: variables
105
88
  ? {
@@ -113,10 +96,6 @@ export abstract class GraphQLIntegrationClient implements IntegrationClientImpl
113
96
  failOnGraphqlErrors: true,
114
97
  };
115
98
 
116
- if (headerProps.length > 0) {
117
- request.headers = headerProps;
118
- }
119
-
120
99
  // Execute query through orchestrator
121
100
  const response = await this.executeQuery(request, undefined, metadata);
122
101
 
@@ -659,27 +659,7 @@ describe("resolveIntegrationDocumentation", () => {
659
659
  }
660
660
  });
661
661
 
662
- it("throws when overlay entry has neither versionRange nor sdkVersionRange", async () => {
663
- const integrationsDirectory = createPluginDocsFixture("dropbox", {
664
- "README.md": "base",
665
- "docs.manifest.json": JSON.stringify({
666
- overlays: [{ file: "overlays/01.md" }],
667
- }),
668
- });
669
-
670
- try {
671
- await expect(
672
- resolveIntegrationDocumentation("dropbox", {
673
- pluginVersion: "0.4.0",
674
- integrationsDirectory,
675
- }),
676
- ).rejects.toThrowError(/Invalid overlay entry/);
677
- } finally {
678
- rmSync(integrationsDirectory, { recursive: true, force: true });
679
- }
680
- });
681
-
682
- it("throws when overlay entry has empty versionRange and no sdkVersionRange", async () => {
662
+ it("throws when overlay entry has empty versionRange", async () => {
683
663
  const integrationsDirectory = createPluginDocsFixture("dropbox", {
684
664
  "README.md": "base",
685
665
  "docs.manifest.json": JSON.stringify({
@@ -700,144 +680,6 @@ describe("resolveIntegrationDocumentation", () => {
700
680
  });
701
681
  });
702
682
 
703
- describe("sdkVersionRange", () => {
704
- it("applies overlay when sdkVersion matches sdkVersionRange", async () => {
705
- const integrationsDirectory = createPluginDocsFixture("graphql", {
706
- "README.md": "base-graphql-docs",
707
- "docs.manifest.json": JSON.stringify({
708
- overlays: [
709
- { file: "overlays/headers.md", sdkVersionRange: ">=0.0.2" },
710
- ],
711
- }),
712
- "overlays/headers.md": "dynamic-headers-docs",
713
- });
714
-
715
- try {
716
- const docs = await resolveIntegrationDocumentation("graphql", {
717
- sdkVersion: "0.0.2",
718
- integrationsDirectory,
719
- });
720
- expect(docs).toBe("base-graphql-docs\n\ndynamic-headers-docs");
721
- } finally {
722
- rmSync(integrationsDirectory, { recursive: true, force: true });
723
- }
724
- });
725
-
726
- it("skips overlay when sdkVersion does not match sdkVersionRange", async () => {
727
- const integrationsDirectory = createPluginDocsFixture("graphql", {
728
- "README.md": "base-graphql-docs",
729
- "docs.manifest.json": JSON.stringify({
730
- overlays: [
731
- { file: "overlays/headers.md", sdkVersionRange: ">=0.0.2" },
732
- ],
733
- }),
734
- "overlays/headers.md": "dynamic-headers-docs",
735
- });
736
-
737
- try {
738
- const docs = await resolveIntegrationDocumentation("graphql", {
739
- sdkVersion: "0.0.1",
740
- integrationsDirectory,
741
- });
742
- expect(docs).toBe("base-graphql-docs");
743
- } finally {
744
- rmSync(integrationsDirectory, { recursive: true, force: true });
745
- }
746
- });
747
-
748
- it("skips overlay when sdkVersion is not provided", async () => {
749
- const integrationsDirectory = createPluginDocsFixture("graphql", {
750
- "README.md": "base-graphql-docs",
751
- "docs.manifest.json": JSON.stringify({
752
- overlays: [
753
- { file: "overlays/headers.md", sdkVersionRange: ">=0.0.2" },
754
- ],
755
- }),
756
- "overlays/headers.md": "dynamic-headers-docs",
757
- });
758
-
759
- try {
760
- const docs = await resolveIntegrationDocumentation("graphql", {
761
- pluginVersion: "0.0.10",
762
- integrationsDirectory,
763
- });
764
- expect(docs).toBe("base-graphql-docs");
765
- } finally {
766
- rmSync(integrationsDirectory, { recursive: true, force: true });
767
- }
768
- });
769
-
770
- it("requires both versionRange and sdkVersionRange to match when both are specified", async () => {
771
- const integrationsDirectory = createPluginDocsFixture("graphql", {
772
- "README.md": "base",
773
- "docs.manifest.json": JSON.stringify({
774
- overlays: [
775
- {
776
- file: "overlays/both.md",
777
- versionRange: ">=0.0.10",
778
- sdkVersionRange: ">=0.0.2",
779
- },
780
- ],
781
- }),
782
- "overlays/both.md": "both-match-overlay",
783
- });
784
-
785
- try {
786
- // Both match
787
- expect(
788
- await resolveIntegrationDocumentation("graphql", {
789
- pluginVersion: "0.0.10",
790
- sdkVersion: "0.0.2",
791
- integrationsDirectory,
792
- }),
793
- ).toBe("base\n\nboth-match-overlay");
794
-
795
- // Only plugin matches
796
- expect(
797
- await resolveIntegrationDocumentation("graphql", {
798
- pluginVersion: "0.0.10",
799
- sdkVersion: "0.0.1",
800
- integrationsDirectory,
801
- }),
802
- ).toBe("base");
803
-
804
- // Only sdk matches
805
- expect(
806
- await resolveIntegrationDocumentation("graphql", {
807
- pluginVersion: "0.0.9",
808
- sdkVersion: "0.0.2",
809
- integrationsDirectory,
810
- }),
811
- ).toBe("base");
812
- } finally {
813
- rmSync(integrationsDirectory, { recursive: true, force: true });
814
- }
815
- });
816
-
817
- it("allows overlay with only sdkVersionRange (no versionRange)", async () => {
818
- const integrationsDirectory = createPluginDocsFixture("graphql", {
819
- "README.md": "base",
820
- "docs.manifest.json": JSON.stringify({
821
- overlays: [
822
- { file: "overlays/sdk-only.md", sdkVersionRange: ">=0.0.2" },
823
- ],
824
- }),
825
- "overlays/sdk-only.md": "sdk-gated-overlay",
826
- });
827
-
828
- try {
829
- // No pluginVersion needed — only sdkVersion matters
830
- const docs = await resolveIntegrationDocumentation("graphql", {
831
- sdkVersion: "0.0.3",
832
- integrationsDirectory,
833
- });
834
- expect(docs).toBe("base\n\nsdk-gated-overlay");
835
- } finally {
836
- rmSync(integrationsDirectory, { recursive: true, force: true });
837
- }
838
- });
839
- });
840
-
841
683
  it("blocks overlay paths outside the plugin directory", async () => {
842
684
  const integrationsDirectory = createPluginDocsFixture("dropbox", {
843
685
  "README.md": "base",
@@ -11,13 +11,7 @@ const DOC_DIRECTORY_ALIASES = {
11
11
 
12
12
  interface DocumentationOverlay {
13
13
  file: string;
14
- versionRange?: string;
15
- /** When set, checks against the sdk-api version ("javascriptsdkapi") running
16
- * in the orchestrator instead of the plugin-specific version. Use this to
17
- * gate overlays on sdk-api features that ship independently of plugin
18
- * version bumps. Both versionRange and sdkVersionRange can be specified
19
- * together — the overlay is applied only when all specified ranges match. */
20
- sdkVersionRange?: string;
14
+ versionRange: string;
21
15
  }
22
16
 
23
17
  interface DocumentationManifest {
@@ -38,7 +32,6 @@ type OverlayOperation =
38
32
 
39
33
  export interface ResolveIntegrationDocumentationOptions {
40
34
  pluginVersion?: SemVer;
41
- sdkVersion?: SemVer;
42
35
  integrationsDirectory?: string;
43
36
  }
44
37
 
@@ -89,17 +82,16 @@ async function parseDocumentationManifest(
89
82
  typeof overlay !== "object" ||
90
83
  overlay === null ||
91
84
  !("file" in overlay) ||
92
- (!("versionRange" in overlay) && !("sdkVersionRange" in overlay))
85
+ !("versionRange" in overlay)
93
86
  ) {
94
87
  throw new Error(
95
88
  `Invalid overlay entry at index ${index} in ${manifestPath}.`,
96
89
  );
97
90
  }
98
91
 
99
- const { file, versionRange, sdkVersionRange } = overlay as {
92
+ const { file, versionRange } = overlay as {
100
93
  file: unknown;
101
94
  versionRange: unknown;
102
- sdkVersionRange: unknown;
103
95
  };
104
96
 
105
97
  if (typeof file !== "string" || file.trim().length === 0) {
@@ -107,35 +99,18 @@ async function parseDocumentationManifest(
107
99
  `Invalid "file" for overlay index ${index} in ${manifestPath}.`,
108
100
  );
109
101
  }
110
-
111
- const hasVersionRange =
112
- typeof versionRange === "string" && versionRange.trim().length > 0;
113
- const hasSdkVersionRange =
114
- typeof sdkVersionRange === "string" &&
115
- sdkVersionRange.trim().length > 0;
116
-
117
- if ("versionRange" in overlay && !hasVersionRange) {
102
+ if (
103
+ typeof versionRange !== "string" ||
104
+ versionRange.trim().length === 0
105
+ ) {
118
106
  throw new Error(
119
107
  `Invalid "versionRange" for overlay index ${index} in ${manifestPath}.`,
120
108
  );
121
109
  }
122
- if ("sdkVersionRange" in overlay && !hasSdkVersionRange) {
123
- throw new Error(
124
- `Invalid "sdkVersionRange" for overlay index ${index} in ${manifestPath}.`,
125
- );
126
- }
127
- if (!hasVersionRange && !hasSdkVersionRange) {
128
- throw new Error(
129
- `Overlay at index ${index} in ${manifestPath} must specify at least one of "versionRange" or "sdkVersionRange".`,
130
- );
131
- }
132
110
 
133
111
  return {
134
112
  file,
135
- ...(hasVersionRange ? { versionRange: versionRange as string } : {}),
136
- ...(hasSdkVersionRange
137
- ? { sdkVersionRange: sdkVersionRange as string }
138
- : {}),
113
+ versionRange,
139
114
  };
140
115
  },
141
116
  );
@@ -405,38 +380,11 @@ function ensureOverlayPathIsWithinPluginDir(
405
380
  }
406
381
  }
407
382
 
408
- function overlayMatchesVersions(
409
- overlay: DocumentationOverlay,
410
- pluginVersion: SemVer | undefined,
411
- sdkVersion: SemVer | undefined,
412
- ): boolean {
413
- if (
414
- overlay.versionRange &&
415
- (!pluginVersion ||
416
- !versionMatchesRange(pluginVersion, overlay.versionRange))
417
- ) {
418
- return false;
419
- }
420
-
421
- if (
422
- overlay.sdkVersionRange &&
423
- (!sdkVersion || !versionMatchesRange(sdkVersion, overlay.sdkVersionRange))
424
- ) {
425
- return false;
426
- }
427
-
428
- return true;
429
- }
430
-
431
383
  export async function resolveIntegrationDocumentation(
432
384
  pluginId: string,
433
385
  options: ResolveIntegrationDocumentationOptions = {},
434
386
  ): Promise<string> {
435
- const {
436
- pluginVersion,
437
- sdkVersion,
438
- integrationsDirectory = INTEGRATIONS_DIR,
439
- } = options;
387
+ const { pluginVersion, integrationsDirectory = INTEGRATIONS_DIR } = options;
440
388
 
441
389
  const pluginDirectory = resolve(
442
390
  integrationsDirectory,
@@ -449,13 +397,13 @@ export async function resolveIntegrationDocumentation(
449
397
  const baseDocumentationPath = resolve(pluginDirectory, baseFileName);
450
398
  const baseDocumentation = await readFile(baseDocumentationPath, "utf8");
451
399
 
452
- if (!manifest) {
400
+ if (!manifest || !pluginVersion) {
453
401
  return baseDocumentation;
454
402
  }
455
403
 
456
404
  let resolvedDocumentation = baseDocumentation;
457
405
  for (const overlay of manifest.overlays) {
458
- if (!overlayMatchesVersions(overlay, pluginVersion, sdkVersion)) {
406
+ if (!versionMatchesRange(pluginVersion, overlay.versionRange)) {
459
407
  continue;
460
408
  }
461
409
 
@@ -1,10 +1,5 @@
1
1
  {
2
2
  "pluginId": "graphql",
3
3
  "base": "README.md",
4
- "overlays": [
5
- {
6
- "file": "overlays/dynamic-headers.md",
7
- "sdkVersionRange": ">=0.0.2"
8
- }
9
- ]
4
+ "overlays": []
10
5
  }
@@ -62,17 +62,6 @@ import type { TraceMetadata } from "../registry.js";
62
62
  * { response: MutationResponseSchema },
63
63
  * { name: 'John Doe' }
64
64
  * );
65
- *
66
- * // Send per-request headers (e.g. a dynamic Authorization token).
67
- * // Static headers and auth configured on the integration apply automatically;
68
- * // use this parameter only for values that vary per request.
69
- * await graphql.query(
70
- * `query { me { id } }`,
71
- * { response: z.object({ data: z.object({ me: z.object({ id: z.string() }) }) }) },
72
- * undefined,
73
- * undefined,
74
- * { Authorization: `Bearer ${token}` },
75
- * );
76
65
  * ```
77
66
  */
78
67
  export interface GraphQLClient extends BaseIntegrationClient {
@@ -85,10 +74,6 @@ export interface GraphQLClient extends BaseIntegrationClient {
85
74
  * `metadata` accept plain objects, pass `undefined` for variables when you only need metadata:
86
75
  * `query(q, schema, undefined, { label: "..." })`
87
76
  * @param metadata - Optional trace metadata for observability
88
- * @param headers - Optional HTTP headers to include on this request. Static
89
- * headers and auth configured on the integration apply automatically; use
90
- * this parameter only for values that vary per request (e.g. a bearer token
91
- * derived from the API's input).
92
77
  * @returns Validated query result
93
78
  *
94
79
  * @example
@@ -110,7 +95,6 @@ export interface GraphQLClient extends BaseIntegrationClient {
110
95
  schema: { response: z.ZodSchema<TResponse> },
111
96
  variables?: Record<string, unknown>,
112
97
  metadata?: TraceMetadata,
113
- headers?: Record<string, string>,
114
98
  ): Promise<TResponse>;
115
99
 
116
100
  /**
@@ -122,10 +106,6 @@ export interface GraphQLClient extends BaseIntegrationClient {
122
106
  * `metadata` accept plain objects, pass `undefined` for variables when you only need metadata:
123
107
  * `mutation(m, schema, undefined, { label: "..." })`
124
108
  * @param metadata - Optional trace metadata for observability
125
- * @param headers - Optional HTTP headers to include on this request. Static
126
- * headers and auth configured on the integration apply automatically; use
127
- * this parameter only for values that vary per request (e.g. a bearer token
128
- * derived from the API's input).
129
109
  * @returns Validated mutation result
130
110
  *
131
111
  * @example
@@ -148,6 +128,5 @@ export interface GraphQLClient extends BaseIntegrationClient {
148
128
  schema: { response: z.ZodSchema<TResponse> },
149
129
  variables?: Record<string, unknown>,
150
130
  metadata?: TraceMetadata,
151
- headers?: Record<string, string>,
152
131
  ): Promise<TResponse>;
153
132
  }
@@ -1,15 +0,0 @@
1
- /**
2
- * Tests for GraphQLClientImpl.
3
- *
4
- * Validates:
5
- * - The proto request built by query()/mutation() matches the
6
- * graphql.v1.Plugin shape expected by the orchestrator.
7
- * - Optional per-request headers are forwarded as the proto's repeated
8
- * `headers` field (key/value Property entries) so dynamic values like
9
- * Authorization tokens can be sent from API code.
10
- * - Variables are serialized into the proto `custom.variables` Property.
11
- * - Trace metadata is passed through to the executeQuery callback.
12
- * - Response Zod validation throws RestApiValidationError on mismatch.
13
- */
14
- export {};
15
- //# sourceMappingURL=client.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../../src/integrations/graphql/client.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -1,148 +0,0 @@
1
- /**
2
- * Tests for GraphQLClientImpl.
3
- *
4
- * Validates:
5
- * - The proto request built by query()/mutation() matches the
6
- * graphql.v1.Plugin shape expected by the orchestrator.
7
- * - Optional per-request headers are forwarded as the proto's repeated
8
- * `headers` field (key/value Property entries) so dynamic values like
9
- * Authorization tokens can be sent from API code.
10
- * - Variables are serialized into the proto `custom.variables` Property.
11
- * - Trace metadata is passed through to the executeQuery callback.
12
- * - Response Zod validation throws RestApiValidationError on mismatch.
13
- */
14
- import { describe, it, expect, vi } from "vitest";
15
- import { z } from "zod";
16
- import { RestApiValidationError } from "../../errors.js";
17
- import { GraphQLClientImpl } from "./client.js";
18
- const TEST_CONFIG = {
19
- id: "graphql-test-id",
20
- name: "Test GraphQL",
21
- pluginId: "graphqlintegration",
22
- configuration: {},
23
- };
24
- function createClient(mockResult) {
25
- const executeQuery = vi.fn().mockResolvedValue(mockResult);
26
- const client = new GraphQLClientImpl(TEST_CONFIG, executeQuery);
27
- return { client, executeQuery };
28
- }
29
- const UserResponseSchema = z.object({
30
- data: z.object({
31
- user: z.object({
32
- id: z.string(),
33
- name: z.string(),
34
- }),
35
- }),
36
- });
37
- const SAMPLE_QUERY = `query GetUser($id: ID!) {
38
- user(id: $id) { id name }
39
- }`;
40
- const SAMPLE_MUTATION = `mutation CreateUser($name: String!) {
41
- createUser(name: $name) { id name }
42
- }`;
43
- describe("GraphQLClientImpl", () => {
44
- describe("query()", () => {
45
- it("returns validated data on a successful response", async () => {
46
- const { client } = createClient({
47
- data: { user: { id: "u1", name: "Alice" } },
48
- });
49
- const result = await client.query(SAMPLE_QUERY, { response: UserResponseSchema }, { id: "u1" });
50
- expect(result.data.user).toEqual({ id: "u1", name: "Alice" });
51
- });
52
- it("builds the proto request with body, variables, and defaults", async () => {
53
- const { client, executeQuery } = createClient({
54
- data: { user: { id: "u1", name: "Alice" } },
55
- });
56
- await client.query(SAMPLE_QUERY, { response: UserResponseSchema }, { id: "u1" });
57
- expect(executeQuery).toHaveBeenCalledOnce();
58
- const request = executeQuery.mock.calls[0][0];
59
- expect(request.body).toBe(SAMPLE_QUERY);
60
- expect(request.verboseHttpOutput).toBe(false);
61
- expect(request.failOnGraphqlErrors).toBe(true);
62
- expect(request.custom).toEqual({
63
- variables: {
64
- key: "variables",
65
- value: JSON.stringify({ id: "u1" }),
66
- },
67
- });
68
- expect(request.headers).toBeUndefined();
69
- });
70
- it("omits custom when no variables are provided", async () => {
71
- const { client, executeQuery } = createClient({
72
- data: { user: { id: "u1", name: "Alice" } },
73
- });
74
- await client.query(SAMPLE_QUERY, { response: UserResponseSchema });
75
- const request = executeQuery.mock.calls[0][0];
76
- expect(request.custom).toBeUndefined();
77
- });
78
- it("forwards per-request headers into the proto headers field", async () => {
79
- const { client, executeQuery } = createClient({
80
- data: { user: { id: "u1", name: "Alice" } },
81
- });
82
- await client.query(SAMPLE_QUERY, { response: UserResponseSchema }, { id: "u1" }, undefined, {
83
- Authorization: "Bearer abc123",
84
- "X-Trace-Id": "trace-1",
85
- });
86
- const request = executeQuery.mock.calls[0][0];
87
- expect(request.headers).toEqual([
88
- { key: "Authorization", value: "Bearer abc123" },
89
- { key: "X-Trace-Id", value: "trace-1" },
90
- ]);
91
- });
92
- it("does not set headers when an empty headers object is passed", async () => {
93
- const { client, executeQuery } = createClient({
94
- data: { user: { id: "u1", name: "Alice" } },
95
- });
96
- await client.query(SAMPLE_QUERY, { response: UserResponseSchema }, undefined, undefined, {});
97
- const request = executeQuery.mock.calls[0][0];
98
- expect(request.headers).toBeUndefined();
99
- });
100
- it("passes trace metadata through to executeQuery", async () => {
101
- const { client, executeQuery } = createClient({
102
- data: { user: { id: "u1", name: "Alice" } },
103
- });
104
- await client.query(SAMPLE_QUERY, { response: UserResponseSchema }, undefined, { label: "graphql.getUser", description: "Fetch a user by id" });
105
- expect(executeQuery).toHaveBeenCalledWith(expect.any(Object), undefined, {
106
- label: "graphql.getUser",
107
- description: "Fetch a user by id",
108
- });
109
- });
110
- it("throws RestApiValidationError when the response fails schema validation", async () => {
111
- const { client } = createClient({
112
- data: { user: { id: "u1" /* missing name */ } },
113
- });
114
- await expect(client.query(SAMPLE_QUERY, { response: UserResponseSchema })).rejects.toThrow(RestApiValidationError);
115
- });
116
- });
117
- describe("mutation()", () => {
118
- it("returns validated data on a successful response", async () => {
119
- const { client } = createClient({
120
- data: { createUser: { id: "u2", name: "Bob" } },
121
- });
122
- const Schema = z.object({
123
- data: z.object({
124
- createUser: z.object({ id: z.string(), name: z.string() }),
125
- }),
126
- });
127
- const result = await client.mutation(SAMPLE_MUTATION, { response: Schema }, { name: "Bob" });
128
- expect(result.data.createUser).toEqual({ id: "u2", name: "Bob" });
129
- });
130
- it("forwards per-request headers into the proto headers field", async () => {
131
- const { client, executeQuery } = createClient({
132
- data: { createUser: { id: "u2", name: "Bob" } },
133
- });
134
- const Schema = z.object({
135
- data: z.object({
136
- createUser: z.object({ id: z.string(), name: z.string() }),
137
- }),
138
- });
139
- await client.mutation(SAMPLE_MUTATION, { response: Schema }, { name: "Bob" }, undefined, { Authorization: "Bearer xyz" });
140
- const request = executeQuery.mock.calls[0][0];
141
- expect(request.body).toBe(SAMPLE_MUTATION);
142
- expect(request.headers).toEqual([
143
- { key: "Authorization", value: "Bearer xyz" },
144
- ]);
145
- });
146
- });
147
- });
148
- //# sourceMappingURL=client.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../../src/integrations/graphql/client.test.ts"],"names":[],"mappings":"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"}