diff --git a/.github/workflows/node-ci.yml b/.github/workflows/node-ci.yml index 091389d8..c3b41308 100644 --- a/.github/workflows/node-ci.yml +++ b/.github/workflows/node-ci.yml @@ -14,17 +14,21 @@ concurrency: jobs: test: - name: ${{ matrix.os }} / node-${{ matrix.node }} + name: ${{ matrix.os }} / node-${{ matrix.node == '22.13.0' && '22' || matrix.node }} runs-on: ${{ matrix.os }} timeout-minutes: 20 strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - node: ["22"] + node: ["22.13.0"] include: + - os: ubuntu-latest + node: "24.0.0" - os: ubuntu-latest node: "24" + - os: ubuntu-latest + node: "26.0.0" - os: ubuntu-latest node: "26" @@ -56,6 +60,10 @@ jobs: - name: Install dependencies run: pnpm --dir sdk/typescript install --frozen-lockfile + - name: Audit production dependencies + if: matrix.os == 'ubuntu-latest' && matrix.node == '22.13.0' + run: pnpm --dir sdk/typescript run audit:prod + - name: Typecheck run: pnpm --dir sdk/typescript run types diff --git a/.github/workflows/node-release.yml b/.github/workflows/node-release.yml index 4aef8108..0c7ca663 100644 --- a/.github/workflows/node-release.yml +++ b/.github/workflows/node-release.yml @@ -98,6 +98,9 @@ jobs: - name: Install dependencies run: sfw pnpm --dir sdk/typescript install --frozen-lockfile + - name: Audit production dependencies + run: sfw pnpm --dir sdk/typescript run audit:prod + - name: Verify run: | pnpm --dir sdk/typescript run types diff --git a/README.md b/README.md index 517aaa4d..58953319 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ ## Quick start -Requires Node.js 22 or later, Python 3.10 or later, and access to Codex Security. +Requires Node.js 22.13.0 or later in the 22.x release line, Node.js 24.x, or +Node.js 26.x; Python 3.10 or later; and access to Codex Security. ```bash npm install @openai/codex-security diff --git a/sdk/typescript/README.md b/sdk/typescript/README.md index 2582c7bf..d36e5d82 100644 --- a/sdk/typescript/README.md +++ b/sdk/typescript/README.md @@ -15,10 +15,11 @@ npm install @openai/codex-security npx @openai/codex-security --version ``` -The package supports macOS, Linux, and Windows and requires Node.js 22 or -later. Scanning and exporting findings also require Python 3.10 or later. If -you use Python 3.10, install the `tomli` package. Select another interpreter -with `--python`, `pythonPath`, or `PYTHON` when needed. +The package supports macOS, Linux, and Windows and requires Node.js 22.13.0 or +later in the 22.x release line, Node.js 24.x, or Node.js 26.x. Scanning and +exporting findings also require Python 3.10 or later. If you use Python 3.10, +install the `tomli` package. Select another interpreter with `--python`, +`pythonPath`, or `PYTHON` when needed. When a newer version is available, the CLI shows the update command for your installation method. Set `CODEX_SECURITY_NO_UPDATE_NOTICE=1` to hide the diff --git a/sdk/typescript/package.json b/sdk/typescript/package.json index a3760f70..ac9479c7 100644 --- a/sdk/typescript/package.json +++ b/sdk/typescript/package.json @@ -13,7 +13,7 @@ "bugs": "https://github.com/openai/codex-security/issues", "type": "module", "engines": { - "node": ">=22" + "node": "^22.13.0 || ^24.0.0 || ^26.0.0" }, "packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b", "main": "./dist/index.js", @@ -39,13 +39,15 @@ "access": "public" }, "scripts": { + "audit:prod": "pnpm audit --prod --audit-level high", "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"", - "build": "pnpm run clean && tsc -p tsconfig.build.json", + "build": "node --run clean && tsc -p tsconfig.build.json", "check:package": "node scripts/check-package.mjs", "format": "prettier --check --ignore-path .gitignore --ignore-path .prettierignore \"**/*.{cjs,mjs,js,ts,json,md}\"", "generate:models": "node scripts/generate-models.cjs", "generate:models:check": "node scripts/generate-models.cjs --check", "lint": "tsc --noEmit", + "prepack": "node --run build", "test": "bun test --timeout 30000 ./tests-ts", "test:package": "node scripts/smoke-package.mjs", "types": "pnpm run generate:models:check && tsc --noEmit" diff --git a/sdk/typescript/tests-ts/skeleton.test.ts b/sdk/typescript/tests-ts/skeleton.test.ts index cc5df587..c97fe65e 100644 --- a/sdk/typescript/tests-ts/skeleton.test.ts +++ b/sdk/typescript/tests-ts/skeleton.test.ts @@ -28,6 +28,62 @@ function capture(): { } describe("TypeScript package skeleton", () => { + test("advertises the tested Node.js 22, 24, and 26 release lines", async () => { + const packageJson = JSON.parse( + await readFile(new URL("../package.json", import.meta.url), "utf8"), + ); + + const supportedReleases = ["22.13.0", "22.14.0", "24.0.0", "26.0.0"]; + const unsupportedReleases = [ + "22.12.0", + "23.0.0", + "23.4.0", + "23.5.0", + "25.0.0", + "27.0.0", + ]; + + expect( + supportedReleases.filter((version) => + Bun.semver.satisfies(version, packageJson.engines.node), + ), + ).toEqual(supportedReleases); + expect( + unsupportedReleases.filter((version) => + Bun.semver.satisfies(version, packageJson.engines.node), + ), + ).toEqual([]); + }); + + test("pins each Node.js minimum and preserves protected and latest LTS checks", async () => { + const ciWorkflow = await readFile( + new URL("../../../.github/workflows/node-ci.yml", import.meta.url), + "utf8", + ); + + expect(ciWorkflow).toContain( + "${{ matrix.node == '22.13.0' && '22' || matrix.node }}", + ); + expect(ciWorkflow).toContain('node: ["22.13.0"]'); + for (const version of ["24.0.0", "24", "26.0.0", "26"]) { + expect(ciWorkflow).toContain(`node: "${version}"`); + } + }); + + test("builds packages without a preinstalled package manager and provides a production audit", async () => { + const packageJson = JSON.parse( + await readFile(new URL("../package.json", import.meta.url), "utf8"), + ); + + expect(packageJson.scripts.build).toBe( + "node --run clean && tsc -p tsconfig.build.json", + ); + expect(packageJson.scripts.prepack).toBe("node --run build"); + expect(packageJson.scripts["audit:prod"]).toBe( + "pnpm audit --prod --audit-level high", + ); + }); + test("exposes canonical finding and hardening fields with public types", () => { const finding = {} as Finding; const scan = {} as ScanRecord;