in lib/swaggerValidator/modelValidator.ts [526:647]
private schemaIssuesToModelValidationIssues(
operationId: string,
isRequest: boolean,
errors: SchemaValidateIssue[],
exampleUrl: string,
exampleContent: any,
parameters?: Parameter[],
statusCode?: string,
httpMethod?: string
) {
for (const err of errors) {
// ignore below schema errors
if (
(err.code === "NOT_PASSED" &&
(err.message.includes('should match "else" schema') ||
err.message.includes('should match "then" schema'))) ||
((err.code as any) === "SECRET_PROPERTY" && httpMethod === "post")
) {
continue;
}
let isSuppressed = false;
let schemaPosition;
let examplePosition;
let externalSwagger;
let schemaUrl = this.specPath;
const exampleJsonPaths: string[] = [];
if (isRequest) {
for (const p of parameters!) {
const parameter = this.jsonLoader.resolveRefObj(p);
if (
err.schemaPath.indexOf(parameter.name) > 0 ||
(err.jsonPathsInPayload.length > 0 &&
(err.jsonPathsInPayload[0].includes(parameter.name) ||
(err.jsonPathsInPayload[0].includes(".body") && parameter.in === "body")))
) {
schemaPosition = err.source.position;
if (parameter.in !== "body") {
const index = err.schemaPath.indexOf(parameter.name);
err.schemaPath = index > 0 ? err.schemaPath.substr(index) : err.schemaPath;
}
if (isSuppressedInPath(parameter, err.code, err.message)) {
isSuppressed = true;
}
exampleJsonPaths.push(`$parameters.${parameter.name}`);
break;
}
}
} else {
// response error case
let sourceSwagger = this.swagger;
if (err.source.url !== this.swagger._filePath) {
// use external swagger when the error points to external file
sourceSwagger = this.jsonLoader.getFileContentFromCache(err.source.url) as any;
schemaUrl = err.source.url;
}
// check x-nullable value when body is null
if (err.jsonPathsInPayload.length === 1 && err.jsonPathsInPayload[0] === ".body") {
const idx = err.source.jsonRef?.indexOf("#");
if (idx !== undefined && idx !== -1) {
const jsonRef = err.source.jsonRef?.substr(idx + 1);
const bodySchema = jsonPointer.get(sourceSwagger, jsonRef!);
if (bodySchema?.[C.xNullable] === true) {
continue;
}
}
}
if (
(err.code as any) === "MISSING_RESOURCE_ID" &&
exampleContent.responses[statusCode!].body &&
Object.keys(exampleContent.responses[statusCode!].body).length === 0
) {
// ignore this error when whole body of response is empty
continue;
}
const node = this.getNotSuppressedErrorPath(err);
if (node === undefined) {
continue;
}
if (externalSwagger === undefined) {
schemaPosition = getInfo(node)?.position;
} else {
schemaPosition = err.source.position;
}
for (let path of err.jsonPathsInPayload) {
// If parameter name includes ".", path should use "[]" for better understand.
for (const parameter of err.params) {
if (
typeof parameter === "string" &&
path.includes(`.${parameter}`) &&
parameter.includes(".")
) {
path = path.substring(0, path.indexOf(`.${parameter}`)) + `['${parameter}']`;
}
}
exampleJsonPaths.push(`$responses.${statusCode}${path}`);
}
}
if (!isSuppressed) {
for (const jsonPath of exampleJsonPaths) {
examplePosition = getFilePositionFromJsonPath(exampleContent, jsonPath);
this.errors.push({
code: err.code,
message: err.message,
schemaUrl,
exampleUrl,
schemaPosition: schemaPosition,
schemaJsonPath: err.schemaPath,
examplePosition,
exampleJsonPath: jsonPath,
severity: err.severity,
source: isRequest ? ValidationResultSource.REQUEST : ValidationResultSource.RESPONSE,
operationId,
});
}
}
}
}