@glubean/graphql 0.1.7 → 0.2.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.
@@ -0,0 +1,358 @@
1
+ /**
2
+ * GraphQL contract types.
3
+ *
4
+ * User-facing authoring types + adapter-level payload types for the
5
+ * GraphQL contract adapter (single-package model — see
6
+ * `internal/40-discovery/proposals/contract-grpc-graphql-expansion.md` §6.1).
7
+ *
8
+ * Structure mirrors `packages/grpc/src/contract/types.ts` where applicable,
9
+ * with GraphQL-specific design:
10
+ *
11
+ * - **Target model:** GraphQL typically has a single `/graphql` endpoint,
12
+ * so `endpoint` is spec-level (not per-case). `endpoint` is
13
+ * **projection-only** in Phase 1 — it travels on `meta.endpoint`
14
+ * for markdown / scanner / MCP display, but the adapter dispatches
15
+ * through the supplied `GraphQLClient` whose endpoint was fixed at
16
+ * construction time. Multi-endpoint is expressed by multiple
17
+ * clients, not by per-contract endpoint strings. Contract identity
18
+ * = `contractId + caseKey`, NOT operationName (proposal §3.2).
19
+ *
20
+ * - **Selection-set-per-case coupling (proposal §3.2 b):** unlike
21
+ * HTTP/gRPC where response shape is determined by endpoint/method,
22
+ * GraphQL response shape is determined by the *query string* in each
23
+ * case. Each case therefore carries its own `query` + `variables` +
24
+ * `responseSchema` triple. A contract-level `responseSchema` may still
25
+ * apply if all cases share the same selection set (rare).
26
+ *
27
+ * - **Explicit type declarations (proposal §7b.2):** `types` is a
28
+ * deferred projection hint for Phase 2 SDL generation. Phase 1 stores
29
+ * it as opaque metadata — adapter / scanner carry it forward so
30
+ * projection tooling can consume it later.
31
+ *
32
+ * - **3-layer classifyFailure (proposal §3.2 c):**
33
+ * transport (HTTP status 4xx/5xx/network)
34
+ * → payload errors (GraphQL `errors` array, HTTP 200)
35
+ * → data shape mismatch (schema validation on `data`)
36
+ *
37
+ * - **Phase 1 scope:** query + mutation only (subscriptions deferred
38
+ * to Phase 2 streaming work).
39
+ */
40
+ import type { SchemaLike, TestContext } from "@glubean/sdk";
41
+ import type { BaseCaseSpec, Extensions } from "@glubean/sdk";
42
+ import type { GraphQLClient, GraphQLError } from "../index.js";
43
+ /**
44
+ * Field-map declaration for a GraphQL type. Kept minimal and stringly-typed
45
+ * so the declaration surface can evolve without a breaking bump.
46
+ *
47
+ * Phase 1 stores this as opaque metadata. Phase 2 `.gql` projection will
48
+ * consume it — see proposal §7b.2.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * types: {
53
+ * User: { id: "ID!", name: "String!", orders: "[Order!]!" },
54
+ * Order: { id: "ID!", total: "Float!" },
55
+ * }
56
+ * ```
57
+ */
58
+ export type GraphqlTypeDef = Record<string, string>;
59
+ /**
60
+ * Map of type-name → field declaration. Optional; when present, projection
61
+ * tools can emit SDL alongside the per-case markdown.
62
+ */
63
+ export type GraphqlTypeDefs = Record<string, GraphqlTypeDef>;
64
+ /**
65
+ * Defaults for a GraphQL contract instance
66
+ * (`contract.graphql.with("name", {...})`).
67
+ *
68
+ * The `client` binding is the primary reason to use `.with`: supplying a
69
+ * pre-configured GraphQLClient lets the adapter call through it without
70
+ * rebuilding per contract. The GraphQLClient is itself bound to an
71
+ * endpoint at construction time (via `createGraphQLClient(http, { endpoint })`
72
+ * or the `graphql({ endpoint })` plugin factory) — the contract layer
73
+ * does not override that at runtime.
74
+ */
75
+ export interface GraphqlContractDefaults {
76
+ /** Default GraphQL client for all contracts in this instance. */
77
+ client?: GraphQLClient;
78
+ /**
79
+ * Default endpoint **for projection / display only.**
80
+ *
81
+ * This value travels on the projection meta (`meta.endpoint`) so the
82
+ * scanner, `glubean contracts` markdown, and MCP surfaces can show
83
+ * which endpoint the contract points at. At runtime the adapter
84
+ * dispatches through the supplied `client`, whose endpoint was fixed
85
+ * at client-construction time. Changing `endpoint` here does **not**
86
+ * redirect the live call — use a different client instead
87
+ * (e.g. `api_v1 = graphql({endpoint: "/v1/graphql"})`,
88
+ * `api_v2 = graphql({endpoint: "/v2/graphql"})`).
89
+ */
90
+ endpoint?: string;
91
+ /** Tags inherited by all contracts in this instance. */
92
+ tags?: string[];
93
+ /** Default feature grouping key. */
94
+ feature?: string;
95
+ /** Default headers merged into every case. */
96
+ headers?: Record<string, string>;
97
+ /** OpenAPI-style extensions (x-* keys). Inherited by all contracts. */
98
+ extensions?: Extensions;
99
+ }
100
+ export interface GraphqlContractExample<T = unknown> {
101
+ value: T;
102
+ summary?: string;
103
+ description?: string;
104
+ }
105
+ /**
106
+ * Sentinel values for the `errors` expectation.
107
+ *
108
+ * - `"absent"` — `errors` must be undefined or empty (strict success).
109
+ * - `"any"` — accept any errors (only useful with `data` partial match).
110
+ * - `GraphQLError[]` — match each listed error by `message` / `extensions.code`
111
+ * (partial — unlisted errors still fail unless length check relaxed).
112
+ */
113
+ export type GraphqlErrorsExpect = "absent" | "any" | Array<Partial<GraphQLError>>;
114
+ /**
115
+ * Response expectations for a GraphQL case.
116
+ *
117
+ * GraphQL success is nuanced: `errors` may be present alongside `data`
118
+ * (partial success). The adapter's 3-layer `classifyFailure` handles the
119
+ * interpretation. At expect-time:
120
+ *
121
+ * - `data` — partial shape to match against `response.data`.
122
+ * - `errors` — sentinel or array (see `GraphqlErrorsExpect`).
123
+ * - `schema` — per-case Zod/Valibot schema for `data` (selection-set
124
+ * coupling lives here — each case owns its response shape).
125
+ * - `httpStatus` — transport-layer assertion (4xx/5xx for negative cases).
126
+ */
127
+ export interface GraphqlContractExpect<T = unknown> {
128
+ /** Expected HTTP status (from the underlying POST). Default: 200. */
129
+ httpStatus?: number;
130
+ /** Per-case response schema (selection-set-coupled). */
131
+ schema?: SchemaLike<T>;
132
+ /** Partial expected `data` shape (toMatchObject semantics). */
133
+ data?: Partial<T>;
134
+ /** Assertion on GraphQL `errors` array. Default: `"absent"`. */
135
+ errors?: GraphqlErrorsExpect;
136
+ /** Schema for response headers. */
137
+ headers?: SchemaLike<Record<string, string | string[]>>;
138
+ /** Partial expected response headers. */
139
+ headersMatch?: Record<string, string>;
140
+ /** Single response example (for docs / projection). */
141
+ example?: T;
142
+ /** Named response examples. */
143
+ examples?: Record<string, GraphqlContractExample<T>>;
144
+ }
145
+ /**
146
+ * One case on a GraphQL contract.
147
+ *
148
+ * Each case owns its own `query` string — the selection-set is
149
+ * per-case (proposal §3.2 b). Function-valued fields (`variables`,
150
+ * `headers`) reference case-local setup state; in flow mode these are
151
+ * rejected by `validateCaseForFlow`, same discipline as HTTP.
152
+ */
153
+ export interface GraphqlContractCase<Vars = Record<string, unknown>, Res = unknown, S = void> extends BaseCaseSpec {
154
+ /** Per-case client override. */
155
+ client?: GraphQLClient;
156
+ /** Why this case exists — required. */
157
+ description: string;
158
+ /**
159
+ * Operation type. Defaults to `"query"` when omitted.
160
+ * Phase 1: `query | mutation`. `subscription` is Phase 2 (streaming).
161
+ */
162
+ operation?: "query" | "mutation";
163
+ /**
164
+ * GraphQL document. Required per case (selection-set is per-case).
165
+ *
166
+ * Can be authored inline, via the `gql` tagged template, or loaded from
167
+ * a `.gql` file via `fromGql()`.
168
+ */
169
+ query: string;
170
+ /** Optional operationName override. If omitted, parsed from `query`. */
171
+ operationName?: string;
172
+ /** Expected response. */
173
+ expect?: GraphqlContractExpect<Res>;
174
+ /**
175
+ * Variables. Object shorthand or a function of setup state.
176
+ * Merged deep-style over `defaults.variables` → `spec.defaultVariables`.
177
+ */
178
+ variables?: Vars | ((state: S) => Vars);
179
+ /** Per-call headers (merged with instance + contract defaults). */
180
+ headers?: Record<string, string> | ((state: S) => Record<string, string>);
181
+ /** Setup runs before the call. Return value flows to variables/headers fn + teardown. */
182
+ setup?: (ctx: TestContext) => Promise<S>;
183
+ /** Teardown runs after verify, even on failure. */
184
+ teardown?: (ctx: TestContext, state: S) => Promise<void>;
185
+ /** Business-logic verify — runs after transport + schema + data match. */
186
+ verify?: (ctx: TestContext, res: GraphqlCaseResult<Res>) => void | Promise<void>;
187
+ }
188
+ /**
189
+ * Result of running a single case. This is also the `CaseOutput` shape that
190
+ * flow `step.out(state, res)` lens receives.
191
+ *
192
+ * Mirrors `GraphQLResult<T>` from the transport layer (CG-10) plus the
193
+ * parsed `operationName` for display/routing. Kept as a distinct type so
194
+ * adapter-layer additions (e.g. assertion diagnostics) can grow
195
+ * independently of the transport envelope.
196
+ */
197
+ export interface GraphqlCaseResult<Res = unknown> {
198
+ /** Decoded `data` field (null if all fields errored or transport failed). */
199
+ data: Res | null;
200
+ /** GraphQL `errors` array (undefined when absent). */
201
+ errors?: GraphQLError[];
202
+ /** GraphQL `extensions` (server-side tracing/cost/etc). */
203
+ extensions?: Record<string, unknown>;
204
+ /** HTTP status from the underlying POST. */
205
+ httpStatus: number;
206
+ /** Response headers (lowercased keys). */
207
+ headers: Record<string, string | string[]>;
208
+ /** Raw response body string (null on network error). */
209
+ rawBody: string | null;
210
+ /** Resolved operation name (from case.operationName or parsed from query). */
211
+ operationName: string;
212
+ /** Duration in ms. */
213
+ duration: number;
214
+ }
215
+ /**
216
+ * User-facing GraphQL contract specification.
217
+ *
218
+ * Contract identity = contract id (string) + case key. `operationName` is
219
+ * a display/routing hint, NOT an identity (proposal §5.3 — same rule as
220
+ * gRPC `Service/Method`).
221
+ */
222
+ export interface GraphqlContractSpec<Vars extends Record<string, unknown> = Record<string, unknown>, Res = unknown, Cases extends Record<string, GraphqlContractCase<Vars, Res, any>> = Record<string, GraphqlContractCase<Vars, Res>>> {
223
+ /**
224
+ * Endpoint URL **for projection / display only.**
225
+ *
226
+ * Travels on the projection `meta.endpoint`. The adapter does NOT use
227
+ * this to redirect the runtime call — the call is dispatched through
228
+ * the supplied `client`, whose endpoint was fixed at construction time
229
+ * (see `GraphqlContractDefaults.endpoint` for the full rationale). To
230
+ * target a different endpoint at runtime, construct a separate client.
231
+ */
232
+ endpoint?: string;
233
+ /** Default GraphQL client for all cases. */
234
+ client?: GraphQLClient;
235
+ description?: string;
236
+ feature?: string;
237
+ /**
238
+ * Explicit type declarations (proposal §7b.2). Stored opaque in Phase 1;
239
+ * consumed by Phase 2 `.gql` projection. Safe to omit — nothing else
240
+ * depends on it at runtime.
241
+ */
242
+ types?: GraphqlTypeDefs;
243
+ /**
244
+ * Default operation type for cases that don't set their own.
245
+ * Default when both spec and case omit: `"query"`.
246
+ */
247
+ defaultOperation?: "query" | "mutation";
248
+ /**
249
+ * Contract-level variables schema. Per-case schemas (on `expect.schema`)
250
+ * cover response shape; variables often share structure so this sits at
251
+ * the contract level.
252
+ */
253
+ variablesSchema?: SchemaLike<Vars>;
254
+ /**
255
+ * Contract-level response schema — used when all cases share the same
256
+ * selection set. Per-case `expect.schema` overrides.
257
+ */
258
+ responseSchema?: SchemaLike<Res>;
259
+ /** Contract-level default variables (merged under each case's variables). */
260
+ defaultVariables?: Partial<Vars>;
261
+ /** Contract-level default headers (merged under each case's headers). */
262
+ defaultHeaders?: Record<string, string>;
263
+ tags?: string[];
264
+ deprecated?: string;
265
+ extensions?: Extensions;
266
+ /** Named spec cases. */
267
+ cases: Cases;
268
+ }
269
+ /**
270
+ * Runtime (live) payload shape for the GraphQL adapter. Contains SchemaLike
271
+ * references. Converted to `GraphqlSafeSchemas` by adapter.normalize.
272
+ *
273
+ * Per the selection-set coupling (proposal §3.2 b), the most important
274
+ * field here is `response` — it's the per-case response schema. `variables`
275
+ * and `request` (= the query document string) accompany it so the triple
276
+ * travels together through projection.
277
+ */
278
+ export interface GraphqlPayloadSchemas {
279
+ /** Query document string (the "request" for GraphQL). */
280
+ query?: string;
281
+ /** Operation type (query / mutation). */
282
+ operation?: "query" | "mutation";
283
+ /** Resolved operationName (display/routing hint). */
284
+ operationName?: string;
285
+ /** Variables schema. */
286
+ variables?: SchemaLike<unknown>;
287
+ /** Per-case response schema (selection-set-coupled). */
288
+ response?: SchemaLike<unknown>;
289
+ /** Response headers schema. */
290
+ headers?: SchemaLike<Record<string, string | string[]>>;
291
+ /** Variables examples (for docs / projection). */
292
+ variablesExample?: unknown;
293
+ variablesExamples?: Record<string, GraphqlContractExample<unknown>>;
294
+ }
295
+ /**
296
+ * JSON-safe payload shape. Produced by adapter.normalize.
297
+ * SchemaLike references are converted to JSON Schema fragments.
298
+ */
299
+ export interface GraphqlSafeSchemas {
300
+ query?: string;
301
+ operation?: "query" | "mutation";
302
+ operationName?: string;
303
+ variables?: Record<string, unknown>;
304
+ response?: Record<string, unknown>;
305
+ headers?: Record<string, unknown>;
306
+ variablesExample?: unknown;
307
+ variablesExamples?: Record<string, GraphqlContractExample<unknown>>;
308
+ }
309
+ /**
310
+ * Runtime contract-level meta. Carried on the projection so scanner / MCP /
311
+ * Cloud can surface structural info without needing the live spec.
312
+ *
313
+ * Note: explicit `types` map (when present) is JSON-safe by construction
314
+ * (stringly-typed field declarations), so it travels unchanged from
315
+ * runtime to safe meta.
316
+ */
317
+ export interface GraphqlContractMeta {
318
+ /** Endpoint URL (normalized; may be undefined if transport-owned). */
319
+ endpoint?: string;
320
+ /** Default operation type for the contract. */
321
+ defaultOperation?: "query" | "mutation";
322
+ /** Contract-level default headers (for projection display). */
323
+ defaultHeaders?: Record<string, string>;
324
+ /** Explicit type declarations (Phase 2 projection hint). */
325
+ types?: GraphqlTypeDefs;
326
+ /** Contract instance name (contract.graphql.with("name")). */
327
+ instanceName?: string;
328
+ }
329
+ /**
330
+ * JSON-safe meta. Same shape as runtime meta (no live references).
331
+ */
332
+ export type GraphqlContractSafeMeta = GraphqlContractMeta;
333
+ /**
334
+ * What `executeCaseInFlow` returns, and what flow `step.out(state, res)`
335
+ * receives in its `res` parameter. Mirrors `GraphqlCaseResult` — kept as a
336
+ * distinct export to make the flow-output contract explicit (parallel to
337
+ * gRPC's `GrpcFlowCaseOutput` convention).
338
+ */
339
+ export type GraphqlFlowCaseOutput<Res = unknown> = GraphqlCaseResult<Res>;
340
+ /**
341
+ * Signature of `contract.graphql.with("name", defaults)`. Returns a contract
342
+ * factory that creates contracts under this instance's defaults.
343
+ *
344
+ * Actual implementation in `./factory.ts` (CG-12).
345
+ */
346
+ export type GraphqlContractRoot = {
347
+ with: (instanceName: string, defaults?: GraphqlContractDefaults) => GraphqlContractFactory;
348
+ };
349
+ export type GraphqlContractFactory = <Vars extends Record<string, unknown>, Res, Cases extends Record<string, GraphqlContractCase<Vars, Res, any>>>(id: string, spec: GraphqlContractSpec<Vars, Res, Cases>) => unknown;
350
+ /**
351
+ * Infer variables type from a GraphqlContractCase.
352
+ */
353
+ export type InferGraphqlVariables<C> = C extends GraphqlContractCase<infer V, any, any> ? V : never;
354
+ /**
355
+ * Infer response type from a GraphqlContractCase.
356
+ */
357
+ export type InferGraphqlResponse<C> = C extends GraphqlContractCase<any, infer R, any> ? R : never;
358
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/contract/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * GraphQL contract types.
3
+ *
4
+ * User-facing authoring types + adapter-level payload types for the
5
+ * GraphQL contract adapter (single-package model — see
6
+ * `internal/40-discovery/proposals/contract-grpc-graphql-expansion.md` §6.1).
7
+ *
8
+ * Structure mirrors `packages/grpc/src/contract/types.ts` where applicable,
9
+ * with GraphQL-specific design:
10
+ *
11
+ * - **Target model:** GraphQL typically has a single `/graphql` endpoint,
12
+ * so `endpoint` is spec-level (not per-case). `endpoint` is
13
+ * **projection-only** in Phase 1 — it travels on `meta.endpoint`
14
+ * for markdown / scanner / MCP display, but the adapter dispatches
15
+ * through the supplied `GraphQLClient` whose endpoint was fixed at
16
+ * construction time. Multi-endpoint is expressed by multiple
17
+ * clients, not by per-contract endpoint strings. Contract identity
18
+ * = `contractId + caseKey`, NOT operationName (proposal §3.2).
19
+ *
20
+ * - **Selection-set-per-case coupling (proposal §3.2 b):** unlike
21
+ * HTTP/gRPC where response shape is determined by endpoint/method,
22
+ * GraphQL response shape is determined by the *query string* in each
23
+ * case. Each case therefore carries its own `query` + `variables` +
24
+ * `responseSchema` triple. A contract-level `responseSchema` may still
25
+ * apply if all cases share the same selection set (rare).
26
+ *
27
+ * - **Explicit type declarations (proposal §7b.2):** `types` is a
28
+ * deferred projection hint for Phase 2 SDL generation. Phase 1 stores
29
+ * it as opaque metadata — adapter / scanner carry it forward so
30
+ * projection tooling can consume it later.
31
+ *
32
+ * - **3-layer classifyFailure (proposal §3.2 c):**
33
+ * transport (HTTP status 4xx/5xx/network)
34
+ * → payload errors (GraphQL `errors` array, HTTP 200)
35
+ * → data shape mismatch (schema validation on `data`)
36
+ *
37
+ * - **Phase 1 scope:** query + mutation only (subscriptions deferred
38
+ * to Phase 2 streaming work).
39
+ */
40
+ export {};
41
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/contract/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG"}
package/dist/index.d.ts CHANGED
@@ -51,7 +51,7 @@
51
51
  *
