UNPKG

graphql-yoga

Version:
107 lines (106 loc) • 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.INCREMENTAL_DELIVERY_SPECS = exports.getMultipartContentType = exports.DEFAULT_MULTIPART_CONTENT_TYPE = void 0; exports.getMediaTypesForRequestInOrder = getMediaTypesForRequestInOrder; exports.isMatchingMediaType = isMatchingMediaType; exports.negotiateIncrementalSpecFromMediaType = negotiateIncrementalSpecFromMediaType; exports.getIncrementalSpecForRequest = getIncrementalSpecForRequest; const utils_1 = require("@graphql-tools/utils"); var utils_2 = require("@graphql-tools/utils"); Object.defineProperty(exports, "DEFAULT_MULTIPART_CONTENT_TYPE", { enumerable: true, get: function () { return utils_2.DEFAULT_MULTIPART_CONTENT_TYPE; } }); Object.defineProperty(exports, "getMultipartContentType", { enumerable: true, get: function () { return utils_2.getMultipartContentType; } }); Object.defineProperty(exports, "INCREMENTAL_DELIVERY_SPECS", { enumerable: true, get: function () { return utils_2.INCREMENTAL_DELIVERY_SPECS; } }); function typeAndSubtype(mediaType) { const [essence] = mediaType.split(';'); const [pre, suf] = (essence ?? '').split('/'); return [pre ?? '', suf ?? '']; } function parseMediaTypeParams(mediaType) { const params = {}; const parts = mediaType.split(';'); for (let i = 1; i < parts.length; i++) { const part = parts[i]; if (part == null) continue; const eq = part.indexOf('='); if (eq === -1) continue; let value = part.slice(eq + 1); if (value.startsWith('"') && value.endsWith('"') && value.length >= 2) { value = value.slice(1, -1); } params[part.slice(0, eq)] = value; } return params; } function getMediaTypesForRequestInOrder(request, specs = utils_1.INCREMENTAL_DELIVERY_SPECS) { const specParamNames = (0, utils_1.getIncrementalSpecParameterNames)(specs); const accepts = (request.headers.get('accept') || '*/*') .replace(/\s/g, '') .toLowerCase() .split(','); const mediaTypes = []; for (const accept of accepts) { const [mediaType, ...params] = accept.split(';'); if (mediaType === undefined) continue; // If true, malformed header. const charset = params?.find(param => param.includes('charset=')) || 'charset=utf-8'; // utf-8 is assumed when not specified; if (charset !== 'charset=utf-8') { // only utf-8 is supported continue; } const specParams = params.filter(param => { const name = param.split('=')[0]; return name != null && specParamNames.has(name); }); mediaTypes.push(specParams.length ? `${mediaType};${specParams.join(';')}` : mediaType); } return mediaTypes.reverse(); } function isMatchingMediaType(askedMediaType, processorMediaType) { const [askedPre, askedSuf] = typeAndSubtype(askedMediaType); const [pre, suf] = typeAndSubtype(processorMediaType); if ((pre === '*' || pre === askedPre) && (suf === '*' || suf === askedSuf)) { return true; } return false; } /** * Map a single Accept media type to an executor `incrementalSpec` using the * registered HTTP parameter table. Non-multipart types return `undefined`. */ function negotiateIncrementalSpecFromMediaType(mediaType, specs = utils_1.INCREMENTAL_DELIVERY_SPECS) { const [type, subtype] = typeAndSubtype(mediaType); if (type !== 'multipart' || subtype !== 'mixed') { return undefined; } const lookedUp = (0, utils_1.lookupIncrementalDeliverySpec)(parseMediaTypeParams(mediaType), specs); if (lookedUp === 'unsupported') { return 'unsupported'; } if (lookedUp) { return { spec: lookedUp.id, contentType: (0, utils_1.getMultipartContentType)(lookedUp, { echoSpec: true }), }; } const fallback = (0, utils_1.getDefaultIncrementalDeliverySpec)(specs); return { spec: fallback.id, contentType: (0, utils_1.getMultipartContentType)(fallback, { echoSpec: false }), }; } /** * Last matching `multipart/mixed` in the request Accept list (same last-match * rule as result-processor selection). `undefined` leaves the executor default. */ function getIncrementalSpecForRequest(request, specs = utils_1.INCREMENTAL_DELIVERY_SPECS) { let spec; for (const mediaType of getMediaTypesForRequestInOrder(request, specs)) { const negotiated = negotiateIncrementalSpecFromMediaType(mediaType, specs); if (negotiated && negotiated !== 'unsupported') { spec = negotiated.spec; } } return spec; }