Skip to content

Commit ab5796d

Browse files
authored
[BREAKING] feat: Improved scripting support and TypeScript tests (#297)
1 parent c29ff2f commit ab5796d

35 files changed

+1144
-418
lines changed

.c8rc.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"statements": "80",
2+
"statements": "72",
33
"branches": "84",
4-
"functions": "86",
5-
"lines": "80"
4+
"functions": "76",
5+
"lines": "71"
66
}

.mocharc.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
{
22
"$schema": "https://json.schemastore.org/mocharc",
3+
"require": "ts-node/register",
4+
"extensions": [
5+
"ts"
6+
],
37
"timeout": 40000,
48
"recursive": true,
59
"reporter": "spec",
10+
"spec": [
11+
"test/*.spec.ts"
12+
],
613
"exit": true
714
}

.vscode/launch.json

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,17 @@
66
"request": "launch",
77
"name": "Mocha All",
88
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
9-
"args": ["--timeout", "999999", "--colors", "${workspaceFolder}/test"],
9+
"args": [
10+
"-r",
11+
"ts-node/register",
12+
"--timeout",
13+
"999999",
14+
"--extensions",
15+
"ts",
16+
"--recursive",
17+
"--colors",
18+
"${workspaceFolder}/test/*.spec.ts"
19+
],
1020
"console": "integratedTerminal",
1121
"internalConsoleOptions": "neverOpen"
1222
},
@@ -15,7 +25,17 @@
1525
"request": "launch",
1626
"name": "Mocha Current File",
1727
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
18-
"args": ["--timeout", "999999", "--colors", "${file}"],
28+
"args": [
29+
"-r",
30+
"ts-node/register",
31+
"--timeout",
32+
"999999",
33+
"--extensions",
34+
"ts",
35+
"--recursive",
36+
"--colors",
37+
"${file}"
38+
],
1939
"console": "integratedTerminal",
2040
"internalConsoleOptions": "neverOpen"
2141
}

