1 | "use strict";
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4 | return new (P || (P = Promise))(function (resolve, reject) {
|
5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9 | });
|
10 | };
|
11 | Object.defineProperty(exports, "__esModule", { value: true });
|
12 | exports.ApolloServer = exports.FileUploadRequest = void 0;
|
13 | const apollo_server_core_1 = require("apollo-server-core");
|
14 | const graphql_playground_html_1 = require("@apollographql/graphql-playground-html");
|
15 | const apollo_server_env_1 = require("apollo-server-env");
|
16 | const stream_1 = require("stream");
|
17 | function eventHttpMethod(event) {
|
18 | return 'httpMethod' in event
|
19 | ? event.httpMethod
|
20 | : event.requestContext.http.method;
|
21 | }
|
22 | function eventPath(event) {
|
23 | return 'path' in event ? event.path : event.rawPath;
|
24 | }
|
25 | class FileUploadRequest extends stream_1.Readable {
|
26 | }
|
27 | exports.FileUploadRequest = FileUploadRequest;
|
28 | function maybeCallbackify(asyncHandler) {
|
29 | return (event, context, callback) => {
|
30 | if (callback) {
|
31 | context.callbackWaitsForEmptyEventLoop = false;
|
32 | asyncHandler(event, context).then((r) => callback(null, r), (e) => callback(e));
|
33 | return;
|
34 | }
|
35 | else {
|
36 | return asyncHandler(event, context);
|
37 | }
|
38 | };
|
39 | }
|
40 | class ApolloServer extends apollo_server_core_1.ApolloServerBase {
|
41 | serverlessFramework() {
|
42 | return true;
|
43 | }
|
44 | supportsUploads() {
|
45 | return true;
|
46 | }
|
47 | createGraphQLServerOptions(event, context) {
|
48 | return super.graphQLServerOptions({ event, context });
|
49 | }
|
50 | createHandler({ cors, onHealthCheck } = {
|
51 | cors: undefined,
|
52 | onHealthCheck: undefined,
|
53 | }) {
|
54 | const corsHeaders = new apollo_server_env_1.Headers();
|
55 | if (cors) {
|
56 | if (cors.methods) {
|
57 | if (typeof cors.methods === 'string') {
|
58 | corsHeaders.set('access-control-allow-methods', cors.methods);
|
59 | }
|
60 | else if (Array.isArray(cors.methods)) {
|
61 | corsHeaders.set('access-control-allow-methods', cors.methods.join(','));
|
62 | }
|
63 | }
|
64 | if (cors.allowedHeaders) {
|
65 | if (typeof cors.allowedHeaders === 'string') {
|
66 | corsHeaders.set('access-control-allow-headers', cors.allowedHeaders);
|
67 | }
|
68 | else if (Array.isArray(cors.allowedHeaders)) {
|
69 | corsHeaders.set('access-control-allow-headers', cors.allowedHeaders.join(','));
|
70 | }
|
71 | }
|
72 | if (cors.exposedHeaders) {
|
73 | if (typeof cors.exposedHeaders === 'string') {
|
74 | corsHeaders.set('access-control-expose-headers', cors.exposedHeaders);
|
75 | }
|
76 | else if (Array.isArray(cors.exposedHeaders)) {
|
77 | corsHeaders.set('access-control-expose-headers', cors.exposedHeaders.join(','));
|
78 | }
|
79 | }
|
80 | if (cors.credentials) {
|
81 | corsHeaders.set('access-control-allow-credentials', 'true');
|
82 | }
|
83 | if (typeof cors.maxAge === 'number') {
|
84 | corsHeaders.set('access-control-max-age', cors.maxAge.toString());
|
85 | }
|
86 | }
|
87 | return maybeCallbackify((event, context) => __awaiter(this, void 0, void 0, function* () {
|
88 | const eventHeaders = new apollo_server_env_1.Headers(event.headers);
|
89 | const requestCorsHeaders = new apollo_server_env_1.Headers(corsHeaders);
|
90 | if (cors && cors.origin) {
|
91 | const requestOrigin = eventHeaders.get('origin');
|
92 | if (typeof cors.origin === 'string') {
|
93 | requestCorsHeaders.set('access-control-allow-origin', cors.origin);
|
94 | }
|
95 | else if (requestOrigin &&
|
96 | (typeof cors.origin === 'boolean' ||
|
97 | (Array.isArray(cors.origin) &&
|
98 | requestOrigin &&
|
99 | cors.origin.includes(requestOrigin)))) {
|
100 | requestCorsHeaders.set('access-control-allow-origin', requestOrigin);
|
101 | }
|
102 | const requestAccessControlRequestHeaders = eventHeaders.get('access-control-request-headers');
|
103 | if (!cors.allowedHeaders && requestAccessControlRequestHeaders) {
|
104 | requestCorsHeaders.set('access-control-allow-headers', requestAccessControlRequestHeaders);
|
105 | }
|
106 | }
|
107 | const requestCorsHeadersObject = Array.from(requestCorsHeaders).reduce((headersObject, [key, value]) => {
|
108 | headersObject[key] = value;
|
109 | return headersObject;
|
110 | }, {});
|
111 | if (eventHttpMethod(event) === 'OPTIONS') {
|
112 | return {
|
113 | body: '',
|
114 | statusCode: 204,
|
115 | headers: Object.assign({}, requestCorsHeadersObject),
|
116 | };
|
117 | }
|
118 | if (eventPath(event).endsWith('/.well-known/apollo/server-health')) {
|
119 | if (onHealthCheck) {
|
120 | try {
|
121 | yield onHealthCheck(event);
|
122 | }
|
123 | catch (_) {
|
124 | return {
|
125 | body: JSON.stringify({ status: 'fail' }),
|
126 | statusCode: 503,
|
127 | headers: Object.assign({ 'Content-Type': 'application/json' }, requestCorsHeadersObject),
|
128 | };
|
129 | }
|
130 | }
|
131 | return {
|
132 | body: JSON.stringify({ status: 'pass' }),
|
133 | statusCode: 200,
|
134 | headers: Object.assign({ 'Content-Type': 'application/json' }, requestCorsHeadersObject),
|
135 | };
|
136 | }
|
137 | if (this.playgroundOptions && eventHttpMethod(event) === 'GET') {
|
138 | const acceptHeader = event.headers['Accept'] || event.headers['accept'];
|
139 | if (acceptHeader && acceptHeader.includes('text/html')) {
|
140 | const path = eventPath(event) || '/';
|
141 | const playgroundRenderPageOptions = Object.assign({ endpoint: path }, this.playgroundOptions);
|
142 | return {
|
143 | body: graphql_playground_html_1.renderPlaygroundPage(playgroundRenderPageOptions),
|
144 | statusCode: 200,
|
145 | headers: Object.assign({ 'Content-Type': 'text/html' }, requestCorsHeadersObject),
|
146 | };
|
147 | }
|
148 | }
|
149 | const response = new stream_1.Writable();
|
150 | const contentType = (event.headers['content-type'] ||
|
151 | event.headers['Content-Type'] ||
|
152 | '').toLowerCase();
|
153 | const isMultipart = contentType.startsWith('multipart/form-data');
|
154 | let bodyFromFileUploads;
|
155 | if (isMultipart && typeof apollo_server_core_1.processFileUploads === 'function') {
|
156 | const request = new FileUploadRequest();
|
157 | request.push(Buffer.from(event.body, event.isBase64Encoded ? 'base64' : 'ascii'));
|
158 | request.push(null);
|
159 | request.headers = event.headers;
|
160 | try {
|
161 | bodyFromFileUploads = yield apollo_server_core_1.processFileUploads(request, response, this.uploadsConfig || {});
|
162 | }
|
163 | catch (error) {
|
164 | throw apollo_server_core_1.formatApolloErrors([error], {
|
165 | formatter: this.requestOptions.formatError,
|
166 | debug: this.requestOptions.debug,
|
167 | });
|
168 | }
|
169 | }
|
170 | try {
|
171 | let { body, isBase64Encoded } = event;
|
172 | let query;
|
173 | if (body && isBase64Encoded && !isMultipart) {
|
174 | body = Buffer.from(body, 'base64').toString();
|
175 | }
|
176 | if (eventHttpMethod(event) === 'POST' && !body) {
|
177 | return {
|
178 | body: 'POST body missing.',
|
179 | statusCode: 500,
|
180 | };
|
181 | }
|
182 | if (bodyFromFileUploads) {
|
183 | query = bodyFromFileUploads;
|
184 | }
|
185 | else if (body && eventHttpMethod(event) === 'POST' && isMultipart) {
|
186 | query = body;
|
187 | }
|
188 | else if (body && eventHttpMethod(event) === 'POST') {
|
189 | query = JSON.parse(body);
|
190 | }
|
191 | else {
|
192 | query = event.queryStringParameters || {};
|
193 | }
|
194 | try {
|
195 | const { graphqlResponse, responseInit } = yield apollo_server_core_1.runHttpQuery([event, context], {
|
196 | method: eventHttpMethod(event),
|
197 | options: () => __awaiter(this, void 0, void 0, function* () {
|
198 | return this.createGraphQLServerOptions(event, context);
|
199 | }),
|
200 | query,
|
201 | request: {
|
202 | url: eventPath(event),
|
203 | method: eventHttpMethod(event),
|
204 | headers: eventHeaders,
|
205 | },
|
206 | });
|
207 | return {
|
208 | body: graphqlResponse,
|
209 | statusCode: 200,
|
210 | headers: Object.assign(Object.assign({}, responseInit.headers), requestCorsHeadersObject),
|
211 | };
|
212 | }
|
213 | catch (error) {
|
214 | if (error.name !== 'HttpQueryError')
|
215 | throw error;
|
216 | const httpQueryError = error;
|
217 | return {
|
218 | body: httpQueryError.message,
|
219 | statusCode: httpQueryError.statusCode,
|
220 | headers: Object.assign(Object.assign({}, httpQueryError.headers), requestCorsHeadersObject),
|
221 | };
|
222 | }
|
223 | }
|
224 | finally {
|
225 | response.end();
|
226 | }
|
227 | }));
|
228 | }
|
229 | }
|
230 | exports.ApolloServer = ApolloServer;
|
231 |
|
\ | No newline at end of file |