@lewebsimple/nuxt-graphql 0.5.2 → 0.5.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/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-graphql",
3
3
  "configKey": "graphql",
4
- "version": "0.5.2",
4
+ "version": "0.5.3",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { mkdirSync, writeFileSync } from 'node:fs';
2
- import { resolve, dirname, relative } from 'node:path';
3
- import { defineNuxtModule, useLogger, createResolver, addTemplate, addServerHandler, addPlugin, addImportsDir, addServerImportsDir } from '@nuxt/kit';
2
+ import { dirname, relative, resolve } from 'node:path';
3
+ import { defineNuxtModule, useLogger, createResolver, addTemplate, addServerTemplate, addTypeTemplate, addServerHandler, addPlugin, addImportsDir, addServerImportsDir } from '@nuxt/kit';
4
+ import { defu } from 'defu';
4
5
  import { hash } from 'ohash';
5
6
  import { loadDocuments as loadDocuments$1 } from '@graphql-tools/load';
6
7
  import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
@@ -56,7 +57,7 @@ async function renderFragmentsTemplate({ documents }) {
56
57
  }
57
58
  return [
58
59
  `export type {`,
59
- ...fragments.map((name) => ` ${name} as ${name}Fragment,`),
60
+ ...fragments.map((name) => ` ${name}Fragment,`),
60
61
  `} from "./operations";`
61
62
  ].join("\n");
62
63
  }
@@ -85,29 +86,51 @@ async function renderOperationsTemplate({ schema, documents }) {
85
86
  schema,
86
87
  documents,
87
88
  plugins: [
88
- { typescript: {} },
89
- { typescriptOperations: {} },
90
- { typedDocumentNode: {} }
89
+ {
90
+ typescript: {
91
+ avoidOptionals: true,
92
+ defaultScalarType: "never",
93
+ enumsAsTypes: true,
94
+ immutableTypes: true,
95
+ maybeValue: "T | null",
96
+ preResolveTypes: false,
97
+ strictScalars: true,
98
+ useTypeImports: true
99
+ }
100
+ },
101
+ {
102
+ typescriptOperations: {
103
+ avoidOptionals: true,
104
+ defaultScalarType: "never",
105
+ enumsAsTypes: true,
106
+ exportFragmentSpreadSubTypes: true,
107
+ immutableTypes: true,
108
+ inlineFragmentTypes: "combine",
109
+ maybeValue: "T | null",
110
+ operationResultSuffix: "Result",
111
+ operationVariablesSuffix: "Variables",
112
+ preResolveTypes: false,
113
+ skipTypename: true,
114
+ strictScalars: true,
115
+ useTypeImports: true
116
+ }
117
+ },
118
+ {
119
+ typedDocumentNode: {
120
+ documentVariableSuffix: "Document",
121
+ operationResultSuffix: "Result",
122
+ operationVariablesSuffix: "Variables",
123
+ optimizeDocumentNode: true,
124
+ useTypeImports: true
125
+ }
126
+ }
91
127
  ],
92
128
  pluginMap: {
93
129
  typescript: typescriptPlugin,
94
130
  typescriptOperations: typescriptOperationsPlugin,
95
131
  typedDocumentNode: typedDocumentNodePlugin
96
132
  },
97
- config: {
98
- defaultScalarType: "never",
99
- documentMode: "documentNode",
100
- documentVariableSuffix: "Document",
101
- enumsAsTypes: true,
102
- inlineFragmentTypes: "combine",
103
- omitOperationSuffix: true,
104
- operationResultSuffix: "Result",
105
- operationVariablesSuffix: "Variables",
106
- preResolveTypes: false,
107
- skipTypename: true,
108
- strictScalars: true,
109
- useTypeImports: true
110
- }
133
+ config: {}
111
134
  });
112
135
  return output;
113
136
  }
