Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 29x 29x 29x 29x 29x 29x 71x 71x 71x 71x 71x 71x 119x 119x 98x 98x 80x 80x 80x 78x 78x 78x 78x 78x 78x 78x 78x 8x 78x 78x 78x 83x 74x 74x 74x 11x 71x 78x 78x | // Assertation 1. Request body objects must have a `content` property // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#requestBodyObject // covered by Spectral's oas3-schema rule // Assertation 2. Operations with non-form request bodies should set the `x-codegen-request-body-name` // annotation (for code generation purposes) // Assertation 3. Request bodies with application/json content should not use schema // type: string, format: binary. const pick = require('lodash/pick'); const each = require('lodash/each'); const { hasRefProperty } = require('../../../utils'); const MessageCarrier = require('../../../utils/messageCarrier'); const findOctetSequencePaths = require('../../../utils/findOctetSequencePaths') .findOctetSequencePaths; module.exports.validate = function({ resolvedSpec, jsSpec }, config) { const messages = new MessageCarrier(); const configSchemas = config.schemas; config = config.operations; const REQUEST_BODY_NAME = 'x-codegen-request-body-name'; // get, head, and delete are not in this list because they are not allowed // to have request bodies const allowedOps = ['post', 'put', 'patch', 'options', 'trace']; each(resolvedSpec.paths, (path, pathName) => { const operations = pick(path, allowedOps); each(operations, (op, opName) => { Iif (!op || op['x-sdk-exclude'] === true) { return; } if (op.requestBody) { const requestBodyContent = op.requestBody.content; const requestBodyMimeTypes = op.requestBody.content && Object.keys(requestBodyContent); if (requestBodyContent && requestBodyMimeTypes.length) { // request body has content const firstMimeType = requestBodyMimeTypes[0]; // code generation uses the first mime type const oneContentType = requestBodyMimeTypes.length === 1; const isJson = firstMimeType === 'application/json' || firstMimeType.endsWith('+json'); const hasArraySchema = requestBodyContent[firstMimeType].schema && requestBodyContent[firstMimeType].schema.type === 'array'; const hasRequestBodyName = op[REQUEST_BODY_NAME] && op[REQUEST_BODY_NAME].trim().length; // non-array json responses with only one content type will have // the body exploded in sdk generation, no need for name const explodingBody = oneContentType && isJson && !hasArraySchema; // referenced request bodies have names const hasReferencedRequestBody = hasRefProperty(jsSpec, [ 'paths', pathName, opName, 'requestBody' ]); // form params do not need names if ( !isFormParameter(firstMimeType) && !explodingBody && !hasReferencedRequestBody && !hasRequestBodyName ) { messages.addMessage( `paths.${pathName}.${opName}`, 'Operations with non-form request bodies should set a name with the x-codegen-request-body-name annotation.', config.no_request_body_name, 'no_request_body_name' ); } // Assertation 3 const binaryStringStatus = configSchemas.json_or_param_binary_string; Eif (binaryStringStatus !== 'off') { for (const mimeType of requestBodyMimeTypes) { if (mimeType === 'application/json') { const schemaPath = `paths.${pathName}.${opName}.requestBody.content.${mimeType}.schema`; const octetSequencePaths = findOctetSequencePaths( requestBodyContent[mimeType].schema, schemaPath ); for (const p of octetSequencePaths) { messages.addMessage( p, 'JSON request/response bodies should not contain binary (type: string, format: binary) values.', binaryStringStatus, 'json_or_param_binary_string' ); } } } } } } }); }); return messages; }; function isFormParameter(mimeType) { const formDataMimeTypes = [ 'multipart/form-data', 'application/x-www-form-urlencoded', 'application/octet-stream' ]; return formDataMimeTypes.includes(mimeType); } |