UNPKG

graphql-yoga

Version:

<div align="center"><img src="./website/public/cover.png" width="720" /></div>

127 lines (126 loc) 5.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useCORS = exports.getCORSHeadersByRequestAndOptions = void 0; function getCORSHeadersByRequestAndOptions(request, corsOptions) { const currentOrigin = request.headers.get('origin'); if (corsOptions === false || currentOrigin == null) { return null; } const headers = {}; // If defined origins have '*' or undefined by any means, we should allow all origins if (corsOptions.origin == null || corsOptions.origin.length === 0 || corsOptions.origin.includes('*')) { headers['Access-Control-Allow-Origin'] = currentOrigin; // Vary by origin because there are multiple origins headers['Vary'] = 'Origin'; } else if (typeof corsOptions.origin === 'string') { // If there is one specific origin is specified, use it directly headers['Access-Control-Allow-Origin'] = corsOptions.origin; } else if (Array.isArray(corsOptions.origin)) { // If there is only one origin defined in the array, consider it as a single one if (corsOptions.origin.length === 1) { headers['Access-Control-Allow-Origin'] = corsOptions.origin[0]; } else if (corsOptions.origin.includes(currentOrigin)) { // If origin is available in the headers, use it headers['Access-Control-Allow-Origin'] = currentOrigin; // Vary by origin because there are multiple origins headers['Vary'] = 'Origin'; } else { // There is no origin found in the headers, so we should return null headers['Access-Control-Allow-Origin'] = 'null'; } } if (corsOptions.methods?.length) { headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', '); } else { const requestMethod = request.headers.get('access-control-request-method'); if (requestMethod) { headers['Access-Control-Allow-Methods'] = requestMethod; } } if (corsOptions.allowedHeaders?.length) { headers['Access-Control-Allow-Headers'] = corsOptions.allowedHeaders.join(', '); } else { const requestHeaders = request.headers.get('access-control-request-headers'); if (requestHeaders) { headers['Access-Control-Allow-Headers'] = requestHeaders; if (headers['Vary']) { headers['Vary'] += ', Access-Control-Request-Headers'; } headers['Vary'] = 'Access-Control-Request-Headers'; } } if (corsOptions.credentials != null) { if (corsOptions.credentials === true) { headers['Access-Control-Allow-Credentials'] = 'true'; } } else if (headers['Access-Control-Allow-Origin'] !== '*') { headers['Access-Control-Allow-Credentials'] = 'true'; } if (corsOptions.exposedHeaders) { headers['Access-Control-Expose-Headers'] = corsOptions.exposedHeaders.join(', '); } if (corsOptions.maxAge) { headers['Access-Control-Max-Age'] = corsOptions.maxAge.toString(); } return headers; } exports.getCORSHeadersByRequestAndOptions = getCORSHeadersByRequestAndOptions; async function getCORSResponseHeaders(request, corsOptionsFactory, serverContext) { const corsOptions = await corsOptionsFactory(request, serverContext); return getCORSHeadersByRequestAndOptions(request, corsOptions); } // eslint-disable-next-line @typescript-eslint/no-explicit-any function useCORS(options) { let corsOptionsFactory = () => ({}); if (options != null) { if (typeof options === 'function') { corsOptionsFactory = options; } else if (typeof options === 'object') { const corsOptions = { ...options, }; corsOptionsFactory = () => corsOptions; } else if (options === false) { corsOptionsFactory = () => false; } } return { onRequest({ request, fetchAPI, endResponse }) { if (request.method.toUpperCase() === 'OPTIONS') { const response = new fetchAPI.Response(null, { status: 204, // Safari (and potentially other browsers) need content-length 0, // for 204 or they just hang waiting for a body // see: https://github.com/expressjs/cors/blob/master/lib/index.js#L176 headers: { 'Content-Length': '0', }, }); endResponse(response); } }, async onResponse({ request, serverContext, response }) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const headers = await getCORSResponseHeaders(request, corsOptionsFactory, serverContext); if (headers != null) { for (const headerName in headers) { response.headers.set(headerName, headers[headerName]); } } }, }; } exports.useCORS = useCORS;