@@ -118,63 +141,41 @@ async function renderRegistryTemplate({ documents }) {
118
141
  `import type { DocumentNode } from "graphql";`,
119
142
  `import {`,
120
143
  ...operations.map(
121
- ({ name }) => ` ${name}Document, type ${name}Variables, type ${name}Result,`
144
+ ({ name }) => ` ${name}Document, type ${name}QueryVariables, type ${name}QueryResult,`
122
145
  ),
123
146
  `} from "./operations";`,
124
147
  ``,
125
148
  // Operation entry
126
- `export interface OperationEntry<`,
127
- ` TVariables,`,
128
- ` TResult,`,
129
- ` TKind extends "query" | "mutation" | "subscription"`,
130
- `> {`,
149
+ `export interface OperationEntry<TVariables, TResult, TKind extends "query" | "mutation" | "subscription"> {`,
131
150
  ` kind: TKind;`,
132
151
  ` variables: TVariables;`,
133
152
  ` result: TResult;`,
134
153
  ` document: DocumentNode;`,
135
154
  `}`,
136
155
  ``,
156
+ // Operation registry type
137
157
  `export type OperationRegistry = {`,
138
158
  ...operations.map(
139
- ({ name, kind }) => ` ${name}: OperationEntry<${name}Variables, ${name}Result, "${kind}">;`
159
+ ({ name, kind }) => ` ${name}: OperationEntry<${name}QueryVariables, ${name}QueryResult, "${kind}">;`
140
160
  ),
141
161
  `};`,
142
162
  ``,
143
- `export type OperationName = keyof OperationRegistry;`,
144
- ``,
145
- `export type QueryName = {`,
146
- ` [K in keyof OperationRegistry]:`,
147
- ` OperationRegistry[K]["kind"] extends "query" ? K : never`,
148
- `}[keyof OperationRegistry];`,
149
- ``,
150
- `export type MutationName = {`,
151
- ` [K in keyof OperationRegistry]:`,
152
- ` OperationRegistry[K]["kind"] extends "mutation" ? K : never`,
153
- `}[keyof OperationRegistry];`,
154
- ``,
155
- `export type SubscriptionName = {`,
156
- ` [K in keyof OperationRegistry]:`,
157
- ` OperationRegistry[K]["kind"] extends "subscription" ? K : never`,
158
- `}[keyof OperationRegistry];`,
159
- ``,
160
- // Projection helpers
161
- `export type VariablesOf<TName extends keyof OperationRegistry> =`,
162
- ` OperationRegistry[TName]["variables"];`,
163
+ // Operation name types
164
+ `export type QueryName = { [K in keyof OperationRegistry]: OperationRegistry[K]["kind"] extends "query" ? K : never }[keyof OperationRegistry];`,
165
+ `export type MutationName = { [K in keyof OperationRegistry]: OperationRegistry[K]["kind"] extends "mutation" ? K : never }[keyof OperationRegistry];`,
166
+ `export type SubscriptionName = { [K in keyof OperationRegistry]: OperationRegistry[K]["kind"] extends "subscription" ? K : never }[keyof OperationRegistry];`,
163
167
  ``,
164
- `export type ResultOf<TName extends keyof OperationRegistry> =`,
165
- ` OperationRegistry[TName]["result"];`,
168
+ // Projection helpers (variables / result)
169
+ `export type VariablesOf<TName extends keyof OperationRegistry> = OperationRegistry[TName]["variables"];`,
170
+ `export type ResultOf<TName extends keyof OperationRegistry> = OperationRegistry[TName]["result"];`,
166
171
  ``,
167
172
  // Runtime registry (document + kind only)
168
- `export const registry: {`,
169
- ` [K in keyof OperationRegistry]: {`,
170
- ` kind: OperationRegistry[K]["kind"];`,
171
- ` document: DocumentNode;`,
172
- ` };`,
173
- `} = {`,
173
+ `export const registry: { [K in keyof OperationRegistry]: { kind: OperationRegistry[K]["kind"]; document: DocumentNode; }; } = {`,
174
174
  ...operations.map(
175
175
  ({ name, kind }) => ` ${name}: { kind: "${kind}", document: ${name}Document },`
176
176
  ),
177
- `};`
177
+ `};`,
178
+ ``
178
179
  ].join("\n");
179
180
  }
