@adguard/tsurlfilter

中文文档
6.0.4发布于 2026/10/15GPL-3.0-onlyTypeScriptESM + CJS近 30 天下载 3126

This is a TypeScript library that implements AdGuard's content blocking rules

原始使用文档
文档目录6 节
  1. Idea
  2. Installation
  3. API description
  4. Public properties
  5. Public classes
  6. Documentation

TSUrlFilter

npm-badge license-badge

This is a TypeScript library that implements AdGuard's content blocking rules.

Idea

The idea is to have a single library that we can reuse for the following tasks:

Installation

You can install the package via:

  • Yarn: yarn add @adguard/tsurlfilter
  • NPM: npm install @adguard/tsurlfilter
  • PNPM: pnpm install @adguard/tsurlfilter

API description

Public properties

TSURLFILTER_VERSION

type: string

Version of the library.

Public classes

Engine

Engine is a main class of this library. It represents the filtering functionality for loaded rules

Factory

You can create engine via factories. There are two modes: sync and async.

Important: The content field in EngineFactoryOptions accepts either a raw string or a FilterList instance. If you provide a string, it will be automatically wrapped in a FilterList and converted. If you provide a FilterList instance, you have full control over the conversion process by optionally providing conversion data to the FilterList constructor.

Note: tsurlfilter only supports AdGuard filter syntax. If you need to convert rules from other syntaxes (e.g., uBlock Origin, Adblock Plus), use the FilterList class which automatically converts rules to AdGuard format via RawRuleConverter.convertToAdg(). This conversion should be done at the filter list level before the engine processes the rules.

Sync mode

Create engine synchronously.

/**
 * Creates an instance of the network engine in sync mode.
 *
 * @param options Engine factory options.
 *
 * @returns An instance of the network engine.
 */
public static createSync(options: EngineFactoryOptions): Engine;
Async mode

Create engine asynchronously. We use this approach in AdGuard browser extension to avoid UI lags.

/**
 * Creates an instance of the network engine in async mode.
 *
 * @param options Engine factory options.
 *
 * @returns An instance of the network engine.
 */
public static createAsync(options: EngineFactoryOptions): Promise<Engine>;
Example
const engine = await Engine.createAsync({
    filters: [
        {
            id: 1,
            content: '||example.com^',
        },
    ],
});
matchRequest
/**
 * Matches the specified request against the filtering engine and returns the matching result.
 * In case frameRules parameter is not specified, frame rules will be selected matching request.sourceUrl.
 *
 * @param request - request to check
 * @param frameRules - source rules or undefined
 * @returns matching result
 */
matchRequest(request: Request, frameRule: NetworkRule | null = null): MatchingResult;
matchFrame
/**
  * Matches current frame and returns document-level allowlist rule if found.
  *
  * @param frameUrl
  */
matchFrame(frameUrl: string): NetworkRule | null;
Starting engine
import { Engine, setConfiguration } from '@adguard/tsurlfilter';

const rawFilter = [
  '[AdGuard]',
  '! Title: Example filter',
  '! Description: This is just an example filter.',
  'example.com##h1',
].join('\n');

const config = {
    engine: 'extension',
    version: '1.0.0',
    verbose: true,
};

setConfiguration(config);

// Create engine using the factory method
const engine = Engine.createSync({
    filters: [
        {
            id: 0,
            content: rawFilter,
        },
    ],
});

console.log(`Engine loaded with ${engine.getRulesCount()} rule(s)`);
Matching requests
const request = new Request(url, sourceUrl, RequestType.Document);
const result = engine.matchRequest(request);
Retrieving cosmetic data
const cosmeticResult = engine.getCosmeticResult(request, CosmeticOption.CosmeticOptionAll);

MatchingResult

MatchingResult contains all the rules matching a web request, and provides methods that define how a web request should be processed

getBasicResult
/**
 * GetBasicResult returns a rule that should be applied to the web request.
 * Possible outcomes are:
 * returns null -- bypass the request.
 * returns a allowlist rule -- bypass the request.
 * returns a blocking rule -- block the request.
 *
 * @returns basic result rule
 */
