// This function runs after the common function, // `src/execute/index.js#buildRequest` import { isPlainObject } from 'is-plain-object'; import btoa from '../../helpers/btoa.node.js'; export default function buildRequest(options, req) { const { operation, requestBody, securities, spec, attachContentTypeForEmptyPayload } = options; let { requestContentType } = options; req = applySecurities({ request: req, securities, operation, spec }); const requestBodyDef = operation.requestBody || {}; const requestBodyMediaTypes = Object.keys(requestBodyDef.content || {}); const isExplicitContentTypeValid = requestContentType && requestBodyMediaTypes.indexOf(requestContentType) > -1; // for OAS3: set the Content-Type if (requestBody || attachContentTypeForEmptyPayload) { // does the passed requestContentType appear in the requestBody definition? if (requestContentType && isExplicitContentTypeValid) { req.headers['Content-Type'] = requestContentType; } else if (!requestContentType) { const firstMediaType = requestBodyMediaTypes[0]; if (firstMediaType) { req.headers['Content-Type'] = firstMediaType; requestContentType = firstMediaType; } } } else if (requestContentType && isExplicitContentTypeValid) { req.headers['Content-Type'] = requestContentType; } if (!options.responseContentType && operation.responses) { const mediaTypes = Object.entries(operation.responses).filter(([key, value]) => { const code = parseInt(key, 10); return code >= 200 && code < 300 && isPlainObject(value.content); }).reduce((acc, [, value]) => acc.concat(Object.keys(value.content)), []); if (mediaTypes.length > 0) { req.headers.accept = mediaTypes.join(', '); } } // for OAS3: add requestBody to request if (requestBody) { if (requestContentType) { if (requestBodyMediaTypes.indexOf(requestContentType) > -1) { // only attach body if the requestBody has a definition for the // contentType that has been explicitly set if (requestContentType === 'application/x-www-form-urlencoded' || requestContentType === 'multipart/form-data') { if (typeof requestBody === 'object') { var _requestBodyDef$conte, _requestBodyDef$conte2; const encoding = (_requestBodyDef$conte = (_requestBodyDef$conte2 = requestBodyDef.content[requestContentType]) === null || _requestBodyDef$conte2 === void 0 ? void 0 : _requestBodyDef$conte2.encoding) !== null && _requestBodyDef$conte !== void 0 ? _requestBodyDef$conte : {}; req.form = {}; Object.keys(requestBody).forEach(k => { req.form[k] = { value: requestBody[k], encoding: encoding[k] || {} }; }); } else { req.form = requestBody; } } else { req.body = requestBody; } } } else { req.body = requestBody; } } return req; } // Add security values, to operations - that declare their need on them // Adapted from the Swagger2 implementation export function applySecurities({ request, securities = {}, operation = {}, spec }) { var _spec$components; const result = { ...request }; const { authorized = {} } = securities; const security = operation.security || spec.security || []; const isAuthorized = authorized && !!Object.keys(authorized).length; const securityDef = (spec === null || spec === void 0 || (_spec$components = spec.components) === null || _spec$components === void 0 ? void 0 : _spec$components.securitySchemes) || {}; result.headers = result.headers || {}; result.query = result.query || {}; if (!Object.keys(securities).length || !isAuthorized || !security || Array.isArray(operation.security) && !operation.security.length) { return request; } security.forEach(securityObj => { Object.keys(securityObj).forEach(key => { const auth = authorized[key]; const schema = securityDef[key]; if (!auth) { return; } const value = auth.value || auth; const { type } = schema; if (auth) { if (type === 'apiKey') { if (schema.in === 'query') { result.query[schema.name] = value; } if (schema.in === 'header') { result.headers[schema.name] = value; } if (schema.in === 'cookie') { result.cookies[schema.name] = value; } } else if (type === 'http') { if (/^basic$/i.test(schema.scheme)) { const username = value.username || ''; const password = value.password || ''; const encoded = btoa(`${username}:${password}`); result.headers.Authorization = `Basic ${encoded}`; } if (/^bearer$/i.test(schema.scheme)) { result.headers.Authorization = `Bearer ${value}`; } } else if (type === 'oauth2' || type === 'openIdConnect') { const token = auth.token || {}; const tokenName = schema['x-tokenName'] || 'access_token'; const tokenValue = token[tokenName]; let tokenType = token.token_type; if (!tokenType || tokenType.toLowerCase() === 'bearer') { tokenType = 'Bearer'; } result.headers.Authorization = `${tokenType} ${tokenValue}`; } } }); }); return result; }