52
52
  * @module graphql
53
53
  */
54
- import type { HttpClient, PluginFactory } from "@glubean/sdk";
54
+ import type { ClientFactory, HttpClient, PluginManifest } from "@glubean/sdk";
55
55
  /**
56
56
  * A single GraphQL error as defined by the
57
57
  * [GraphQL spec](https://spec.graphql.org/October2021/#sec-Errors).
@@ -96,6 +96,25 @@ export interface GraphQLResponse<T = unknown> {
96
96
  /** Optional server extensions (e.g., tracing, cost). */
97
97
  extensions?: Record<string, unknown>;
98
98
  }
99
+ /**
100
+ * Extended result type returned by the client. Contains the full
101
+ * `GraphQLResponse` shape plus transport envelope fields used by
102
+ * the contract adapter layer (negative-transport assertions,
103
+ * `classifyFailure`, flow `out` lens inspection).
104
+ *
105
+ * Additive since v0.2.0 — users who only destructure `{ data, errors }`
106
+ * see no change. Users who need transport info read the new fields.
107
+ *
108
+ * @template T Shape of the `data` field
109
+ */
110
+ export interface GraphQLResult<T = unknown> extends GraphQLResponse<T> {
111
+ /** HTTP status from the underlying POST (200 on most GraphQL success, even with `errors`). */
112
+ httpStatus: number;
113
+ /** Response headers (lowercased keys). */
114
+ headers: Record<string, string | string[]>;
115
+ /** Raw response body string — present when available (null on network error). */
116
+ rawBody: string | null;
117
+ }
99
118
  /**
100
119
  * Options for a single GraphQL request.
101
120
  */
