- Project Overview
- Technical Context
- Project Structure
- Build And Test Commands
- Contribution Instructions
- Code Guidelines
@adguard/filters-downloader is a utility library that downloads filter
list source files by resolving preprocessor directives. It handles conditional
compilation (!#if/!#else/!#endif), file inclusion (!#include), checksum
validation (MD5), and differential (patch-based) filter updates. The library
ships dual builds for Node.js (CJS) and Browser (ESM) environments using a
platform-agnostic core with injected platform-specific file download wrappers.
| Field | Value |
|---|---|
| Language / Version | TypeScript 5.3, targeting ESNext |
| Runtime | Node.js 22.21+ (22.x) or 24+, modern browsers |
| Package Manager | pnpm ≥ 10.33.4, < 11 |
| Bundler | Rollup 4 with @rollup/plugin-typescript |
| Primary Dependencies | @adguard/diff-builder (patches), crypto-js |
| Testing | Vitest 4.x + legacy QUnit suite |
| Linting | ESLint 8 (airbnb-typescript + jsdoc plugin) |
| Type Checking | tsc --noEmit (strict mode) |
| Pre-commit Hooks | Husky + lint-staged |
| CI | GitHub Actions (ci, mirror, prepare-release, publish-release) |
| Storage | N/A |
| Project Type | Library (single package, dual CJS/ESM output) |
| Target Platform | Node.js and Browser |
| Performance Goals | N/A |
| Scale / Scope | Used as a dependency by AdGuard products |
├── src/ # Library source code
│ ├── index.ts # Node.js entry point (re-exports from creator)
│ ├── index.browser.ts # Browser entry point (re-exports from creator)
│ ├── filters-downloader-creator.ts # Core logic: directive parsing, includes, conditions
│ ├── checksum.ts # MD5 checksum calculation and validation
│ ├── common/ # Shared utilities
│ ├── helpers/ # Error reporting with context (logger)
│ ├── node/ # Node.js file-download wrapper (fetch + fs)
│ └── browser/ # Browser file-download wrapper (fetch + XHR fallback)
├── test/ # Vitest test suite
│ ├── *.test.ts
│ ├── browser/ # Browser file-download wrapper tests
│ ├── server/ # Express test server for integration tests
│ └── fixtures/ # Test fixture filter files and patches
├── _qunit_tests_/ # Legacy QUnit test suite
├── .github/ # CI/CD workflows (ci, mirror, prepare-release, publish-release)
├── package.json
├── tsconfig.json # TypeScript config (includes all sources)
├── tsconfig.build.json # TypeScript config for production build
├── rollup.config.ts # Dual-target Rollup build (Node CJS + Browser ESM)
├── vitest.config.ts # Vitest config (node env, include/exclude)
└── .eslintrc.js # ESLint config (airbnb-typescript + jsdoc)
| Command | Description |
|---|---|
pnpm install |
Install dependencies |
pnpm build |
Build Node.js (CJS) and Browser (ESM) to dist/ |
pnpm test |
Run QUnit tests + Vitest tests |
pnpm lint |
Run ESLint, TypeScript check, and Markdown lint |
pnpm watch |
Build in watch mode |
pnpm tgz |
Pack tarball for local testing |
To run only Vitest tests:
pnpx vitest runTo run a single Vitest test file:
pnpx vitest run test/checksum.test.tsAfter completing any code change, verify correctness by following these steps:
-
Run the linter, type checker, and markdown linter. Execute
pnpm lint. Fix all errors before proceeding. (Note: pre-existing lint errors in_qunit_tests_/for../distimports are known — do not introduce new ones.) -
Run the full test suite. Execute
pnpm test. All tests must pass. -
Update or add tests. If you changed or added functionality, add or update corresponding tests in
test/. Every new public function or changed behavior must have test coverage. -
Build the project. Execute
pnpm buildand verify it completes without errors. The library ships compiled output — confirm the build succeeds after your changes. -
Follow Code Guidelines. Verify your code adheres to every rule in the Code Guidelines section below.
-
Update the CHANGELOG. If the change is user-facing, add an entry to
CHANGELOG.md. Start the entry with its subject, not with the category verb: under### Fixed, write- The Node.js build ..., not- Fixed the Node.js build ....
- Factory pattern with dependency injection. The core logic lives in
FiltersDownloaderCreator, a factory function that accepts a platform-specificFileDownloadWrapper. Node.js and browser entry points each provide their own wrapper. New platform support follows the same pattern: create a wrapper and a new entry point. - Keep the core platform-agnostic. Do not import Node.js builtins (e.g.,
fs,path) or browser APIs directly infilters-downloader-creator.ts. Platform-specific behavior belongs in the wrapper modules. - Dual build output. Node.js build is CJS (
dist/index.js); browser build is ESM (dist/index.browser.js). Both are configured inrollup.config.ts.
General code style guidelines are available via link: https://github.com/AdguardTeam/CodeGuidelines/blob/master/JavaScript/Javascript.md.
- TypeScript strict mode. The project uses
"strict": true. Do not useany— provide explicit types. - All other style rules (indentation, line length, explicit return types, JSDoc,
Airbnb conventions, unused variables) are enforced by
.eslintrc.js. Runpnpm lintto check.
- Vitest for new tests. Write new tests in the
test/directory using Vitest (describe/it/expectfromvitest). Do not add new QUnit tests. - Integration test server. The Vitest suite starts an Express server
(
test/server/index.ts) to serve fixture files. Use it for tests that require HTTP downloads. - Test fixtures. Place filter files and patches in
test/fixtures/. Organize by scenario in numbered subdirectories.
- Imports do not use file extensions. ESLint enforces
import/extensionswithts: 'never'. - Error messages include context. Use the logger helpers
(
throwError,mergeErrorDetails) to report errors with surrounding filter lines for debuggability. - Validate Markdown after editing. When editing any
.mdfile, runpnpm lint:mdto verify the syntax is correct.