diff --git a/package-lock.json b/package-lock.json index 174dd5a765..17eba9f922 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "@snyk/graphlib": "^2.1.9-patch.3", "@snyk/snyk-cocoapods-plugin": "2.5.2", "@snyk/snyk-hex-plugin": "1.1.4", + "@types/jest-json-schema": "^6.1.1", "@types/marked": "^4.0.0", "abbrev": "^1.1.1", "adm-zip": "^0.5.9", @@ -35,6 +36,7 @@ "env-paths": "^2.0.0", "glob": "^7.1.7", "global-agent": "^2.1.12", + "jest-json-schema": "^6.1.0", "jsondiffpatch": "^0.4.1", "lodash.assign": "^4.2.0", "lodash.camelcase": "^4.3.0", @@ -2653,12 +2655,20 @@ "version": "27.0.1", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.1.tgz", "integrity": "sha512-HTLpVXHrY69556ozYkcq47TtQJXpcWAWfkoqz+ZGz2JnmZhzlRjprCIyFnetSy8gpDWwTTGBcRVv1J1I1vBrHw==", - "dev": true, "dependencies": { "jest-diff": "^27.0.0", "pretty-format": "^27.0.0" } }, + "node_modules/@types/jest-json-schema": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/jest-json-schema/-/jest-json-schema-6.1.1.tgz", + "integrity": "sha512-tb+4AHBx+EwV3xSlZHMLE10MvitNGFpnQIZSTzZOPg15rXBdqig63BBE+pNAIN1226lP2L7zaVUcbvAsqMFluA==", + "dependencies": { + "@types/jest": "*", + "ajv": "^6.10.2" + } + }, "node_modules/@types/js-yaml": { "version": "3.12.7", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.7.tgz", @@ -3897,7 +3907,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3909,6 +3918,42 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -6412,7 +6457,6 @@ "version": "27.4.0", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", - "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } @@ -7648,8 +7692,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.2.7", @@ -7698,8 +7741,7 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -10170,7 +10212,6 @@ "version": "27.4.6", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", - "dev": true, "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^27.4.0", @@ -10185,7 +10226,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -10200,7 +10240,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10216,7 +10255,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -10227,14 +10265,12 @@ "node_modules/jest-diff/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -10243,7 +10279,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -10388,7 +10423,6 @@ "version": "27.4.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", - "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } @@ -10530,6 +10564,104 @@ "node": ">=8" } }, + "node_modules/jest-json-schema": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jest-json-schema/-/jest-json-schema-6.1.0.tgz", + "integrity": "sha512-LMHuLmKjr/4X+H8v1xF5TEwfYEkzwGeWJ0epYQVQhlVTDDR5FWCdSO8vmsecb5cLf9NeWAqMKn3qhJvP9um0AA==", + "dependencies": { + "ajv": "^8.8.2", + "ajv-formats": "^2.1.1", + "chalk": "^4.1.2", + "jest-matcher-utils": "^27.3.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-json-schema/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/jest-json-schema/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-json-schema/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-json-schema/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-json-schema/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-json-schema/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-json-schema/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/jest-json-schema/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-leak-detector": { "version": "27.4.6", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", @@ -10547,7 +10679,6 @@ "version": "27.4.6", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", - "dev": true, "dependencies": { "chalk": "^4.0.0", "jest-diff": "^27.4.6", @@ -10562,7 +10693,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -10577,7 +10707,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10593,7 +10722,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -10604,14 +10732,12 @@ "node_modules/jest-matcher-utils/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -10620,7 +10746,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -11745,8 +11870,7 @@ "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -14878,7 +15002,6 @@ "version": "27.4.6", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -14892,7 +15015,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, "engines": { "node": ">=10" }, @@ -15074,7 +15196,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { "node": ">=6" } @@ -15256,8 +15377,7 @@ "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "node_modules/read-pkg": { "version": "3.0.0", @@ -15607,7 +15727,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -18858,7 +18977,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -22016,12 +22134,20 @@ "version": "27.0.1", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.1.tgz", "integrity": "sha512-HTLpVXHrY69556ozYkcq47TtQJXpcWAWfkoqz+ZGz2JnmZhzlRjprCIyFnetSy8gpDWwTTGBcRVv1J1I1vBrHw==", - "dev": true, "requires": { "jest-diff": "^27.0.0", "pretty-format": "^27.0.0" } }, + "@types/jest-json-schema": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/jest-json-schema/-/jest-json-schema-6.1.1.tgz", + "integrity": "sha512-tb+4AHBx+EwV3xSlZHMLE10MvitNGFpnQIZSTzZOPg15rXBdqig63BBE+pNAIN1226lP2L7zaVUcbvAsqMFluA==", + "requires": { + "@types/jest": "*", + "ajv": "^6.10.2" + } + }, "@types/js-yaml": { "version": "3.12.7", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.7.tgz", @@ -23015,7 +23141,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -23023,6 +23148,32 @@ "uri-js": "^4.2.2" } }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + } + } + }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -25001,8 +25152,7 @@ "diff-sequences": { "version": "27.4.0", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz", - "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==", - "dev": true + "integrity": "sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==" }, "dir-glob": { "version": "3.0.1", @@ -25941,8 +26091,7 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { "version": "3.2.7", @@ -25984,8 +26133,7 @@ "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", @@ -27828,7 +27976,6 @@ "version": "27.4.6", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz", "integrity": "sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==", - "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^27.4.0", @@ -27840,7 +27987,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -27849,7 +27995,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -27859,7 +28004,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -27867,20 +28011,17 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -27992,8 +28133,7 @@ "jest-get-type": { "version": "27.4.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz", - "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==", - "dev": true + "integrity": "sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==" }, "jest-haste-map": { "version": "27.4.6", @@ -28104,6 +28244,78 @@ } } }, + "jest-json-schema": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jest-json-schema/-/jest-json-schema-6.1.0.tgz", + "integrity": "sha512-LMHuLmKjr/4X+H8v1xF5TEwfYEkzwGeWJ0epYQVQhlVTDDR5FWCdSO8vmsecb5cLf9NeWAqMKn3qhJvP9um0AA==", + "requires": { + "ajv": "^8.8.2", + "ajv-formats": "^2.1.1", + "chalk": "^4.1.2", + "jest-matcher-utils": "^27.3.1" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "jest-leak-detector": { "version": "27.4.6", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz", @@ -28118,7 +28330,6 @@ "version": "27.4.6", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz", "integrity": "sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==", - "dev": true, "requires": { "chalk": "^4.0.0", "jest-diff": "^27.4.6", @@ -28130,7 +28341,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -28139,7 +28349,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -28149,7 +28358,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -28157,20 +28365,17 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -29023,8 +29228,7 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -31482,7 +31686,6 @@ "version": "27.4.6", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz", "integrity": "sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==", - "dev": true, "requires": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -31492,8 +31695,7 @@ "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" } } }, @@ -31644,8 +31846,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "q": { "version": "1.5.1", @@ -31777,8 +31978,7 @@ "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "read-pkg": { "version": "3.0.0", @@ -32044,8 +32244,7 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "2.0.0", @@ -34624,7 +34823,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "requires": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index 26c755798d..1404806dac 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@snyk/graphlib": "^2.1.9-patch.3", "@snyk/snyk-cocoapods-plugin": "2.5.2", "@snyk/snyk-hex-plugin": "1.1.4", + "@types/jest-json-schema": "^6.1.1", "@types/marked": "^4.0.0", "abbrev": "^1.1.1", "adm-zip": "^0.5.9", @@ -82,6 +83,7 @@ "env-paths": "^2.0.0", "glob": "^7.1.7", "global-agent": "^2.1.12", + "jest-json-schema": "^6.1.0", "jsondiffpatch": "^0.4.1", "lodash.assign": "^4.2.0", "lodash.camelcase": "^4.3.0", diff --git a/test/fixtures/iac/output-formats/test-error-json-schema.json b/test/fixtures/iac/output-formats/test-error-json-schema.json new file mode 100644 index 0000000000..c4ee351767 --- /dev/null +++ b/test/fixtures/iac/output-formats/test-error-json-schema.json @@ -0,0 +1,10 @@ +{ + "type": "object", + "properties": { + "ok": { "type": "boolean" }, + "error": { "type": "string" }, + "path": { "type": "string" } + }, + "required": ["ok", "error", "path"], + "additionalProperties": false +} diff --git a/test/fixtures/iac/output-formats/test-result-json-schema.json b/test/fixtures/iac/output-formats/test-result-json-schema.json new file mode 100644 index 0000000000..d4835ff4cb --- /dev/null +++ b/test/fixtures/iac/output-formats/test-result-json-schema.json @@ -0,0 +1,250 @@ +{ + "type": "object", + "properties": { + "meta": { + "type": "object", + "properties": { + "isPrivate": { + "type": "boolean" + }, + "isLicensesEnabled": { + "type": "boolean" + }, + "org": { + "type": "string" + }, + "ignoreSettings": { + "type": "object", + "properties": { + "adminOnly": { + "type": "boolean" + }, + "reasonRequired": { + "type": "boolean" + }, + "disregardFilesystemIgnores": { + "type": "boolean" + } + }, + "required": [ + "adminOnly", + "reasonRequired", + "disregardFilesystemIgnores" + ], + "additionalProperties": false, + "nullable": true + }, + "projectId": { + "type": "string" + }, + "policy": { + "type": "string" + }, + "gitRemoteUrl": { + "type": "string" + } + }, + "required": [ + "isPrivate", + "isLicensesEnabled", + "org" + ], + "additionalFields": false + }, + "filesystemPolicy": { + "type": "boolean" + }, + "dependencyCount": { + "type": "number" + }, + "licensesPolicy": { + "type": "null" + }, + "ignoreSettings": { + "type": "null" + }, + "vulnerabilities": { + "type": "array", + "maxItems": 0 + }, + "targetFile": { + "type": "string" + }, + "projectName": { + "type": "string" + }, + "org": { + "type": "string" + }, + "policy": { + "type": "string", + "maxLength": 0 + }, + "isPrivate": { + "type": "boolean" + }, + "targetFilePath": { + "type": "string" + }, + "packageManager": { + "type": "string" + }, + "path": { + "type": "string" + }, + "projectType": { + "type": "string" + }, + "ok": { + "type": "boolean" + }, + "infrastructureAsCodeIssues": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "publicId": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "severity": { + "type": "string", + "enum": [ + "low", + "medium", + "high", + "critical" + ] + }, + "isIgnored": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "subType": { + "type": "string" + }, + "policyEngineType": { + "type": "string" + }, + "references": { + "type": "array", + "items": { + "type": "string" + } + }, + "path": { + "type": "array", + "items": { + "type": "string" + } + }, + "documentation": { + "type": "string" + }, + "isGeneratedByCustomRule": { + "type": "boolean" + }, + "issue": { + "type": "string" + }, + "impact": { + "type": "string" + }, + "resolve": { + "type": "string" + }, + "remediation": { + "type": "object", + "terraform": { + "type": "string" + }, + "cloudformation": { + "type": "string" + }, + "arm": { + "type": "string" + }, + "kubernetes": { + "type": "string" + } + }, + "msg": { + "type": "string" + }, + "compliance": { + "type": "array", + "maxItems": 0 + }, + "lineNumber": { + "type": "number" + }, + "iacDescription": { + "type": "object", + "properties": { + "issue": { + "type": "string" + }, + "impact": { + "type": "string" + }, + "resolve": { + "type": "string" + } + }, + "required": [ + "issue", + "impact", + "resolve" + ], + "additionalProperties": false + } + }, + "requires": [ + "id", + "publicId", + "title", + "severity", + "isIgnored", + "subType", + "references", + "issue", + "impact", + "resolve", + "msg", + "iacDescription" + ], + "additionalProperties": true + } + } + }, + "required": [ + "meta", + "filesystemPolicy", + "dependencyCount", + "licensesPolicy", + "ignoreSettings", + "vulnerabilities", + "targetFile", + "projectName", + "org", + "policy", + "isPrivate", + "targetFilePath", + "packageManager", + "path", + "projectType", + "ok", + "infrastructureAsCodeIssues" + ], + "additionalProperties": false +} diff --git a/test/jest/acceptance/iac/output-formats/json.spec.ts b/test/jest/acceptance/iac/output-formats/json.spec.ts new file mode 100644 index 0000000000..7ab1bad70d --- /dev/null +++ b/test/jest/acceptance/iac/output-formats/json.spec.ts @@ -0,0 +1,200 @@ +import * as fs from 'fs'; +import * as pathLib from 'path'; +import { matchers } from 'jest-json-schema'; + +import { FakeServer } from '../../../../acceptance/fake-server'; +import { startMockServer } from '../helpers'; +import { + spinnerMessage, + spinnerSuccessMessage, +} from '../../../../../src/lib/formatters/iac-output'; + +expect.extend(matchers); + +const IAC_CLI_OUTPUT_FF = 'iacCliOutputRelease'; + +const testResultJsonSchema = JSON.parse( + fs.readFileSync( + pathLib.join( + __dirname, + '..', + '..', + '..', + '..', + 'fixtures', + 'iac', + 'output-formats', + 'test-result-json-schema.json', + ), + 'utf-8', + ), +); + +const testResultsJsonSchema = { + type: 'array', + items: testResultJsonSchema, +}; + +const testErrorJsonSchema = JSON.parse( + fs.readFileSync( + pathLib.join( + __dirname, + '..', + '..', + '..', + '..', + 'fixtures', + 'iac', + 'output-formats', + 'test-error-json-schema.json', + ), + 'utf-8', + ), +); + +const testErrorsJsonSchema = { + type: 'array', + items: testErrorJsonSchema, +}; + +jest.setTimeout(1_000 * 30); + +describe('iac test JSON output', () => { + let server: FakeServer; + let run: ( + cmd: string, + overrides?: Record, + ) => Promise<{ stdout: string; stderr: string; exitCode: number }>; + let teardown: () => Promise; + + beforeAll(async () => { + ({ server, run, teardown } = await startMockServer()); + }); + + afterEach(() => { + server.restore(); + }); + + afterAll(async () => { + await teardown(); + }); + + describe.each` + outputFFValue + ${true} + ${false} + `( + `with \`${IAC_CLI_OUTPUT_FF}\` feature flag as \`$outputFFValue\``, + ({ outputFFValue }) => { + beforeEach(() => { + server.setFeatureFlag(IAC_CLI_OUTPUT_FF, outputFFValue); + }); + + it('should not show an initial message', async () => { + // Arrange + const filePath = './iac/arm/rule_test.json'; + + // Act + const { stdout } = await run(`snyk iac test --json ${filePath}`); + + // Assert + expect(stdout).not.toContain(spinnerMessage); + }); + + it('should not show spinner messages', async () => { + // Arrange + const filePath = './iac/arm/rule_test.json'; + + // Act + const { stdout } = await run(`snyk iac test --json ${filePath}`); + + // Asset + expect(stdout).not.toContain(spinnerMessage); + expect(stdout).not.toContain(spinnerSuccessMessage); + }); + + describe('with a single file', () => { + describe('when the test is successful', () => { + it('should output a result in the correct schema', async () => { + // Arrange + const filePath = 'iac/cloudformation/aurora-valid.yml'; + + // Act + const { stdout } = await run(`snyk iac test --json ${filePath}`); + const outputJson = JSON.parse(stdout); + + // Assert + expect(outputJson).toMatchSchema(testResultJsonSchema); + }); + }); + + describe('when the test fails', () => { + it('should output an error in the correct schema', async () => { + // Arrange + const filePath = 'iac/only-invalid/invalid-file1.yml'; + + // Act + const { stdout } = await run(`snyk iac test --json ${filePath}`); + const outputJson = JSON.parse(stdout); + + // Assert + expect(outputJson).toMatchSchema(testErrorJsonSchema); + }); + }); + }); + + describe('with multiple files', () => { + describe('with some successful tests', () => { + it('should output results in the correct schema', async () => { + // Arrange + const dirPath = 'iac'; + + // Act + const { stdout } = await run(`snyk iac test --json ${dirPath}`); + const outputJson = JSON.parse(stdout); + + // Assert + expect(outputJson).toMatchSchema(testResultsJsonSchema); + }); + + describe('with multiple paths', () => { + it('should return valid output', async () => { + // Arrange + const paths = [ + './iac/arm/rule_test.json', + './iac/cloudformation', + ]; + + // Act + const { stdout, exitCode } = await run( + `snyk iac test --json ${paths.join(' ')}`, + ); + + // Assert + const outputJson = JSON.parse(stdout); + expect(outputJson).toMatchSchema(testResultsJsonSchema); + + expect(stdout).toContain('"id": "SNYK-CC-TF-20",'); + expect(stdout).toContain('"id": "SNYK-CC-AWS-422",'); + expect(exitCode).toBe(1); + }); + }); + }); + + describe('with only failing tests', () => { + it('should output errors in the correct schema', async () => { + // Arrange + const dirPath = 'iac/only-invalid'; + + // Act + const { stdout } = await run(`snyk iac test --json ${dirPath}`); + const outputJson = JSON.parse(stdout); + + // Assert + expect(outputJson).toMatchSchema(testErrorsJsonSchema); + }); + }); + }); + }, + ); +}); diff --git a/test/jest/acceptance/iac/output-formats/sarif.spec.ts b/test/jest/acceptance/iac/output-formats/sarif.spec.ts new file mode 100644 index 0000000000..325101a391 --- /dev/null +++ b/test/jest/acceptance/iac/output-formats/sarif.spec.ts @@ -0,0 +1,86 @@ +import { FakeServer } from '../../../../acceptance/fake-server'; +import { isValidJSONString, startMockServer } from '../helpers'; +import { + spinnerMessage, + spinnerSuccessMessage, +} from '../../../../../src/lib/formatters/iac-output'; + +const IAC_CLI_OUTPUT_FF = 'iacCliOutputRelease'; + +jest.setTimeout(1_000 * 30); + +describe('iac test SARIF output', () => { + let server: FakeServer; + let run: ( + cmd: string, + overrides?: Record, + ) => Promise<{ stdout: string; stderr: string; exitCode: number }>; + let teardown: () => Promise; + + beforeAll(async () => { + ({ server, run, teardown } = await startMockServer()); + }); + + afterEach(() => { + server.restore(); + }); + + afterAll(async () => { + await teardown(); + }); + + describe.each` + outputFFValue + ${true} + ${false} + `( + `with \`${IAC_CLI_OUTPUT_FF}\` feature flag as \`$outputFFValue\``, + ({ outputFFValue }) => { + beforeEach(() => { + server.setFeatureFlag(IAC_CLI_OUTPUT_FF, outputFFValue); + }); + + it('should not show an initial message', async () => { + // Arrange + const filePath = './iac/arm/rule_test.json'; + + // Act + const { stdout } = await run(`snyk iac test --sarif ${filePath}`); + + // Assert + expect(stdout).not.toContain(spinnerMessage); + }); + + it('should not show spinner messages', async () => { + // Arrange + const filePath = './iac/arm/rule_test.json'; + + // Act + const { stdout } = await run(`snyk iac test --sarif ${filePath}`); + + // Asset + expect(stdout).not.toContain(spinnerMessage); + expect(stdout).not.toContain(spinnerSuccessMessage); + }); + + describe('with multiple paths', () => { + it('should return valid output', async () => { + // Arrange + const paths = ['./iac/arm/rule_test.json', './iac/cloudformation']; + + // Act + const { stdout, exitCode } = await run( + `snyk iac test --sarif ${paths.join(' ')}`, + ); + + // Assert + expect(isValidJSONString(stdout)).toBe(true); + + expect(stdout).toContain('"id": "SNYK-CC-TF-20",'); + expect(stdout).toContain('"id": "SNYK-CC-AWS-422",'); + expect(exitCode).toBe(1); + }); + }); + }, + ); +}); diff --git a/test/jest/acceptance/iac/iac-output.spec.ts b/test/jest/acceptance/iac/output-formats/text.spec.ts similarity index 91% rename from test/jest/acceptance/iac/iac-output.spec.ts rename to test/jest/acceptance/iac/output-formats/text.spec.ts index 5903828f13..9f4bc6ff6b 100644 --- a/test/jest/acceptance/iac/iac-output.spec.ts +++ b/test/jest/acceptance/iac/output-formats/text.spec.ts @@ -1,19 +1,16 @@ import chalk from 'chalk'; import { EOL } from 'os'; import * as pathLib from 'path'; -import { - spinnerMessage, - spinnerSuccessMessage, -} from '../../../../src/lib/formatters/iac-output'; +import { spinnerMessage } from '../../../../../src/lib/formatters/iac-output'; -import { FakeServer } from '../../../acceptance/fake-server'; -import { isValidJSONString, startMockServer } from './helpers'; +import { FakeServer } from '../../../../acceptance/fake-server'; +import { startMockServer } from '../helpers'; const IAC_CLI_OUTPUT_FF = 'iacCliOutputRelease'; -jest.setTimeout(1000 * 30); +jest.setTimeout(1_000 * 30); -describe('iac test output', () => { +describe('iac test text output', () => { let server: FakeServer; let run: ( cmd: string, @@ -128,33 +125,6 @@ Target file: ${dirPath}/`); expect(stdout).not.toContain('Test Failures'); }); - describe.each` - dataFormat | dataFormatFlag - ${'JSON'} | ${'--json'} - ${'SARIF'} | ${'--sarif'} - `( - 'when providing the $dataFormatFlag flag for the $dataFormat format', - ({ dataFormatFlag }) => { - it(`should not show spinner messages`, async () => { - const { stdout } = await run( - `snyk iac test ${dataFormatFlag} ./iac/arm/rule_test.json`, - ); - expect(stdout).not.toContain(chalk.reset(spinnerMessage)); - expect(stdout).not.toContain(chalk.reset(spinnerSuccessMessage)); - }); - - it(`should return results with multiple paths`, async () => { - const { stdout, exitCode } = await run( - `snyk iac test ${dataFormatFlag} ./iac/arm/rule_test.json ./iac/cloudformation/`, - ); - expect(isValidJSONString(stdout)).toBe(true); - expect(stdout).toContain('"id": "SNYK-CC-TF-20",'); - expect(stdout).toContain('"id": "SNYK-CC-AWS-422",'); - expect(exitCode).toBe(1); - }); - }, - ); - describe('with multiple test results', () => { describe('with test failures', () => { it('should show the failures list section with the correct values', async () => {