nitro-graphql 1.6.0 → 1.7.0-beta.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/dist/ecosystem/nuxt.mjs +3 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +23 -1
- package/dist/rollup.mjs +2 -2
- package/dist/routes/apollo-server-ws.d.mts +6 -0
- package/dist/routes/apollo-server-ws.mjs +298 -0
- package/dist/routes/apollo-server.d.mts +2 -2
- package/dist/routes/apollo-server.mjs +2 -2
- package/dist/routes/graphql-yoga-ws.d.mts +6 -0
- package/dist/routes/graphql-yoga-ws.mjs +298 -0
- package/dist/routes/graphql-yoga.d.mts +2 -2
- package/dist/subscribe/index.d.mts +146 -0
- package/dist/subscribe/index.mjs +830 -0
- package/dist/templates/subscribe-client.mjs +59 -0
- package/dist/types/index.d.mts +16 -1
- package/dist/utils/apollo.d.mts +1 -1
- package/dist/utils/apollo.mjs +1 -1
- package/dist/utils/client-codegen.d.mts +15 -1
- package/dist/utils/client-codegen.mjs +407 -8
- package/dist/utils/define.d.mts +1 -1
- package/dist/utils/type-generation.mjs +7 -3
- package/dist/utils/ws-protocol.d.mts +25 -0
- package/dist/utils/ws-protocol.mjs +99 -0
- package/dist/utils/ws-schema.d.mts +6 -0
- package/dist/utils/ws-schema.mjs +58 -0
- package/package.json +59 -56
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { parse, subscribe, validate } from "graphql";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/ws-protocol.ts
|
|
4
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
5
|
+
function devLog(message, ...args) {
|
|
6
|
+
if (isDev) console.log(message, ...args);
|
|
7
|
+
}
|
|
8
|
+
function sendMessage(peer, message) {
|
|
9
|
+
peer.send(JSON.stringify(message));
|
|
10
|
+
}
|
|
11
|
+
function sendErrorMessage(peer, id, errors) {
|
|
12
|
+
sendMessage(peer, {
|
|
13
|
+
id,
|
|
14
|
+
type: "error",
|
|
15
|
+
payload: errors
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function sendNextMessage(peer, id, payload) {
|
|
19
|
+
sendMessage(peer, {
|
|
20
|
+
id,
|
|
21
|
+
type: "next",
|
|
22
|
+
payload
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function sendCompleteMessage(peer, id) {
|
|
26
|
+
sendMessage(peer, {
|
|
27
|
+
id,
|
|
28
|
+
type: "complete"
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function handleConnectionInit(peer) {
|
|
32
|
+
sendMessage(peer, { type: "connection_ack" });
|
|
33
|
+
}
|
|
34
|
+
function handlePing(peer) {
|
|
35
|
+
sendMessage(peer, { type: "pong" });
|
|
36
|
+
}
|
|
37
|
+
async function handleSubscribe(peer, msg, schema, subscriptions) {
|
|
38
|
+
if (!msg.id || !msg.payload) {
|
|
39
|
+
sendErrorMessage(peer, msg.id, [{ message: "Invalid subscribe message" }]);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const { query, variables, operationName } = msg.payload;
|
|
44
|
+
const document = typeof query === "string" ? parse(query) : query;
|
|
45
|
+
const validationErrors = validate(schema, document);
|
|
46
|
+
if (validationErrors.length > 0) {
|
|
47
|
+
sendErrorMessage(peer, msg.id, validationErrors.map((err) => ({
|
|
48
|
+
message: err.message,
|
|
49
|
+
locations: err.locations,
|
|
50
|
+
path: err.path
|
|
51
|
+
})));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const result = await subscribe({
|
|
55
|
+
schema,
|
|
56
|
+
document,
|
|
57
|
+
variableValues: variables,
|
|
58
|
+
operationName,
|
|
59
|
+
contextValue: {}
|
|
60
|
+
});
|
|
61
|
+
if (Symbol.asyncIterator in result) {
|
|
62
|
+
subscriptions.set(msg.id, result);
|
|
63
|
+
(async () => {
|
|
64
|
+
try {
|
|
65
|
+
for await (const value of result) sendNextMessage(peer, msg.id, value);
|
|
66
|
+
sendCompleteMessage(peer, msg.id);
|
|
67
|
+
subscriptions.delete(msg.id);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error("[GraphQL WS] Subscription error:", error);
|
|
70
|
+
sendErrorMessage(peer, msg.id, [{ message: error instanceof Error ? error.message : "Subscription error" }]);
|
|
71
|
+
subscriptions.delete(msg.id);
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
} else {
|
|
75
|
+
sendNextMessage(peer, msg.id, result);
|
|
76
|
+
sendCompleteMessage(peer, msg.id);
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error("[GraphQL WS] Operation error:", error);
|
|
80
|
+
sendErrorMessage(peer, msg.id, [{ message: error instanceof Error ? error.message : "Operation failed" }]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function handleComplete(msg, subscriptions) {
|
|
84
|
+
if (!msg.id) return;
|
|
85
|
+
const iterator = subscriptions.get(msg.id);
|
|
86
|
+
if (iterator && typeof iterator.return === "function") await iterator.return();
|
|
87
|
+
subscriptions.delete(msg.id);
|
|
88
|
+
}
|
|
89
|
+
async function cleanupSubscriptions(subscriptions) {
|
|
90
|
+
for (const [id, iterator] of subscriptions.entries()) if (typeof iterator.return === "function") try {
|
|
91
|
+
await iterator.return();
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error(`[GraphQL WS] Error cleaning up subscription ${id}:`, error);
|
|
94
|
+
}
|
|
95
|
+
subscriptions.clear();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
//#endregion
|
|
99
|
+
export { cleanupSubscriptions, devLog, handleComplete, handleConnectionInit, handlePing, handleSubscribe, sendCompleteMessage, sendErrorMessage, sendMessage, sendNextMessage };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { parse } from "graphql";
|
|
2
|
+
import { mergeResolvers, mergeTypeDefs } from "@graphql-tools/merge";
|
|
3
|
+
import { moduleConfig } from "#nitro-internal-virtual/module-config";
|
|
4
|
+
import { directives } from "#nitro-internal-virtual/server-directives";
|
|
5
|
+
import { resolvers } from "#nitro-internal-virtual/server-resolvers";
|
|
6
|
+
import { schemas } from "#nitro-internal-virtual/server-schemas";
|
|
7
|
+
import { makeExecutableSchema } from "@graphql-tools/schema";
|
|
8
|
+
|
|
9
|
+
//#region src/utils/ws-schema.ts
|
|
10
|
+
let buildSubgraphSchema = null;
|
|
11
|
+
async function loadFederationSupport() {
|
|
12
|
+
if (buildSubgraphSchema !== null) return buildSubgraphSchema;
|
|
13
|
+
try {
|
|
14
|
+
buildSubgraphSchema = (await import("@apollo/subgraph")).buildSubgraphSchema;
|
|
15
|
+
} catch {
|
|
16
|
+
buildSubgraphSchema = false;
|
|
17
|
+
}
|
|
18
|
+
return buildSubgraphSchema;
|
|
19
|
+
}
|
|
20
|
+
async function createMergedSchema() {
|
|
21
|
+
try {
|
|
22
|
+
const typeDefs = mergeTypeDefs([schemas.map((schema$1) => schema$1.def).join("\n\n")], {
|
|
23
|
+
throwOnConflict: true,
|
|
24
|
+
commentDescriptions: true,
|
|
25
|
+
sort: true
|
|
26
|
+
});
|
|
27
|
+
const mergedResolvers = mergeResolvers(resolvers.map((r) => r.resolver));
|
|
28
|
+
const federationEnabled = moduleConfig.federation?.enabled;
|
|
29
|
+
let schema;
|
|
30
|
+
if (federationEnabled) {
|
|
31
|
+
const buildSubgraph = await loadFederationSupport();
|
|
32
|
+
if (buildSubgraph) schema = buildSubgraph({
|
|
33
|
+
typeDefs: typeof typeDefs === "string" ? parse(typeDefs) : typeDefs,
|
|
34
|
+
resolvers: mergedResolvers
|
|
35
|
+
});
|
|
36
|
+
else {
|
|
37
|
+
console.warn("[GraphQL WS] Federation enabled but @apollo/subgraph not available, falling back to regular schema");
|
|
38
|
+
schema = makeExecutableSchema({
|
|
39
|
+
typeDefs,
|
|
40
|
+
resolvers: mergedResolvers
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
} else schema = makeExecutableSchema({
|
|
44
|
+
typeDefs,
|
|
45
|
+
resolvers: mergedResolvers
|
|
46
|
+
});
|
|
47
|
+
if (directives && directives.length > 0) {
|
|
48
|
+
for (const { directive } of directives) if (directive.transformer) schema = directive.transformer(schema);
|
|
49
|
+
}
|
|
50
|
+
return schema;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("[GraphQL WS] Schema merge error:", error);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
export { createMergedSchema };
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-graphql",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
5
|
-
"packageManager": "pnpm@10.24.0",
|
|
4
|
+
"version": "1.7.0-beta.0",
|
|
6
5
|
"description": "GraphQL integration for Nitro",
|
|
7
6
|
"license": "MIT",
|
|
8
7
|
"repository": {
|
|
@@ -56,6 +55,10 @@
|
|
|
56
55
|
"./nuxt": {
|
|
57
56
|
"types": "./dist/ecosystem/nuxt.d.mts",
|
|
58
57
|
"import": "./dist/ecosystem/nuxt.mjs"
|
|
58
|
+
},
|
|
59
|
+
"./subscribe": {
|
|
60
|
+
"types": "./dist/subscribe/index.d.mts",
|
|
61
|
+
"import": "./dist/subscribe/index.mjs"
|
|
59
62
|
}
|
|
60
63
|
},
|
|
61
64
|
"module": "./dist/index.mjs",
|
|
@@ -63,21 +66,6 @@
|
|
|
63
66
|
"files": [
|
|
64
67
|
"dist"
|
|
65
68
|
],
|
|
66
|
-
"scripts": {
|
|
67
|
-
"prepack": "pnpm build",
|
|
68
|
-
"build": "tsdown",
|
|
69
|
-
"dev": "tsdown --watch",
|
|
70
|
-
"bumpp": "bumpp package.json",
|
|
71
|
-
"release": "pnpm build && pnpm bumpp",
|
|
72
|
-
"playground:nitro": "cd playgrounds/nitro && pnpm install && pnpm dev",
|
|
73
|
-
"playground:nuxt": "cd playgrounds/nuxt && pnpm install && pnpm dev",
|
|
74
|
-
"playground:federation": "cd playgrounds/federation && pnpm install && pnpm dev",
|
|
75
|
-
"docs:dev": "cd .docs && pnpm install && pnpm dev",
|
|
76
|
-
"docs:build": "cd .docs && pnpm install && pnpm build",
|
|
77
|
-
"docs:preview": "cd .docs && pnpm preview",
|
|
78
|
-
"lint": "eslint .",
|
|
79
|
-
"lint:fix": "eslint . --fix"
|
|
80
|
-
},
|
|
81
69
|
"peerDependencies": {
|
|
82
70
|
"@apollo/server": "^5.0.0",
|
|
83
71
|
"@apollo/utils.withrequired": "^3.0.0",
|
|
@@ -98,49 +86,64 @@
|
|
|
98
86
|
}
|
|
99
87
|
},
|
|
100
88
|
"dependencies": {
|
|
101
|
-
"@apollo/subgraph": "
|
|
102
|
-
"@graphql-codegen/core": "
|
|
103
|
-
"@graphql-codegen/import-types-preset": "
|
|
104
|
-
"@graphql-codegen/typescript": "
|
|
105
|
-
"@graphql-codegen/typescript-generic-sdk": "
|
|
106
|
-
"@graphql-codegen/typescript-operations": "
|
|
107
|
-
"@graphql-codegen/typescript-resolvers": "
|
|
108
|
-
"@graphql-tools/graphql-file-loader": "
|
|
109
|
-
"@graphql-tools/load": "
|
|
110
|
-
"@graphql-tools/load-files": "
|
|
111
|
-
"@graphql-tools/merge": "
|
|
112
|
-
"@graphql-tools/schema": "
|
|
113
|
-
"@graphql-tools/url-loader": "
|
|
114
|
-
"@graphql-tools/utils": "
|
|
115
|
-
"chokidar": "
|
|
116
|
-
"consola": "
|
|
117
|
-
"defu": "
|
|
118
|
-
"graphql-config": "
|
|
119
|
-
"graphql-scalars": "
|
|
120
|
-
"knitwork": "
|
|
121
|
-
"ohash": "
|
|
122
|
-
"oxc-parser": "
|
|
123
|
-
"pathe": "
|
|
124
|
-
"tinyglobby": "
|
|
89
|
+
"@apollo/subgraph": "^2.12.2",
|
|
90
|
+
"@graphql-codegen/core": "^5.0.0",
|
|
91
|
+
"@graphql-codegen/import-types-preset": "^3.0.1",
|
|
92
|
+
"@graphql-codegen/typescript": "^5.0.6",
|
|
93
|
+
"@graphql-codegen/typescript-generic-sdk": "^4.0.2",
|
|
94
|
+
"@graphql-codegen/typescript-operations": "^5.0.6",
|
|
95
|
+
"@graphql-codegen/typescript-resolvers": "^5.1.4",
|
|
96
|
+
"@graphql-tools/graphql-file-loader": "^8.1.8",
|
|
97
|
+
"@graphql-tools/load": "^8.1.7",
|
|
98
|
+
"@graphql-tools/load-files": "^7.0.1",
|
|
99
|
+
"@graphql-tools/merge": "^9.1.6",
|
|
100
|
+
"@graphql-tools/schema": "^10.0.30",
|
|
101
|
+
"@graphql-tools/url-loader": "^9.0.5",
|
|
102
|
+
"@graphql-tools/utils": "^10.11.0",
|
|
103
|
+
"chokidar": "^5.0.0",
|
|
104
|
+
"consola": "^3.4.2",
|
|
105
|
+
"defu": "^6.1.4",
|
|
106
|
+
"graphql-config": "^5.1.5",
|
|
107
|
+
"graphql-scalars": "^1.25.0",
|
|
108
|
+
"knitwork": "^1.3.0",
|
|
109
|
+
"ohash": "^2.0.11",
|
|
110
|
+
"oxc-parser": "^0.102.0",
|
|
111
|
+
"pathe": "^2.0.3",
|
|
112
|
+
"tinyglobby": "^0.2.15"
|
|
125
113
|
},
|
|
126
114
|
"devDependencies": {
|
|
127
|
-
"@antfu/eslint-config": "
|
|
128
|
-
"@nuxt/kit": "
|
|
129
|
-
"@nuxt/schema": "
|
|
130
|
-
"@types/node": "
|
|
131
|
-
"bumpp": "
|
|
132
|
-
"changelogen": "
|
|
133
|
-
"crossws": "
|
|
134
|
-
"eslint": "
|
|
135
|
-
"graphql": "
|
|
136
|
-
"graphql-yoga": "
|
|
137
|
-
"h3": "
|
|
138
|
-
"nitropack": "
|
|
139
|
-
"tsdown": "
|
|
140
|
-
"typescript": "
|
|
115
|
+
"@antfu/eslint-config": "^6.6.1",
|
|
116
|
+
"@nuxt/kit": "^4.2.2",
|
|
117
|
+
"@nuxt/schema": "^4.2.2",
|
|
118
|
+
"@types/node": "^24.10.3",
|
|
119
|
+
"bumpp": "^10.3.2",
|
|
120
|
+
"changelogen": "^0.6.2",
|
|
121
|
+
"crossws": "0.3.5",
|
|
122
|
+
"eslint": "^9.39.1",
|
|
123
|
+
"graphql": "16.11.0",
|
|
124
|
+
"graphql-yoga": "^5.17.1",
|
|
125
|
+
"h3": "1.15.3",
|
|
126
|
+
"nitropack": "^2.12.9",
|
|
127
|
+
"tsdown": "^0.17.2",
|
|
128
|
+
"typescript": "^5.9.3",
|
|
141
129
|
"vitepress-plugin-llms": "^1.9.3"
|
|
142
130
|
},
|
|
143
131
|
"resolutions": {
|
|
144
132
|
"nitro-graphql": "link:."
|
|
133
|
+
},
|
|
134
|
+
"scripts": {
|
|
135
|
+
"build": "tsdown",
|
|
136
|
+
"dev": "tsdown --watch",
|
|
137
|
+
"bumpp": "bumpp package.json",
|
|
138
|
+
"release": "pnpm build && pnpm bumpp",
|
|
139
|
+
"playground:nitro": "cd playgrounds/nitro && pnpm install && pnpm dev",
|
|
140
|
+
"playground:nuxt": "cd playgrounds/nuxt && pnpm install && pnpm dev",
|
|
141
|
+
"playground:federation": "cd playgrounds/federation && pnpm install && pnpm dev",
|
|
142
|
+
"docs:dev": "cd .docs && pnpm install && pnpm dev",
|
|
143
|
+
"docs:build": "cd .docs && pnpm install && pnpm build",
|
|
144
|
+
"docs:preview": "cd .docs && pnpm preview",
|
|
145
|
+
"lint": "eslint .",
|
|
146
|
+
"lint:fix": "eslint . --fix",
|
|
147
|
+
"typecheck": "tsc --noEmit"
|
|
145
148
|
}
|
|
146
|
-
}
|
|
149
|
+
}
|