@glubean/graphql 0.1.3
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/dist/data.d.ts +37 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +41 -0
- package/dist/data.js.map +1 -0
- package/dist/index.d.ts +325 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +260 -0
- package/dist/index.js.map +1 -0
- package/package.json +29 -0
package/dist/data.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data loaders for GraphQL files.
|
|
3
|
+
*
|
|
4
|
+
* @module data
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Load a GraphQL query from a `.gql` or `.graphql` file.
|
|
8
|
+
*
|
|
9
|
+
* Using external `.gql` files instead of inline strings enables full IDE
|
|
10
|
+
* support: syntax highlighting, field autocomplete, and schema validation
|
|
11
|
+
* (when a `.graphqlrc` config points to your schema).
|
|
12
|
+
*
|
|
13
|
+
* @param path Path to the `.gql` / `.graphql` file, relative to project root
|
|
14
|
+
* @returns The query string (trimmed)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { fromGql } from "@glubean/graphql/data";
|
|
19
|
+
* import { graphql } from "@glubean/graphql";
|
|
20
|
+
* import { test, configure } from "@glubean/sdk";
|
|
21
|
+
*
|
|
22
|
+
* const GetUser = await fromGql("./queries/getUser.gql");
|
|
23
|
+
*
|
|
24
|
+
* const { gql } = configure({
|
|
25
|
+
* plugins: {
|
|
26
|
+
* gql: graphql({ endpoint: "{{graphql_url}}" }),
|
|
27
|
+
* },
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* export const getUser = test("get-user", async (ctx) => {
|
|
31
|
+
* const { data } = await gql.query(GetUser, { variables: { id: "1" } });
|
|
32
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function fromGql(path: string): Promise<string>;
|
|
37
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3D"}
|
package/dist/data.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data loaders for GraphQL files.
|
|
3
|
+
*
|
|
4
|
+
* @module data
|
|
5
|
+
*/
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
/**
|
|
8
|
+
* Load a GraphQL query from a `.gql` or `.graphql` file.
|
|
9
|
+
*
|
|
10
|
+
* Using external `.gql` files instead of inline strings enables full IDE
|
|
11
|
+
* support: syntax highlighting, field autocomplete, and schema validation
|
|
12
|
+
* (when a `.graphqlrc` config points to your schema).
|
|
13
|
+
*
|
|
14
|
+
* @param path Path to the `.gql` / `.graphql` file, relative to project root
|
|
15
|
+
* @returns The query string (trimmed)
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { fromGql } from "@glubean/graphql/data";
|
|
20
|
+
* import { graphql } from "@glubean/graphql";
|
|
21
|
+
* import { test, configure } from "@glubean/sdk";
|
|
22
|
+
*
|
|
23
|
+
* const GetUser = await fromGql("./queries/getUser.gql");
|
|
24
|
+
*
|
|
25
|
+
* const { gql } = configure({
|
|
26
|
+
* plugins: {
|
|
27
|
+
* gql: graphql({ endpoint: "{{graphql_url}}" }),
|
|
28
|
+
* },
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* export const getUser = test("get-user", async (ctx) => {
|
|
32
|
+
* const { data } = await gql.query(GetUser, { variables: { id: "1" } });
|
|
33
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export async function fromGql(path) {
|
|
38
|
+
const content = await readFile(path, "utf-8");
|
|
39
|
+
return content.trim();
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=data.js.map
|
package/dist/data.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAY;IACxC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL plugin for Glubean tests.
|
|
3
|
+
*
|
|
4
|
+
* Provides a thin wrapper over `ctx.http` (or any `HttpClient`) that simplifies
|
|
5
|
+
* GraphQL query/mutation execution with auto-tracing, operationName extraction,
|
|
6
|
+
* and optional error-throwing behavior.
|
|
7
|
+
*
|
|
8
|
+
* ## Usage
|
|
9
|
+
*
|
|
10
|
+
* ### As a plugin via `configure()` (recommended)
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { test, configure } from "@glubean/sdk";
|
|
14
|
+
* import { graphql } from "@glubean/graphql";
|
|
15
|
+
*
|
|
16
|
+
* const { gql } = configure({
|
|
17
|
+
* plugins: {
|
|
18
|
+
* gql: graphql({
|
|
19
|
+
* endpoint: "{{graphql_url}}",
|
|
20
|
+
* headers: { Authorization: "Bearer {{api_key}}" },
|
|
21
|
+
* }),
|
|
22
|
+
* },
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* export const getUser = test("get-user", async (ctx) => {
|
|
26
|
+
* const { data, errors } = await gql.query<{ user: { name: string } }>(`
|
|
27
|
+
* query GetUser($id: ID!) {
|
|
28
|
+
* user(id: $id) { name }
|
|
29
|
+
* }
|
|
30
|
+
* `, { variables: { id: "1" } });
|
|
31
|
+
*
|
|
32
|
+
* ctx.expect(errors).toBeUndefined();
|
|
33
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ### Standalone (without `configure()`)
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { test } from "@glubean/sdk";
|
|
41
|
+
* import { createGraphQLClient } from "@glubean/graphql";
|
|
42
|
+
*
|
|
43
|
+
* export const quick = test("quick-gql", async (ctx) => {
|
|
44
|
+
* const gql = createGraphQLClient(ctx.http, {
|
|
45
|
+
* endpoint: "https://api.example.com/graphql",
|
|
46
|
+
* });
|
|
47
|
+
* const { data } = await gql.query(`{ health }`);
|
|
48
|
+
* ctx.assert(data?.health === "ok", "Service healthy");
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @module graphql
|
|
53
|
+
*/
|
|
54
|
+
import type { HttpClient, PluginFactory } from "@glubean/sdk";
|
|
55
|
+
/**
|
|
56
|
+
* A single GraphQL error as defined by the
|
|
57
|
+
* [GraphQL spec](https://spec.graphql.org/October2021/#sec-Errors).
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* // Typical error shape from a GraphQL server
|
|
62
|
+
* {
|
|
63
|
+
* message: "User not found",
|
|
64
|
+
* locations: [{ line: 2, column: 3 }],
|
|
65
|
+
* path: ["user"],
|
|
66
|
+
* extensions: { code: "NOT_FOUND" }
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export interface GraphQLError {
|
|
71
|
+
/** Human-readable error description */
|
|
72
|
+
message: string;
|
|
73
|
+
/** Source locations in the query that caused this error */
|
|
74
|
+
locations?: {
|
|
75
|
+
line: number;
|
|
76
|
+
column: number;
|
|
77
|
+
}[];
|
|
78
|
+
/** Path to the field that produced the error */
|
|
79
|
+
path?: (string | number)[];
|
|
80
|
+
/** Server-defined extension data (e.g., error codes) */
|
|
81
|
+
extensions?: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Standard GraphQL response envelope.
|
|
85
|
+
*
|
|
86
|
+
* Per the spec, `data` is `null` when all requested fields errored,
|
|
87
|
+
* and `errors` is absent when there are no errors.
|
|
88
|
+
*
|
|
89
|
+
* @template T Shape of the `data` field
|
|
90
|
+
*/
|
|
91
|
+
export interface GraphQLResponse<T = unknown> {
|
|
92
|
+
/** The result of the query/mutation. `null` if all fields errored. */
|
|
93
|
+
data: T | null;
|
|
94
|
+
/** Array of errors, if any. Absent when no errors. */
|
|
95
|
+
errors?: GraphQLError[];
|
|
96
|
+
/** Optional server extensions (e.g., tracing, cost). */
|
|
97
|
+
extensions?: Record<string, unknown>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Options for a single GraphQL request.
|
|
101
|
+
*/
|
|
102
|
+
export interface GraphQLRequestOptions {
|
|
103
|
+
/** Variables to pass to the query/mutation */
|
|
104
|
+
variables?: Record<string, unknown>;
|
|
105
|
+
/**
|
|
106
|
+
* Explicit operationName. If omitted, the client parses the first named
|
|
107
|
+
* operation from the query string (e.g., `query GetUser` -> `"GetUser"`).
|
|
108
|
+
*/
|
|
109
|
+
operationName?: string;
|
|
110
|
+
/** Additional headers for this request only */
|
|
111
|
+
headers?: Record<string, string>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Options for creating a GraphQL client.
|
|
115
|
+
*/
|
|
116
|
+
export interface GraphQLClientOptions {
|
|
117
|
+
/** The GraphQL endpoint URL (e.g., "https://api.example.com/graphql") */
|
|
118
|
+
endpoint: string;
|
|
119
|
+
/** Default headers sent with every request */
|
|
120
|
+
headers?: Record<string, string>;
|
|
121
|
+
/**
|
|
122
|
+
* If `true`, the client throws a `GraphQLResponseError` when the response
|
|
123
|
+
* contains `errors`, even though the HTTP status is 200.
|
|
124
|
+
*
|
|
125
|
+
* Default: `false` -- errors are returned in the response object.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* const gql = createGraphQLClient(ctx.http, {
|
|
130
|
+
* endpoint: "https://api.example.com/graphql",
|
|
131
|
+
* throwOnGraphQLErrors: true,
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* try {
|
|
135
|
+
* const { data } = await gql.query(`{ me { name } }`);
|
|
136
|
+
* } catch (err) {
|
|
137
|
+
* if (err instanceof GraphQLResponseError) {
|
|
138
|
+
* console.log(err.errors); // GraphQLError[]
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
throwOnGraphQLErrors?: boolean;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Error thrown when a GraphQL response contains errors and
|
|
147
|
+
* `throwOnGraphQLErrors` is enabled.
|
|
148
|
+
*/
|
|
149
|
+
export declare class GraphQLResponseError extends Error {
|
|
150
|
+
/** The GraphQL errors from the response */
|
|
151
|
+
readonly errors: GraphQLError[];
|
|
152
|
+
/** The original response (may contain partial `data`) */
|
|
153
|
+
readonly response: GraphQLResponse;
|
|
154
|
+
constructor(errors: GraphQLError[], response: GraphQLResponse);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* A GraphQL client bound to a specific endpoint.
|
|
158
|
+
*
|
|
159
|
+
* All requests are auto-traced via the underlying `HttpClient`.
|
|
160
|
+
* The operation name is injected into traces via the `X-Glubean-Op` header,
|
|
161
|
+
* so the dashboard can distinguish between different GraphQL operations
|
|
162
|
+
* instead of showing a generic `POST /graphql`.
|
|
163
|
+
*/
|
|
164
|
+
export interface GraphQLClient {
|
|
165
|
+
/**
|
|
166
|
+
* Execute a GraphQL query.
|
|
167
|
+
*
|
|
168
|
+
* @template T Shape of the `data` field
|
|
169
|
+
* @param query The GraphQL query string
|
|
170
|
+
* @param options Variables, operationName, and extra headers
|
|
171
|
+
* @returns The parsed GraphQL response
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* const { data, errors } = await gql.query<{ users: User[] }>(`
|
|
176
|
+
* query ListUsers($limit: Int) {
|
|
177
|
+
* users(limit: $limit) { id name }
|
|
178
|
+
* }
|
|
179
|
+
* `, { variables: { limit: 10 } });
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
query<T = unknown>(query: string, options?: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;
|
|
183
|
+
/**
|
|
184
|
+
* Execute a GraphQL mutation.
|
|
185
|
+
*
|
|
186
|
+
* Functionally identical to `query()` -- the distinction is purely semantic
|
|
187
|
+
* to improve readability in test code.
|
|
188
|
+
*
|
|
189
|
+
* @template T Shape of the `data` field
|
|
190
|
+
* @param mutation The GraphQL mutation string
|
|
191
|
+
* @param options Variables, operationName, and extra headers
|
|
192
|
+
* @returns The parsed GraphQL response
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* const { data } = await gql.mutate<{ createUser: { id: string } }>(`
|
|
197
|
+
* mutation CreateUser($input: CreateUserInput!) {
|
|
198
|
+
* createUser(input: $input) { id }
|
|
199
|
+
* }
|
|
200
|
+
* `, { variables: { input: { name: "Alice" } } });
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
mutate<T = unknown>(mutation: string, options?: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Extract the first named operation from a GraphQL query string.
|
|
207
|
+
*
|
|
208
|
+
* Matches patterns like:
|
|
209
|
+
* - `query GetUser` -> "GetUser"
|
|
210
|
+
* - `mutation CreateUser` -> "CreateUser"
|
|
211
|
+
* - `subscription OnMessage` -> "OnMessage"
|
|
212
|
+
* - `query GetUser($id: ID!)` -> "GetUser"
|
|
213
|
+
*
|
|
214
|
+
* Returns `undefined` for anonymous operations (e.g., `{ users { id } }`).
|
|
215
|
+
*
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
export declare function parseOperationName(query: string): string | undefined;
|
|
219
|
+
/**
|
|
220
|
+
* Tagged template literal for GraphQL queries.
|
|
221
|
+
*
|
|
222
|
+
* This is an identity function -- it returns the query string as-is.
|
|
223
|
+
* Its purpose is purely for IDE integration: the VSCode GraphQL extension
|
|
224
|
+
* recognizes the `gql` tag and enables syntax highlighting (and autocomplete
|
|
225
|
+
* when a `.graphqlrc` schema is configured).
|
|
226
|
+
*
|
|
227
|
+
* For full IDE support (autocomplete, validation), prefer `.gql` files
|
|
228
|
+
* loaded via `fromGql()`. Use `gql` for quick inline queries where a
|
|
229
|
+
* separate file would be overkill.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* import { gql } from "@glubean/graphql";
|
|
234
|
+
*
|
|
235
|
+
* const GET_USER = gql`
|
|
236
|
+
* query GetUser($id: ID!) {
|
|
237
|
+
* user(id: $id) { name email }
|
|
238
|
+
* }
|
|
239
|
+
* `;
|
|
240
|
+
*
|
|
241
|
+
* const { data } = await client.query(GET_USER, { variables: { id: "1" } });
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export declare function gql(strings: TemplateStringsArray, ...values: unknown[]): string;
|
|
245
|
+
/**
|
|
246
|
+
* Create a GraphQL client bound to a specific endpoint.
|
|
247
|
+
*
|
|
248
|
+
* The client wraps the provided `HttpClient` (typically `ctx.http`), so all
|
|
249
|
+
* requests inherit auto-tracing, auto-metrics, and retry behavior.
|
|
250
|
+
*
|
|
251
|
+
* The operation name is injected via the `X-Glubean-Op` request header.
|
|
252
|
+
* The runner's harness reads this header to set `trace.name`, making
|
|
253
|
+
* individual GraphQL operations distinguishable in the dashboard.
|
|
254
|
+
*
|
|
255
|
+
* @param http The base HTTP client (e.g., `ctx.http`)
|
|
256
|
+
* @param options Endpoint URL, default headers, error handling
|
|
257
|
+
* @returns A bound `GraphQLClient` instance
|
|
258
|
+
*
|
|
259
|
+
* @example Basic usage
|
|
260
|
+
* ```ts
|
|
261
|
+
* import { createGraphQLClient } from "@glubean/graphql";
|
|
262
|
+
*
|
|
263
|
+
* export const myTest = test("gql-test", async (ctx) => {
|
|
264
|
+
* const gql = createGraphQLClient(ctx.http, {
|
|
265
|
+
* endpoint: ctx.vars.require("GQL_URL"),
|
|
266
|
+
* headers: { Authorization: `Bearer ${ctx.secrets.require("TOKEN")}` },
|
|
267
|
+
* });
|
|
268
|
+
*
|
|
269
|
+
* const { data } = await gql.query<{ user: { name: string } }>(`
|
|
270
|
+
* query GetUser($id: ID!) { user(id: $id) { name } }
|
|
271
|
+
* `, { variables: { id: "1" } });
|
|
272
|
+
*
|
|
273
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
274
|
+
* });
|
|
275
|
+
* ```
|
|
276
|
+
*
|
|
277
|
+
* @example With throwOnGraphQLErrors
|
|
278
|
+
* ```ts
|
|
279
|
+
* const gql = createGraphQLClient(ctx.http, {
|
|
280
|
+
* endpoint: ctx.vars.require("GQL_URL"),
|
|
281
|
+
* throwOnGraphQLErrors: true,
|
|
282
|
+
* });
|
|
283
|
+
*
|
|
284
|
+
* // This will throw GraphQLResponseError if the response contains errors
|
|
285
|
+
* const { data } = await gql.query(`{ me { name } }`);
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
export declare function createGraphQLClient(http: HttpClient, options: GraphQLClientOptions): GraphQLClient;
|
|
289
|
+
/**
|
|
290
|
+
* Create a GraphQL plugin for use with `configure({ plugins })`.
|
|
291
|
+
*
|
|
292
|
+
* Resolves `{{template}}` placeholders in `endpoint` and `headers` using
|
|
293
|
+
* the Glubean runtime (vars and secrets). The returned `GraphQLClient` is
|
|
294
|
+
* lazily created on first access.
|
|
295
|
+
*
|
|
296
|
+
* @param options GraphQL client options (endpoint may use `{{var_name}}` templates)
|
|
297
|
+
* @returns A `PluginFactory` that produces a `GraphQLClient`
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```ts
|
|
301
|
+
* import { test, configure } from "@glubean/sdk";
|
|
302
|
+
* import { graphql } from "@glubean/graphql";
|
|
303
|
+
*
|
|
304
|
+
* const { gql } = configure({
|
|
305
|
+
* plugins: {
|
|
306
|
+
* gql: graphql({
|
|
307
|
+
* endpoint: "{{graphql_url}}",
|
|
308
|
+
* headers: { Authorization: "Bearer {{api_key}}" },
|
|
309
|
+
* throwOnGraphQLErrors: true,
|
|
310
|
+
* }),
|
|
311
|
+
* },
|
|
312
|
+
* });
|
|
313
|
+
*
|
|
314
|
+
* export const getUser = test("get-user", async (ctx) => {
|
|
315
|
+
* const { data } = await gql.query<{ user: { name: string } }>(
|
|
316
|
+
* `query GetUser($id: ID!) { user(id: $id) { name } }`,
|
|
317
|
+
* { variables: { id: "1" } },
|
|
318
|
+
* );
|
|
319
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
320
|
+
* });
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
export declare function graphql(options: GraphQLClientOptions): PluginFactory<GraphQLClient>;
|
|
324
|
+
export { fromGql } from "./data.js";
|
|
325
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL plugin for Glubean tests.
|
|
3
|
+
*
|
|
4
|
+
* Provides a thin wrapper over `ctx.http` (or any `HttpClient`) that simplifies
|
|
5
|
+
* GraphQL query/mutation execution with auto-tracing, operationName extraction,
|
|
6
|
+
* and optional error-throwing behavior.
|
|
7
|
+
*
|
|
8
|
+
* ## Usage
|
|
9
|
+
*
|
|
10
|
+
* ### As a plugin via `configure()` (recommended)
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { test, configure } from "@glubean/sdk";
|
|
14
|
+
* import { graphql } from "@glubean/graphql";
|
|
15
|
+
*
|
|
16
|
+
* const { gql } = configure({
|
|
17
|
+
* plugins: {
|
|
18
|
+
* gql: graphql({
|
|
19
|
+
* endpoint: "{{graphql_url}}",
|
|
20
|
+
* headers: { Authorization: "Bearer {{api_key}}" },
|
|
21
|
+
* }),
|
|
22
|
+
* },
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* export const getUser = test("get-user", async (ctx) => {
|
|
26
|
+
* const { data, errors } = await gql.query<{ user: { name: string } }>(`
|
|
27
|
+
* query GetUser($id: ID!) {
|
|
28
|
+
* user(id: $id) { name }
|
|
29
|
+
* }
|
|
30
|
+
* `, { variables: { id: "1" } });
|
|
31
|
+
*
|
|
32
|
+
* ctx.expect(errors).toBeUndefined();
|
|
33
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ### Standalone (without `configure()`)
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { test } from "@glubean/sdk";
|
|
41
|
+
* import { createGraphQLClient } from "@glubean/graphql";
|
|
42
|
+
*
|
|
43
|
+
* export const quick = test("quick-gql", async (ctx) => {
|
|
44
|
+
* const gql = createGraphQLClient(ctx.http, {
|
|
45
|
+
* endpoint: "https://api.example.com/graphql",
|
|
46
|
+
* });
|
|
47
|
+
* const { data } = await gql.query(`{ health }`);
|
|
48
|
+
* ctx.assert(data?.health === "ok", "Service healthy");
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @module graphql
|
|
53
|
+
*/
|
|
54
|
+
import { definePlugin } from "@glubean/sdk/plugin";
|
|
55
|
+
/**
|
|
56
|
+
* Error thrown when a GraphQL response contains errors and
|
|
57
|
+
* `throwOnGraphQLErrors` is enabled.
|
|
58
|
+
*/
|
|
59
|
+
export class GraphQLResponseError extends Error {
|
|
60
|
+
/** The GraphQL errors from the response */
|
|
61
|
+
errors;
|
|
62
|
+
/** The original response (may contain partial `data`) */
|
|
63
|
+
response;
|
|
64
|
+
constructor(errors, response) {
|
|
65
|
+
const summary = errors.map((e) => e.message).join("; ");
|
|
66
|
+
super(`GraphQL errors: ${summary}`);
|
|
67
|
+
this.name = "GraphQLResponseError";
|
|
68
|
+
this.errors = errors;
|
|
69
|
+
this.response = response;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// Helpers
|
|
74
|
+
// =============================================================================
|
|
75
|
+
/**
|
|
76
|
+
* Extract the first named operation from a GraphQL query string.
|
|
77
|
+
*
|
|
78
|
+
* Matches patterns like:
|
|
79
|
+
* - `query GetUser` -> "GetUser"
|
|
80
|
+
* - `mutation CreateUser` -> "CreateUser"
|
|
81
|
+
* - `subscription OnMessage` -> "OnMessage"
|
|
82
|
+
* - `query GetUser($id: ID!)` -> "GetUser"
|
|
83
|
+
*
|
|
84
|
+
* Returns `undefined` for anonymous operations (e.g., `{ users { id } }`).
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
export function parseOperationName(query) {
|
|
89
|
+
const match = query.match(/(?:query|mutation|subscription)\s+([A-Za-z_]\w*)/);
|
|
90
|
+
return match?.[1];
|
|
91
|
+
}
|
|
92
|
+
// =============================================================================
|
|
93
|
+
// Tagged template
|
|
94
|
+
// =============================================================================
|
|
95
|
+
/**
|
|
96
|
+
* Tagged template literal for GraphQL queries.
|
|
97
|
+
*
|
|
98
|
+
* This is an identity function -- it returns the query string as-is.
|
|
99
|
+
* Its purpose is purely for IDE integration: the VSCode GraphQL extension
|
|
100
|
+
* recognizes the `gql` tag and enables syntax highlighting (and autocomplete
|
|
101
|
+
* when a `.graphqlrc` schema is configured).
|
|
102
|
+
*
|
|
103
|
+
* For full IDE support (autocomplete, validation), prefer `.gql` files
|
|
104
|
+
* loaded via `fromGql()`. Use `gql` for quick inline queries where a
|
|
105
|
+
* separate file would be overkill.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* import { gql } from "@glubean/graphql";
|
|
110
|
+
*
|
|
111
|
+
* const GET_USER = gql`
|
|
112
|
+
* query GetUser($id: ID!) {
|
|
113
|
+
* user(id: $id) { name email }
|
|
114
|
+
* }
|
|
115
|
+
* `;
|
|
116
|
+
*
|
|
117
|
+
* const { data } = await client.query(GET_USER, { variables: { id: "1" } });
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export function gql(strings, ...values) {
|
|
121
|
+
let result = strings[0];
|
|
122
|
+
for (let i = 0; i < values.length; i++) {
|
|
123
|
+
result += String(values[i]) + strings[i + 1];
|
|
124
|
+
}
|
|
125
|
+
return result.replace(/\s+/g, " ").trim();
|
|
126
|
+
}
|
|
127
|
+
// =============================================================================
|
|
128
|
+
// Client implementation
|
|
129
|
+
// =============================================================================
|
|
130
|
+
/**
|
|
131
|
+
* Create a GraphQL client bound to a specific endpoint.
|
|
132
|
+
*
|
|
133
|
+
* The client wraps the provided `HttpClient` (typically `ctx.http`), so all
|
|
134
|
+
* requests inherit auto-tracing, auto-metrics, and retry behavior.
|
|
135
|
+
*
|
|
136
|
+
* The operation name is injected via the `X-Glubean-Op` request header.
|
|
137
|
+
* The runner's harness reads this header to set `trace.name`, making
|
|
138
|
+
* individual GraphQL operations distinguishable in the dashboard.
|
|
139
|
+
*
|
|
140
|
+
* @param http The base HTTP client (e.g., `ctx.http`)
|
|
141
|
+
* @param options Endpoint URL, default headers, error handling
|
|
142
|
+
* @returns A bound `GraphQLClient` instance
|
|
143
|
+
*
|
|
144
|
+
* @example Basic usage
|
|
145
|
+
* ```ts
|
|
146
|
+
* import { createGraphQLClient } from "@glubean/graphql";
|
|
147
|
+
*
|
|
148
|
+
* export const myTest = test("gql-test", async (ctx) => {
|
|
149
|
+
* const gql = createGraphQLClient(ctx.http, {
|
|
150
|
+
* endpoint: ctx.vars.require("GQL_URL"),
|
|
151
|
+
* headers: { Authorization: `Bearer ${ctx.secrets.require("TOKEN")}` },
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* const { data } = await gql.query<{ user: { name: string } }>(`
|
|
155
|
+
* query GetUser($id: ID!) { user(id: $id) { name } }
|
|
156
|
+
* `, { variables: { id: "1" } });
|
|
157
|
+
*
|
|
158
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
159
|
+
* });
|
|
160
|
+
* ```
|
|
161
|
+
*
|
|
162
|
+
* @example With throwOnGraphQLErrors
|
|
163
|
+
* ```ts
|
|
164
|
+
* const gql = createGraphQLClient(ctx.http, {
|
|
165
|
+
* endpoint: ctx.vars.require("GQL_URL"),
|
|
166
|
+
* throwOnGraphQLErrors: true,
|
|
167
|
+
* });
|
|
168
|
+
*
|
|
169
|
+
* // This will throw GraphQLResponseError if the response contains errors
|
|
170
|
+
* const { data } = await gql.query(`{ me { name } }`);
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export function createGraphQLClient(http, options) {
|
|
174
|
+
const { endpoint, headers: defaultHeaders, throwOnGraphQLErrors } = options;
|
|
175
|
+
async function execute(query, requestOptions) {
|
|
176
|
+
const opName = requestOptions?.operationName ?? parseOperationName(query) ?? "anonymous";
|
|
177
|
+
const mergedHeaders = {
|
|
178
|
+
...defaultHeaders,
|
|
179
|
+
...requestOptions?.headers,
|
|
180
|
+
"X-Glubean-Op": opName,
|
|
181
|
+
};
|
|
182
|
+
const body = { query };
|
|
183
|
+
if (requestOptions?.variables) {
|
|
184
|
+
body.variables = requestOptions.variables;
|
|
185
|
+
}
|
|
186
|
+
if (opName !== "anonymous") {
|
|
187
|
+
body.operationName = opName;
|
|
188
|
+
}
|
|
189
|
+
const response = await http
|
|
190
|
+
.post(endpoint, {
|
|
191
|
+
json: body,
|
|
192
|
+
headers: mergedHeaders,
|
|
193
|
+
throwHttpErrors: false,
|
|
194
|
+
})
|
|
195
|
+
.json();
|
|
196
|
+
if (throwOnGraphQLErrors && response.errors && response.errors.length > 0) {
|
|
197
|
+
throw new GraphQLResponseError(response.errors, response);
|
|
198
|
+
}
|
|
199
|
+
return response;
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
query: (query, options) => execute(query, options),
|
|
203
|
+
mutate: (mutation, options) => execute(mutation, options),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// =============================================================================
|
|
207
|
+
// Plugin factory
|
|
208
|
+
// =============================================================================
|
|
209
|
+
/**
|
|
210
|
+
* Create a GraphQL plugin for use with `configure({ plugins })`.
|
|
211
|
+
*
|
|
212
|
+
* Resolves `{{template}}` placeholders in `endpoint` and `headers` using
|
|
213
|
+
* the Glubean runtime (vars and secrets). The returned `GraphQLClient` is
|
|
214
|
+
* lazily created on first access.
|
|
215
|
+
*
|
|
216
|
+
* @param options GraphQL client options (endpoint may use `{{var_name}}` templates)
|
|
217
|
+
* @returns A `PluginFactory` that produces a `GraphQLClient`
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```ts
|
|
221
|
+
* import { test, configure } from "@glubean/sdk";
|
|
222
|
+
* import { graphql } from "@glubean/graphql";
|
|
223
|
+
*
|
|
224
|
+
* const { gql } = configure({
|
|
225
|
+
* plugins: {
|
|
226
|
+
* gql: graphql({
|
|
227
|
+
* endpoint: "{{graphql_url}}",
|
|
228
|
+
* headers: { Authorization: "Bearer {{api_key}}" },
|
|
229
|
+
* throwOnGraphQLErrors: true,
|
|
230
|
+
* }),
|
|
231
|
+
* },
|
|
232
|
+
* });
|
|
233
|
+
*
|
|
234
|
+
* export const getUser = test("get-user", async (ctx) => {
|
|
235
|
+
* const { data } = await gql.query<{ user: { name: string } }>(
|
|
236
|
+
* `query GetUser($id: ID!) { user(id: $id) { name } }`,
|
|
237
|
+
* { variables: { id: "1" } },
|
|
238
|
+
* );
|
|
239
|
+
* ctx.expect(data?.user.name).toBe("Alice");
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
export function graphql(options) {
|
|
244
|
+
return definePlugin((runtime) => {
|
|
245
|
+
const resolved = {
|
|
246
|
+
...options,
|
|
247
|
+
endpoint: runtime.resolveTemplate(options.endpoint),
|
|
248
|
+
};
|
|
249
|
+
if (options.headers) {
|
|
250
|
+
resolved.headers = {};
|
|
251
|
+
for (const [k, v] of Object.entries(options.headers)) {
|
|
252
|
+
resolved.headers[k] = runtime.resolveTemplate(v);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return createGraphQLClient(runtime.http, resolved);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
// Re-export data loader for convenience (spec: `import { fromGql } from "@glubean/graphql"`)
|
|
259
|
+
export { fromGql } from "./data.js";
|
|
260
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@glubean/graphql",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"./data": {
|
|
11
|
+
"types": "./dist/data.d.ts",
|
|
12
|
+
"import": "./dist/data.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@glubean/sdk": "0.1.3"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"vitest": "^3.2.1",
|
|
23
|
+
"typescript": "^5.8.3"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.build.json",
|
|
27
|
+
"test": "vitest run"
|
|
28
|
+
}
|
|
29
|
+
}
|