lib/allowlist.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { GitHubAdvisoryId } from "audit-types";
22
import { isGitHubAdvisoryId } from "./common";
3-
import type { AuditCiPreprocessedConfig } from "./config";
43
import {
54
type NSPContent,
65
type NSPRecord,
@@ -107,7 +106,7 @@ class Allowlist {
107106
}
108107

109108
static mapConfigToAllowlist(
110-
config: Pick<AuditCiPreprocessedConfig, "allowlist">
109+
config: Readonly<{ allowlist: AllowlistRecord[] }>
111110
) {
112111
const { allowlist } = config;
113112
const deduplicatedAllowlist = dedupeAllowlistRecords(allowlist || []);

lib/audit-ci-version.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import type { AuditCiConfig } from "./config";
1+
import type { AuditCiFullConfig } from "./config";
22
// Ignoring importing package.json because that changes the package's build
33
// eslint-disable-next-line @typescript-eslint/no-var-requires
44
const { version } = require("../package.json");
55

66
export const auditCiVersion = version as string;
77

88
export function printAuditCiVersion(
9-
outputFormat?: AuditCiConfig["output-format"]
9+
outputFormat?: AuditCiFullConfig["output-format"]
1010
) {
1111
if (outputFormat === "text") {
1212
console.log(`audit-ci version: ${auditCiVersion}`);

lib/audit-ci.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { printAuditCiVersion } from "./audit-ci-version";
33
import { green, red } from "./colors";
44
import { runYargs } from "./config";
55

6+
/**
7+
* Runs the audit-ci CLI.
8+
*/
69
export async function runAuditCi() {
710
const auditCiConfig = await runYargs();
811

@@ -16,9 +19,9 @@ export async function runAuditCi() {
1619
if (outputFormat === "text") {
1720
console.log(green, `Passed ${packageManager} security audit.`);
1821
}
19-
} catch (error: any) {
22+
} catch (error: unknown) {
2023
if (outputFormat === "text") {
21-
const message = error.message || error;
24+
const message = error instanceof Error ? error.message : error;
2225
console.error(red, message);
2326
console.error(red, "Exiting...");
2427
}

lib/audit.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { yellow } from "./colors";
2-
import type { AuditCiConfig } from "./config";
2+
import { ReportConfig } from "./common";
3+
import type { AuditCiFullConfig } from "./config";
34
import type { Summary } from "./model";
45
import * as npmAuditer from "./npm-auditer";
56
import * as pnpmAuditer from "./pnpm-auditer";
@@ -11,9 +12,11 @@ const PARTIAL_RETRY_ERROR_MSG = {
1112
// `Your configured registry (${opts.registry}) does not support audit requests.`
1213
// `Your configured registry (${opts.registry}) may not support audit requests, or the audit endpoint may be temporarily unavailable.`
1314
// Between them, all three use the phrasing 'not support audit'.
14-
npm: `not support audit`,
15-
yarn: "503 Service Unavailable",
16-
};
15+
npm: [`not support audit`],
16+
yarn: ["503 Service Unavailable"],
17+
// TODO: Identify retry-able error message for pnpm
18+
pnpm: [],
19+
} as const;
1720

1821
function getAuditor(
1922
packageManager: "npm" | "yarn" | "pnpm"
@@ -31,8 +34,8 @@ function getAuditor(
3134
}
3235

3336
async function audit(
34-
config: AuditCiConfig,
35-
reporter?: (summary: Summary, config: AuditCiConfig) => Summary
37+
config: AuditCiFullConfig,
38+
reporter?: (summary: Summary, config: ReportConfig) => Summary
3639
) {
3740
const {
3841
"pass-enoaudit": passENoAudit,
@@ -42,15 +45,17 @@ async function audit(
4245
} = config;
4346
const auditor = getAuditor(packageManager);
4447

45-
async function run(attempt = 0) {
48+
async function run(attempt = 0): Promise<Summary | undefined> {
4649
try {
47-
const result = await auditor.audit(config, reporter);
50+
const result = await auditor.auditWithFullConfig(config, reporter);
4851
return result;
4952
} catch (error: any) {
5053
const message = error.message || error;
5154
const isRetryableMessage =
5255
typeof message === "string" &&
53-
message.includes(PARTIAL_RETRY_ERROR_MSG[packageManager]);
56+
PARTIAL_RETRY_ERROR_MSG[packageManager].some((retryErrorMessage) =>
57+
message.includes(retryErrorMessage)
58+
);
5459
const shouldRetry = attempt < maxRetryCount && isRetryableMessage;
5560
if (shouldRetry) {
5661
if (outputFormat === "text") {

lib/common.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import escapeStringRegexp from "escape-string-regexp";
55
import * as eventStream from "event-stream";
66
import * as JSONStream from "JSONStream";
77
import ReadlineTransform from "readline-transform";
8+
import Allowlist from "./allowlist";
89
import { blue, yellow } from "./colors";
910
import { AuditCiConfig } from "./config";
1011
import { Summary } from "./model";
@@ -21,7 +22,12 @@ export function partition<T>(a: T[], fun: (parameter: T) => boolean) {
2122
return returnValue;
2223
}
2324

24-
export function reportAudit(summary: Summary, config: AuditCiConfig) {
25+
export type ReportConfig = Pick<
26+
AuditCiConfig,
27+
"show-found" | "show-not-found" | "output-format"
28+
> & { allowlist: Allowlist };
29+
30+
export function reportAudit(summary: Summary, config: ReportConfig) {
2531
const {
2632
allowlist,
2733
"show-not-found": showNotFound,
@@ -129,8 +135,8 @@ export function runProgram(
129135
command: string,
130136
arguments_: readonly string[],
131137
options: SpawnOptionsWithoutStdio,
132-
stdoutListener,
133-
stderrListener
138+
stdoutListener: (data: any) => void,
139+
stderrListener: (data: any) => void
134140
) {
135141
const transform = new ReadlineTransform({ skipEmpty: true });
136142
const proc = spawn(command, arguments_, options);

0 commit comments

Comments
 (0)