getBasicResult(): NetworkRule | null;
getDocumentBlockingResult
/**
 * Returns a rule that should block a document request.
 *
 * @returns Document blocking rule if any, null otherwise.
 */
getDocumentBlockingResult(): NetworkRule | null;
getCosmeticOption

This flag should be used for getCosmeticResult(request: Request, option: CosmeticOption)

/**
  * Returns a bit-flag with the list of cosmetic options
  *
  * @returns {CosmeticOption} mask
  */
getCosmeticOption(): CosmeticOption;
Other rules
/**
  * Return an array of replace rules
  */
getReplaceRules(): NetworkRule[]

/**
  * Returns an array of csp rules
  */
getCspRules(): NetworkRule[]

/**
  * Returns an array of cookie rules
  */
getCookieRules(): NetworkRule[]

CosmeticResult

Cosmetic result is the representation of matching cosmetic rules. It contains the following properties:

/**
 * Storage of element hiding rules
 */
public elementHiding: CosmeticStylesResult;

/**
 * Storage of CSS rules
 */
public CSS: CosmeticStylesResult;

/**
 * Storage of JS rules
 */
public JS: CosmeticScriptsResult;

/**
 * Storage of Html filtering rules
 */
public Html: CosmeticHtmlResult;

/**
 * Script rules
 */
public getScriptRules(): CosmeticRule[];
Applying cosmetic result - CSS
const css = [...cosmeticResult.elementHiding.generic, ...cosmeticResult.elementHiding.specific]
        .map((rule) => `${rule.getContent()} { display: none!important; }`);

const styleText = css.join('\n');
const injectDetails = {
    code: styleText,
    runAt: 'document_start',
};

chrome.tabs.insertCSS(tabId, injectDetails);
Applying cosmetic result - scripts
const cosmeticRules = cosmeticResult.getScriptRules();
const scriptsCode = cosmeticRules.map((x) => x.getScript()).join('\r\n');
const toExecute = buildScriptText(scriptsCode);

chrome.tabs.executeScript(tabId, {
    code: toExecute,
});

DnsEngine

DNSEngine combines host rules and network rules and is supposed to quickly find matching rules for hostnames.

Constructor
/**
  * Builds an instance of dns engine
  *
  * @param storage
  */
constructor(storage: RuleStorage);
match
/**
 * Match searches over all filtering and host rules loaded to the engine
 *
 * @param hostname to check
 * @returns dns result object
 */
public match(hostname: string): DnsResult;
Matching hostname
const dnsResult = dnsEngine.match(hostname);
if (dnsResult.basicRule && !dnsResult.basicRule.isAllowlist()) {
    // blocking rule found
    ...
}

if (dnsResult.hostRules.length > 0) {
    // hosts rules found
    ...
}

RuleSyntaxUtils

This module is not used in the engine directly, but it can be used in other libraries

Public methods
/**
 * Checks if rule can be matched by domain
 *
 * @param ruleText Rule text
 * @param domain Domain to check
 */
public static isRuleForDomain(ruleText: string, domain: string): boolean
/**
 * Checks if rule can be matched by URL
 *
 * @param ruleText Rule text
 * @param url URL to check
 */
public static isRuleForUrl(ruleText: string, url: string): boolean;

FilterList

FilterList is a class that represents a converted filter list with efficient access to both converted and original rule content.

Key Features
  • Automatic Rule Conversion: Converts filter rules to AdGuard format using RawRuleConverter.convertToAdg()
  • O(1) Access: Provides constant-time access to original filtering rules via conversion data
  • Bidirectional Mapping: Maintains mappings between converted and original rules
  • Content Restoration: Can restore the original filter list from converted content
Constructor
/**
 * Creates a new FilterList instance.
 *
 * @param content Filter list content.
 * @param data Optional conversion data. If not provided, the filter list will be prepared.
 */
constructor(content: string, data?: ConversionData)
Conversion Data Structure

The ConversionData interface tracks the relationship between converted and original rules:

interface ConversionData {
    /**
     * Original filter list rules that were converted.
     */
    originals: string[];

