GraphQL Plugin (@glubean/graphql)
@glubean/graphql is a first-party GraphQL client plugin for Glubean.
Status: Experimental (pre-1.0). API may evolve.
Install
npm install @glubean/graphqlProject setup — install the plugin manifest
@glubean/graphql ships two things: a plugin manifest (registers the graphql contract protocol, toHaveGraphql* matchers, and toHaveHttpStatus) and the client factory shown in the quick start below. The manifest must be installed once per project from glubean.setup.ts at the project root:
// glubean.setup.ts
import { installPlugin } from "@glubean/sdk";
import graphqlPlugin from "@glubean/graphql";
await installPlugin(graphqlPlugin);Without this file, contract.graphql.with(...) and ctx.expect(result).toHaveGraphqlData(...) will throw “unknown protocol” / missing-matcher errors at runtime. A top-level import "@glubean/graphql" no longer auto-registers these globals.
Quick Start (configure plugin mode)
import { configure, test } from "@glubean/sdk";
import { graphql } from "@glubean/graphql";
const { gql } = configure({
plugins: {
gql: graphql({
endpoint: "{{GRAPHQL_URL}}",
headers: { Authorization: "Bearer {{API_KEY}}" },
throwOnGraphQLErrors: true,
}),
},
});
export const getUser = test("get-user", async (ctx) => {
const { data } = await gql.query<{ user: { name: string } }>(
`query GetUser($id: ID!) { user(id: $id) { name } }`,
{ variables: { id: "1" } },
);
ctx.expect(data?.user.name).toBe("Alice");
});Contract protocol
Use contract.graphql.with(...) when the GraphQL operation is a durable API
promise that should run as a check and project into Specifications.
import { configure, contract } from "@glubean/sdk";
import { gql, graphql } from "@glubean/graphql";
const { graph } = configure({
plugins: {
graph: graphql({
endpoint: "{{GRAPHQL_URL}}",
headers: { Authorization: "Bearer {{API_KEY}}" },
}),
},
});
const userGraph = contract.graphql.with("userGraph", {
client: graph,
endpoint: "{{GRAPHQL_URL}}",
tags: ["users"],
});
export const userLookup = userGraph("user-lookup", {
description: "Users can be fetched by id",
cases: {
ok: {
description: "existing user returns profile fields",
operation: "query",
query: gql`
query GetUser($id: ID!) {
user(id: $id) { id name }
}
`,
variables: { id: "1" },
expect: {
errors: "absent",
data: { user: { id: "1" } },
},
},
},
});The client owns the runtime endpoint. The optional endpoint value on the
contract instance is projection/display metadata so Specifications can show
where the promise points.
Standalone mode (createGraphQLClient)
Use this when you need a one-off GraphQL client instead of a named
configure({ plugins }) client. In real projects, still keep environment access
in configure().
import { configure, test } from "@glubean/sdk";
import { createGraphQLClient } from "@glubean/graphql";
const { http, vars, secrets } = configure({
vars: { gqlUrl: "{{GQL_URL}}" },
secrets: { token: "{{TOKEN}}" },
});
export const quick = test("quick-gql", async (ctx) => {
const gql = createGraphQLClient(http, {
endpoint: vars.gqlUrl,
headers: { Authorization: `Bearer ${secrets.token}` },
});
const { data } = await gql.query<{ health: string }>(`{ health }`);
ctx.expect(data?.health).toBe("ok");
});Extra helpers
gql tagged template
Identity tag for better GraphQL editor highlighting:
import { gql } from "@glubean/graphql";
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) { id name email }
}
`;fromGql(path)
Load query text from .gql files:
import { fromGql } from "@glubean/graphql";
const GET_USER = await fromGql("./queries/get-user.gql");Client methods
gql.query<T>(query, options?)— execute a querygql.mutate<T>(mutation, options?)— execute a mutation
Both return Promise<{ data: T | null; errors?: GraphQLError[] }>.
Options
| Option | Type | Default | Description |
|---|---|---|---|
endpoint | string | (required) | GraphQL endpoint URL ({{KEY}} supported) |
headers | Record<string, string> | {} | Default headers ({{KEY}} supported) |
throwOnGraphQLErrors | boolean | false | Throw when errors array is non-empty |