{"_id":"@adguard/dnr-converter","_rev":"7-12250b5b2bf0dc5589daf5431494b05f","name":"@adguard/dnr-converter","dist-tags":{"latest":"2.0.0","beta":"2.0.0-beta.0"},"versions":{"1.0.0-alpha.2":{"name":"@adguard/dnr-converter","version":"1.0.0-alpha.2","author":{"name":"Adguard Software Ltd."},"license":"GPL-3.0-only","_id":"@adguard/dnr-converter@1.0.0-alpha.2","maintainers":[{"name":"ameshkov","email":"am@adguard.com"},{"name":"maximtop","email":"maximtop@gmail.com"},{"name":"blakhard","email":"vlad.abdulmianov@gmail.com"}],"homepage":"https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/dnr-converter#readme","bugs":{"url":"https://github.com/AdguardTeam/tsurlfilter/issues"},"bin":{"dnr-converter":"dist/cli.cjs"},"dist":{"shasum":"2a5ed63459a6a0688d7d8c8b96f0cf1274a181e3","tarball":"https://registry.npmjs.org/@adguard/dnr-converter/-/dnr-converter-1.0.0-alpha.2.tgz","fileCount":114,"integrity":"sha512-AZ5ElPhpBZQSrNB4w0QYEjR/79lNzVeUUDZRw9FHigVn/kfMV7ZGpqyH41b5Tc+1lCgxl/tPFCvenhICYblnnQ==","signatures":[{"sig":"MEUCIEovhUOkDn0HjMq4dUka93ir5Y1F1mNPhgIVtkjdajkmAiEAweGUpLuWnV0lbbWuhQMPwhJpA6+UnyKZL93hmlr/En0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3531122},"main":"dist/index.js","type":"module","_from":"file:dnr-converter.tgz","types":"dist/types/src/index.d.ts","module":"dist/index.js","engines":{"node":">=22"},"exports":{".":{"types":"./dist/types/src/index.d.ts","import":"./dist/index.js"},"./cli":{"types":"./dist/types/cli/index.d.ts","default":"./dist/cli.cjs"}},"scripts":{"tgz":"pnpm pack --out dnr-converter.tgz","lint":"pnpm lint:code && pnpm lint:types && pnpm lint:md","test":"vitest run","build":"rimraf dist && rollup -c rollup.config.ts --configPlugin typescript","start":"rollup -c rollup.config.ts --configPlugin typescript -w","lint:md":"markdownlint .","test:ci":"vitest run --no-cache --reporter default --reporter junit --outputFile=./tests-reports/dnr-converter.xml","lint:code":"eslint --cache --ignore-path .gitignore .","postbuild":"tsx tasks/build-txt.ts","precommit":"lint-staged","test:prod":"pnpm lint && pnpm test:smoke && pnpm test -- --no-cache","lint:types":"tsc","test:debug":"vitest run --inspect --no-file-parallelism --watch","test:light":"vitest run --exclude \"**/*benchmark*.test.ts\"","test:smoke":"(cd test/smoke/esm && pnpm test) && (cd test/smoke/exports && pnpm test)","test:watch":"vitest run --watch","docs:examples":"tsx tasks/generate-examples.ts","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"maximtop","email":"maximtop@gmail.com"},"_resolved":"/var/atlassian/application-data/bamboo/shared/build-dir/268926980/256475147-256606231/dnr-converter.tgz","_integrity":"sha512-AZ5ElPhpBZQSrNB4w0QYEjR/79lNzVeUUDZRw9FHigVn/kfMV7ZGpqyH41b5Tc+1lCgxl/tPFCvenhICYblnnQ==","repository":{"url":"git+https://github.com/AdguardTeam/tsurlfilter.git","type":"git","directory":"packages/dnr-converter"},"_npmVersion":"10.9.7","description":"A converter that transforms adblock-style filtering rules into rules compatible with the Declarative Net Request (DNR) API.","directories":{},"lint-staged":{"{src,cli,test,tasks}/**/*.ts":["eslint"]},"sideEffects":false,"_nodeVersion":"22.22.2","dependencies":{"valibot":"^1.1.0","punycode":"2.3.1","commander":"^12.1.0","@adguard/agtree":"^4.1.1","@adguard/logger":"^2.0.0","@adguard/scriptlets":"2.4.2"},"typesVersions":{"*":{"*":["dist/types/src/index.d.ts"],"cli":["dist/types/cli/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"tsd":"^0.32.0","tsx":"^4.19.3","eslint":"8.57.1","rimraf":"^6.0.1","rollup":"^4.28.0","vitest":"^4.1.5","typescript":"^5.7.3","@types/node":"^22.14.0","lint-staged":"^13.2.2","markdownlint":"^0.37.4","@types/chrome":"^0.0.305","@types/punycode":"2.1.4","eslint-plugin-n":"^17.21.3","markdownlint-cli":"^0.44.0","rollup-plugin-dts":"^6.0.2","@rollup/plugin-swc":"^0.4.0","rollup-plugin-copy":"^3.5.0","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^4.1.5","eslint-plugin-jsdoc":"^48.11.0","@adguard/tsurlfilter":"^6.0.0","eslint-plugin-import":"^2.29.0","@rollup/plugin-commonjs":"^28.0.1","eslint-plugin-boundaries":"^5.0.1","@rollup/plugin-typescript":"^12.1.1","@typescript-eslint/parser":"^7.5.0","eslint-config-airbnb-base":"15.0.0","@rollup/plugin-node-resolve":"^15.3.0","rollup-plugin-node-externals":"^8.0.0","eslint-plugin-import-newlines":"1.4.0","eslint-config-airbnb-typescript":"^18.0.0","@typescript-eslint/eslint-plugin":"^7.5.0","@adguard/eslint-plugin-logger-context":"^1.0.1"},"peerDependencies":{"@adguard/re2-wasm":"1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/dnr-converter_1.0.0-alpha.2_1784055572500_0.28834468005573766","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@adguard/dnr-converter","version":"1.1.0","author":{"name":"Adguard Software Ltd."},"license":"GPL-3.0-only","_id":"@adguard/dnr-converter@1.1.0","maintainers":[{"name":"ameshkov","email":"am@adguard.com"},{"name":"maximtop","email":"maximtop@gmail.com"},{"name":"blakhard","email":"vlad.abdulmianov@gmail.com"}],"homepage":"https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/dnr-converter#readme","bugs":{"url":"https://github.com/AdguardTeam/tsurlfilter/issues"},"bin":{"dnr-converter":"dist/cli.cjs"},"dist":{"shasum":"8030ed9f2aebd0b4d60cc048503a41229921138d","tarball":"https://registry.npmjs.org/@adguard/dnr-converter/-/dnr-converter-1.1.0.tgz","fileCount":115,"integrity":"sha512-aGfLzcEv9NmJ6Gq+iasyExiREtU6ZVZg7fsnZz6CSICQjS4803AuAop4xn6uzY9nPir0cD3w/+EuRWb4T4Thkg==","signatures":[{"sig":"MEQCIQCfFU+oHuLCoQltZFSOKhjNRIItFagDTSwBUrBjAVrMpAIfPCM4MV7iQCrnOVaSbhbi+nCZt8q912zaRXFXNtmi4A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3549605},"main":"dist/index.js","type":"module","_from":"file:dnr-converter.tgz","types":"dist/types/src/index.d.ts","module":"dist/index.js","engines":{"node":">=22"},"exports":{".":{"types":"./dist/types/src/index.d.ts","import":"./dist/index.js"},"./cli":{"types":"./dist/types/cli/index.d.ts","default":"./dist/cli.cjs"}},"scripts":{"tgz":"pnpm pack --out dnr-converter.tgz","lint":"pnpm lint:code && pnpm lint:types && pnpm lint:md","test":"vitest run","build":"rimraf dist && rollup -c rollup.config.ts --configPlugin typescript","start":"rollup -c rollup.config.ts --configPlugin typescript -w","lint:md":"markdownlint .","test:ci":"vitest run --no-cache --reporter default --reporter junit --outputFile=./tests-reports/dnr-converter.xml","lint:code":"eslint --cache --ignore-path .gitignore .","postbuild":"tsx tasks/build-txt.ts","precommit":"lint-staged","test:prod":"pnpm lint && pnpm test:smoke && pnpm test -- --no-cache","lint:types":"tsc","test:debug":"vitest run --inspect --no-file-parallelism --watch","test:light":"vitest run --exclude \"**/*benchmark*.test.ts\"","test:smoke":"(cd test/smoke/esm && pnpm test) && (cd test/smoke/exports && pnpm test)","test:watch":"vitest run --watch","docs:examples":"tsx tasks/generate-examples.ts","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"maximtop","email":"maximtop@gmail.com"},"_resolved":"/var/atlassian/application-data/bamboo/shared/build-dir/268926977/256475147-256606231/dnr-converter.tgz","_integrity":"sha512-aGfLzcEv9NmJ6Gq+iasyExiREtU6ZVZg7fsnZz6CSICQjS4803AuAop4xn6uzY9nPir0cD3w/+EuRWb4T4Thkg==","repository":{"url":"git+https://github.com/AdguardTeam/tsurlfilter.git","type":"git","directory":"packages/dnr-converter"},"_npmVersion":"10.9.7","description":"A converter that transforms adblock-style filtering rules into rules compatible with the Declarative Net Request (DNR) API.","directories":{},"lint-staged":{"{src,cli,test,tasks}/**/*.ts":["eslint"]},"sideEffects":false,"_nodeVersion":"22.22.2","dependencies":{"valibot":"^1.1.0","punycode":"2.3.1","commander":"^12.1.0","@adguard/agtree":"^4.2.0","@adguard/logger":"^2.0.0","@adguard/scriptlets":"2.5.0"},"typesVersions":{"*":{"*":["dist/types/src/index.d.ts"],"cli":["dist/types/cli/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"tsd":"^0.32.0","tsx":"^4.19.3","eslint":"8.57.1","rimraf":"^6.0.1","rollup":"^4.28.0","vitest":"^4.1.5","typescript":"^5.7.3","@types/node":"^22.14.0","lint-staged":"^13.2.2","markdownlint":"^0.37.4","@types/chrome":"^0.0.305","@types/punycode":"2.1.4","eslint-plugin-n":"^17.21.3","markdownlint-cli":"^0.44.0","rollup-plugin-dts":"^6.0.2","@rollup/plugin-swc":"^0.4.0","rollup-plugin-copy":"^3.5.0","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^4.1.5","eslint-plugin-jsdoc":"^48.11.0","@adguard/tsurlfilter":"^6.0.2","eslint-plugin-import":"^2.29.0","@rollup/plugin-commonjs":"^28.0.1","eslint-plugin-boundaries":"^5.0.1","@rollup/plugin-typescript":"^12.1.1","@typescript-eslint/parser":"^7.5.0","eslint-config-airbnb-base":"15.0.0","@rollup/plugin-node-resolve":"^15.3.0","rollup-plugin-node-externals":"^8.0.0","eslint-plugin-import-newlines":"1.4.0","eslint-config-airbnb-typescript":"^18.0.0","@typescript-eslint/eslint-plugin":"^7.5.0","@adguard/eslint-plugin-logger-context":"^1.0.1"},"peerDependencies":{"@adguard/re2-wasm":"1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/dnr-converter_1.1.0_1785310824230_0.6593101932469312","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@adguard/dnr-converter","version":"1.1.1","author":{"name":"Adguard Software Ltd."},"license":"GPL-3.0-only","_id":"@adguard/dnr-converter@1.1.1","maintainers":[{"name":"ameshkov","email":"am@adguard.com"},{"name":"maximtop","email":"maximtop@gmail.com"},{"name":"blakhard","email":"vlad.abdulmianov@gmail.com"},{"name":"d13410n3","email":"d.naumov@adguard.com"}],"homepage":"https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/dnr-converter#readme","bugs":{"url":"https://github.com/AdguardTeam/tsurlfilter/issues"},"bin":{"dnr-converter":"dist/cli.cjs"},"dist":{"shasum":"27ad080804f288137aef01bee1e1286b6687a816","tarball":"https://registry.npmjs.org/@adguard/dnr-converter/-/dnr-converter-1.1.1.tgz","fileCount":115,"integrity":"sha512-9287mJD/CkLNw25xkAVAuWObV1bN4+qJWa0wD6i33rRlttT4hkt4QM6Riqe3SPVYofrsLJBq0YUblGGU4WJ7ww==","signatures":[{"sig":"MEUCIQDvf5MH7KoCmSh2iOlPnWPVMAlS42pMBbuI9eoaUiQCEAIgKz+yEs3M9ORsBWVj5AlOp8wP4u4atnnRSYHEhcJsWgA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3563661},"main":"dist/index.js","type":"module","_from":"file:dnr-converter.tgz","types":"dist/types/src/index.d.ts","module":"dist/index.js","engines":{"node":">=22"},"exports":{".":{"types":"./dist/types/src/index.d.ts","import":"./dist/index.js"},"./cli":{"types":"./dist/types/cli/index.d.ts","default":"./dist/cli.cjs"}},"scripts":{"tgz":"pnpm pack --out dnr-converter.tgz","lint":"pnpm lint:code && pnpm lint:types && pnpm lint:md","test":"vitest run","build":"rimraf dist && rollup -c rollup.config.ts --configPlugin typescript","start":"rollup -c rollup.config.ts --configPlugin typescript -w","lint:md":"markdownlint .","test:ci":"vitest run --no-cache --reporter default --reporter junit --outputFile=./tests-reports/dnr-converter.xml","lint:code":"eslint --cache --ignore-path .gitignore .","postbuild":"tsx tasks/build-txt.ts","precommit":"lint-staged","test:prod":"pnpm lint && pnpm test:smoke && pnpm test -- --no-cache","lint:types":"tsc","test:debug":"vitest run --inspect --no-file-parallelism --watch","test:light":"vitest run --exclude \"**/*benchmark*.test.ts\"","test:smoke":"(cd test/smoke/esm && pnpm test) && (cd test/smoke/exports && pnpm test)","test:watch":"vitest run --watch","docs:examples":"tsx tasks/generate-examples.ts","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"maximtop","email":"maximtop@gmail.com"},"_resolved":"/var/atlassian/application-data/bamboo/shared/build-dir/296714528/256475147-256606231/dnr-converter.tgz","_integrity":"sha512-9287mJD/CkLNw25xkAVAuWObV1bN4+qJWa0wD6i33rRlttT4hkt4QM6Riqe3SPVYofrsLJBq0YUblGGU4WJ7ww==","repository":{"url":"git+https://github.com/AdguardTeam/tsurlfilter.git","type":"git","directory":"packages/dnr-converter"},"_npmVersion":"10.9.7","description":"A converter that transforms adblock-style filtering rules into rules compatible with the Declarative Net Request (DNR) API.","directories":{},"lint-staged":{"{src,cli,test,tasks}/**/*.ts":["eslint"]},"sideEffects":false,"_nodeVersion":"22.22.2","dependencies":{"valibot":"^1.1.0","punycode":"2.3.1","commander":"^12.1.0","@adguard/agtree":"^4.2.1","@adguard/logger":"^2.0.0","@adguard/scriptlets":"2.5.0"},"typesVersions":{"*":{"*":["dist/types/src/index.d.ts"],"cli":["dist/types/cli/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"tsd":"^0.32.0","tsx":"^4.19.3","eslint":"8.57.1","rimraf":"^6.0.1","rollup":"^4.28.0","vitest":"^4.1.5","typescript":"^5.7.3","@types/node":"^22.14.0","lint-staged":"^13.2.2","markdownlint":"^0.37.4","@types/chrome":"^0.0.305","@types/punycode":"2.1.4","eslint-plugin-n":"^17.21.3","markdownlint-cli":"^0.44.0","rollup-plugin-dts":"^6.0.2","@rollup/plugin-swc":"^0.4.0","rollup-plugin-copy":"^3.5.0","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^4.1.5","eslint-plugin-jsdoc":"^48.11.0","@adguard/tsurlfilter":"^6.0.2","eslint-plugin-import":"^2.29.0","@rollup/plugin-commonjs":"^28.0.1","eslint-plugin-boundaries":"^5.0.1","@rollup/plugin-typescript":"^12.1.1","@typescript-eslint/parser":"^7.5.0","eslint-config-airbnb-base":"15.0.0","@rollup/plugin-node-resolve":"^15.3.0","rollup-plugin-node-externals":"^8.0.0","eslint-plugin-import-newlines":"1.4.0","eslint-config-airbnb-typescript":"^18.0.0","@typescript-eslint/eslint-plugin":"^7.5.0","@adguard/eslint-plugin-logger-context":"^1.0.1"},"peerDependencies":{"@adguard/re2-wasm":"1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/dnr-converter_1.1.1_1787581143875_0.14191331169049493","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@adguard/dnr-converter","version":"1.1.2","author":{"name":"Adguard Software Ltd."},"license":"GPL-3.0-only","_id":"@adguard/dnr-converter@1.1.2","maintainers":[{"name":"ameshkov","email":"am@adguard.com"},{"name":"maximtop","email":"maximtop@gmail.com"},{"name":"blakhard","email":"vlad.abdulmianov@gmail.com"},{"name":"d13410n3","email":"d.naumov@adguard.com"}],"homepage":"https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/dnr-converter#readme","bugs":{"url":"https://github.com/AdguardTeam/tsurlfilter/issues"},"bin":{"dnr-converter":"dist/cli.cjs"},"dist":{"shasum":"e648f6c97ff37428801df317bf1450abe8b52b36","tarball":"https://registry.npmjs.org/@adguard/dnr-converter/-/dnr-converter-1.1.2.tgz","fileCount":115,"integrity":"sha512-YYjKN5Oa87XGybUd1ByLf+b1AjV/TrNEDBtDDyeDdE5nCZ84Rt2BGW9qzKQRShk5YsLTD4NQkaW3GiKZr1vq6w==","signatures":[{"sig":"MEYCIQDmzlalhjaBtCS2H1fmCeatTtVoNx3zxr5cQ9nlAYmdeQIhAN3V0KDuwxCQ53swvZJH6uBEDZEPB80nhx9eqISqZKDs","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3563661},"main":"dist/index.js","type":"module","_from":"file:dnr-converter.tgz","types":"dist/types/src/index.d.ts","module":"dist/index.js","engines":{"node":">=22"},"exports":{".":{"types":"./dist/types/src/index.d.ts","import":"./dist/index.js"},"./cli":{"types":"./dist/types/cli/index.d.ts","default":"./dist/cli.cjs"}},"scripts":{"tgz":"pnpm pack --out dnr-converter.tgz","lint":"pnpm lint:code && pnpm lint:types && pnpm lint:md","test":"vitest run","build":"rimraf dist && rollup -c rollup.config.ts --configPlugin typescript","start":"rollup -c rollup.config.ts --configPlugin typescript -w","lint:md":"markdownlint .","test:ci":"vitest run --no-cache --reporter default --reporter junit --outputFile=./tests-reports/dnr-converter.xml","lint:code":"eslint --cache --ignore-path .gitignore .","postbuild":"tsx tasks/build-txt.ts","precommit":"lint-staged","test:prod":"pnpm lint && pnpm test:smoke && pnpm test -- --no-cache","lint:types":"tsc","test:debug":"vitest run --inspect --no-file-parallelism --watch","test:light":"vitest run --exclude \"**/*benchmark*.test.ts\"","test:smoke":"(cd test/smoke/esm && pnpm test) && (cd test/smoke/exports && pnpm test)","test:watch":"vitest run --watch","docs:examples":"tsx tasks/generate-examples.ts","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"maximtop","email":"maximtop@gmail.com"},"_resolved":"/var/atlassian/application-data/bamboo/shared/build-dir/268926977/256475147-256606231/dnr-converter.tgz","_integrity":"sha512-YYjKN5Oa87XGybUd1ByLf+b1AjV/TrNEDBtDDyeDdE5nCZ84Rt2BGW9qzKQRShk5YsLTD4NQkaW3GiKZr1vq6w==","repository":{"url":"git+https://github.com/AdguardTeam/tsurlfilter.git","type":"git","directory":"packages/dnr-converter"},"_npmVersion":"10.9.7","description":"A converter that transforms adblock-style filtering rules into rules compatible with the Declarative Net Request (DNR) API.","directories":{},"lint-staged":{"{src,cli,test,tasks}/**/*.ts":["eslint"]},"sideEffects":false,"_nodeVersion":"22.22.2","dependencies":{"valibot":"^1.1.0","punycode":"2.3.1","commander":"^12.1.0","@adguard/agtree":"^4.2.1","@adguard/logger":"^2.0.0","@adguard/scriptlets":"2.5.1"},"typesVersions":{"*":{"*":["dist/types/src/index.d.ts"],"cli":["dist/types/cli/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"tsd":"^0.32.0","tsx":"^4.19.3","eslint":"8.57.1","rimraf":"^6.0.1","rollup":"^4.28.0","vitest":"^4.1.5","typescript":"^5.7.3","@types/node":"^22.14.0","lint-staged":"^13.2.2","markdownlint":"^0.37.4","@types/chrome":"^0.0.305","@types/punycode":"2.1.4","eslint-plugin-n":"^17.21.3","markdownlint-cli":"^0.44.0","rollup-plugin-dts":"^6.0.2","@rollup/plugin-swc":"^0.4.0","rollup-plugin-copy":"^3.5.0","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^4.1.5","eslint-plugin-jsdoc":"^48.11.0","@adguard/tsurlfilter":"^6.0.3","eslint-plugin-import":"^2.29.0","@rollup/plugin-commonjs":"^28.0.1","eslint-plugin-boundaries":"^5.0.1","@rollup/plugin-typescript":"^12.1.1","@typescript-eslint/parser":"^7.5.0","eslint-config-airbnb-base":"15.0.0","@rollup/plugin-node-resolve":"^15.3.0","rollup-plugin-node-externals":"^8.0.0","eslint-plugin-import-newlines":"1.4.0","eslint-config-airbnb-typescript":"^18.0.0","@typescript-eslint/eslint-plugin":"^7.5.0","@adguard/eslint-plugin-logger-context":"^1.0.1"},"peerDependencies":{"@adguard/re2-wasm":"1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/dnr-converter_1.1.2_1787640776507_0.8430688504699644","host":"s3://npm-registry-packages-npm-production"}},"2.0.0-beta.0":{"name":"@adguard/dnr-converter","version":"2.0.0-beta.0","author":{"name":"Adguard Software Ltd."},"license":"GPL-3.0-only","_id":"@adguard/dnr-converter@2.0.0-beta.0","maintainers":[{"name":"ameshkov","email":"am@adguard.com"},{"name":"maximtop","email":"maximtop@gmail.com"},{"name":"blakhard","email":"vlad.abdulmianov@gmail.com"},{"name":"d13410n3","email":"d.naumov@adguard.com"}],"homepage":"https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/dnr-converter#readme","bugs":{"url":"https://github.com/AdguardTeam/tsurlfilter/issues"},"bin":{"dnr-converter":"dist/cli.cjs"},"dist":{"shasum":"b35e9f32e1f9fa5c63f222403315dc1dd3f9218b","tarball":"https://registry.npmjs.org/@adguard/dnr-converter/-/dnr-converter-2.0.0-beta.0.tgz","fileCount":121,"integrity":"sha512-RS7eoQX9o+7q5XJnbDzIuqe2G9EwN/0isH4j7ZYdOSom2AxD6N2Rc6fyamUmWB/3m+2jMXfNOSokSwkTS0DZ/w==","signatures":[{"sig":"MEQCIBUfVQTWIrUzMLlF6ox6g3I39p6dKvusmw1TnFZdsnCwAiBaBoMnj2qFDPE1+bK5D/rXCZ1k+N9b1mrdAahLUViC8Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIE/IHlo9tVXhZMGLNXDMWvhTRC4gTnbVxf0FxTE7wmV2AiAN/uP6atzwV/1c8+iNstNzhPyH7v7jrbfx4qkww8P3nQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3655880},"main":"dist/index.js","type":"module","_from":"file:dnr-converter.tgz","types":"dist/types/src/index.d.ts","module":"dist/index.js","engines":{"node":">=22"},"exports":{".":{"types":"./dist/types/src/index.d.ts","import":"./dist/index.js"},"./cli":{"types":"./dist/types/cli/index.d.ts","default":"./dist/cli.cjs"}},"scripts":{"tgz":"pnpm pack --out dnr-converter.tgz","lint":"pnpm lint:code && pnpm lint:types && pnpm lint:md","test":"vitest run","build":"rimraf dist && rollup -c rollup.config.ts --configPlugin typescript","start":"rollup -c rollup.config.ts --configPlugin typescript -w","lint:md":"markdownlint .","test:ci":"vitest run --no-cache --reporter default --reporter junit --outputFile=./tests-reports/dnr-converter.xml","lint:code":"eslint --cache --ignore-path .gitignore .","precommit":"lint-staged","test:prod":"pnpm lint && pnpm test:smoke && pnpm test -- --no-cache","lint:types":"tsc","test:debug":"vitest run --inspect --no-file-parallelism --watch","test:light":"vitest run --exclude \"**/*benchmark*.test.ts\"","test:smoke":"(cd test/smoke/esm && pnpm test) && (cd test/smoke/exports && pnpm test)","test:watch":"vitest run --watch","docs:examples":"tsx tasks/generate-examples.ts","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:c711bb27-3d93-45c5-8535-c2c6b23cb6ee"}},"_resolved":"/home/runner/work/ext-tsurlfilter/ext-tsurlfilter/dnr-converter.tgz","_integrity":"sha512-RS7eoQX9o+7q5XJnbDzIuqe2G9EwN/0isH4j7ZYdOSom2AxD6N2Rc6fyamUmWB/3m+2jMXfNOSokSwkTS0DZ/w==","repository":{"url":"git+https://github.com/AdGuardSoftwareLimited/ext-tsurlfilter.git","type":"git","directory":"packages/dnr-converter"},"_npmVersion":"11.19.0","description":"A converter that transforms adblock-style filtering rules into rules compatible with the Declarative Net Request (DNR) API.","directories":{},"lint-staged":{"{src,cli,test,tasks}/**/*.ts":["eslint"]},"sideEffects":false,"_nodeVersion":"24.21.0","dependencies":{"valibot":"^1.1.0","punycode":"2.3.1","commander":"^12.1.0","@adguard/agtree":"^4.2.1","@adguard/logger":"^2.0.1","@adguard/scriptlets":"2.5.1"},"typesVersions":{"*":{"*":["dist/types/src/index.d.ts"],"cli":["dist/types/cli/index.d.ts"]}},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsd":"^0.32.0","tsx":"^4.19.3","eslint":"8.57.1","rimraf":"^6.0.1","rollup":"^4.28.0","vitest":"^5.0.0","typescript":"^5.7.3","@types/node":"^22.14.0","lint-staged":"^13.2.2","markdownlint":"^0.37.4","@types/chrome":"^0.0.305","@types/punycode":"2.1.4","eslint-plugin-n":"^17.21.3","markdownlint-cli":"^0.44.0","rollup-plugin-dts":"^6.0.2","@rollup/plugin-swc":"^0.4.0","rollup-plugin-copy":"^3.5.0","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^5.0.0","eslint-plugin-jsdoc":"^48.11.0","@adguard/tsurlfilter":"^6.0.3","eslint-plugin-import":"^2.29.0","@rollup/plugin-commonjs":"^28.0.1","eslint-plugin-boundaries":"^5.0.1","@rollup/plugin-typescript":"^12.1.1","@typescript-eslint/parser":"^7.5.0","eslint-config-airbnb-base":"15.0.0","@rollup/plugin-node-resolve":"^15.3.0","rollup-plugin-node-externals":"^8.0.0","eslint-plugin-import-newlines":"1.4.0","eslint-config-airbnb-typescript":"^18.0.0","@typescript-eslint/eslint-plugin":"^7.5.0","@adguard/eslint-plugin-logger-context":"^1.0.1"},"peerDependencies":{"@adguard/re2-wasm":"1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/dnr-converter_2.0.0-beta.0_1790626387128_0.5299037177650603","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"_id":"@adguard/dnr-converter@2.0.0","bin":{"dnr-converter":"dist/cli.cjs"},"bugs":{"url":"https://github.com/AdguardTeam/tsurlfilter/issues"},"dist":{"shasum":"51d10519da352afab99caf48acb11b665642888f","tarball":"https://registry.npmjs.org/@adguard/dnr-converter/-/dnr-converter-2.0.0.tgz","fileCount":121,"integrity":"sha512-BkbnLsUlRCMOLT7UgDg9RIJY/tZ24GYA8FQeaC6VU4QgzRH3idLexp1BfiN7m4/7oAt0FKuu/Ew8Gv7OWostdQ==","signatures":[{"sig":"MEYCIQCq8NLy3caIfEMj6M2lzrl1fn+CQZb5MHeMI9rJ5Ozs7gIhAIE463HijSklNbMQo0uebKhOKeO8/PjV+HdJ+VFuKzd/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICVpQDPIoSuVHGbCuR70CgsVSwPDb/RWQf9n53Qckz2qAiBQncpmaKFemqXfHn/NL6fNCfxcDvGu1xtkiIZojmpSrA=="}],"unpackedSize":3655859},"main":"dist/index.js","name":"@adguard/dnr-converter","type":"module","_from":"file:dnr-converter.tgz","types":"dist/types/src/index.d.ts","author":{"name":"Adguard Software Ltd."},"module":"dist/index.js","engines":{"node":">=22"},"exports":{".":{"types":"./dist/types/src/index.d.ts","import":"./dist/index.js"},"./cli":{"types":"./dist/types/cli/index.d.ts","default":"./dist/cli.cjs"}},"license":"GPL-3.0-only","scripts":{"tgz":"pnpm pack --out dnr-converter.tgz","lint":"pnpm lint:code && pnpm lint:types && pnpm lint:md","test":"vitest run","build":"rimraf dist && rollup -c rollup.config.ts --configPlugin typescript","start":"rollup -c rollup.config.ts --configPlugin typescript -w","lint:md":"markdownlint .","test:ci":"vitest run --no-cache --reporter default --reporter junit --outputFile=./tests-reports/dnr-converter.xml","lint:code":"eslint --cache --ignore-path .gitignore .","precommit":"lint-staged","test:prod":"pnpm lint && pnpm test:smoke && pnpm test -- --no-cache","lint:types":"tsc","test:debug":"vitest run --inspect --no-file-parallelism --watch","test:light":"vitest run --exclude \"**/*benchmark*.test.ts\"","test:smoke":"(cd test/smoke/esm && pnpm test) && (cd test/smoke/exports && pnpm test)","test:watch":"vitest run --watch","docs:examples":"tsx tasks/generate-examples.ts","test:coverage":"vitest run --coverage"},"version":"2.0.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"c711bb27-3d93-45c5-8535-c2c6b23cb6ee"}},"homepage":"https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/dnr-converter#readme","_resolved":"/home/runner/work/ext-tsurlfilter/ext-tsurlfilter/dnr-converter.tgz","_integrity":"sha512-BkbnLsUlRCMOLT7UgDg9RIJY/tZ24GYA8FQeaC6VU4QgzRH3idLexp1BfiN7m4/7oAt0FKuu/Ew8Gv7OWostdQ==","repository":{"url":"git+https://github.com/AdGuardSoftwareLimited/ext-tsurlfilter.git","type":"git","directory":"packages/dnr-converter"},"_npmVersion":"11.19.0","description":"A converter that transforms adblock-style filtering rules into rules compatible with the Declarative Net Request (DNR) API.","directories":{},"lint-staged":{"{src,cli,test,tasks}/**/*.ts":["eslint"]},"maintainers":[{"name":"ameshkov","email":"am@adguard.com"},{"name":"maximtop","email":"maximtop@gmail.com"},{"name":"blakhard","email":"vlad.abdulmianov@gmail.com"},{"name":"d13410n3","email":"d.naumov@adguard.com"}],"sideEffects":false,"_nodeVersion":"24.21.0","dependencies":{"valibot":"^1.1.0","punycode":"2.3.1","commander":"^12.1.0","@adguard/agtree":"^4.2.1","@adguard/logger":"^2.0.1","@adguard/scriptlets":"2.5.1"},"typesVersions":{"*":{"*":["dist/types/src/index.d.ts"],"cli":["dist/types/cli/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"tsd":"^0.32.0","tsx":"^4.19.3","eslint":"8.57.1","rimraf":"^6.0.1","rollup":"^4.28.0","vitest":"^5.0.0","typescript":"^5.7.3","@types/node":"^22.14.0","lint-staged":"^13.2.2","markdownlint":"^0.37.4","@types/chrome":"^0.0.305","@types/punycode":"2.1.4","eslint-plugin-n":"^17.21.3","markdownlint-cli":"^0.44.0","rollup-plugin-dts":"^6.0.2","@rollup/plugin-swc":"^0.4.0","rollup-plugin-copy":"^3.5.0","@rollup/plugin-json":"^6.1.0","@vitest/coverage-v8":"^5.0.0","eslint-plugin-jsdoc":"^48.11.0","@adguard/tsurlfilter":"^6.0.3","eslint-plugin-import":"^2.29.0","@rollup/plugin-commonjs":"^28.0.1","eslint-plugin-boundaries":"^5.0.1","@rollup/plugin-typescript":"^12.1.1","@typescript-eslint/parser":"^7.5.0","eslint-config-airbnb-base":"15.0.0","@rollup/plugin-node-resolve":"^15.3.0","rollup-plugin-node-externals":"^8.0.0","eslint-plugin-import-newlines":"1.4.0","eslint-config-airbnb-typescript":"^18.0.0","@typescript-eslint/eslint-plugin":"^7.5.0","@adguard/eslint-plugin-logger-context":"^1.0.1"},"peerDependencies":{"@adguard/re2-wasm":"1.2.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dnr-converter_2.0.0_1790669343123_0.9529363907503734"}}},"time":{"created":"2026-07-14T18:59:32.311Z","modified":"2026-09-29T08:09:03.474Z","1.0.0-alpha.2":"2026-07-14T18:59:32.708Z","1.1.0":"2026-07-29T07:40:24.411Z","1.1.1":"2026-08-24T14:19:04.120Z","1.1.2":"2026-08-25T06:52:56.703Z","2.0.0-beta.0":"2026-09-28T20:13:07.245Z","2.0.0":"2026-09-29T08:09:03.245Z"},"bugs":{"url":"https://github.com/AdguardTeam/tsurlfilter/issues"},"author":{"name":"Adguard Software Ltd."},"license":"GPL-3.0-only","homepage":"https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/dnr-converter#readme","repository":{"url":"git+https://github.com/AdGuardSoftwareLimited/ext-tsurlfilter.git","type":"git","directory":"packages/dnr-converter"},"description":"A converter that transforms adblock-style filtering rules into rules compatible with the Declarative Net Request (DNR) API.","maintainers":[{"name":"ameshkov","email":"am@adguard.com"},{"name":"maximtop","email":"maximtop@gmail.com"},{"name":"blakhard","email":"vlad.abdulmianov@gmail.com"},{"name":"d13410n3","email":"d.naumov@adguard.com"}],"readme":"<!-- omit in toc -->\n# DNR Converter\n\n[![npm-badge]][npm-url] [![license-badge]][license-url]\n\n[npm-badge]: https://img.shields.io/npm/v/@adguard/dnr-converter\n[npm-url]: https://www.npmjs.com/package/@adguard/dnr-converter\n[license-badge]: https://img.shields.io/npm/l/@adguard/dnr-converter\n[license-url]: https://github.com/AdguardTeam/tsurlfilter/blob/master/packages/dnr-converter/LICENSE\n\nA TypeScript library that converts adblock-style filtering rules into rules\ncompatible with Chrome's\n[Declarative Net Request (DNR)][dnr-api-url] API. It is designed for developers\nbuilding Manifest V3 browser extensions that need to translate existing AdGuard\nor other adblock filter lists into the DNR format required by modern Chrome\nextensions.\n\n[dnr-api-url]: https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest\n\n- [Key concepts](#key-concepts)\n    - [Supported rule types](#supported-rule-types)\n- [Installation](#installation)\n    - [Peer dependencies](#peer-dependencies)\n- [API overview](#api-overview)\n    - [`IFilter`](#ifilter)\n    - [`Filter`](#filter)\n    - [`ConverterOptions`](#converteroptions)\n    - [Simple flow: `FilterConverter` + `Ruleset`](#simple-flow-filterconverter--ruleset)\n    - [Advanced flow: `FilterConverter` with `withSourceMap: true` + `RulesetWithSourceMap`](#advanced-flow-filterconverter-with-withsourcemap-true--rulesetwithsourcemap)\n    - [Compact ruleset file format](#compact-ruleset-file-format)\n    - [`MetadataRuleset`](#metadataruleset)\n    - [`isSafeRule(rule)`](#issaferulerule)\n    - [`DNR_CONVERTER_VERSION`](#dnr_converter_version)\n    - [Network rule types](#network-rule-types)\n- [CLI](#cli)\n    - [Commands](#commands)\n    - [Programmatic API](#programmatic-api)\n- [Documentation](#documentation)\n\n## Key concepts\n\n- **Filter** — an adblock filter list represented as an object with an `id` and\n  text `content`. Each filter list (e.g. AdGuard Base, EasyList) becomes one\n  `Filter` input.\n- **Declarative rule** — a\n  [`chrome.declarativeNetRequest.Rule`][dnr-rule-url] object that the browser\n  evaluates natively. The converter produces these from filter text.\n- **Source map** — a mapping from each generated declarative rule back to its\n  originating filter and rule index, enabling reverse lookup when a declarative\n  rule fires.\n- **Rule safety** — Chrome\n  [classifies DNR rules][dnr-safe-rules-url] as *safe* (block, allow,\n  allowAllRequests, upgradeScheme) or *unsafe* (redirect, modifyHeaders). The\n  library exposes a helper to check safety.\n- **Converter options** — limits and paths that control conversion output\n  (maximum rule counts, resource paths for redirects).\n\n[dnr-rule-url]: https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#type-Rule\n[dnr-safe-rules-url]: https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#safe_rules\n\n### Supported rule types\n\nThe converter supports virtually all adblock network rule modifiers. The known\nMV3 limitations (inherent to the Declarative Net Request API) are:\n\n**Supported modifiers** (with MV3 notes):\n\n- Basic blocking/allowing rules, `$third-party`, `$domain` (no regexps / `.*`\n  TLDs), all content types (`$script`, `$image`, `$stylesheet`, etc.)\n- `$important`, `$match-case`, `$method`, `$to`, `$denyallow`, `$header`\n  (no regex values), `$all`\n- `$redirect` — allowlist rules not supported\n- `$csp`, `$removeparam`, `$removeheader`, `$permissions` — allowlist rules\n  not supported; rules with identical conditions are combined only within the\n  same filter, not across filters\n- `$urltransform` — limited; complex transforms produce multiple declarative\n  rules via pipeline stages\n- `$cookie` — limited; only supported without parameters (bare `$cookie`)\n- `$badfilter` — partial: does not handle `$domain` intersections correctly\n\n**Not yet supported / not convertible to DNR**:\n\n- `$popup`, `$redirect-rule`, `$referrerpolicy` — not yet implemented\n- `$replace`, `$jsonprune`, `$xmlprune`, `$hls`, `$network`, DNS modifiers (`$client`,\n  `$dnsrewrite`, `$dnstype`, `$ctag`) — not expressible in DNR; produce\n  conversion errors and are skipped\n- Exception modifiers `$jsinject`, `$stealth`, `$urlblock`, `$genericblock` —\n  not yet implemented\n- `$webrtc` — deprecated and not supported\n\nFor detailed conversion examples with output, see\n[Conversion Examples](src/examples/README.md).\n\n## Installation\n\n```bash\n# pnpm\npnpm install @adguard/dnr-converter\n\n# yarn\nyarn add @adguard/dnr-converter\n\n# npm\nnpm install @adguard/dnr-converter\n```\n\n### Peer dependencies\n\nThe package requires [`@adguard/re2-wasm`](https://www.npmjs.com/package/@adguard/re2-wasm)\n(`1.2.0`) as a peer dependency for regex validation.\n\n## API overview\n\nThe library uses a single `FilterConverter` class with **two conversion modes**\nselected by the `withSourceMap` option:\n\n| | Simple mode (default) | Advanced mode (`withSourceMap: true`) |\n| --- | --- | --- |\n| **Converter** | `FilterConverter` | `FilterConverter` |\n| **Ruleset** | `Ruleset` (sync, in-memory) | `RulesetWithSourceMap` (lazy-load, source map) |\n| **Input filter** | `IFilter` | `IFilter` |\n| **Use case** | When you only need `DeclarativeRule[]` output from plain filter text | When you need source maps, `$badfilter` cross-filter application, and serialization |\n\n### `IFilter`\n\n```ts\nimport type { IFilter } from '@adguard/dnr-converter';\n```\n\nSingle interface used by both conversion flows:\n\n| Method | Type | Description |\n| --- | --- | --- |\n| `getId()` | `number` | Unique filter identifier |\n| `getContent()` | `Promise<string>` | Returns the full text of the filter list |\n| `getRuleByIndex(index)` | `Promise<string>` | Returns original rule text by character offset |\n| `unloadContent()` | `void` | Releases loaded content from memory |\n\n### `Filter`\n\nThe single concrete `IFilter` implementation shipped by the library supports two\nconstruction modes:\n\n- **Pre-loaded** (`new Filter(id, content: string)`) — accepts the filter text\n  directly as a string. `getContent()` resolves immediately; `unloadContent()`\n  is a no-op. Use for simple conversion or when content is already in memory.\n\n- **Lazy-loaded** (`new Filter(id, source: () => Promise<string>)`) —\n  accepts an async callback that fetches the content on demand. Supports promise\n  deduplication across concurrent callers, and `unloadContent()` releases the\n  cached content. Use with `withSourceMap: true` (advanced mode).\n\n```ts\nimport { Filter } from '@adguard/dnr-converter';\n\n// Pre-loaded (simple mode)\nconst filter = new Filter(1, '||example.com^');\n\n// Lazy-loaded (advanced mode with withSourceMap: true)\nconst lazyFilter = new Filter(1, async () => fetchFilterText());\n```\n\n### `ConverterOptions`\n\n```ts\nimport type { ConverterOptions } from '@adguard/dnr-converter';\n```\n\nConfiguration for the conversion process:\n\n| Property | Type | Description |\n| --- | --- | --- |\n| `resourcesPath` | `string?` | Path to web-accessible resources relative to the extension root (starts with `/`, no trailing `/`). Required for `$redirect` rules. |\n| `maxNumberOfRules` | `number?` | Maximum total declarative rules to produce. Excess rules are trimmed. |\n| `maxNumberOfUnsafeRules` | `number?` | Maximum unsafe (dynamic) rules allowed. |\n| `maxNumberOfRegexpRules` | `number?` | Maximum rules using `regexFilter`. |\n| `combine` | `boolean?` | Merge all input filters into a single combined rule set. |\n| `withSourceMap` | `boolean?` | When `true`, returns `RulesetWithSourceMap` instead of `Ruleset`. Enables source maps, `$badfilter` cross-filter support, and lazy loading. |\n| `badFilterRules` | `Rule[]?` | Static `$badfilter` rules to apply at scan time (`withSourceMap: true` only). |\n\n### Simple flow: `FilterConverter` + `Ruleset`\n\nUse this flow when you only need `DeclarativeRule[]` output from plain filter\ntext, without source maps or lazy loading.\n\n```ts\nimport { FilterConverter, Filter } from '@adguard/dnr-converter';\n\nconst filter = new Filter(1, '||example.com^\\n@@||example.com/path^');\n\nconst converter = new FilterConverter();\nconst [{ ruleset, errors, limitations }] = await converter.convert([filter]);\n\nconsole.log(ruleset.getDeclarativeRules()); // DeclarativeRule[]\nconsole.log(ruleset.getSafeRulesCount());    // 2\nconsole.log(errors.length);                 // 0\n```\n\n**Combine multiple filters into one ruleset:**\n\n```ts\nconst [{ ruleset }] = await converter.convert(\n    [filter1, filter2],\n    { combine: true },\n);\n// ruleset.getId() === FilterConverter.COMBINED_RULESET_ID\n```\n\n**Serialize and restore:**\n\n```ts\nconst json = ruleset.serialize();   // JSON string of DeclarativeRule[]\n\nconst { Ruleset } = await import('@adguard/dnr-converter');\nconst restored = Ruleset.deserialize(ruleset.getId(), json);\n```\n\n`Ruleset` (returned by default, without `withSourceMap`) implements `IRuleset`:\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `getId()` | `string` | Rule set identifier (e.g. `\"ruleset_1\"`) |\n| `getSafeRulesCount()` | `number` | Count of safe declarative rules (excludes unsafe) |\n| `getUnsafeRulesCount()` | `number` | Count of unsafe rules |\n| `getRegexpRulesCount()` | `number` | Count of regexp-based rules |\n| `getDeclarativeRules()` | `DeclarativeRule[]` | All converted DNR rules (synchronous) |\n| `serialize()` | `string` | JSON serialization of declarative rules |\n| `Ruleset.deserialize(id, json)` | `Ruleset` | Static: reconstruct from serialized JSON |\n\n### Advanced flow: `FilterConverter` with `withSourceMap: true` + `RulesetWithSourceMap`\n\nUse this mode in browser extension internals when you need source maps,\n`$badfilter` cross-filter application, serialization with hash maps, and lazy\ncontent loading. Pass `withSourceMap: true` in the options to get\n`RulesetWithSourceMap` results.\n\n```ts\nimport { Filter, FilterConverter } from '@adguard/dnr-converter';\n\nconst filter = new Filter(1, async () => '||example.com^\\n@@||example.com/path^');\n\nconst converter = new FilterConverter();\nconst [{ ruleset, errors }] = await converter.convert([filter], { withSourceMap: true });\n\nconst declarativeRules = await ruleset.getDeclarativeRules(); // Promise<DeclarativeRule[]>\nconst sources = await ruleset.getRulesById(declarativeRules[0].id);\nconsole.log(sources[0].sourceRule); // '||example.com^'\n```\n\n**Apply `$badfilter` from dynamic filters against static rule sets:**\n\n```ts\nconst [{ ruleset: dynamicRuleset }] = await converter.convert(\n    [dynamicFilter],\n    { withSourceMap: true },\n);\nconst rulesToDisable = await converter.computeRulesToDisable(\n    [dynamicRuleset],\n    [staticRuleset],\n);\n// rulesToDisable: UpdateStaticRulesOptions[]\n```\n\n`RulesetWithSourceMap` (returned when `withSourceMap: true`) implements\n`IRulesetWithSourceMap`:\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `getId()` | `string` | Rule set identifier |\n| `getSafeRulesCount()` | `number` | Count of safe declarative rules (excludes unsafe) |\n| `getUnsafeRulesCount()` | `number` | Count of unsafe rules |\n| `getRegexpRulesCount()` | `number` | Count of regexp-based rules |\n| `getDeclarativeRules()` | `Promise<DeclarativeRule[]>` | All converted DNR rules (lazy) |\n| `getUnsafeRules()` | `Promise<DeclarativeRule[]>` | Unsafe rules subset (lazy) |\n| `getRulesById(id)` | `Promise<SourceRuleAndFilterId[]>` | Source rules for a DNR rule |\n| `getBadFilterRules()` | `NetworkRule[]` | `$badfilter` rules in this set |\n| `getRulesHashMap()` | `IRulesHashMap` | Hash map for fast `$badfilter` matching |\n| `getMetadataRulesCount()` | `number` | Metadata rules in the ruleset file the rule set was read from (0 if not read from a file) |\n| `serializeCompact(unsafeRules, prettyPrint?)` | `Promise<string>` | Ruleset file in the [compact ruleset file format](#compact-ruleset-file-format) |\n| `unloadContent()` | `void` | Release lazy-loaded content |\n| `RulesetWithSourceMap.fromCompact(id, content, filters)` | `RulesetWithSourceMap` | Build a rule set from `parseCompactRuleset()` output |\n| `RulesetWithSourceMap.fromDeserialized(deserialized, metadataRulesCount)` | `RulesetWithSourceMap` | Build a rule set from `RulesetWithSourceMap.deserialize()` output |\n\n```ts\nimport type { ConversionResult } from '@adguard/dnr-converter';\n```\n\nResult returned by converter methods:\n\n| Property | Type | Description |\n| --- | --- | --- |\n| `ruleset` | `IRuleset` / `IRulesetWithSourceMap` | The converted rule set |\n| `errors` | `(ConversionError \\| Error)[]` | Rules that could not be converted |\n| `limitations` | `LimitationError[]` | Warnings about exceeded limits |\n| `declarativeRulesToCancel` | `UpdateStaticRulesOptions[]?` | Static rule IDs to disable (from `computeRulesToDisable`) |\n\n### Compact ruleset file format\n\n`serializeCompact()` and `MetadataRuleset.serialize()` write a JSON array of\nDNR rules. The array starts with one or more **metadata rules**: block rules\nwhose `condition.urlFilter` is `dummy.rule.adguard.com` (they never match a\nrequest) and whose `metadata` value is `{ \"chunk\": \"<fragment>\" }`. Joining\nthe fragments in array order gives the serialized metadata. Every `metadata`\nvalue, including JSON escaping and the wrapper, is at most 65,536 UTF-8\nbytes: Edge Add-ons rejects packages with larger values. The ordinary\ndeclarative rules follow the metadata rules.\n\nA metadata rule is recognized by the marker `urlFilter` together with the\n`metadata` key. A converted rule for the host `dummy.rule.adguard.com`\nwithout a `metadata` key is an ordinary rule.\n\nMetadata rules are static DNR rules: they count towards the static rule\nquota and get the smallest IDs not used by any other rule of the ruleset.\nOrdinary rule IDs are never changed.\n\n```json\n[\n    { \"id\": 1, \"action\": { \"type\": \"block\" }, \"condition\": { \"urlFilter\": \"dummy.rule.adguard.com\", \"resourceTypes\": [\"xmlhttprequest\"] }, \"metadata\": { \"chunk\": \"{\\\"metadata\\\":{...},\\\"lazyMetadata\\\":{...},\\\"filterCon\" } },\n    { \"id\": 2, \"action\": { \"type\": \"block\" }, \"condition\": { \"urlFilter\": \"dummy.rule.adguard.com\", \"resourceTypes\": [\"xmlhttprequest\"] }, \"metadata\": { \"chunk\": \"tent\\\":\\\"||example.com^\\\"}\" } },\n    { \"id\": 1234567, \"action\": { \"type\": \"block\" }, \"condition\": { \"urlFilter\": \"||example.com^\" } }\n]\n```\n\nRead a filter ruleset file with `parseCompactRuleset()`:\n\n```ts\nimport { Filter, parseCompactRuleset, RulesetWithSourceMap } from '@adguard/dnr-converter';\n\nconst content = parseCompactRuleset('ruleset_1', JSON.parse(fileText));\ncontent.metadata;           // SerializedRulesetData\ncontent.lazyMetadata;       // SerializedRulesetLazyData\ncontent.filterContent;      // original filter text\ncontent.declarativeRules;   // ordinary DNR rules, without the metadata rules\ncontent.metadataRulesCount; // number of metadata rules, for static rule quota accounting\n\n// Build the rule set directly from the parsed content.\nconst ruleset = RulesetWithSourceMap.fromCompact('ruleset_1', content, [new Filter(1, content.filterContent)]);\n```\n\n`fromCompact()` validates `metadata` at once and the lazy metadata and\nordinary rules on first load, with the same schemas as\n`RulesetWithSourceMap.deserialize()`. The rule set keeps the parsed content\nin memory for its whole lifetime; `unloadContent()` does not release it.\n\nWhen the parts are stored as strings, for example in IndexedDB, load them\nlazily with `deserialize()` and build the rule set with `fromDeserialized()`,\npassing the stored `metadataRulesCount`:\n\n```ts\nconst ruleset = RulesetWithSourceMap.fromDeserialized(\n    await RulesetWithSourceMap.deserialize(id, rawData, loadLazyData, loadDeclarativeRules, filters),\n    metadataRulesCount,\n);\n```\n\nThe reader takes only the leading run of metadata rules, joins them and\nparses the result once. It throws `InvalidMetadataChunksError` (with a\n`rulesetId` property) when the input is not an array, has no leading\nmetadata rule, has a metadata rule without a string `chunk`, or when the\njoined fragments are not valid JSON.\n\n### `MetadataRuleset`\n\n```ts\nimport { MetadataRuleset, METADATA_RULESET_ID } from '@adguard/dnr-converter';\n```\n\nA specialized ruleset that stores checksums and additional properties for a\ncollection of DNR rule sets. It serializes in the\n[compact ruleset file format](#compact-ruleset-file-format): a JSON array\nthat contains only metadata rules carrying `{ checksums, additionalProperties }`\nin `metadata.chunk` fragments.\n\n`METADATA_RULESET_ID` is the constant `0`; the ruleset's string ID is always\n`\"ruleset_0\"`.\n\n**Checksum methods:**\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `getId()` | `string` | Always `\"ruleset_0\"` |\n| `setChecksum(rulesetId, checksum)` | `void` | Store checksum for a rule set |\n| `getChecksum(rulesetId)` | `string \\| undefined` | Retrieve checksum, or `undefined` if not set |\n| `getRulesetIds()` | `string[]` | All rule set IDs that have checksums |\n\n**Additional-property methods:**\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `setAdditionalProperty(key, value)` | `void` | Store an arbitrary JSON-serializable property |\n| `getAdditionalProperty(key)` | `unknown \\| undefined` | Retrieve a property value |\n| `hasAdditionalProperty(key)` | `boolean` | Check whether a property exists |\n| `removeAdditionalProperty(key)` | `void` | Remove a property (no-op if missing) |\n\n**Serialization:**\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `serialize(pretty?)` | `string` | JSON string; `pretty=true` for human-readable output |\n| `MetadataRuleset.deserialize(json)` | `MetadataRuleset` | Reconstruct from a serialized string; throws `SyntaxError` on invalid JSON, `InvalidMetadataChunksError` on malformed metadata rules, a validation error on a bad payload |\n\n```ts\nconst meta = new MetadataRuleset();\nmeta.setChecksum('ruleset_1', 'abc123');\nmeta.setAdditionalProperty('version', '2.0');\n\nconst json = meta.serialize();\nconst restored = MetadataRuleset.deserialize(json);\n\nconsole.log(restored.getChecksum('ruleset_1')); // \"abc123\"\nconsole.log(restored.getAdditionalProperty('version')); // \"2.0\"\n```\n\n### `isSafeRule(rule)`\n\n```ts\nimport { isSafeRule } from '@adguard/dnr-converter';\n\n// DeclarativeRule from the DNR API\nconst rule = {\n    id: 2,\n    priority: 1,\n    action: { type: 'block' },\n    condition: { urlFilter: 'example.com' },\n};\n\nisSafeRule(rule); // true — \"block\" is a safe action\n```\n\nReturns `true` if the declarative rule's action is one of the\n[safe rule actions][dnr-safe-rules-url] (`block`, `allow`,\n`allowAllRequests`, `upgradeScheme`). Useful for separating safe static rules\nfrom unsafe dynamic rules that require additional review.\n\n### `DNR_CONVERTER_VERSION`\n\n```ts\nimport { DNR_CONVERTER_VERSION } from '@adguard/dnr-converter';\n\nconsole.log(DNR_CONVERTER_VERSION); // e.g. \"0.0.1\"\n```\n\nA string constant with the current library version.\n\n### Network rule types\n\nThe package exports types related to network rule parsing and validation:\n\n```ts\nimport {\n    Rule,\n    HttpHeaderMatcher,\n    RuleDeclarativeValidator,\n} from '@adguard/dnr-converter';\n```\n\n- **`Rule`** — parsed network rule with accessors for domains, resource\n  types, methods, advanced modifier values, priority, and option flags.\n  Create instances via `Rule.createFromText(filterListId, index, text)`.\n- **`HttpHeaderMatcher`** — type describing the parsed `$header` modifier\n  value.\n- **`RuleDeclarativeValidator`** — static helper that checks whether a\n  `Rule` can be converted to a DNR rule. Call\n  `RuleDeclarativeValidator.shouldConvertRule(rule)` — returns\n  `true` if the rule is convertible, `false` if it should be silently skipped,\n  or throws `UnsupportedModifierError` if the rule uses an unsupported\n  modifier.\n\n## CLI\n\nThe package ships a `dnr-converter` command-line tool for converting filter\nlists to DNR rulesets and extracting filter content back from compiled rulesets.\n\n### Commands\n\n#### `convert`\n\nConverts AdGuard filter lists from a metadata directory into DNR rulesets.\n\n```bash\ndnr-converter convert \\\n  ./filters \\\n  ./resources \\\n  ./dist/rulesets\n```\n\n**Arguments:**\n\n| Argument | Description | Default |\n| --- | --- | --- |\n| `<filters_and_metadata_dir>` | Directory containing `filters.json` and filter list files | *(required)* |\n| `<resources_dir>` | Directory with redirect resources | *(required)* |\n| `[dest_rule_sets_dir]` | Output directory for generated rulesets | `./build/rulesets` |\n\n**Options:**\n\n| Option | Description | Default |\n| --- | --- | --- |\n| `--debug` | Enable debug logging | `false` |\n| `--prettify-json <bool>` | Pretty-print JSON output files | `true` |\n| `--additional-properties <json>` | Additional properties to include in the metadata ruleset as JSON string | `{}` |\n\nThe `filters.json` metadata file must be an array of filter metadata objects\neach with at minimum `filterId` and `name` fields.\n\n#### `extract-filters`\n\nExtracts original filter list content that was embedded in compiled DNR rulesets\nby the `convert` command.\n\n```bash\ndnr-converter extract-filters \\\n  ./dist/rulesets \\\n  ./extracted-filters\n```\n\n**Arguments:**\n\n| Argument | Description |\n| --- | --- |\n| `<path-to-rulesets>` | Directory containing compiled ruleset files |\n| `<path-to-output>` | Directory to write extracted filter files |\n\n### Programmatic API\n\nThe CLI logic is also available as a programmatic API via the\n`@adguard/dnr-converter/cli` subpath export:\n\n```ts\nimport { convertFilters, generateMD5Hash, type ConvertFiltersOptions } from '@adguard/dnr-converter/cli';\n\nawait convertFilters(\n    './filters',\n    './resources',\n    './dist/rulesets',\n    { debug: true, prettifyJson: true },\n);\n```\n\n## Documentation\n\n- [Changelog](CHANGELOG.md)\n- [Development](DEVELOPMENT.md)\n- [Migration from tsurlfilter](MIGRATION.md)\n- [Conversion Examples](src/examples/README.md)\n- [LLM agent rules](AGENTS.md)\n","readmeFilename":"README.md"}