Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
137 lines
3.8 KiB
Plaintext
137 lines
3.8 KiB
Plaintext
import { configToSchema } from '@payloadcms/graphql';
|
|
import { createHandler } from 'graphql-http/lib/use/fetch';
|
|
import { status as httpStatus } from 'http-status';
|
|
import { addDataAndFileToRequest, addLocalesToRequestFromData, createPayloadRequest, headersWithCors, logError, mergeHeaders } from 'payload';
|
|
const handleError = async ({
|
|
err,
|
|
payload,
|
|
req
|
|
}) => {
|
|
const status = err.originalError.status || httpStatus.INTERNAL_SERVER_ERROR;
|
|
let errorMessage = err.message;
|
|
logError({
|
|
err,
|
|
payload
|
|
});
|
|
// Internal server errors can contain anything, including potentially sensitive data.
|
|
// Therefore, error details will be hidden from the response unless `config.debug` is `true`
|
|
if (!payload.config.debug && status === httpStatus.INTERNAL_SERVER_ERROR) {
|
|
errorMessage = 'Something went wrong.';
|
|
}
|
|
let response = {
|
|
extensions: {
|
|
name: err?.originalError?.name || undefined,
|
|
data: err && err.originalError && err.originalError.data || undefined,
|
|
stack: payload.config.debug ? err.stack : undefined,
|
|
statusCode: status
|
|
},
|
|
locations: err.locations,
|
|
message: errorMessage,
|
|
path: err.path
|
|
};
|
|
await payload.config.hooks.afterError?.reduce(async (promise, hook) => {
|
|
await promise;
|
|
const result = await hook({
|
|
context: req.context,
|
|
error: err,
|
|
graphqlResult: response,
|
|
req
|
|
});
|
|
if (result) {
|
|
response = result.graphqlResult || response;
|
|
}
|
|
}, Promise.resolve());
|
|
return response;
|
|
};
|
|
let cached = global._payload_graphql;
|
|
if (!cached) {
|
|
cached = global._payload_graphql = {
|
|
graphql: null,
|
|
promise: null
|
|
};
|
|
}
|
|
export const getGraphql = async config => {
|
|
if (process.env.NODE_ENV === 'development') {
|
|
cached = global._payload_graphql = {
|
|
graphql: null,
|
|
promise: null
|
|
};
|
|
}
|
|
if (cached.graphql) {
|
|
return cached.graphql;
|
|
}
|
|
if (!cached.promise) {
|
|
const resolvedConfig = await config;
|
|
cached.promise = new Promise(resolve => {
|
|
const schema = configToSchema(resolvedConfig);
|
|
resolve(cached.graphql || schema);
|
|
});
|
|
}
|
|
try {
|
|
cached.graphql = await cached.promise;
|
|
} catch (e) {
|
|
cached.promise = null;
|
|
throw e;
|
|
}
|
|
return cached.graphql;
|
|
};
|
|
export const POST = config => async request => {
|
|
const originalRequest = request.clone();
|
|
const req = await createPayloadRequest({
|
|
canSetHeaders: true,
|
|
config,
|
|
request
|
|
});
|
|
await addDataAndFileToRequest(req);
|
|
addLocalesToRequestFromData(req);
|
|
const {
|
|
schema,
|
|
validationRules
|
|
} = await getGraphql(config);
|
|
const {
|
|
payload
|
|
} = req;
|
|
const headers = {};
|
|
const apiResponse = await createHandler({
|
|
context: {
|
|
headers,
|
|
req
|
|
},
|
|
onOperation: async (request, args, result) => {
|
|
const response = typeof payload.extensions === 'function' ? await payload.extensions({
|
|
args,
|
|
req: request,
|
|
result
|
|
}) : result;
|
|
if (response.errors) {
|
|
const errors = await Promise.all(result.errors.map(error => {
|
|
return handleError({
|
|
err: error,
|
|
payload,
|
|
req
|
|
});
|
|
}));
|
|
// errors type should be FormattedGraphQLError[] but onOperation has a return type of ExecutionResult instead of FormattedExecutionResult
|
|
return {
|
|
...response,
|
|
errors
|
|
};
|
|
}
|
|
return response;
|
|
},
|
|
schema,
|
|
validationRules: (_, args, defaultRules) => defaultRules.concat(validationRules(args))
|
|
})(originalRequest);
|
|
const resHeaders = headersWithCors({
|
|
headers: new Headers(apiResponse.headers),
|
|
req
|
|
});
|
|
for (const key in headers) {
|
|
resHeaders.append(key, headers[key]);
|
|
}
|
|
return new Response(apiResponse.body, {
|
|
headers: req.responseHeaders ? mergeHeaders(req.responseHeaders, resHeaders) : resHeaders,
|
|
status: apiResponse.status
|
|
});
|
|
};
|
|
//# sourceMappingURL=handler.js.map |