@lewebsimple/nuxt-graphql 0.6.0 → 0.6.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/README.md CHANGED
@@ -18,7 +18,7 @@ Opinionated Nuxt module that wires a typed GraphQL server + client into your app
18
18
  - 🧠 **Type-safe helpers** for **queries, mutations, and subscriptions**, shared across **client + server**
19
19
  - 🧊 **SSR-friendly** by default: request header forwarding + server-side schema execution helpers
20
20
  - 🚀 **Client-side cache** for `useAsyncGraphQLQuery` (cache policies + optional persistence in localStorage)
21
- - 🧯 **Unified error model** via `SafeResult` and `NormalizedError`
21
+ - 🧯 **Unified error model** via `GraphQLExecutionResult` and `NormalizedError`
22
22
 
23
23
 
24
24
  ## Getting started
@@ -38,13 +38,12 @@ Declare your schemas, context, documents glob and optional client cache in [nuxt
38
38
  export default defineNuxtConfig({
39
39
  modules: ["@lewebsimple/nuxt-graphql"],
40
40
  graphql: {
41
- yoga: {
41
+ server: {
42
42
  // Schemas to stitch together (local and/or remote)
43
- schemas: {
44
- local: {
45
- type: "local",
46
- path: "server/graphql/schema.ts",
47
- },
43
+ schema: {
44
+ // Local schema example
45
+ local: { type: "local", path: "server/graphql/schema.ts" },
46
+
48
47
  // Remote schema example
49
48
  swapi: {
50
49
  type: "remote",
@@ -91,7 +90,7 @@ export default defineNuxtConfig({
91
90
  ```
92
91
 
93
92
 
94
- ### Define schema(s) (local and/or remote)
93
+ ### Define GraphQL schema (local and/or remote)
95
94
 
96
95
  **Local schemas** must live under `server/` and export a `GraphQLSchema` as `schema`.
97
96
 
@@ -134,12 +133,14 @@ export const schema = createSchema<GraphQLContext>({
134
133
  });
135
134
  ```
136
135
 
137
- **Remote schemas** are introspected at build time from the required endpoint URL and executed via an HTTP executor at runtime. Subscriptions are stripped from remote schemas.
136
+ **Remote schemas** are introspected at build time from the endpoint URL and executed via an HTTP executor at runtime. Subscriptions are stripped from remote schemas.
137
+
138
+ The final schema is stitched from the all of the defined local / remote schemas.
138
139
 
139
140
 
140
- ### Define GraphQL context factories (optional)
141
+ ### Define GraphQL context (optional)
141
142
 
142
- Context factories are optional and run on the server in order. Their return types are merged into a single `GraphQLContext` type. You can use the auto-imported `defineGraphQLContext` helper for type-safety.
143
+ Context definition is optional and factories resolve in order on the server. Their return types are merged into a single `GraphQLContext` type which is exported from `#graphql/context`. You can use the auto-imported `defineGraphQLContext` helper for type-safety.
143
144
 
144
145
  For example, create [server/graphql/context.ts](server/graphql/context.ts):
145
146
 
@@ -157,15 +158,10 @@ export default defineGraphQLContext(async (event) => {
157
158
 
158
159
  ### Write GraphQL documents (.gql)
159
160
 
160
- Write operations in `.gql` files; operation names become registry keys like `useGraphQLQuery("HelloWorld")`.
161
+ By default, the module scans `**/*.gql` files for **named operations** and **fragments** which are converted into **types** and **typed document nodes** in `#graphql/operations`. The operations are exposed by name in `#graphql/registry` to allow type-safe execution with the provided **composables** and **server utils**.
161
162
 
162
163
  ⚠️ Operation names are required and must be unique.
163
164
 
164
- By default, the module scans `**/*.gql` and generates:
165
-
166
- - Typed documents and operations / fragments types in virtual modules under the `#graphql/operations` alias (internal)
167
- - Operation registry in virtual modules under the `#graphql/registry` alias (internal)
168
-
169
165
  Example document files:
170
166
 
171
167
  ```graphql
@@ -231,25 +227,13 @@ The auto-imported composables allow executing queries, mutations, and subscripti
231
227
 
232
228
  ```ts
233
229
  // Cached query via useAsyncData
234
- const { data, pending, error, refresh } = await useAsyncGraphQLQuery(
235
- "HelloWorld",
236
- undefined,
237
- {
238
- headers: {
239
- "X-Request-Header": "request-header-value",
240
- },
241
- },
242
- );
230
+ const { data, pending, error, refresh } = await useAsyncGraphQLQuery("HelloWorld", undefined);
243
231
 
244
232
  // Direct HTTP query (SafeResult)
245
233
  const { data: queryData, error: queryError } = await useGraphQLQuery("HelloWorld");
246
234
 
247
235
  // Mutation (SafeResult)
248
- const { mutate, pending: mutationPending } = useGraphQLMutation("Ping", {
249
- headers: {
250
- "X-Request-Header": "request-header-value",
251
- },
252
- });
236
+ const { mutate, pending: mutationPending } = useGraphQLMutation("Ping");
253
237
  const { data: mutationData, error: mutationError } = await mutate({ message: "Hello!" });
254
238
 
255
239
  // Subscription (client-only, SSE)
@@ -257,30 +241,24 @@ const { data, error, start, stop } = useGraphQLSubscription("Time");
257
241
  ```
258
242
 
259
243
 
260
- ### Use the auto-imported server-side utilities
244
+ ### Use the auto-imported server utils
261
245
 
262
246
  In server routes, you can execute queries and mutations directly against the stitched schema (no HTTP roundtrip):
263
247
 
264
248
  ```ts
265
249
  export default defineEventHandler(async (event) => {
266
250
  // Server-side GraphQL query example
267
- const { data: queryData, error: queryError } = await useServerGraphQLQuery(
268
- event,
269
- "HelloWorld",
270
- );
251
+ const { data: queryData, error: queryError } = await useGraphQLOperation(event, "HelloWorld" );
271
252
 
272
253
  // Server-side GraphQL mutation example
273
- const { data: mutationData } = await useServerGraphQLMutation(
274
- event,
275
- "Ping",
276
- { message: queryData?.hello ?? "fallback" },
254
+ const { data: mutationData } = await useGraphQLOperation(event, "Ping", { message: queryData?.hello ?? "Pong" },
277
255
  );
278
256
 
279
257
  return { queryData, mutationData, queryError };
280
258
  });
281
259
  ```
282
260
 
283
- Server helpers return a `SafeResult` in the same format as the client helpers.
261
+ Server helpers return a `GraphQLExecutionResult` in the same format as some composables, i.e. `{ data: TResult, error: null } | { data: null, error: NormalizedError }`
284
262
 
285
263
 
286
264
  ### Query caching (client-side only)
@@ -293,10 +271,10 @@ Server helpers return a `SafeResult` in the same format as the client helpers.
293
271
 
294
272
  #### Cache policies
295
273
 
296
- - "no-cache": always fetches from the network (still dedupes in-flight).
297
- - "cache-first": returns cached value when present, otherwise fetches.
298
- - "network-first": tries the network first, falls back to cached value on error.
299
- - "swr": returns cached value immediately and refreshes in the background.
274
+ - `"no-cache"`: always fetches from the network (still dedupes in-flight).
275
+ - `"cache-first"`: returns cached value when present, otherwise fetches.
276
+ - `"network-first"`: tries the network first, falls back to cached value on error.
277
+ - `"swr"`: returns cached value immediately and refreshes in the background.
300
278
 
301
279
  #### Per-query overrides
302
280
 
@@ -334,20 +312,16 @@ You can define custom logic around the remote executor for each remote schema by
334
312
  For the example configuration above, create [server/graphql/swapi-hooks.ts](server/graphql/swapi-hooks.ts):
335
313
 
336
314
  ```ts
315
+ import { defu } from "defu";
316
+
337
317
  export default defineRemoteExecutorHooks({
338
318
  onRequest(request) {
339
- // Dynamically inject headers
340
- request.extensions ??= {};
341
- request.extensions.headers = {
342
- ...request.extensions.headers,
343
- "X-Remote-Exec-Request-Header": "custom-value",
344
- };
345
- },
346
- onResult(result) {
347
- console.log("Remote result", result);
348
- },
349
- onError(error) {
350
- console.error("Remote error", error);
319
+ const { remoteAuthToken } = request.context || {};
320
+ request.extensions = defu(request.extensions, {
321
+ headers: {
322
+ "XAuthorization": `Bearer ${remoteAuthToken || ""}`,
323
+ },
324
+ });
351
325
  },
352
326
  });
353
327
  ```
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lewebsimple/nuxt-graphql",
3
3
  "configKey": "graphql",
4
- "version": "0.6.0",
4
+ "version": "0.6.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -149,7 +149,7 @@ const executor = getRemoteExecutor({
149
149
  hooks: [${hooksArray.join(", ")}],
150
150
  });
151
151
 
152
- const sdl = \`${sdl.replace(/`/g, "\\`")}\`;
152
+ const sdl = ${JSON.stringify(sdl)};
153
153
 
154
154
  // SubschemaConfig exported for stitching
155
155
  export const schema = {
@@ -203,7 +203,7 @@ function addUniversalTemplate({ filename, getContents, emitTs }) {
203
203
  return modulePath;
204
204
  }
205
205
 
206
- const version = "0.6.0";
206
+ const version = "0.6.2";
207
207
 
208
208
  async function getDocuments(documentsGlob) {
209
209
  try {
@@ -1,6 +1,8 @@
1
1
  import type { ExecutionRequest, ExecutionResult } from "@graphql-tools/utils";
2
+ import type { GraphQLContext } from "#graphql/context";
2
3
  import { type HeadersInput } from "../../shared/lib/headers.js";
3
- type GraphQLExecutionRequest = ExecutionRequest & {
4
+ import type { GraphQLVariables } from "../../shared/lib/types.js";
5
+ type GraphQLExecutionRequest = ExecutionRequest<GraphQLVariables, GraphQLContext> & {
4
6
  extensions?: {
5
7
  headers?: HeadersInput;
6
8
  };
@@ -5,7 +5,7 @@ export function getYogaInstance() {
5
5
  if (!yoga) {
6
6
  yoga = createYoga({
7
7
  graphqlEndpoint: "/api/graphql",
8
- graphiql: true,
8
+ graphiql: import.meta.dev,
9
9
  fetchAPI: globalThis,
10
10
  schema
11
11
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lewebsimple/nuxt-graphql",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Opinionated Nuxt module for using GraphQL",
5
5
  "repository": "your-org/@lewebsimple/nuxt-graphql",
6
6
  "license": "AGPL-3.0-only",