@snyk/code-client
Advanced tools
Comparing version 4.18.7 to 4.19.0
import { GetAnalysisOptions } from './http'; | ||
import { AnalysisResult } from './interfaces/analysis-result.interface'; | ||
import { FileAnalysisOptions } from './interfaces/analysis-options.interface'; | ||
import { AnalysisResult, ScmAnalysis } from './interfaces/analysis-result.interface'; | ||
import { FileAnalysisOptions, ScmAnalysisOptions } from './interfaces/analysis-options.interface'; | ||
import { FileAnalysis } from './interfaces/files.interface'; | ||
export declare function analyzeBundle(options: GetAnalysisOptions): Promise<AnalysisResult>; | ||
/** | ||
* Perform a file-based analysis. | ||
* Optionally with reporting of results to the platform. | ||
*/ | ||
export declare function analyzeFolders(options: FileAnalysisOptions): Promise<FileAnalysis | null>; | ||
@@ -10,1 +14,6 @@ export declare function extendAnalysis(options: FileAnalysis & { | ||
}): Promise<FileAnalysis | null>; | ||
/** | ||
* Perform an SCM-based analysis for an existing project, | ||
* with reporting of results to the platform. | ||
*/ | ||
export declare function analyzeScmProject(options: ScmAnalysisOptions): Promise<ScmAnalysis | null>; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.extendAnalysis = exports.analyzeFolders = exports.analyzeBundle = void 0; | ||
exports.analyzeScmProject = exports.extendAnalysis = exports.analyzeFolders = exports.analyzeBundle = void 0; | ||
/* eslint-disable no-await-in-loop */ | ||
@@ -18,2 +18,13 @@ const lodash_omit_1 = __importDefault(require("lodash.omit")); | ||
const sleep = (duration) => new Promise(resolve => setTimeout(resolve, duration)); | ||
function getConnectionOptions(connectionOptions) { | ||
var _a; | ||
return { | ||
...connectionOptions, | ||
// Ensure requestId is set. | ||
requestId: (_a = connectionOptions.requestId) !== null && _a !== void 0 ? _a : (0, uuid_1.v4)(), | ||
}; | ||
} | ||
function getAnalysisContext(analysisContext) { | ||
return analysisContext ? { analysisContext } : {}; | ||
} | ||
async function pollAnalysis(options) { | ||
@@ -71,9 +82,12 @@ let analysisResponse; | ||
} | ||
/** | ||
* Perform a file-based analysis. | ||
* Optionally with reporting of results to the platform. | ||
*/ | ||
async function analyzeFolders(options) { | ||
var _a, _b; | ||
if (!options.connection.requestId) { | ||
options.connection.requestId = (0, uuid_1.v4)(); | ||
} | ||
const connectionOptions = getConnectionOptions(options.connection); | ||
const analysisContext = getAnalysisContext(options.analysisContext); | ||
const fileBundle = await (0, bundles_1.createBundleFromFolders)({ | ||
...options.connection, | ||
...connectionOptions, | ||
...options.fileOptions, | ||
@@ -86,6 +100,6 @@ languages: options.languages, | ||
bundleHash: fileBundle.bundleHash, | ||
...options.connection, | ||
...connectionOptions, | ||
...options.analysisOptions, | ||
shard: (0, files_1.calcHash)(fileBundle.baseDir), | ||
...(options.analysisContext ? { analysisContext: options.analysisContext } : {}), | ||
...analysisContext, | ||
}; | ||
@@ -248,2 +262,18 @@ let analysisResults; | ||
exports.extendAnalysis = extendAnalysis; | ||
/** | ||
* Perform an SCM-based analysis for an existing project, | ||
* with reporting of results to the platform. | ||
*/ | ||
async function analyzeScmProject(options) { | ||
const connectionOptions = getConnectionOptions(options.connection); | ||
const analysisContext = getAnalysisContext(options.analysisContext); | ||
const { analysisResult: analysisResults, uploadResult: reportResults } = await (0, report_1.reportScm)({ | ||
...connectionOptions, | ||
...options.analysisOptions, | ||
...options.reportOptions, | ||
...analysisContext, | ||
}); | ||
return { analysisResults, reportResults }; | ||
} | ||
exports.analyzeScmProject = analyzeScmProject; | ||
//# sourceMappingURL=analysis.js.map |
@@ -5,3 +5,3 @@ /// <reference types="node" /> | ||
import { AnalysisResult, ReportResult } from './interfaces/analysis-result.interface'; | ||
import { AnalysisOptions, AnalysisContext, ReportOptions } from './interfaces/analysis-options.interface'; | ||
import { AnalysisOptions, AnalysisContext, ReportOptions, ScmReportOptions } from './interfaces/analysis-options.interface'; | ||
type ResultSuccess<T> = { | ||
@@ -40,2 +40,3 @@ type: 'success'; | ||
export declare function startSession(options: StartSessionOptions): StartSessionResponseDto; | ||
export declare function getVerifyCallbackUrl(authHost: string): string; | ||
export type IpFamily = 6 | undefined; | ||
@@ -102,4 +103,6 @@ /** | ||
} | ||
export interface ScmUploadReportOptions extends ConnectionOptions, AnalysisOptions, AnalysisContext, ScmReportOptions { | ||
} | ||
export interface GetReportOptions extends ConnectionOptions { | ||
reportId: string; | ||
pollId: string; | ||
} | ||
@@ -109,6 +112,22 @@ export type InitUploadResponseDto = { | ||
}; | ||
export type InitScmUploadResponseDto = { | ||
testId: string; | ||
}; | ||
export type UploadReportResponseDto = ReportResult | AnalysisFailedResponse | AnalysisResponseProgress; | ||
export declare function initReport(options: UploadReportOptions): Promise<Result<InitUploadResponseDto, ReportErrorCodes>>; | ||
/** | ||
* Trigger a file-based test with reporting. | ||
*/ | ||
export declare function initReport(options: UploadReportOptions): Promise<Result<string, ReportErrorCodes>>; | ||
/** | ||
* Retrieve a file-based test with reporting. | ||
*/ | ||
export declare function getReport(options: GetReportOptions): Promise<Result<UploadReportResponseDto, ReportErrorCodes>>; | ||
export declare function getVerifyCallbackUrl(authHost: string): string; | ||
/** | ||
* Trigger an SCM-based test with reporting. | ||
*/ | ||
export declare function initScmReport(options: ScmUploadReportOptions): Promise<Result<string, ReportErrorCodes>>; | ||
/** | ||
* Fetch an SCM-based test with reporting. | ||
*/ | ||
export declare function getScmReport(options: GetReportOptions): Promise<Result<UploadReportResponseDto, ReportErrorCodes>>; | ||
export {}; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getVerifyCallbackUrl = exports.getReport = exports.initReport = exports.getAnalysis = exports.AnalysisStatus = exports.extendBundle = exports.checkBundle = exports.createBundle = exports.getFilters = exports.checkSession = exports.getIpFamily = exports.startSession = exports.compressAndEncode = void 0; | ||
exports.getScmReport = exports.initScmReport = exports.getReport = exports.initReport = exports.getAnalysis = exports.AnalysisStatus = exports.extendBundle = exports.checkBundle = exports.createBundle = exports.getFilters = exports.checkSession = exports.getIpFamily = exports.getVerifyCallbackUrl = exports.startSession = exports.compressAndEncode = void 0; | ||
const uuid_1 = require("uuid"); | ||
@@ -15,2 +15,3 @@ const lodash_pick_1 = __importDefault(require("lodash.pick")); | ||
// The trick to typecast union type alias | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function isSubsetErrorCode(code, messages) { | ||
@@ -61,2 +62,6 @@ if (code in messages) { | ||
exports.startSession = startSession; | ||
function getVerifyCallbackUrl(authHost) { | ||
return `${authHost}/api/verify/callback`; | ||
} | ||
exports.getVerifyCallbackUrl = getVerifyCallbackUrl; | ||
/** | ||
@@ -250,2 +255,5 @@ * Dispatches a FORCED IPv6 request to test client's ISP and network capability. | ||
}; | ||
/** | ||
* Trigger a file-based test with reporting. | ||
*/ | ||
async function initReport(options) { | ||
@@ -276,6 +284,9 @@ const config = { | ||
if (res.success) | ||
return { type: 'success', value: res.body }; | ||
return { type: 'success', value: res.body.reportId }; | ||
return generateError(res.errorCode, REPORT_ERROR_MESSAGES, 'initReport'); | ||
} | ||
exports.initReport = initReport; | ||
/** | ||
* Retrieve a file-based test with reporting. | ||
*/ | ||
async function getReport(options) { | ||
@@ -287,3 +298,3 @@ var _a; | ||
}, | ||
url: `${options.baseURL}/report/${options.reportId}`, | ||
url: `${options.baseURL}/report/${options.pollId}`, | ||
method: 'get', | ||
@@ -297,6 +308,44 @@ }; | ||
exports.getReport = getReport; | ||
function getVerifyCallbackUrl(authHost) { | ||
return `${authHost}/api/verify/callback`; | ||
/** | ||
* Trigger an SCM-based test with reporting. | ||
*/ | ||
async function initScmReport(options) { | ||
const config = { | ||
headers: { | ||
...commonHttpHeaders(options), | ||
}, | ||
url: `${options.baseURL}/test`, | ||
method: 'post', | ||
body: { | ||
workflowData: { | ||
projectId: options.projectId, | ||
commitHash: options.commitId, | ||
}, | ||
...(0, lodash_pick_1.default)(options, ['severity', 'prioritized', 'analysisContext']), | ||
}, | ||
}; | ||
const res = await (0, needle_1.makeRequest)(config); | ||
if (res.success) | ||
return { type: 'success', value: res.body.testId }; | ||
return generateError(res.errorCode, REPORT_ERROR_MESSAGES, 'initReport'); | ||
} | ||
exports.getVerifyCallbackUrl = getVerifyCallbackUrl; | ||
exports.initScmReport = initScmReport; | ||
/** | ||
* Fetch an SCM-based test with reporting. | ||
*/ | ||
async function getScmReport(options) { | ||
var _a; | ||
const config = { | ||
headers: { | ||
...commonHttpHeaders(options), | ||
}, | ||
url: `${options.baseURL}/test/${options.pollId}`, | ||
method: 'get', | ||
}; | ||
const res = await (0, needle_1.makeRequest)(config); | ||
if (res.success) | ||
return { type: 'success', value: res.body }; | ||
return generateError(res.errorCode, REPORT_ERROR_MESSAGES, 'getReport', (_a = res.error) === null || _a === void 0 ? void 0 : _a.message); | ||
} | ||
exports.getScmReport = getScmReport; | ||
//# sourceMappingURL=http.js.map |
@@ -1,2 +0,2 @@ | ||
import { analyzeFolders, extendAnalysis } from './analysis'; | ||
import { analyzeFolders, extendAnalysis, analyzeScmProject } from './analysis'; | ||
import { getSupportedFiles, createBundleFromFolders, createBundleWithCustomFiles } from './bundles'; | ||
@@ -10,3 +10,3 @@ import { emitter } from './emitter'; | ||
import { AnalysisSeverity, AnalysisContext } from './interfaces/analysis-options.interface'; | ||
import { AnalysisResult, AnalysisResultSarif, AnalysisResultLegacy, FilePath, FileSuggestion, Suggestion, Marker, ReportResult } from './interfaces/analysis-result.interface'; | ||
export { getGlobPatterns, analyzeFolders, getSupportedFiles, createBundleFromFolders, createBundleWithCustomFiles, extendAnalysis, emitter, MAX_FILE_SIZE, constants, AnalysisSeverity, AnalysisResult, AnalysisResultSarif, AnalysisResultLegacy, SupportedFiles, FileAnalysis, FilePath, FileSuggestion, Suggestion, Marker, getAnalysis, startSession, checkSession, getIpFamily, IpFamily, AnalysisContext, ReportResult, }; | ||
import { AnalysisResult, AnalysisResultSarif, AnalysisResultLegacy, FilePath, FileSuggestion, Suggestion, Marker, ReportResult, ScmAnalysis } from './interfaces/analysis-result.interface'; | ||
export { getGlobPatterns, analyzeFolders, analyzeScmProject, getSupportedFiles, createBundleFromFolders, createBundleWithCustomFiles, extendAnalysis, emitter, MAX_FILE_SIZE, constants, AnalysisSeverity, AnalysisResult, AnalysisResultSarif, AnalysisResultLegacy, SupportedFiles, FileAnalysis, FilePath, FileSuggestion, Suggestion, Marker, getAnalysis, startSession, checkSession, getIpFamily, IpFamily, AnalysisContext, ReportResult, ScmAnalysis, }; |
@@ -26,6 +26,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getIpFamily = exports.checkSession = exports.startSession = exports.getAnalysis = exports.AnalysisSeverity = exports.constants = exports.MAX_FILE_SIZE = exports.emitter = exports.extendAnalysis = exports.createBundleWithCustomFiles = exports.createBundleFromFolders = exports.getSupportedFiles = exports.analyzeFolders = exports.getGlobPatterns = void 0; | ||
exports.getIpFamily = exports.checkSession = exports.startSession = exports.getAnalysis = exports.AnalysisSeverity = exports.constants = exports.MAX_FILE_SIZE = exports.emitter = exports.extendAnalysis = exports.createBundleWithCustomFiles = exports.createBundleFromFolders = exports.getSupportedFiles = exports.analyzeScmProject = exports.analyzeFolders = exports.getGlobPatterns = void 0; | ||
const analysis_1 = require("./analysis"); | ||
Object.defineProperty(exports, "analyzeFolders", { enumerable: true, get: function () { return analysis_1.analyzeFolders; } }); | ||
Object.defineProperty(exports, "extendAnalysis", { enumerable: true, get: function () { return analysis_1.extendAnalysis; } }); | ||
Object.defineProperty(exports, "analyzeScmProject", { enumerable: true, get: function () { return analysis_1.analyzeScmProject; } }); | ||
const bundles_1 = require("./bundles"); | ||
@@ -32,0 +33,0 @@ Object.defineProperty(exports, "getSupportedFiles", { enumerable: true, get: function () { return bundles_1.getSupportedFiles; } }); |
@@ -54,2 +54,6 @@ import { SupportedFiles } from '..'; | ||
} | ||
export interface ScmReportOptions { | ||
projectId?: string; | ||
commitId?: string; | ||
} | ||
export interface FileAnalysisOptions extends AnalysisContext { | ||
@@ -62,1 +66,6 @@ connection: ConnectionOptions; | ||
} | ||
export interface ScmAnalysisOptions extends AnalysisContext { | ||
connection: ConnectionOptions; | ||
analysisOptions: AnalysisOptions; | ||
reportOptions: ScmReportOptions; | ||
} |
@@ -85,2 +85,6 @@ import { Log } from 'sarif'; | ||
export type AnalysisResult = AnalysisResultSarif | AnalysisResultLegacy; | ||
export interface ScmAnalysis { | ||
analysisResults: AnalysisResultSarif; | ||
reportResults?: ReportUploadResult; | ||
} | ||
export {}; |
@@ -1,3 +0,4 @@ | ||
import { UploadReportOptions } from './http'; | ||
import { UploadReportOptions, ScmUploadReportOptions } from './http'; | ||
import { ReportResult } from './interfaces/analysis-result.interface'; | ||
export declare function reportBundle(options: UploadReportOptions): Promise<ReportResult>; | ||
export declare function reportScm(options: ScmUploadReportOptions): Promise<ReportResult>; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -6,3 +29,4 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.reportBundle = void 0; | ||
exports.reportScm = exports.reportBundle = void 0; | ||
const uuid = __importStar(require("uuid")); | ||
const lodash_pick_1 = __importDefault(require("lodash.pick")); | ||
@@ -13,15 +37,3 @@ const constants_1 = require("./constants"); | ||
const sleep = (duration) => new Promise(resolve => setTimeout(resolve, duration)); | ||
async function pollReport(options) { | ||
var _a, _b; | ||
const projectName = (_b = (_a = options.report) === null || _a === void 0 ? void 0 : _a.projectName) === null || _b === void 0 ? void 0 : _b.trim(); | ||
const projectNameMaxLength = 64; | ||
if (!projectName || projectName.length === 0) { | ||
throw new Error('"project-name" must be provided for "report"'); | ||
} | ||
if (projectName.length > projectNameMaxLength) { | ||
throw new Error(`"project-name" must not exceed ${projectNameMaxLength} characters`); | ||
} | ||
if (/[^A-Za-z0-9-_/]/g.test(projectName)) { | ||
throw new Error(`"project-name" must not contain spaces or special characters except [/-_]`); | ||
} | ||
async function initAndPollReportGeneric(initReportFunc, getReportFunc, options) { | ||
emitter_1.emitter.analyseProgress({ | ||
@@ -32,7 +44,7 @@ status: http_1.AnalysisStatus.waiting, | ||
// First init the report | ||
const initResponse = await (0, http_1.initReport)(options); | ||
const initResponse = await initReportFunc(options); | ||
if (initResponse.type === 'error') { | ||
return initResponse; | ||
} | ||
const { reportId } = initResponse.value; | ||
const pollId = initResponse.value; | ||
let apiResponse; | ||
@@ -43,5 +55,5 @@ let response; | ||
// eslint-disable-next-line no-await-in-loop | ||
apiResponse = await (0, http_1.getReport)({ | ||
apiResponse = await getReportFunc({ | ||
...(0, lodash_pick_1.default)(options, ['baseURL', 'sessionToken', 'source', 'requestId', 'org']), | ||
reportId, | ||
pollId, | ||
}); | ||
@@ -73,4 +85,16 @@ if (apiResponse.type === 'error') { | ||
async function reportBundle(options) { | ||
// Call remote bundle for analysis results and emit intermediate progress | ||
const response = await pollReport(options); | ||
var _a, _b; | ||
const projectName = (_b = (_a = options.report) === null || _a === void 0 ? void 0 : _a.projectName) === null || _b === void 0 ? void 0 : _b.trim(); | ||
const projectNameMaxLength = 64; | ||
if (!projectName || projectName.length === 0) { | ||
throw new Error('"project-name" must be provided for "report"'); | ||
} | ||
if (projectName.length > projectNameMaxLength) { | ||
throw new Error(`"project-name" must not exceed ${projectNameMaxLength} characters`); | ||
} | ||
if (/[^A-Za-z0-9-_/]/g.test(projectName)) { | ||
throw new Error(`"project-name" must not contain spaces or special characters except [/-_]`); | ||
} | ||
// Trigger bundle analysis and emit intermediate progress. | ||
const response = await initAndPollReportGeneric(http_1.initReport, http_1.getReport, options); | ||
if (response.type === 'error') { | ||
@@ -85,2 +109,26 @@ throw response.error; | ||
exports.reportBundle = reportBundle; | ||
async function reportScm(options) { | ||
var _a, _b; | ||
const projectId = (_a = options.projectId) === null || _a === void 0 ? void 0 : _a.trim(); | ||
if (!projectId || projectId.length === 0) { | ||
throw new Error('"project-id" must be provided for "report"'); | ||
} | ||
if (!uuid.validate(projectId)) { | ||
throw new Error('"project-id" must be a valid UUID'); | ||
} | ||
const commitId = (_b = options.commitId) === null || _b === void 0 ? void 0 : _b.trim(); | ||
if (!commitId || commitId.length === 0) { | ||
throw new Error('"commit-id" must be provided for "report"'); | ||
} | ||
// Trigger SCM project analysis and emit intermediate progress. | ||
const response = await initAndPollReportGeneric(http_1.initScmReport, http_1.getScmReport, options); | ||
if (response.type === 'error') { | ||
throw response.error; | ||
} | ||
else if (response.value.status === http_1.AnalysisStatus.failed) { | ||
throw new Error('Analysis has failed'); | ||
} | ||
return response.value; | ||
} | ||
exports.reportScm = reportScm; | ||
//# sourceMappingURL=report.js.map |
@@ -67,2 +67,3 @@ { | ||
"jsonschema": "^1.2.11", | ||
"nock": "^13.3.2", | ||
"npm-run-all": "^4.1.5", | ||
@@ -94,3 +95,3 @@ "prettier": "^2.1.1", | ||
}, | ||
"version": "4.18.7" | ||
"version": "4.19.0" | ||
} |
@@ -119,2 +119,21 @@ # code-client | ||
### Run analysis and report results to platform | ||
```javascript | ||
const results = await codeClient.analyzeFolders({ | ||
connection: { baseURL, sessionToken, source }, | ||
analysisOptions: { | ||
severity: 1, | ||
}, | ||
fileOptions: { | ||
paths: ['/home/user/repo'], | ||
symlinksEnabled: false, | ||
}, | ||
reportOptions: { | ||
enabled: true, | ||
projectName: 'example-project', | ||
}, | ||
}); | ||
``` | ||
### Creates a new bundle based on a previously uploaded one | ||
@@ -133,2 +152,17 @@ | ||
### Run analysis on an existing SCM project and report results to platform | ||
```javascript | ||
const results = await codeClient.analyzeScmProject({ | ||
connection: { baseURL, sessionToken, source }, | ||
analysisOptions: { | ||
severity: 1, | ||
}, | ||
reportOptions: { | ||
projectId: '<Snyk Project UUID>', | ||
commitId: '<Commit SHA to scan>', | ||
}, | ||
}); | ||
``` | ||
### Errors | ||
@@ -135,0 +169,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
173652
2453
205
21