@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 CHANGED
@@ -17,7 +17,6 @@ declare module "moleculer-apollo-server" {
17
17
  defaultPlaygroundOptions,
18
18
  } from "apollo-server-core";
19
19
 
20
- export { GraphQLUpload } from "graphql-upload";
21
20
 
22
21
  export * from "graphql-tools";
23
22
 
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.1",
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": "^8.0.11",
53
- "apollo-server-core": "^2.22.2",
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": "^11.0.0",
56
+ "graphql-upload": "^17.0.0",
58
57
  "lodash": "^4.17.21",
59
58
  "object-hash": "^2.2.0"
60
59
  },
61
- "gitHead": "3b62a855a71457d7a8bfeb47ba6d6863a7aa9763"
60
+ "gitHead": "d862431920494f1011ba354e0d0051c7da8e2479"
62
61
  }
@@ -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
- res.statusCode = statusCode;
53
+ res.statusCode = statusCode;
11
54
 
12
- const ctx = res.$ctx;
13
- if (!ctx.meta.$responseType) {
14
- ctx.meta.$responseType = responseType;
15
- }
55
+ const ctx = res.$ctx;
56
+ if (!ctx.meta.$responseType) {
57
+ ctx.meta.$responseType = responseType;
58
+ }
16
59
 
17
- const route = res.$route;
18
- if (route.onAfterCall) {
19
- data = await route.onAfterCall.call(this, ctx, route, req, res, data);
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
- const service = res.$service;
23
- service.sendResponse(req, res, data);
65
+ const service = res.$service;
66
+ service.sendResponse(req, res, data);
24
67
  }
25
68
 
26
69
  class ApolloServer extends ApolloServerBase {
27
- // Extract Apollo Server options from the request.
28
- createGraphQLServerOptions(req, res) {
29
- return super.graphQLServerOptions({ req, res });
30
- }
31
-
32
- // Prepares and returns an async function that can be used to handle
33
- // GraphQL requests.
34
- createHandler({ path, disableHealthCheck, onHealthCheck } = {}) {
35
- const promiseWillStart = this.willStart();
36
-
37
- return async (req, res) => {
38
- this.graphqlPath = path || "/graphql";
39
-
40
- await promiseWillStart;
41
-
42
- // If file uploads are detected, prepare them for easier handling with
43
- // the help of `graphql-upload`.
44
- if (this.uploadsConfig) {
45
- const contentType = req.headers["content-type"];
46
- if (contentType && contentType.startsWith("multipart/form-data")) {
47
- req.filePayload = await processRequest(req, res, this.uploadsConfig);
48
- }
49
- }
50
-
51
- // If health checking is enabled, trigger the `onHealthCheck`
52
- // function when the health check URL is requested.
53
- if (!disableHealthCheck && req.url === "/.well-known/apollo/server-health")
54
- return await this.handleHealthCheck({ req, res, onHealthCheck });
55
-
56
- // If the `playgroundOptions` are set, register a `graphql-playground` instance
57
- // (not available in production) that is then used to handle all
58
- // incoming GraphQL requests.
59
- if (this.playgroundOptions && req.method === "GET") {
60
- const { mediaTypes } = accept.parseAll(req.headers);
61
- const prefersHTML =
62
- mediaTypes.find(x => x === "text/html" || x === "application/json") ===
63
- "text/html";
64
-
65
- if (prefersHTML) {
66
- const middlewareOptions = Object.assign(
67
- {
68
- endpoint: this.graphqlPath,
69
- subscriptionEndpoint: this.subscriptionsPath,
70
- },
71
- this.playgroundOptions
72
- );
73
- return send(
74
- req,
75
- res,
76
- 200,
77
- renderPlaygroundPage(middlewareOptions),
78
- "text/html"
79
- );
80
- }
81
- }
82
-
83
- // Handle incoming GraphQL requests using Apollo Server.
84
- const graphqlHandler = moleculerApollo(() => this.createGraphQLServerOptions(req, res));
85
- const responseData = await graphqlHandler(req, res);
86
- return send(req, res, 200, responseData);
87
- };
88
- }
89
-
90
- // This integration supports file uploads.
91
- supportsUploads() {
92
- return true;
93
- }
94
-
95
- // This integration supports subscriptions.
96
- supportsSubscriptions() {
97
- return true;
98
- }
99
-
100
- async handleHealthCheck({ req, res, onHealthCheck }) {
101
- onHealthCheck = onHealthCheck || (() => undefined);
102
- try {
103
- const result = await onHealthCheck(req);
104
- return send(req, res, 200, { status: "pass", result }, "application/health+json");
105
- } catch (error) {
106
- const result = error instanceof Error ? error.toString() : error;
107
- return send(req, res, 503, { status: "fail", result }, "application/health+json");
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
- ApolloServer,
113
- };
180
+ ApolloServer,
181
+ };