@steedos/moleculer-apollo-server 3.0.4-beta.1 → 3.0.4-beta.10
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/index.d.ts +0 -1
- package/index.js +0 -4
- package/package.json +5 -6
- package/src/ApolloServer.js +166 -98
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"use strict";
|
|
16
16
|
|
|
17
17
|
const core = require("apollo-server-core");
|
|
18
|
-
const { GraphQLUpload } = require("graphql-upload");
|
|
19
18
|
const { ApolloServer } = require("./src/ApolloServer");
|
|
20
19
|
const ApolloService = require("./src/service");
|
|
21
20
|
const gql = require("./src/gql");
|
|
@@ -36,9 +35,6 @@ module.exports = {
|
|
|
36
35
|
// GraphQL tools
|
|
37
36
|
...require("graphql-tools"),
|
|
38
37
|
|
|
39
|
-
// GraphQL Upload
|
|
40
|
-
GraphQLUpload,
|
|
41
|
-
|
|
42
38
|
// Apollo Server
|
|
43
39
|
ApolloServer,
|
|
44
40
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steedos/moleculer-apollo-server",
|
|
3
|
-
"version": "3.0.4-beta.
|
|
3
|
+
"version": "3.0.4-beta.10",
|
|
4
4
|
"description": "Apollo GraphQL server for Moleculer API Gateway",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -47,16 +47,15 @@
|
|
|
47
47
|
"node": ">= 10.x.x"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@apollographql/graphql-playground-html": "^1.6.29",
|
|
51
50
|
"@hapi/accept": "^3.2.4",
|
|
52
|
-
"@types/graphql-upload": "^
|
|
53
|
-
"apollo-server-core": "^
|
|
51
|
+
"@types/graphql-upload": "^17.0.0",
|
|
52
|
+
"apollo-server-core": "^3.13.0",
|
|
54
53
|
"dataloader": "^2.1.0",
|
|
55
54
|
"graphql-subscriptions": "^1.2.1",
|
|
56
55
|
"graphql-tools": "^9.0.11",
|
|
57
|
-
"graphql-upload": "^
|
|
56
|
+
"graphql-upload": "^17.0.0",
|
|
58
57
|
"lodash": "^4.17.21",
|
|
59
58
|
"object-hash": "^2.2.0"
|
|
60
59
|
},
|
|
61
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "d862431920494f1011ba354e0d0051c7da8e2479"
|
|
62
61
|
}
|
package/src/ApolloServer.js
CHANGED
|
@@ -1,113 +1,181 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
const { ApolloServerBase } = require("apollo-server-core");
|
|
4
|
-
const { processRequest } = require("graphql-upload");
|
|
5
|
-
const { renderPlaygroundPage } = require("@apollographql/graphql-playground-html");
|
|
6
4
|
const accept = require("@hapi/accept");
|
|
7
5
|
const moleculerApollo = require("./moleculerApollo");
|
|
8
6
|
|
|
7
|
+
// ... [Keep your renderPlaygroundPage function exactly as is] ...
|
|
8
|
+
function renderPlaygroundPage({ endpoint, subscriptionEndpoint, ...options }) {
|
|
9
|
+
const settings = JSON.stringify({
|
|
10
|
+
endpoint,
|
|
11
|
+
subscriptionEndpoint,
|
|
12
|
+
...options,
|
|
13
|
+
});
|
|
14
|
+
const unpkgUrl = process.env.STEEDOS_UNPKG_URL || "https://unpkg.com";
|
|
15
|
+
|
|
16
|
+
return `
|
|
17
|
+
<!DOCTYPE html>
|
|
18
|
+
<html>
|
|
19
|
+
<head>
|
|
20
|
+
<meta charset=utf-8 />
|
|
21
|
+
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
|
|
22
|
+
<title>GraphQL Playground</title>
|
|
23
|
+
<link rel="stylesheet" href="${unpkgUrl}/graphql-playground-react/build/static/css/index.css" />
|
|
24
|
+
<link rel="shortcut icon" href="${unpkgUrl}/graphql-playground-react/build/favicon.png" />
|
|
25
|
+
<script src="${unpkgUrl}/graphql-playground-react/build/static/js/middleware.js"></script>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<div id="root">
|
|
29
|
+
<style>
|
|
30
|
+
body { background-color: rgb(23, 42, 58); font-family: Open Sans, sans-serif; height: 100vh; margin: 0; overflow: hidden; }
|
|
31
|
+
#root { height: 100%; width: 100%; display: flex; align-items: center; justify-content: center; }
|
|
32
|
+
.loading { font-size: 32px; font-weight: 200; color: rgba(255, 255, 255, .6); margin-left: 20px; }
|
|
33
|
+
img { width: 78px; height: 78px; }
|
|
34
|
+
.title { font-weight: 400; }
|
|
35
|
+
</style>
|
|
36
|
+
<img src='${unpkgUrl}/graphql-playground-react/build/logo.png' alt=''>
|
|
37
|
+
<div class="loading"> Loading
|
|
38
|
+
<span class="title">GraphQL Playground</span>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
<script>
|
|
42
|
+
window.addEventListener('load', function (event) {
|
|
43
|
+
GraphQLPlayground.init(document.getElementById('root'), ${settings})
|
|
44
|
+
})
|
|
45
|
+
</script>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ... [Keep your send function as is] ...
|
|
9
52
|
async function send(req, res, statusCode, data, responseType = "application/json") {
|
|
10
|
-
|
|
53
|
+
res.statusCode = statusCode;
|
|
11
54
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
55
|
+
const ctx = res.$ctx;
|
|
56
|
+
if (!ctx.meta.$responseType) {
|
|
57
|
+
ctx.meta.$responseType = responseType;
|
|
58
|
+
}
|
|
16
59
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
60
|
+
const route = res.$route;
|
|
61
|
+
if (route.onAfterCall) {
|
|
62
|
+
data = await route.onAfterCall.call(this, ctx, route, req, res, data);
|
|
63
|
+
}
|
|
21
64
|
|
|
22
|
-
|
|
23
|
-
|
|
65
|
+
const service = res.$service;
|
|
66
|
+
service.sendResponse(req, res, data);
|
|
24
67
|
}
|
|
25
68
|
|
|
26
69
|
class ApolloServer extends ApolloServerBase {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
70
|
+
// --- ADDED: Constructor to handle playground options manually ---
|
|
71
|
+
constructor(config) {
|
|
72
|
+
super(config);
|
|
73
|
+
// Apollo Server v3 removes the playground option from the instance.
|
|
74
|
+
// We must manually capture it.
|
|
75
|
+
// We default to {} (enabled) if it is not explicitly set to false.
|
|
76
|
+
this.playgroundOptions = config.playground !== false ? (config.playground || {}) : false;
|
|
77
|
+
|
|
78
|
+
// Also capture uploads config manually if needed, though v3 usually preserves it in other ways,
|
|
79
|
+
// it's safer to ensure it exists for your handler logic below.
|
|
80
|
+
this.uploadsConfig = config.uploads !== false ? (config.uploads || {}) : false;
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
createGraphQLServerOptions(req, res) {
|
|
85
|
+
return super.graphQLServerOptions({ req, res });
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
createHandler({ path, disableHealthCheck, onHealthCheck } = {}) {
|
|
89
|
+
// FIX: Support Apollo Server v3 (.start) and v2 (.willStart)
|
|
90
|
+
let promiseWillStart;
|
|
91
|
+
if (typeof this.start === 'function') {
|
|
92
|
+
promiseWillStart = this.start();
|
|
93
|
+
} else if (typeof this.willStart === 'function') {
|
|
94
|
+
promiseWillStart = this.willStart();
|
|
95
|
+
} else {
|
|
96
|
+
promiseWillStart = Promise.resolve();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return async (req, res) => {
|
|
100
|
+
this.graphqlPath = path || "/graphql";
|
|
101
|
+
|
|
102
|
+
await promiseWillStart;
|
|
103
|
+
|
|
104
|
+
// Handle File Uploads (graphql-upload v17)
|
|
105
|
+
if (this.uploadsConfig) {
|
|
106
|
+
const contentType = req.headers["content-type"];
|
|
107
|
+
if (contentType && contentType.startsWith("multipart/form-data")) {
|
|
108
|
+
try {
|
|
109
|
+
const { processRequest } = await import("graphql-upload/processRequest.mjs");
|
|
110
|
+
// Note: processRequest no longer takes options in v17,
|
|
111
|
+
// but we pass this.uploadsConfig just in case you wrap/shim it,
|
|
112
|
+
// typically it just takes (req, res).
|
|
113
|
+
// If you need to configure limits, you usually do it via middleware before this
|
|
114
|
+
// or ensure processRequest respects the limits you want.
|
|
115
|
+
req.filePayload = await processRequest(req, res, this.uploadsConfig);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error.status && error.expose) {
|
|
118
|
+
return send(req, res, error.status, error.message);
|
|
119
|
+
}
|
|
120
|
+
return send(req, res, 500, "File upload processing failed.");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!disableHealthCheck && req.url === "/.well-known/apollo/server-health")
|
|
126
|
+
return await this.handleHealthCheck({ req, res, onHealthCheck });
|
|
127
|
+
|
|
128
|
+
// Handle Playground (GET requests requiring HTML)
|
|
129
|
+
// This will now work because this.playgroundOptions is set in the constructor
|
|
130
|
+
if (this.playgroundOptions && req.method === "GET") {
|
|
131
|
+
const { mediaTypes } = accept.parseAll(req.headers);
|
|
132
|
+
const prefersHTML =
|
|
133
|
+
mediaTypes.find(x => x === "text/html" || x === "application/json") ===
|
|
134
|
+
"text/html";
|
|
135
|
+
|
|
136
|
+
if (prefersHTML) {
|
|
137
|
+
const middlewareOptions = Object.assign(
|
|
138
|
+
{
|
|
139
|
+
endpoint: this.graphqlPath,
|
|
140
|
+
subscriptionEndpoint: this.subscriptionsPath,
|
|
141
|
+
},
|
|
142
|
+
this.playgroundOptions
|
|
143
|
+
);
|
|
144
|
+
return send(
|
|
145
|
+
req,
|
|
146
|
+
res,
|
|
147
|
+
200,
|
|
148
|
+
renderPlaygroundPage(middlewareOptions),
|
|
149
|
+
"text/html"
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const graphqlHandler = moleculerApollo(() => this.createGraphQLServerOptions(req, res));
|
|
155
|
+
const responseData = await graphqlHandler(req, res);
|
|
156
|
+
return send(req, res, 200, responseData);
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
supportsUploads() {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
supportsSubscriptions() {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async handleHealthCheck({ req, res, onHealthCheck }) {
|
|
169
|
+
onHealthCheck = onHealthCheck || (() => undefined);
|
|
170
|
+
try {
|
|
171
|
+
const result = await onHealthCheck(req);
|
|
172
|
+
return send(req, res, 200, { status: "pass", result }, "application/health+json");
|
|
173
|
+
} catch (error) {
|
|
174
|
+
const result = error instanceof Error ? error.toString() : error;
|
|
175
|
+
return send(req, res, 503, { status: "fail", result }, "application/health+json");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
110
178
|
}
|
|
111
179
|
module.exports = {
|
|
112
|
-
|
|
113
|
-
};
|
|
180
|
+
ApolloServer,
|
|
181
|
+
};
|