Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: consolidate json streaming #5293

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions src/cli/commands/test/iac/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,23 +101,21 @@ export function buildOutput({
const mappedResults = results.map(mapIacTestResult);

const {
stdout: dataToSend,
stringifiedData,
stringifiedJsonData,
stringifiedSarifData,
dataToSend,
jsonData,
sarifData,
} = extractDataToSendFromResults(results, mappedResults, options);

if (options.json || options.sarif) {
// if all results are ok (.ok == true)
if (mappedResults.every((res) => res.ok)) {
return TestCommandResult.createJsonTestCommandResult(
stringifiedData,
stringifiedJsonData,
stringifiedSarifData,
jsonData,
sarifData,
);
}

const err = new Error(stringifiedData) as any;
const err = new Error() as any;

if (foundVulnerabilities) {
err.code = 'VULNS';
Expand All @@ -134,9 +132,8 @@ export function buildOutput({
// the first error.
err.code = errorResults[0].code;
}
err.json = stringifiedData;
err.jsonStringifiedResults = stringifiedJsonData;
err.sarifStringifiedResults = stringifiedSarifData;
err.jsonData = jsonData;
err.sarifData = sarifData;
throw err;
}

Expand Down Expand Up @@ -228,15 +225,15 @@ export function buildOutput({
// first one
error.code = vulnerableResults[0].code || 'VULNS';
error.userMessage = vulnerableResults[0].userMessage;
error.jsonStringifiedResults = stringifiedJsonData;
error.sarifStringifiedResults = stringifiedSarifData;
error.jsonData = jsonData;
error.sarifData = sarifData;
throw error;
}

return TestCommandResult.createHumanReadableTestCommandResult(
response,
stringifiedJsonData,
stringifiedSarifData,
jsonData,
sarifData,
);
}

Expand Down
48 changes: 13 additions & 35 deletions src/cli/commands/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,37 +202,28 @@ export default async function test(
const mappedResults = createErrorMappedResultsForJsonOutput(results);

const {
stdout: dataToSend,
stringifiedData,
stringifiedJsonData,
stringifiedSarifData,
dataToSend,
jsonData,
sarifData,
} = extractDataToSendFromResults(results, mappedResults, options);

const jsonPayload = stringifiedJsonData.length === 0 ? dataToSend : null;

if (options.json || options.sarif) {
// if all results are ok (.ok == true)
if (mappedResults.every((res) => res.ok)) {
return TestCommandResult.createJsonTestCommandResult(
stringifiedData,
stringifiedJsonData,
stringifiedSarifData,
jsonPayload,
jsonData, sarifData,
);
}

const err = new Error(stringifiedData) as any;
const err = new Error() as any;

if (foundVulnerabilities) {
if (options.failOn) {
const fail = shouldFail(vulnerableResults, options.failOn);
if (!fail) {
// return here to prevent failure
return TestCommandResult.createJsonTestCommandResult(
stringifiedData,
stringifiedJsonData,
stringifiedSarifData,
jsonPayload,
jsonData, sarifData,
);
}
}
Expand All @@ -249,13 +240,8 @@ export default async function test(
// the first error.
err.code = errorResults[0].code;
}
err.json = stringifiedData;
err.jsonStringifiedResults = stringifiedJsonData;
err.sarifStringifiedResults = stringifiedSarifData;
// set jsonPayload if we failed to stringify it
if (jsonPayload) {
err.jsonPayload = jsonPayload;
}
err.jsonData = jsonData;
err.sarifData = sarifData;
throw err;
}

Expand Down Expand Up @@ -315,10 +301,7 @@ export default async function test(
);

return TestCommandResult.createHumanReadableTestCommandResult(
response,
stringifiedJsonData,
stringifiedSarifData,
jsonPayload,
response, jsonData, sarifData,
);
}
}
Expand All @@ -339,12 +322,8 @@ export default async function test(
// first one
error.code = vulnerableResults[0].code || 'VULNS';
error.userMessage = vulnerableResults[0].userMessage;
error.jsonStringifiedResults = stringifiedJsonData;
error.sarifStringifiedResults = stringifiedSarifData;
// conditionally set jsonPayload for now, to determine whether to stream data to destination
if (stringifiedJsonData.length === 0) {
error.jsonPayload = dataToSend;
}
error.jsonData
error.sarifData
throw error;
}

Expand All @@ -356,9 +335,8 @@ export default async function test(

return TestCommandResult.createHumanReadableTestCommandResult(
response,
stringifiedJsonData,
stringifiedSarifData,
jsonPayload,
jsonData,
sarifData,
);
}

Expand Down
96 changes: 24 additions & 72 deletions src/cli/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,113 +15,65 @@ export class CommandResult {
}
}

export abstract class TestCommandResult extends CommandResult {
protected jsonResult = '';
protected sarifResult = '';
protected jsonData = {};
export type JsonDocument = Record<string, undefined> | Array<JsonDocument>;

public getJsonResult(): string {
return this.jsonResult;
}
export abstract class TestCommandResult extends CommandResult {
protected jsonData?: JsonDocument;
protected sarifData?: JsonDocument;

public getSarifResult(): string {
return this.sarifResult;
public getJsonData(): JsonDocument | undefined {
return this.jsonData;
}

public getJsonData(): Record<string, unknown> {
return this.jsonData;
public getSarifData(): JsonDocument | undefined {
return this.sarifData;
}

public static createHumanReadableTestCommandResult(
humanReadableResult: string,
jsonResult: string,
sarifResult?: string,
jsonData?: Record<string, unknown>,
jsonData?: JsonDocument,
sarifData?: JsonDocument,
): HumanReadableTestCommandResult {
return new HumanReadableTestCommandResult(
humanReadableResult,
jsonResult,
sarifResult,
jsonData,
sarifData,
);
}

public static createJsonTestCommandResult(
stdout: string,
jsonResult?: string,
sarifResult?: string,
jsonPayload?: Record<string, unknown>,
jsonData?: JsonDocument,
sarifData?: JsonDocument,
): JsonTestCommandResult {
return new JsonTestCommandResult(
stdout,
jsonResult,
sarifResult,
jsonPayload,
'',
jsonData,
sarifData,
);
}
}

class HumanReadableTestCommandResult extends TestCommandResult {
protected jsonResult = '';
protected sarifResult = '';
protected jsonData = {};

constructor(
humanReadableResult: string,
jsonResult: string,
sarifResult?: string,
jsonData?: Record<string, unknown>,
jsonData?: JsonDocument,
sarifData?: JsonDocument,
) {
super(humanReadableResult);
this.jsonResult = jsonResult;
if (sarifResult) {
this.sarifResult = sarifResult;
}
if (jsonData) {
this.jsonData = jsonData;
}
}

public getJsonResult(): string {
return this.jsonResult;
}

public getSarifResult(): string {
return this.sarifResult;
}

public getJsonData(): Record<string, unknown> {
return this.jsonData;
this.jsonData = jsonData;
this.sarifData = sarifData;
}
}

class JsonTestCommandResult extends TestCommandResult {
constructor(
stdout: string,
jsonResult?: string,
sarifResult?: string,
jsonData?: Record<string, unknown>,
jsonData?: JsonDocument,
sarifData?: JsonDocument,
) {
super(stdout);
if (jsonResult) {
this.jsonResult = jsonResult;
}
if (sarifResult) {
this.sarifResult = sarifResult;
} else {
this.jsonResult = stdout;
}
if (jsonData) {
this.jsonData = jsonData;
}
}

public getJsonResult(): string {
return this.jsonResult;
}

public getSarifResult(): string {
return this.sarifResult;
this.jsonData = jsonData;
this.sarifData = sarifData;
}
}

Expand Down
Loading
Loading