    /**
     * Conversion map.
     * Maps line start offsets in the converted content to indexes in the originals array.
     * Keys are 0-based line start offsets, values are 0-based indexes in originals array.
     */
    conversions: Record<number, number>;
}
Main Methods
Getting Converted Content
/**
 * Returns the converted content.
 */
public getContent(): string;
Getting Rule Text
/**
 * Returns the rule text for a given offset in the converted content.
 * This may be a converted rule.
 *
 * @param offset Line start offset in the converted content.
 * @returns Rule as string, or null if not found.
 */
public getRuleText(offset: number): string | null;
Getting Original Rule Text
/**
 * Returns the original rule text for a given offset.
 * If the rule was converted, returns the original from conversion data.
 * If not converted, returns the rule text (which is already the original).
 *
 * @param offset Line start offset in the converted content.
 * @returns Original rule text, or null if offset is invalid.
 */
public getOriginalRuleText(offset: number): string | null;
Getting Converted Rule Original (Strict)
/**
 * Returns the original rule text only if the rule was actually converted.
 * Unlike getOriginalRuleText(), this returns null for unconverted rules.
 *
 * @param offset Line start offset in the converted content.
 * @returns Original rule text if converted, or null if not converted or invalid offset.
 */
public getConvertedRuleOriginal(offset: number): string | null;
Restoring Original Content
/**
 * Restores the original filter list content from the converted content.
 *
 * @returns Original filter list content.
 */
public getOriginalContent(): string;
Static Methods
/**
 * Creates an empty converted filter list.
 */
public static createEmpty(): FilterList;

/**
 * Creates an empty conversion data.
 */
public static createEmptyConversionData(): ConversionData;
Usage Example
import { FilterList } from '@adguard/tsurlfilter';

// Create a filter list (automatically converts rules)
const filterList = new FilterList('||example.com^$third-party');

// Get converted content
const converted = filterList.getContent();

// Get rule at specific offset
const rule = filterList.getRuleText(0);

// Get original rule if it was converted
const original = filterList.getOriginalRuleText(0);

// Restore full original content
const originalContent = filterList.getOriginalContent();

// Create from existing conversion data (no re-conversion)
const data = filterList.getConversionData();
const filterList2 = new FilterList(converted, data);

Documentation

版本与发布记录

@adguard/tsurlfilter 共发布 248 个版本,首次发布于 2020/07/15;过去 12 个月发布了 16 个版本。

版本发布日期距今
6.0.4latest2026/10/1523 天前
6.0.32026/08/252 个月前
6.0.22026/07/293 个月前
5.0.12026/04/276 个月前
5.0.0-beta.1beta2026/04/176 个月前
5.0.0-beta2026/04/166 个月前

其他发布通道:alpha → 3.3.0-alpha.0,beta → 5.0.0-beta.1。

关于 @adguard/tsurlfilter 的常见问题

@adguard/tsurlfilter 是什么?

This is a TypeScript library that implements AdGuard's content blocking rules

如何安装 @adguard/tsurlfilter?

在项目目录运行 npm install @adguard/tsurlfilter,或使用 pnpm add / yarn add / bun add。

@adguard/tsurlfilter 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@adguard/tsurlfilter 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@adguard/tsurlfilter 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@adguard/tsurlfilter 可以商用吗?

@adguard/tsurlfilter 使用 GPL-3.0-only 许可。强 Copyleft:分发包含该代码的软件时,整个作品需以 GPL-3.0 兼容许可开源,并附带专利与反锁定条款。仅内部使用不触发此义务。以上为概括,不构成法律意见,请以许可原文为准。

@adguard/tsurlfilter 的下载量有多少?

根据 npm 官方下载统计,@adguard/tsurlfilter 在 2026/10/05 – 2026/11/03 这 30 天内被下载 3,126 次,日均约 104 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adguard/tsurlfilter 还在维护吗?

最新版本 6.0.4 发布于 2026/10/15(23 天前);至今共发布 248 个版本,其中过去 12 个月发布了 16 个;首次发布于 2020/07/15。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。