180
181
  function collectOperations(documents) {
@@ -290,30 +291,65 @@ async function loadStitchedSchema(schemaDefs) {
290
291
  return stitchSchemas({ subschemas });
291
292
  }
292
293
 
293
- function renderTypesTemplate() {
294
- return `// Nuxt GraphQL types
295
- declare module "#graphql/context" {
296
- export { createContext } from "#build/graphql/context";
297
- export type { GraphQLContext } from "#build/graphql/context";
294
+ function renderAppTypesTemplate() {
295
+ return `// Nuxt GraphQL types (app)
296
+ import type { GraphQLClient } from "graphql-request";
297
+ import type { Client as SSEClient } from "graphql-sse";
298
+
299
+ declare module "#app/nuxt" {
300
+ interface NuxtApp {
301
+ $getGraphQLClient: () => GraphQLClient;
302
+ $getGraphQLSSEClient: () => SSEClient;
303
+ }
298
304
  }
299
305
 
300
- declare module "#graphql/operations" {
301
- export * from "#build/graphql/operations";
306
+ declare module "#app" {
307
+ interface NuxtApp {
308
+ $getGraphQLClient: () => GraphQLClient;
309
+ $getGraphQLSSEClient: () => SSEClient;
310
+ }
302
311
  }
303
312
 
304
- declare module "#graphql/fragments" {
305
- export * from "#build/graphql/fragments";
313
+ export {};
314
+ `;
306
315
  }
316
+ function renderServerTypesTemplate() {
317
+ return `// Nuxt GraphQL types (server)
318
+ import type { GraphQLSchema } from "graphql";
307
319
 
308
- declare module "#graphql/registry" {
309
- import type { DocumentNode } from "graphql";
310
- export type { OperationName, QueryName, MutationName, SubscriptionName, VariablesOf, ResultOf } from "#build/graphql/registry";
311
- export const registry: Readonly<Record<OperationName, { readonly document: DocumentNode; }>>;
320
+ declare module "#graphql/context" {
321
+ export type { GraphQLContext };
312
322
  }
313
323
 
314
324
  declare module "#graphql/schema" {
315
- export { schema } from "#build/graphql/schema";
316
- }`;
325
+ export const schema: GraphQLSchema;
326
+ }
327
+
328
+ declare module "h3" {
329
+ interface H3EventContext {
330
+ _graphqlInFlightRequestsMap?: Map<string, Promise<unknown>>;
331
+ }
332
+ }
333
+
334
+ export {};
335
+ `;
336
+ }
337
+ function renderSharedTypesTemplate() {
338
+ return `// Nuxt GraphQL types (shared)
339
+ import type { DocumentNode } from "graphql";
340
+ import type { CacheConfig } from "nuxt-graphql/runtime/shared/lib/cache-config";
341
+
342
+ declare module "nuxt/schema" {
343
+ interface PublicRuntimeConfig {
344
+ graphql: {
345
+ cacheConfig?: CacheConfig;
346
+ ssrForwardHeaders: string[];
347
+ };
348
+ }
349
+ }
350
+
351
+ export {};
352
+ `;
317
353
  }
318
354
 
319
355
  const module$1 = defineNuxtModule({
@@ -324,6 +360,7 @@ const module$1 = defineNuxtModule({
324
360
  defaults: {},
325
361
  async setup(options, nuxt) {
326
362
  const logger = useLogger("graphql");
363
+ const { resolve: resolveBuild } = createResolver(nuxt.options.buildDir);
327
364
  const { resolve: resolveModule } = createResolver(import.meta.url);
328
365
  const { resolve: resolveRoot, resolvePath: _resolveRootPath } = createResolver(nuxt.options.rootDir);
329
366
  async function resolveRootPath(path, required = true) {
@@ -345,32 +382,23 @@ const module$1 = defineNuxtModule({
345
382
  return relativePath;
346
383
  }
347
384
  nuxt.options.alias ||= {};
348
- nuxt.options.alias["#graphql"] = resolve(nuxt.options.buildDir, "graphql");
349
- const nitroAlias = {};
385
+ nuxt.options.alias["#graphql"] ||= resolveBuild("graphql");
350
386
  const contextModules = [
351
387
  resolveModule("./runtime/server/lib/default-context"),
352
388
  ...await Promise.all((options.yoga?.context || []).map((path) => resolveRootPath(path, true)))
353
389
  ];
354
- const contextTemplate = addTemplate({
355
- filename: "graphql/context.ts",
356
- getContents: () => renderContextTemplate({ contextModules }),
357
- write: true
358
- });
359
- nitroAlias["#graphql/context"] = contextTemplate.dst;
390
+ addTemplate({ filename: "graphql/context.ts", getContents: () => renderContextTemplate({ contextModules }), write: true });
391
+ addServerTemplate({ filename: "#graphql/#context.ts", getContents: () => renderContextTemplate({ contextModules }) });
360
392
  const schemaDefs = {};
361
393
  for (const [schemaName, schemaDef] of Object.entries(options.yoga?.schemas || {})) {
362
- let schemaTemplate2;
363
394
  if (schemaDef.type === "local") {
364
395
  const localSchemaDef = {
365
396
  ...schemaDef,
366
397
  path: await resolveRootPath(schemaDef.path, true)
367
398
  };
368
399
  schemaDefs[schemaName] = localSchemaDef;
369
- schemaTemplate2 = addTemplate({
370
- filename: `graphql/schemas/${schemaName}.ts`,
371
- getContents: async () => renderLocalSchemaTemplate({ ...localSchemaDef }),
372
- write: true
373
- });
400
+ addTemplate({ filename: `graphql/schemas/${schemaName}.ts`, getContents: async () => renderLocalSchemaTemplate({ ...localSchemaDef }), write: true });
401
+ addServerTemplate({ filename: `#graphql/schemas/${schemaName}.ts`, getContents: async () => renderLocalSchemaTemplate({ ...localSchemaDef }) });
374
402
  } else if (schemaDef.type === "remote") {
375
403
  const remoteSchemaDef = {
376
404
  ...schemaDef,
@@ -378,24 +406,14 @@ const module$1 = defineNuxtModule({
378
406
  remoteExecutorModule: resolveModule("./runtime/server/lib/remote-executor")
379
407
  };
380
408
  schemaDefs[schemaName] = remoteSchemaDef;
381
- schemaTemplate2 = addTemplate({
382
- filename: `graphql/schemas/${schemaName}.ts`,
383
- getContents: async () => await renderRemoteSchemaTemplate({ ...remoteSchemaDef }),
384
- write: true
385
- });
409
+ addTemplate({ filename: `graphql/schemas/${schemaName}.ts`, getContents: async () => await renderRemoteSchemaTemplate({ ...remoteSchemaDef }), write: true });
410
+ addServerTemplate({ filename: `#graphql/schemas/${schemaName}.ts`, getContents: async () => await renderRemoteSchemaTemplate({ ...remoteSchemaDef }) });
386
411
  } else {
387
412
  throw new Error(`Unknown schema type for schema "${schemaName}"`);
388
413
  }
389
- nitroAlias[`#graphql/schemas/${schemaName}`] = schemaTemplate2.dst;
390
414
  }
391
- const schemaTemplate = addTemplate({
392
- filename: "graphql/schema.ts",
393
- getContents: () => renderStitchedSchemaTemplate({
394
- schemaNames: Object.keys(options.yoga?.schemas || {})
395
- }),
396
- write: true
397
- });
398
- nitroAlias["#graphql/schema"] = schemaTemplate.dst;
415
+ addTemplate({ filename: "graphql/schema.ts", getContents: () => renderStitchedSchemaTemplate({ schemaNames: Object.keys(options.yoga?.schemas || {}) }), write: true });
416
+ addServerTemplate({ filename: "#graphql/schema.ts", getContents: () => renderStitchedSchemaTemplate({ schemaNames: Object.keys(options.yoga?.schemas || {}) }) });
399
417
  let documentsCache = null;
400
418
  async function getDocuments(glob) {
401
419
  const key = `documents:${glob}`;
@@ -439,27 +457,17 @@ const module$1 = defineNuxtModule({
439
457
  }),
440
458
  write: true
441
459
  });
460
+ addTypeTemplate({ filename: "types/nuxt-graphql.app.d.ts", getContents: () => renderAppTypesTemplate() }, { nuxt: true });
461
+ addTypeTemplate({ filename: "types/nuxt-graphql.server.d.ts", getContents: () => renderServerTypesTemplate() }, { nitro: true });
462
+ addTypeTemplate({ filename: "types/nuxt-graphql.shared.d.ts", getContents: () => renderSharedTypesTemplate() }, { nuxt: true, nitro: true });
442
463
  const configPath = resolveRoot(options.saveConfig || "graphql.config.json");
443
464
  const config = { schema: getRelativePath(sdlPath), documents: options.client?.documents || "**/*.gql" };
444
465
  mkdirSync(dirname(configPath), { recursive: true });
445
466
  writeFileSync(configPath, JSON.stringify(config, null, 2), { encoding: "utf-8" });
446
467
  logger.info(`GraphQL config saved to: ${cyan}${getRelativePath(configPath)}${reset}`);
447
- const typesTemplate = addTemplate({
448
- filename: "graphql/types.d.ts",
449
- getContents: () => renderTypesTemplate(),
450
- write: true
451
- });
452
- nuxt.options.runtimeConfig.public.graphql = {
468
+ nuxt.options.runtimeConfig.public.graphql = defu(nuxt.options.runtimeConfig.public.graphql, {
453
469
  cacheConfig: resolveCacheConfig(options.client?.cache),
454
470
  ssrForwardHeaders: options.client?.ssrForwardHeaders || ["authorization", "cookie"]
455
- };
456
- nuxt.hook("prepare:types", ({ sharedReferences }) => {
457
- sharedReferences.push({ path: typesTemplate.dst });
458
- sharedReferences.push({ path: resolveModule("./runtime/shared/types/nuxt-graphql.d.ts") });
459
- });
460
- nuxt.hook("nitro:config", (nitroConfig) => {
461
- nitroConfig.alias ||= {};
462
- Object.assign(nitroConfig.alias, nitroAlias);
463
471
  });
464
472
  if (nuxt.options.dev) {
465
473
  nuxt.hook("builder:watch", async (_event, changedPath) => {
@@ -471,7 +479,7 @@ const module$1 = defineNuxtModule({
471
479
  }
472
480
  addServerHandler({ route: "/api/graphql", handler: resolveModule("./runtime/server/api/graphql") });
473
481
  nuxt.hook("listen", (_, { url }) => {
474
- logger.success(`GraphQL Yoga ready: ${cyan}${url.replace(/\/$/, "")} / api / graphql${reset}`);
482
+ logger.success(`GraphQL Yoga ready: ${cyan}${url.replace(/\/$/, "")}/api/graphql${reset}`);
475
483
  });
476
484
  addPlugin(resolveModule("./runtime/app/plugins/graphql-request"));
477
485
  addPlugin(resolveModule("./runtime/app/plugins/graphql-sse.client"));
@@ -1,5 +1,5 @@
1
1
  type GraphQLCachePolicy = "no-cache" | "cache-first" | "network-first" | "swr";
2
- export interface CacheConfig {
2
+ export type CacheConfig = {
3
3
  /**
4
4
  * Prefix used for all persisted cache keys.
5
5
  *
@@ -31,7 +31,7 @@ export interface CacheConfig {
31
31
  * - > 0 → expires after TTL
32
32
  */
33
33
  ttl?: number;
34
- }
34
+ };
35
35
  /**
36
36
  * Merge the default cache config with user overrides.
37
37
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lewebsimple/nuxt-graphql",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Opinionated Nuxt module for using GraphQL",
5
5
  "repository": "lewebsimple/nuxt-graphql",
6
6
  "license": "AGPL-3.0-only",
@@ -36,6 +36,7 @@
36
36
  "@graphql-tools/load": "^8.1.8",
37
37
  "@graphql-tools/stitch": "^10.1.8",
38
38
  "@nuxt/kit": "^4.2.2",
39
+ "defu": "^6.1.4",
39
40
  "graphql": "^16.12.0",
40
41
  "graphql-request": "^7.4.0",
41
42
  "graphql-sse": "^2.6.0",
@@ -1,33 +0,0 @@
1
- import type { GraphQLClient } from "graphql-request";
2
- import type { Client as SSEClient } from "graphql-sse";
3
-
4
- declare module "h3" {
5
- interface H3EventContext {
6
- _graphqlInFlightRequestsMap?: Map<string, Promise<unknown>>;
7
- }
8
- }
9
-
10
- declare module "nuxt/schema" {
11
- interface PublicRuntimeConfig {
12
- graphql: {
13
- cacheConfig: GraphQLCacheConfig;
14
- ssrForwardHeaders: string[];
15
- };
16
- }
17
- }
18
-
19
- declare module "#app/nuxt" {
20
- interface NuxtApp {
21
- $getGraphQLClient: () => GraphQLClient;
22
- $getGraphQLSSEClient: () => SSEClient;
23
- }
24
- }
25
-
26
- declare module "#app" {
27
- interface NuxtApp {
28
- $getGraphQLClient: () => GraphQLClient;
29
- $getGraphQLSSEClient: () => SSEClient;
30
- }
31
- }
32
-
33
- export { };