diff --git a/package-lock.json b/package-lock.json index 3286845..9228931 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,15 @@ "version": "0.2.3", "license": "MIT", "dependencies": { - "@clack/prompts": "^0.7.0" + "@clack/prompts": "^0.7.0", + "ws": "^8.21.1" }, "bin": { "polylane": "dist/polylane.mjs" }, "devDependencies": { "@types/node": "^22.0.0", + "@types/ws": "^8.18.1", "esbuild": "^0.25.0", "eslint": "^9.0.0", "tsx": "^4.23.1", @@ -724,6 +726,16 @@ "undici-types": "~6.21.0" } }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.58.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.1.tgz", @@ -2543,6 +2555,27 @@ "node": ">=0.10.0" } }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 888a4aa..4ff3472 100644 --- a/package.json +++ b/package.json @@ -43,10 +43,12 @@ "test:watch": "node --test --watch --import tsx test/*.test.ts" }, "dependencies": { - "@clack/prompts": "^0.7.0" + "@clack/prompts": "^0.7.0", + "ws": "^8.21.1" }, "devDependencies": { "@types/node": "^22.0.0", + "@types/ws": "^8.18.1", "esbuild": "^0.25.0", "eslint": "^9.0.0", "tsx": "^4.23.1", diff --git a/test/scan.test.ts b/test/scan.test.ts index 363fbf9..78c0d56 100644 --- a/test/scan.test.ts +++ b/test/scan.test.ts @@ -1,6 +1,20 @@ -import { describe, it } from 'node:test'; +import { describe, it, after } from 'node:test'; import assert from 'node:assert/strict'; -import { +import { mkdtempSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import type { ScanTarget } from '../src/commands/scan'; +import type { ScanReport, ScanReportRisk } from '../src/client/scan-reports'; + +// Point HOME at a temp dir before importing any source module, so credential +// resolution never reads the developer's real ~/.polylane/credentials.json +// (an expiring stored token would trigger a refresh fetch inside mocked-fetch +// tests). Same pattern as signup.test.ts. +const tempHome = mkdtempSync(join(tmpdir(), 'polylane-scan-test-')); +process.env.HOME = tempHome; +after(() => rmSync(tempHome, { recursive: true, force: true })); + +const { buildRiskNavigatorOptions, issueConsoleUrl, rankRisks, @@ -10,11 +24,9 @@ import { scanProgressLabel, scansIndexUrl, seedInvestigations, - type ScanTarget, -} from '../src/commands/scan'; -import { investigateScanRisks } from '../src/client/scan-reports'; -import type { ScanReport, ScanReportRisk } from '../src/client/scan-reports'; -import { mockConfig } from './helpers/config'; +} = await import('../src/commands/scan'); +const { investigateScanRisks } = await import('../src/client/scan-reports'); +const { mockConfig } = await import('./helpers/config'); function risk(severity: ScanReportRisk['severity'], title: string): ScanReportRisk { return { title, detail: '', severity, resourceIds: [], resourceTypes: [] };