@@ -179,7 +198,7 @@ export interface GraphQLClient {
179
198
  * `, { variables: { limit: 10 } });
180
199
  * ```
181
200
  */
182
- query<T = unknown>(query: string, options?: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;
201
+ query<T = unknown>(query: string, options?: GraphQLRequestOptions): Promise<GraphQLResult<T>>;
183
202
  /**
184
203
  * Execute a GraphQL mutation.
185
204
  *
@@ -200,7 +219,7 @@ export interface GraphQLClient {
200
219
  * `, { variables: { input: { name: "Alice" } } });
201
220
  * ```
202
221
  */
203
- mutate<T = unknown>(mutation: string, options?: GraphQLRequestOptions): Promise<GraphQLResponse<T>>;
222
+ mutate<T = unknown>(mutation: string, options?: GraphQLRequestOptions): Promise<GraphQLResult<T>>;
204
223
  }
205
224
  /**
206
225
  * Extract the first named operation from a GraphQL query string.
@@ -320,6 +339,33 @@ export declare function createGraphQLClient(http: HttpClient, options: GraphQLCl
320
339
  * });
321
340
  * ```
322
341
  */
323
- export declare function graphql(options: GraphQLClientOptions): PluginFactory<GraphQLClient>;
342
+ export declare function graphql(options: GraphQLClientOptions): ClientFactory<GraphQLClient>;
324
343
  export { fromGql } from "./data.js";
344
+ /**
345
+ * Plugin manifest for `@glubean/graphql`. Declares:
346
+ *
347
+ * - `matchers` — 5 GraphQL-specific matchers (`toHaveGraphqlData`,
348
+ * `toHaveGraphqlNoErrors`, `toHaveGraphqlErrorCode`,
349
+ * `toHaveGraphqlExtension`, `toHaveHttpStatus`)
350
+ * - `contracts` — `graphql` protocol adapter
351
+ * - `setup()` — wraps the auto-attached `contract.graphql` dispatcher
352
+ * with `createGraphqlRoot` so `contract.graphql.with(...)`
353
+ * UX works
354
+ *
355
+ * Install explicitly in your project's `glubean.setup.ts`:
356
+ *
357
+ * ```ts
358
+ * import { installPlugin } from "@glubean/sdk";
359
+ * import graphqlPlugin from "@glubean/graphql";
360
+ * await installPlugin(graphqlPlugin);
361
+ * ```
362
+ *
363
+ * **Note:** top-level `import "@glubean/graphql"` is **no longer** a side-effect
364
+ * registration. The manifest must be explicitly installed (directly or via
365
+ * `bootstrap(projectRoot)` which loads `glubean.setup.ts`).
366
+ */
367
+ declare const graphqlPlugin: PluginManifest;
368
+ export default graphqlPlugin;
369
+ export { graphqlAdapter, createGraphqlFactory, createGraphqlRoot, graphqlMatchers, } from "./contract/index.js";
370
+ export type { GraphqlContractCase, GraphqlContractDefaults, GraphqlContractExample, GraphqlContractExpect, GraphqlContractFactory, GraphqlContractMeta, GraphqlContractRoot, GraphqlContractSafeMeta, GraphqlContractSpec, GraphqlCaseResult, GraphqlErrorsExpect, GraphqlFlowCaseOutput, GraphqlPayloadSchemas, GraphqlSafeSchemas, GraphqlTypeDef, GraphqlTypeDefs, InferGraphqlVariables, InferGraphqlResponse, } from "./contract/index.js";
325
371
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -51,7 +51,10 @@
51
51
  *
52
52
  * @module graphql
53
53
  */
54
- import { definePlugin } from "@glubean/sdk/plugin";
54
+ import { contract, defineClientFactory, definePlugin } from "@glubean/sdk";
55
+ import { graphqlAdapter } from "./contract/adapter.js";
56
+ import { createGraphqlRoot } from "./contract/factory.js";
57
+ import { graphqlMatchers } from "./contract/matchers.js";
55
58
  /**
56
59
  * Error thrown when a GraphQL response contains errors and
57
60
  * `throwOnGraphQLErrors` is enabled.
@@ -186,17 +189,33 @@ export function createGraphQLClient(http, options) {
186
189
  if (opName !== "anonymous") {
187
190
  body.operationName = opName;
188
191
  }
189
- const response = await http
190
- .post(endpoint, {
192
+ const res = await http.post(endpoint, {
191
193
  json: body,
192
194
  headers: mergedHeaders,
193
195
  throwHttpErrors: false,
194
- })
195
- .json();
196
- if (throwOnGraphQLErrors && response.errors && response.errors.length > 0) {
197
- throw new GraphQLResponseError(response.errors, response);
196
+ });
197
+ const rawBody = await res.text();
198
+ const headers = {};
199
+ res.headers.forEach((value, key) => {
200
+ headers[key.toLowerCase()] = value;
201
+ });
202
+ let parsed;
203
+ try {
204
+ parsed = rawBody ? JSON.parse(rawBody) : { data: null };
198
205
  }
199
- return response;
206
+ catch {
207
+ parsed = { data: null };
208
+ }
209
+ const result = {
210
+ ...parsed,
211
+ httpStatus: res.status,
212
+ headers,
213
+ rawBody,
214
+ };
215
+ if (throwOnGraphQLErrors && result.errors && result.errors.length > 0) {
216
+ throw new GraphQLResponseError(result.errors, result);
217
+ }
218
+ return result;
200
219
  }
201
220
  return {
202
221
  query: (query, options) => execute(query, options),
@@ -241,7 +260,7 @@ export function createGraphQLClient(http, options) {
241
260
  * ```
242
261
  */
243
262
  export function graphql(options) {
244
- return definePlugin((runtime) => {
263
+ return defineClientFactory((runtime) => {
245
264
  const resolved = {
246
265
  ...options,
247
266
  endpoint: runtime.resolveTemplate(options.endpoint),
@@ -257,4 +276,45 @@ export function graphql(options) {
257
276
  }
258
277
  // Re-export data loader for convenience (spec: `import { fromGql } from "@glubean/graphql"`)
259
278
  export { fromGql } from "./data.js";
279
+ // =============================================================================
280
+ // Plugin manifest (default export)
281
+ // =============================================================================
282
+ /**
283
+ * Plugin manifest for `@glubean/graphql`. Declares:
284
+ *
285
+ * - `matchers` — 5 GraphQL-specific matchers (`toHaveGraphqlData`,
286
+ * `toHaveGraphqlNoErrors`, `toHaveGraphqlErrorCode`,
287
+ * `toHaveGraphqlExtension`, `toHaveHttpStatus`)
288
+ * - `contracts` — `graphql` protocol adapter
289
+ * - `setup()` — wraps the auto-attached `contract.graphql` dispatcher
290
+ * with `createGraphqlRoot` so `contract.graphql.with(...)`
291
+ * UX works
292
+ *
293
+ * Install explicitly in your project's `glubean.setup.ts`:
294
+ *
295
+ * ```ts
296
+ * import { installPlugin } from "@glubean/sdk";
297
+ * import graphqlPlugin from "@glubean/graphql";
298
+ * await installPlugin(graphqlPlugin);
299
+ * ```
300
+ *
301
+ * **Note:** top-level `import "@glubean/graphql"` is **no longer** a side-effect
302
+ * registration. The manifest must be explicitly installed (directly or via
303
+ * `bootstrap(projectRoot)` which loads `glubean.setup.ts`).
304
+ */
305
+ const graphqlPlugin = definePlugin({
306
+ name: "@glubean/graphql",
307
+ matchers: graphqlMatchers,
308
+ contracts: { graphql: graphqlAdapter },
309
+ setup() {
310
+ // Replace the auto-attached dispatcher with the scoped-defaults factory
311
+ // so `contract.graphql.with("api", { client })("case", spec)` works.
312
+ // Runs after installPlugin calls contract.register().
313
+ const dispatcher = contract.graphql;
314
+ contract.graphql = createGraphqlRoot(dispatcher);
315
+ },
316
+ });
317
+ export default graphqlPlugin;
318
+ // Re-export contract surface for type consumers
319
+ export { graphqlAdapter, createGraphqlFactory, createGraphqlRoot, graphqlMatchers, } from "./contract/index.js";
260
320
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}