@lewebsimple/nuxt-graphql 0.4.0 → 0.5.0
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 +134 -188
- package/dist/module.d.mts +74 -22
- package/dist/module.json +2 -2
- package/dist/module.mjs +408 -369
- package/dist/runtime/app/composables/useAsyncGraphQLQuery.d.ts +19 -0
- package/dist/runtime/app/composables/useAsyncGraphQLQuery.js +82 -0
- package/dist/runtime/app/composables/useGraphQLCache.client.d.ts +10 -7
- package/dist/runtime/app/composables/useGraphQLCache.client.js +16 -31
- package/dist/runtime/app/composables/useGraphQLMutation.d.ts +10 -18
- package/dist/runtime/app/composables/useGraphQLMutation.js +7 -11
- package/dist/runtime/app/composables/useGraphQLQuery.d.ts +11 -9
- package/dist/runtime/app/composables/useGraphQLQuery.js +20 -78
- package/dist/runtime/app/composables/useGraphQLSubscription.client.d.ts +19 -0
- package/dist/runtime/app/composables/{useGraphQLSubscription.js → useGraphQLSubscription.client.js} +9 -14
- package/dist/runtime/app/lib/cache.d.ts +18 -0
- package/dist/runtime/app/lib/cache.js +9 -0
- package/dist/runtime/app/lib/execute-http.d.ts +14 -0
- package/dist/runtime/app/lib/execute-http.js +8 -0
- package/dist/runtime/app/lib/in-flight.d.ts +14 -0
- package/dist/runtime/app/lib/{graphql-cache.js → in-flight.js} +2 -7
- package/dist/runtime/app/lib/persisted.d.ts +26 -0
- package/dist/runtime/app/plugins/graphql-request.d.ts +7 -2
- package/dist/runtime/app/plugins/graphql-request.js +13 -14
- package/dist/runtime/app/plugins/graphql-sse.client.d.ts +7 -2
- package/dist/runtime/server/api/graphql.d.ts +8 -0
- package/dist/runtime/server/api/graphql.js +16 -0
- package/dist/runtime/server/lib/context.d.ts +10 -0
- package/dist/runtime/server/lib/context.js +3 -0
- package/dist/runtime/server/lib/default-context.d.ts +5 -0
- package/dist/runtime/server/lib/default-context.js +2 -0
- package/dist/runtime/server/lib/default-schema.d.ts +7 -0
- package/dist/runtime/server/lib/default-schema.js +18 -0
- package/dist/runtime/server/lib/execute-schema.d.ts +11 -0
- package/dist/runtime/server/lib/execute-schema.js +23 -0
- package/dist/runtime/server/lib/remote-executor.d.ts +29 -34
- package/dist/runtime/server/lib/remote-executor.js +27 -59
- package/dist/runtime/server/lib/schemas.d.ts +14 -0
- package/dist/runtime/server/lib/schemas.js +3 -0
- package/dist/runtime/server/lib/yoga.d.ts +6 -0
- package/dist/runtime/server/lib/yoga.js +20 -0
- package/dist/runtime/server/utils/useServerGraphQLMutation.d.ts +16 -8
- package/dist/runtime/server/utils/useServerGraphQLMutation.js +12 -11
- package/dist/runtime/server/utils/useServerGraphQLQuery.d.ts +16 -3
- package/dist/runtime/server/utils/useServerGraphQLQuery.js +16 -4
- package/dist/runtime/shared/lib/cache-config.d.ts +42 -0
- package/dist/runtime/{app → shared}/lib/cache-config.js +3 -3
- package/dist/runtime/shared/lib/error.d.ts +56 -0
- package/dist/runtime/shared/lib/error.js +61 -0
- package/dist/runtime/shared/lib/headers.d.ts +13 -3
- package/dist/runtime/shared/lib/headers.js +10 -35
- package/dist/runtime/shared/lib/registry.d.ts +12 -0
- package/dist/runtime/shared/lib/registry.js +8 -0
- package/dist/runtime/shared/lib/utils.d.ts +1 -0
- package/dist/runtime/shared/lib/utils.js +0 -0
- package/dist/runtime/{app → shared}/types/nuxt-graphql.d.ts +1 -5
- package/dist/types.d.mts +4 -0
- package/package.json +19 -33
- package/dist/helpers.d.mts +0 -3
- package/dist/helpers.mjs +0 -3
- package/dist/runtime/app/composables/useGraphQLSubscription.d.ts +0 -17
- package/dist/runtime/app/lib/cache-config.d.ts +0 -8
- package/dist/runtime/app/lib/graphql-cache.d.ts +0 -7
- package/dist/runtime/server/api/yoga-handler.d.ts +0 -2
- package/dist/runtime/server/api/yoga-handler.js +0 -42
- package/dist/runtime/server/lib/define-graphql-context.d.ts +0 -5
- package/dist/runtime/server/lib/define-graphql-context.js +0 -4
- package/dist/runtime/server/lib/define-remote-exec-middleware.d.ts +0 -30
- package/dist/runtime/server/lib/define-remote-exec-middleware.js +0 -3
- package/dist/runtime/server/lib/define-yoga-middleware.d.ts +0 -21
- package/dist/runtime/server/lib/define-yoga-middleware.js +0 -3
- package/dist/runtime/server/lib/execute-server-graphql.d.ts +0 -7
- package/dist/runtime/server/lib/execute-server-graphql.js +0 -34
- package/dist/runtime/shared/lib/graphql-error.d.ts +0 -17
- package/dist/runtime/shared/lib/graphql-error.js +0 -28
package/dist/module.mjs
CHANGED
|
@@ -1,260 +1,276 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
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';
|
|
4
|
+
import { hash } from 'ohash';
|
|
5
|
+
import { loadDocuments as loadDocuments$1 } from '@graphql-tools/load';
|
|
6
|
+
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
|
|
7
|
+
import { Kind, getIntrospectionQuery, buildClientSchema, GraphQLSchema } from 'graphql';
|
|
8
|
+
import { codegen } from '@graphql-codegen/core';
|
|
9
|
+
import * as typescriptPlugin from '@graphql-codegen/typescript';
|
|
10
|
+
import * as typescriptOperationsPlugin from '@graphql-codegen/typescript-operations';
|
|
11
|
+
import * as typedDocumentNodePlugin from '@graphql-codegen/typed-document-node';
|
|
12
|
+
import { mergeHeaders } from '../dist/runtime/shared/lib/headers.js';
|
|
13
|
+
import { stitchSchemas } from '@graphql-tools/stitch';
|
|
14
|
+
import { resolveCacheConfig } from '../dist/runtime/shared/lib/cache-config.js';
|
|
15
|
+
export { defineGraphQLContext } from '../dist/runtime/server/lib/context.js';
|
|
16
|
+
export { defineRemoteExecutorHooks } from '../dist/runtime/server/lib/remote-executor.js';
|
|
8
17
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
function getGenericServerProxy(modulePath) {
|
|
13
|
-
return `export * from ${JSON.stringify(removeFileExtension(modulePath))};`;
|
|
14
|
-
}
|
|
18
|
+
const cyan = "\x1B[36m";
|
|
19
|
+
const reset = "\x1B[0m";
|
|
15
20
|
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
`export const getGraphQLContext = async () => ({});`,
|
|
20
|
-
`export type GraphQLContext = Awaited<ReturnType<typeof getGraphQLContext>>;`
|
|
21
|
-
].join("\n");
|
|
22
|
-
}
|
|
21
|
+
function renderContextTemplate({ contextModules }) {
|
|
22
|
+
const imports = contextModules.map((module, index) => `import context${index} from ${JSON.stringify(module)};`);
|
|
23
|
+
const types = contextModules.map((_, index) => `Awaited<ReturnType<typeof context${index}>>`);
|
|
23
24
|
return [
|
|
24
|
-
`import
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
`export type GraphQLContext =
|
|
25
|
+
`import type { H3Event } from "h3";`,
|
|
26
|
+
...imports,
|
|
27
|
+
"",
|
|
28
|
+
`export type GraphQLContext = ${types.join("\n & ")};`,
|
|
29
|
+
"",
|
|
30
|
+
"export async function createContext(event: H3Event): Promise<GraphQLContext> {",
|
|
31
|
+
" const parts = await Promise.all([",
|
|
32
|
+
...contextModules.map((_, index) => ` context${index}(event),`),
|
|
33
|
+
" ]);",
|
|
34
|
+
" return Object.assign({}, ...parts) as GraphQLContext;",
|
|
35
|
+
"}"
|
|
28
36
|
].join("\n");
|
|
29
37
|
}
|
|
30
38
|
|
|
31
|
-
async function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
async function loadDocuments(documents) {
|
|
40
|
+
try {
|
|
41
|
+
return await loadDocuments$1([
|
|
42
|
+
documents,
|
|
43
|
+
"!**/.cache/**",
|
|
44
|
+
"!**/.nuxt/**",
|
|
45
|
+
"!**/.output/**",
|
|
46
|
+
"!**/dist/**",
|
|
47
|
+
"!**/node_modules/**"
|
|
48
|
+
], { loaders: [new GraphQLFileLoader()] });
|
|
49
|
+
} catch {
|
|
50
|
+
return [];
|
|
42
51
|
}
|
|
43
52
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
return Array.from(new Set(files));
|
|
51
|
-
}
|
|
52
|
-
function writeFileIfChanged(path, content) {
|
|
53
|
-
if (existsSync(path) && readFileSync(path, "utf-8") === content) {
|
|
54
|
-
return false;
|
|
53
|
+
|
|
54
|
+
async function renderFragmentsTemplate({ documents }) {
|
|
55
|
+
const fragments = collectFragments(documents);
|
|
56
|
+
if (fragments.length === 0) {
|
|
57
|
+
return `export { }`;
|
|
55
58
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
return [
|
|
60
|
+
`export type {`,
|
|
61
|
+
...fragments.map((name) => ` ${name},`),
|
|
62
|
+
`} from "./operations";`
|
|
63
|
+
].join("\n");
|
|
59
64
|
}
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
function collectFragments(documents) {
|
|
66
|
+
const fragments = /* @__PURE__ */ new Set();
|
|
67
|
+
for (const source of documents) {
|
|
68
|
+
const doc = source.document;
|
|
69
|
+
if (!doc) continue;
|
|
70
|
+
for (const def of doc.definitions) {
|
|
71
|
+
if (def.kind !== Kind.FRAGMENT_DEFINITION) continue;
|
|
72
|
+
const name = def.name?.value;
|
|
73
|
+
if (!name) continue;
|
|
74
|
+
if (fragments.has(name)) {
|
|
75
|
+
throw new Error(`Duplicate GraphQL fragment name "${name}"`);
|
|
76
|
+
}
|
|
77
|
+
fragments.add(name);
|
|
78
|
+
}
|
|
65
79
|
}
|
|
66
|
-
return
|
|
80
|
+
return [...fragments.values()];
|
|
67
81
|
}
|
|
68
82
|
|
|
69
|
-
async function
|
|
70
|
-
const
|
|
83
|
+
async function renderOperationsTemplate({ schema, documents }) {
|
|
84
|
+
const output = await codegen({
|
|
85
|
+
filename: "operations.ts",
|
|
86
|
+
// @graphql-codegen/core codegen supports GraphQLSchema at runtime, but types expect DocumentNode
|
|
71
87
|
schema,
|
|
72
88
|
documents,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
inlineFragmentTypes: "combine",
|
|
83
|
-
preResolveTypes: false,
|
|
84
|
-
skipTypename: true,
|
|
85
|
-
strictScalars: true,
|
|
86
|
-
useTypeImports: true
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
+
plugins: [
|
|
90
|
+
{ typescript: {} },
|
|
91
|
+
{ typescriptOperations: {} },
|
|
92
|
+
{ typedDocumentNode: {} }
|
|
93
|
+
],
|
|
94
|
+
pluginMap: {
|
|
95
|
+
typescript: typescriptPlugin,
|
|
96
|
+
typescriptOperations: typescriptOperationsPlugin,
|
|
97
|
+
typedDocumentNode: typedDocumentNodePlugin
|
|
89
98
|
},
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
path: toRelativePath(rootDir, path),
|
|
104
|
-
content: readFileSync(path, "utf-8")
|
|
105
|
-
}));
|
|
106
|
-
const parsed = {
|
|
107
|
-
fragments: /* @__PURE__ */ new Map(),
|
|
108
|
-
operations: {
|
|
109
|
-
query: /* @__PURE__ */ new Map(),
|
|
110
|
-
mutation: /* @__PURE__ */ new Map(),
|
|
111
|
-
subscription: /* @__PURE__ */ new Map()
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
for (const doc of docs) {
|
|
115
|
-
const ast = parse(doc.content);
|
|
116
|
-
for (const def of ast.definitions) {
|
|
117
|
-
switch (def.kind) {
|
|
118
|
-
// Process fragment definitions
|
|
119
|
-
case Kind.FRAGMENT_DEFINITION: {
|
|
120
|
-
const name = def.name.value;
|
|
121
|
-
const existing = parsed.fragments.get(name);
|
|
122
|
-
if (existing) {
|
|
123
|
-
throw new Error(`Duplicate fragment name ${name} in document ${doc.path} (previously defined in ${existing.path})`);
|
|
124
|
-
}
|
|
125
|
-
parsed.fragments.set(name, { kind: "fragment", name, path: doc.path });
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
// Process operation definitions
|
|
129
|
-
case Kind.OPERATION_DEFINITION: {
|
|
130
|
-
const type = def.operation;
|
|
131
|
-
if (!["query", "mutation", "subscription"].includes(type)) continue;
|
|
132
|
-
const name = def.name?.value;
|
|
133
|
-
if (!name) throw new Error(`Unnamed ${type} operation in document ${doc.path}`);
|
|
134
|
-
const existing = parsed.operations[type].get(name);
|
|
135
|
-
if (existing) {
|
|
136
|
-
throw new Error(`Duplicate operation name ${name} in document ${doc.path} (previously defined in ${existing.path})`);
|
|
137
|
-
}
|
|
138
|
-
parsed.operations[type].set(name, { kind: "operation", type, name, path: doc.path });
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
99
|
+
config: {
|
|
100
|
+
defaultScalarType: "never",
|
|
101
|
+
documentMode: "documentNode",
|
|
102
|
+
documentVariableSuffix: "Document",
|
|
103
|
+
enumsAsTypes: true,
|
|
104
|
+
inlineFragmentTypes: "combine",
|
|
105
|
+
omitOperationSuffix: true,
|
|
106
|
+
operationResultSuffix: "Result",
|
|
107
|
+
operationVariablesSuffix: "Variables",
|
|
108
|
+
preResolveTypes: false,
|
|
109
|
+
skipTypename: true,
|
|
110
|
+
strictScalars: true,
|
|
111
|
+
useTypeImports: true
|
|
142
112
|
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
`import * as ops from "#graphql/typed-documents";`,
|
|
146
|
-
``,
|
|
147
|
-
`type ResultOf<T> = T extends { __apiType?: (variables: infer _) => infer R } ? R : never;`,
|
|
148
|
-
`type VariablesOf<T> = T extends { __apiType?: (variables: infer V) => infer _ } ? V : never;`,
|
|
149
|
-
``
|
|
150
|
-
];
|
|
151
|
-
const queries = Array.from(parsed.operations.query.values());
|
|
152
|
-
content.push(
|
|
153
|
-
`// Queries`,
|
|
154
|
-
`export const queries = {`,
|
|
155
|
-
...queries.map(({ name }) => ` ${name}: ops.${name}Document,`),
|
|
156
|
-
`};`,
|
|
157
|
-
`export type QueryName = keyof typeof queries;`,
|
|
158
|
-
`export type QueryResult<N extends QueryName> = ResultOf<(typeof queries)[N]>;`,
|
|
159
|
-
`export type QueryVariables<N extends QueryName> = VariablesOf<(typeof queries)[N]>;`,
|
|
160
|
-
``
|
|
161
|
-
);
|
|
162
|
-
const mutations = Array.from(parsed.operations.mutation.values());
|
|
163
|
-
content.push(
|
|
164
|
-
`// Mutations`,
|
|
165
|
-
`export const mutations = {`,
|
|
166
|
-
...mutations.map(({ name }) => ` ${name}: ops.${name}Document,`),
|
|
167
|
-
`};`,
|
|
168
|
-
`export type MutationName = keyof typeof mutations;`,
|
|
169
|
-
`export type MutationResult<N extends MutationName> = ResultOf<(typeof mutations)[N]>;`,
|
|
170
|
-
`export type MutationVariables<N extends MutationName> = VariablesOf<(typeof mutations)[N]>;`,
|
|
171
|
-
``
|
|
172
|
-
);
|
|
173
|
-
const subscriptions = Array.from(parsed.operations.subscription.values());
|
|
174
|
-
content.push(
|
|
175
|
-
`// Subscriptions`,
|
|
176
|
-
`export const subscriptions = {`,
|
|
177
|
-
...subscriptions.map(({ name }) => ` ${name}: ops.${name}Document,`),
|
|
178
|
-
`};`,
|
|
179
|
-
`export type SubscriptionName = keyof typeof subscriptions;`,
|
|
180
|
-
`export type SubscriptionResult<N extends SubscriptionName> = ResultOf<(typeof subscriptions)[N]>;`,
|
|
181
|
-
`export type SubscriptionVariables<N extends SubscriptionName> = VariablesOf<(typeof subscriptions)[N]>;`,
|
|
182
|
-
``
|
|
183
|
-
);
|
|
184
|
-
return content.join("\n");
|
|
113
|
+
});
|
|
114
|
+
return output;
|
|
185
115
|
}
|
|
186
116
|
|
|
187
|
-
function
|
|
188
|
-
|
|
189
|
-
return [
|
|
190
|
-
`export const remoteExecMiddlewareHandler = undefined;`
|
|
191
|
-
].join("\n");
|
|
192
|
-
}
|
|
117
|
+
async function renderRegistryTemplate({ documents }) {
|
|
118
|
+
const operations = collectOperations(documents);
|
|
193
119
|
return [
|
|
194
|
-
`import
|
|
120
|
+
`import type { DocumentNode } from "graphql";`,
|
|
121
|
+
`import {`,
|
|
122
|
+
...operations.map(
|
|
123
|
+
({ name }) => ` ${name}Document, type ${name}Variables, type ${name}Result,`
|
|
124
|
+
),
|
|
125
|
+
`} from "./operations";`,
|
|
126
|
+
``,
|
|
127
|
+
// Operation entry
|
|
128
|
+
`export interface OperationEntry<`,
|
|
129
|
+
` TVariables,`,
|
|
130
|
+
` TResult,`,
|
|
131
|
+
` TKind extends "query" | "mutation" | "subscription"`,
|
|
132
|
+
`> {`,
|
|
133
|
+
` kind: TKind;`,
|
|
134
|
+
` variables: TVariables;`,
|
|
135
|
+
` result: TResult;`,
|
|
136
|
+
` document: DocumentNode;`,
|
|
137
|
+
`}`,
|
|
138
|
+
``,
|
|
139
|
+
`export type OperationRegistry = {`,
|
|
140
|
+
...operations.map(
|
|
141
|
+
({ name, kind }) => ` ${name}: OperationEntry<${name}Variables, ${name}Result, "${kind}">;`
|
|
142
|
+
),
|
|
143
|
+
`};`,
|
|
144
|
+
``,
|
|
145
|
+
`export type OperationName = keyof OperationRegistry;`,
|
|
146
|
+
``,
|
|
147
|
+
`export type QueryName = {`,
|
|
148
|
+
` [K in keyof OperationRegistry]:`,
|
|
149
|
+
` OperationRegistry[K]["kind"] extends "query" ? K : never`,
|
|
150
|
+
`}[keyof OperationRegistry];`,
|
|
151
|
+
``,
|
|
152
|
+
`export type MutationName = {`,
|
|
153
|
+
` [K in keyof OperationRegistry]:`,
|
|
154
|
+
` OperationRegistry[K]["kind"] extends "mutation" ? K : never`,
|
|
155
|
+
`}[keyof OperationRegistry];`,
|
|
156
|
+
``,
|
|
157
|
+
`export type SubscriptionName = {`,
|
|
158
|
+
` [K in keyof OperationRegistry]:`,
|
|
159
|
+
` OperationRegistry[K]["kind"] extends "subscription" ? K : never`,
|
|
160
|
+
`}[keyof OperationRegistry];`,
|
|
195
161
|
``,
|
|
196
|
-
|
|
162
|
+
// Projection helpers
|
|
163
|
+
`export type VariablesOf<TName extends keyof OperationRegistry> =`,
|
|
164
|
+
` OperationRegistry[TName]["variables"];`,
|
|
165
|
+
``,
|
|
166
|
+
`export type ResultOf<TName extends keyof OperationRegistry> =`,
|
|
167
|
+
` OperationRegistry[TName]["result"];`,
|
|
168
|
+
``,
|
|
169
|
+
// Runtime registry (document + kind only)
|
|
170
|
+
`export const registry: {`,
|
|
171
|
+
` [K in keyof OperationRegistry]: {`,
|
|
172
|
+
` kind: OperationRegistry[K]["kind"];`,
|
|
173
|
+
` document: DocumentNode;`,
|
|
174
|
+
` };`,
|
|
175
|
+
`} = {`,
|
|
176
|
+
...operations.map(
|
|
177
|
+
({ name, kind }) => ` ${name}: { kind: "${kind}", document: ${name}Document },`
|
|
178
|
+
),
|
|
179
|
+
`};`
|
|
197
180
|
].join("\n");
|
|
198
181
|
}
|
|
182
|
+
function collectOperations(documents) {
|
|
183
|
+
const operations = /* @__PURE__ */ new Map();
|
|
184
|
+
for (const source of documents) {
|
|
185
|
+
const doc = source.document;
|
|
186
|
+
if (!doc) continue;
|
|
187
|
+
for (const def of doc.definitions) {
|
|
188
|
+
if (def.kind !== Kind.OPERATION_DEFINITION) continue;
|
|
189
|
+
const name = def.name?.value;
|
|
190
|
+
if (!name) {
|
|
191
|
+
throw new Error("Anonymous GraphQL operations are not allowed");
|
|
192
|
+
}
|
|
193
|
+
if (operations.has(name)) {
|
|
194
|
+
throw new Error(`Duplicate GraphQL operation name "${name}"`);
|
|
195
|
+
}
|
|
196
|
+
operations.set(name, {
|
|
197
|
+
name,
|
|
198
|
+
kind: def.operation
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return [...operations.values()];
|
|
203
|
+
}
|
|
199
204
|
|
|
200
|
-
function
|
|
201
|
-
return
|
|
202
|
-
`import { createSchema } from "graphql-yoga";`,
|
|
203
|
-
``,
|
|
204
|
-
`export const schema = createSchema({`,
|
|
205
|
-
` typeDefs: /* GraphQL */ \``,
|
|
206
|
-
` type Query {`,
|
|
207
|
-
` hello: String!`,
|
|
208
|
-
` } `,
|
|
209
|
-
` \`,`,
|
|
210
|
-
` resolvers: {`,
|
|
211
|
-
` Query: {`,
|
|
212
|
-
` hello: () => "Hello world!",`,
|
|
213
|
-
` },`,
|
|
214
|
-
` },`,
|
|
215
|
-
`});`
|
|
216
|
-
].join("\n");
|
|
205
|
+
function renderLocalSchemaTemplate({ path }) {
|
|
206
|
+
return `export { schema } from ${JSON.stringify(path)};`;
|
|
217
207
|
}
|
|
218
|
-
async function
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
208
|
+
async function loadLocalSchema({ path }) {
|
|
209
|
+
const { createJiti } = await import('jiti');
|
|
210
|
+
const jiti = createJiti(import.meta.url, { interopDefault: true });
|
|
211
|
+
const module = await jiti.import(path);
|
|
212
|
+
if (!module.schema || !(module.schema instanceof Object) || typeof module.schema.getQueryType !== "function") {
|
|
213
|
+
throw new Error(`${path} must export a valid 'schema' of type GraphQLSchema.`);
|
|
214
|
+
}
|
|
215
|
+
return module.schema;
|
|
224
216
|
}
|
|
225
|
-
async function
|
|
226
|
-
const
|
|
227
|
-
const
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
const schemaContent = [
|
|
217
|
+
async function renderRemoteSchemaTemplate({ remoteExecutorModule, type, hooks, ...schemaDef }) {
|
|
218
|
+
const schema = await introspectRemoteSchema(schemaDef);
|
|
219
|
+
const sdl = await printSchemaSDL(schema);
|
|
220
|
+
const imports = (hooks || []).map((hookPath, index) => `import hooks${index} from ${JSON.stringify(hookPath)};`);
|
|
221
|
+
return [
|
|
231
222
|
`import { buildSchema } from "graphql";`,
|
|
232
223
|
`import type { SubschemaConfig } from "@graphql-tools/delegate";`,
|
|
233
|
-
`import {
|
|
234
|
-
|
|
235
|
-
`import { createRemoteExecutor } from "../remote-executor";`,
|
|
236
|
-
``,
|
|
237
|
-
`const headers = ${JSON.stringify(schemaDef.headers ?? {}, null, 2)} as HeadersInit;`,
|
|
224
|
+
`import { createRemoteExecutor } from ${JSON.stringify(remoteExecutorModule)};`,
|
|
225
|
+
...imports,
|
|
238
226
|
``,
|
|
239
|
-
`const
|
|
240
|
-
` url: ${JSON.stringify(schemaDef.url)},`,
|
|
241
|
-
` remoteName: ${JSON.stringify(schemaName)},`,
|
|
242
|
-
` headers,`,
|
|
243
|
-
` middleware: remoteExecMiddlewareHandler,`,
|
|
244
|
-
`});`,
|
|
227
|
+
`const sdl = /* GraphQL */ \`${sdl.replace(/`/g, "\\`")}\`;`,
|
|
245
228
|
``,
|
|
246
229
|
`export const schema: SubschemaConfig = {`,
|
|
247
230
|
` schema: buildSchema(sdl),`,
|
|
248
|
-
` executor
|
|
231
|
+
` executor: createRemoteExecutor({`,
|
|
232
|
+
` ...${JSON.stringify(schemaDef)},`,
|
|
233
|
+
` hooks: [`,
|
|
234
|
+
...(hooks || []).map((_, index) => ` hooks${index},`),
|
|
235
|
+
` ]`,
|
|
236
|
+
` }),`,
|
|
249
237
|
`};`
|
|
250
238
|
].join("\n");
|
|
251
|
-
return { middlewareContent, sdlContent, schemaContent };
|
|
252
239
|
}
|
|
253
|
-
async function
|
|
254
|
-
const
|
|
255
|
-
|
|
240
|
+
async function introspectRemoteSchema({ url, headers }) {
|
|
241
|
+
const response = await fetch(url, {
|
|
242
|
+
method: "POST",
|
|
243
|
+
headers: mergeHeaders({ "Content-Type": "application/json" }, headers),
|
|
244
|
+
body: JSON.stringify({ query: getIntrospectionQuery() })
|
|
245
|
+
});
|
|
246
|
+
const json = await response.json();
|
|
247
|
+
if (json.errors) {
|
|
248
|
+
throw new Error(`Failed to fetch GraphQL schema from ${url}: ${JSON.stringify(json.errors)} `);
|
|
249
|
+
}
|
|
250
|
+
const schema = buildClientSchema(json.data);
|
|
251
|
+
return stripSubscriptions(schema);
|
|
252
|
+
}
|
|
253
|
+
function stripSubscriptions(schema) {
|
|
254
|
+
if (!schema.getSubscriptionType()) {
|
|
255
|
+
return schema;
|
|
256
|
+
}
|
|
257
|
+
return new GraphQLSchema({
|
|
258
|
+
query: schema.getQueryType() ?? void 0,
|
|
259
|
+
mutation: schema.getMutationType() ?? void 0,
|
|
260
|
+
subscription: void 0,
|
|
261
|
+
types: Object.values(schema.getTypeMap()),
|
|
262
|
+
directives: schema.getDirectives()
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
async function printSchemaSDL(schema) {
|
|
266
|
+
const { printSchema, lexicographicSortSchema } = await import('graphql');
|
|
267
|
+
return printSchema(lexicographicSortSchema(schema));
|
|
268
|
+
}
|
|
269
|
+
function renderStitchedSchemaTemplate({ schemaNames }) {
|
|
270
|
+
return [
|
|
256
271
|
`import type { GraphQLSchema } from "graphql"; `,
|
|
257
272
|
`import type { SubschemaConfig } from "@graphql-tools/delegate"; `,
|
|
273
|
+
`import { stitchSchemas } from "@graphql-tools/stitch"; `,
|
|
258
274
|
...schemaNames.map((name) => `import { schema as ${name}Schema } from ${JSON.stringify(`./schemas/${name}`)}; `),
|
|
259
275
|
``,
|
|
260
276
|
`const subschemas: Array<GraphQLSchema | SubschemaConfig> = [`,
|
|
@@ -263,183 +279,206 @@ async function getStitchedSchemaProxy({ schemaNames }) {
|
|
|
263
279
|
``,
|
|
264
280
|
`export const schema = stitchSchemas({ subschemas }); `
|
|
265
281
|
].join("\n");
|
|
266
|
-
return content;
|
|
267
282
|
}
|
|
268
|
-
async function
|
|
269
|
-
const
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
283
|
+
async function loadStitchedSchema(schemaDefs) {
|
|
284
|
+
const subschemas = [];
|
|
285
|
+
for (const schemaDef of Object.values(schemaDefs)) {
|
|
286
|
+
if (schemaDef.type === "local") {
|
|
287
|
+
subschemas.push(await loadLocalSchema(schemaDef));
|
|
288
|
+
} else if (schemaDef.type === "remote") {
|
|
289
|
+
subschemas.push(await introspectRemoteSchema(schemaDef));
|
|
290
|
+
}
|
|
274
291
|
}
|
|
275
|
-
return
|
|
292
|
+
return stitchSchemas({ subschemas });
|
|
276
293
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
});
|
|
284
|
-
const json = await response.json();
|
|
285
|
-
if (json.errors) {
|
|
286
|
-
throw new Error(`Failed to fetch GraphQL schema from ${schemaUrl}: ${JSON.stringify(json.errors)} `);
|
|
287
|
-
}
|
|
288
|
-
return buildClientSchema(json.data);
|
|
294
|
+
|
|
295
|
+
function renderTypesTemplate() {
|
|
296
|
+
return `// Nuxt GraphQL types
|
|
297
|
+
declare module "#graphql/context" {
|
|
298
|
+
export { createContext } from "#build/graphql/context";
|
|
299
|
+
export type { GraphQLContext } from "#build/graphql/context";
|
|
289
300
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
301
|
+
|
|
302
|
+
declare module "#graphql/operations" {
|
|
303
|
+
export * from "#build/graphql/operations";
|
|
293
304
|
}
|
|
294
305
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
+
declare module "#graphql/fragments" {
|
|
307
|
+
export * from "#build/graphql/fragments";
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
declare module "#graphql/registry" {
|
|
311
|
+
import type { DocumentNode } from "graphql";
|
|
312
|
+
export type { OperationName, QueryName, MutationName, SubscriptionName, VariablesOf, ResultOf } from "#build/graphql/registry";
|
|
313
|
+
export const registry: Readonly<Record<OperationName, { readonly document: DocumentNode; }>>;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
declare module "#graphql/schema" {
|
|
317
|
+
export { schema } from "#build/graphql/schema";
|
|
318
|
+
}`;
|
|
306
319
|
}
|
|
307
320
|
|
|
308
321
|
const module$1 = defineNuxtModule({
|
|
309
322
|
meta: {
|
|
310
|
-
name: "
|
|
323
|
+
name: "nuxt-graphql",
|
|
311
324
|
configKey: "graphql"
|
|
312
325
|
},
|
|
313
|
-
defaults: {
|
|
314
|
-
schemas: {}
|
|
315
|
-
},
|
|
326
|
+
defaults: {},
|
|
316
327
|
async setup(options, nuxt) {
|
|
317
|
-
const
|
|
318
|
-
const {
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
329
|
-
serverProxies["context"] = getGraphQLContextProxy(contextPath);
|
|
330
|
-
serverProxies["remote-executor"] = getGenericServerProxy(resolve("./runtime/server/lib/remote-executor.ts"));
|
|
331
|
-
if (Object.keys(options.schemas || {}).length === 0) {
|
|
332
|
-
logger.warn("No GraphQL schemas defined in nuxt.config.ts, using dummy schema.");
|
|
333
|
-
serverProxies["schemas/dummy"] = getDummySchemaProxy();
|
|
334
|
-
serverProxies["schema"] = await getStitchedSchemaProxy({ schemaNames: ["dummy"] });
|
|
335
|
-
} else {
|
|
336
|
-
for (const [schemaName, schemaDef] of Object.entries(options.schemas)) {
|
|
337
|
-
switch (schemaDef.type) {
|
|
338
|
-
case "local": {
|
|
339
|
-
serverProxies[`schemas/${schemaName}`] = await getLocalSchemaProxy({ layerRootDirs, schemaDef });
|
|
340
|
-
break;
|
|
341
|
-
}
|
|
342
|
-
case "remote": {
|
|
343
|
-
const { middlewareContent, sdlContent, schemaContent } = await getRemoteSchemaProxy({ rootDir, schemaName, schemaDef });
|
|
344
|
-
serverProxies[`schemas/${schemaName}-middleware`] = middlewareContent;
|
|
345
|
-
serverProxies[`schemas/${schemaName}-sdl`] = sdlContent;
|
|
346
|
-
serverProxies[`schemas/${schemaName}`] = schemaContent;
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
default:
|
|
350
|
-
throw new Error(`Unsupported GraphQL schema type: ${schemaDef.type}`);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
serverProxies["schema"] = await getStitchedSchemaProxy({ schemaNames: Object.keys(options.schemas) });
|
|
354
|
-
}
|
|
355
|
-
if (options.middleware) {
|
|
356
|
-
const yogaMiddlewarePath = await findSingleFile(layerRootDirs, options.middleware, true);
|
|
357
|
-
logger.info(`GraphQL Yoga middleware registered: ${cyan}${toRelativePath(nuxt.options.rootDir, yogaMiddlewarePath)}${reset}`);
|
|
358
|
-
serverProxies["yoga-middleware"] = getYogaMiddlewareProxy(yogaMiddlewarePath);
|
|
359
|
-
} else {
|
|
360
|
-
serverProxies["yoga-middleware"] = getYogaMiddlewareProxy();
|
|
361
|
-
}
|
|
362
|
-
const sdlPath = options.saveSdl ? join(rootDir, options.saveSdl) : join(buildDir, "graphql/schema.graphql");
|
|
363
|
-
async function generateGraphQLSDL() {
|
|
364
|
-
const schema = await loadGraphQLSchema(join(buildDir, "graphql/schema.ts"));
|
|
365
|
-
const sdlContent = await getSDLFromGraphQLSchema(schema);
|
|
366
|
-
if (writeFileIfChanged(sdlPath, sdlContent)) {
|
|
367
|
-
logger.info(`GraphQL SDL generated: ${cyan}${toRelativePath(rootDir, sdlPath)}${reset}`);
|
|
328
|
+
const logger = useLogger("graphql");
|
|
329
|
+
const { resolve: resolveModule } = createResolver(import.meta.url);
|
|
330
|
+
const { resolve: resolveRoot, resolvePath: _resolveRootPath } = createResolver(nuxt.options.rootDir);
|
|
331
|
+
async function resolveRootPath(path, required = true) {
|
|
332
|
+
try {
|
|
333
|
+
if (!path) throw new Error("No path provided");
|
|
334
|
+
const resolvedPath = await _resolveRootPath(path);
|
|
335
|
+
return resolvedPath.replace(/\.(ts|mjs)$/u, "");
|
|
336
|
+
} catch {
|
|
337
|
+
if (required) throw new Error(`Cannot resolve path in rootDir: ${path}`);
|
|
338
|
+
return void 0;
|
|
368
339
|
}
|
|
369
340
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
logger.info(`GraphQL Config generated: ${cyan}${toRelativePath(rootDir, configPath)}${reset}`);
|
|
341
|
+
function getRelativePath(to) {
|
|
342
|
+
let relativePath = relative(resolve(nuxt.options.rootDir), resolve(to));
|
|
343
|
+
relativePath = relativePath.replace(/\\/g, "/");
|
|
344
|
+
if (!relativePath.startsWith("./") && !relativePath.startsWith("../")) {
|
|
345
|
+
relativePath = `./${relativePath}`;
|
|
376
346
|
}
|
|
347
|
+
return relativePath;
|
|
377
348
|
}
|
|
378
|
-
|
|
379
|
-
nuxt.options.alias["#graphql
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
349
|
+
nuxt.options.alias ||= {};
|
|
350
|
+
nuxt.options.alias["#graphql"] = resolve(nuxt.options.buildDir, "graphql");
|
|
351
|
+
const nitroAlias = {};
|
|
352
|
+
const contextModules = [
|
|
353
|
+
resolveModule("./runtime/server/lib/default-context"),
|
|
354
|
+
...await Promise.all((options.yoga?.context || []).map((path) => resolveRootPath(path, true)))
|
|
355
|
+
];
|
|
356
|
+
const contextTemplate = addTemplate({
|
|
357
|
+
filename: "graphql/context.ts",
|
|
358
|
+
getContents: () => renderContextTemplate({ contextModules }),
|
|
359
|
+
write: true
|
|
360
|
+
});
|
|
361
|
+
nitroAlias["#graphql/context"] = contextTemplate.dst;
|
|
362
|
+
const schemaDefs = {};
|
|
363
|
+
for (const [schemaName, schemaDef] of Object.entries(options.yoga?.schemas || {})) {
|
|
364
|
+
let schemaTemplate2;
|
|
365
|
+
if (schemaDef.type === "local") {
|
|
366
|
+
const localSchemaDef = {
|
|
367
|
+
...schemaDef,
|
|
368
|
+
path: await resolveRootPath(schemaDef.path, true)
|
|
369
|
+
};
|
|
370
|
+
schemaDefs[schemaName] = localSchemaDef;
|
|
371
|
+
schemaTemplate2 = addTemplate({
|
|
372
|
+
filename: `graphql/schemas/${schemaName}.ts`,
|
|
373
|
+
getContents: async () => renderLocalSchemaTemplate({ ...localSchemaDef }),
|
|
374
|
+
write: true
|
|
375
|
+
});
|
|
376
|
+
} else if (schemaDef.type === "remote") {
|
|
377
|
+
const remoteSchemaDef = {
|
|
378
|
+
...schemaDef,
|
|
379
|
+
hooks: await Promise.all((schemaDef.hooks || []).map((hookPath) => resolveRootPath(hookPath, true))),
|
|
380
|
+
remoteExecutorModule: resolveModule("./runtime/server/lib/remote-executor")
|
|
381
|
+
};
|
|
382
|
+
schemaDefs[schemaName] = remoteSchemaDef;
|
|
383
|
+
schemaTemplate2 = addTemplate({
|
|
384
|
+
filename: `graphql/schemas/${schemaName}.ts`,
|
|
385
|
+
getContents: async () => await renderRemoteSchemaTemplate({ ...remoteSchemaDef }),
|
|
386
|
+
write: true
|
|
387
|
+
});
|
|
388
|
+
} else {
|
|
389
|
+
throw new Error(`Unknown schema type for schema "${schemaName}"`);
|
|
392
390
|
}
|
|
391
|
+
nitroAlias[`#graphql/schemas/${schemaName}`] = schemaTemplate2.dst;
|
|
393
392
|
}
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
393
|
+
const schemaTemplate = addTemplate({
|
|
394
|
+
filename: "graphql/schema.ts",
|
|
395
|
+
getContents: () => renderStitchedSchemaTemplate({
|
|
396
|
+
schemaNames: Object.keys(options.yoga?.schemas || {})
|
|
397
|
+
}),
|
|
398
|
+
write: true
|
|
399
|
+
});
|
|
400
|
+
nitroAlias["#graphql/schema"] = schemaTemplate.dst;
|
|
401
|
+
let documentsCache = null;
|
|
402
|
+
async function getDocuments(glob) {
|
|
403
|
+
const key = `documents:${glob}`;
|
|
404
|
+
if (documentsCache?.key === key) return documentsCache.data;
|
|
405
|
+
const documents = await loadDocuments(glob);
|
|
406
|
+
documentsCache = { key, data: documents };
|
|
407
|
+
return documents;
|
|
399
408
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
|
|
409
|
+
const sdlPath = resolveRoot(options.saveSDL || "server/graphql/schema.graphql");
|
|
410
|
+
let schemaCache = null;
|
|
411
|
+
async function getStitchedSchema(schemaDefs2) {
|
|
412
|
+
const key = `schema:${hash(schemaDefs2)}`;
|
|
413
|
+
if (schemaCache?.key === key) return schemaCache.data;
|
|
414
|
+
const schema = await loadStitchedSchema(schemaDefs2);
|
|
415
|
+
schemaCache = { key, data: schema };
|
|
416
|
+
const sdl = await printSchemaSDL(schema);
|
|
417
|
+
mkdirSync(dirname(sdlPath), { recursive: true });
|
|
418
|
+
writeFileSync(sdlPath, sdl, { encoding: "utf-8" });
|
|
419
|
+
logger.info(`GraphQL SDL saved to: ${cyan}${getRelativePath(sdlPath)}${reset}`);
|
|
420
|
+
return schema;
|
|
411
421
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
422
|
+
addTemplate({
|
|
423
|
+
filename: "graphql/operations.ts",
|
|
424
|
+
getContents: async () => await renderOperationsTemplate({
|
|
425
|
+
schema: await getStitchedSchema(schemaDefs),
|
|
426
|
+
documents: await getDocuments(options.client?.documents || "**/*.gql")
|
|
427
|
+
}),
|
|
428
|
+
write: true
|
|
415
429
|
});
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
430
|
+
addTemplate({
|
|
431
|
+
filename: "graphql/fragments.ts",
|
|
432
|
+
getContents: async () => await renderFragmentsTemplate({
|
|
433
|
+
documents: await getDocuments(options.client?.documents || "**/*.gql")
|
|
434
|
+
}),
|
|
435
|
+
write: true
|
|
436
|
+
});
|
|
437
|
+
addTemplate({
|
|
438
|
+
filename: "graphql/registry.ts",
|
|
439
|
+
getContents: async () => await renderRegistryTemplate({
|
|
440
|
+
documents: await getDocuments(options.client?.documents || "**/*.gql")
|
|
441
|
+
}),
|
|
442
|
+
write: true
|
|
428
443
|
});
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
444
|
+
const configPath = resolveRoot(options.saveConfig || "graphql.config.json");
|
|
445
|
+
const config = { schema: getRelativePath(sdlPath), documents: options.client?.documents || "**/*.gql" };
|
|
446
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
447
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), { encoding: "utf-8" });
|
|
448
|
+
logger.info(`GraphQL config saved to: ${cyan}${getRelativePath(configPath)}${reset}`);
|
|
449
|
+
const typesTemplate = addTemplate({
|
|
450
|
+
filename: "graphql/types.d.ts",
|
|
451
|
+
getContents: () => renderTypesTemplate(),
|
|
452
|
+
write: true
|
|
453
|
+
});
|
|
454
|
+
nuxt.options.runtimeConfig.public.graphql = {
|
|
455
|
+
cacheConfig: resolveCacheConfig(options.client?.cache),
|
|
456
|
+
ssrForwardHeaders: options.client?.ssrForwardHeaders || ["authorization", "cookie"]
|
|
457
|
+
};
|
|
458
|
+
nuxt.hook("prepare:types", ({ sharedReferences }) => {
|
|
459
|
+
sharedReferences.push({ path: typesTemplate.dst });
|
|
460
|
+
sharedReferences.push({ path: resolveModule("./runtime/shared/types/nuxt-graphql.d.ts") });
|
|
461
|
+
});
|
|
462
|
+
nuxt.hook("nitro:config", (nitroConfig) => {
|
|
463
|
+
nitroConfig.alias ||= {};
|
|
464
|
+
Object.assign(nitroConfig.alias, nitroAlias);
|
|
433
465
|
});
|
|
434
466
|
if (nuxt.options.dev) {
|
|
435
|
-
nuxt.hook("builder:watch", async (_event,
|
|
436
|
-
if (
|
|
437
|
-
logger.info(`
|
|
438
|
-
|
|
439
|
-
await generateGraphQLRegistry();
|
|
467
|
+
nuxt.hook("builder:watch", async (_event, changedPath) => {
|
|
468
|
+
if (changedPath.endsWith(".gql")) {
|
|
469
|
+
logger.info(`Documents change detected: ${cyan}${getRelativePath(changedPath)}${reset}`);
|
|
470
|
+
documentsCache = null;
|
|
440
471
|
}
|
|
441
472
|
});
|
|
442
473
|
}
|
|
474
|
+
addServerHandler({ route: "/api/graphql", handler: resolveModule("./runtime/server/api/graphql") });
|
|
475
|
+
nuxt.hook("listen", (_, { url }) => {
|
|
476
|
+
logger.success(`GraphQL Yoga ready: ${cyan}${url.replace(/\/$/, "")} / api / graphql${reset}`);
|
|
477
|
+
});
|
|
478
|
+
addPlugin(resolveModule("./runtime/app/plugins/graphql-request"));
|
|
479
|
+
addPlugin(resolveModule("./runtime/app/plugins/graphql-sse.client"));
|
|
480
|
+
addImportsDir(resolveModule("./runtime/app/composables"));
|
|
481
|
+
addServerImportsDir(resolveModule("./runtime/server/utils"));
|
|
443
482
|
}
|
|
444
483
|
});
|
|
445
484
|
|