diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 402e66c..720bd76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,9 @@ on: branches: [main] pull_request: +permissions: + contents: read + jobs: test: runs-on: ubuntu-latest diff --git a/package-lock.json b/package-lock.json index 803ce9e..7c9e381 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@capitoltrace/congress-api", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@capitoltrace/congress-api", - "version": "0.1.0", + "version": "0.2.0", "license": "MIT", "devDependencies": { "tsup": "^8.0.0", @@ -1353,9 +1353,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", - "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "dev": true, "funding": [ { @@ -1441,9 +1441,9 @@ } }, "node_modules/postcss": { - "version": "8.5.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", - "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", "dev": true, "funding": [ { @@ -1461,7 +1461,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, diff --git a/src/client.ts b/src/client.ts index 1467f27..ebe73f6 100644 --- a/src/client.ts +++ b/src/client.ts @@ -51,7 +51,12 @@ export class CongressClient { ); } this.apiKey = options.apiKey; - this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, ''); + // Linear-time trailing-slash strip; /\/+$/ backtracks polynomially (CodeQL js/polynomial-redos). + let baseUrl = options.baseUrl ?? DEFAULT_BASE_URL; + while (baseUrl.endsWith('/')) { + baseUrl = baseUrl.slice(0, -1); + } + this.baseUrl = baseUrl; this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis); this.maxRetries = options.maxRetries ?? 3; this.timeoutMs = options.timeoutMs ?? 30_000;