npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@adguard/api-mv3

v0.2.3

Published

This is a TypeScript library that implements AdGuard's extension API for MV3

Downloads

105

Readme

AdGuard API MV3

AdGuard API is a filtering library that provides the following features:

Table of contents

Installation

  1. Install the @adguard/api-mv3 module via npm or yarn
npm install @adguard/api-mv3

or

yarn add @adguard/api-mv3
  1. Import the AdguardApi class to the background script
import { AdguardApi } from "@adguard/api-mv3";
  1. Import adguard-contents at the top of your content script entry
import '@adguard/api-mv3/content-script';
  1. Import adguard-assistant at the top of your assistant script entry
import '@adguard/api-mv3/assistant';

Required web accessible resources

AdGuard API MV3 requires web accessible resources from the AdGuard Scriptlets library to be able to redirect web requests to a local "resource" using the $redirect rule modifier. You can use @adguard/tswebextension CLI to download it.

Required declarativeNetRequest API assets

IMPORTANT: To correct work of $redirect path should be /web-accessible-resources/redirects. If you are using @adguard/dnr-rulesets package, path to web accessible resources is built-in into converted rules with $redirect modifier and packed inside rulesets.

IMPORTANT: AdGuard Quick Fixes filter with id 24 filter's source and converted ruleset excluded from the build of @adguard/dnr-rulesets, but left in metadata. Because it should used via periodically updating from the remote in the runtime and passed as part of dynamic rules - Configuration.rules.

AdGuard API MV3 requires prebuilt DNR rule sets to be able to filter web requests. You can use @adguard/dnr-rulesets CLI to download it. We also provide a extension example with scripts for loading DNR rulesets and patching manifest in the examples/adguard-api-mv3 directory.

Configuration

Syntax:

type Configuration = {
    filters: number[];
    filteringEnabled: boolean;
    assetsPath: string;
    allowlist?: string[] | undefined;
    blocklist?: string[] | undefined;
    rules?: string[] | undefined;
};

Properties:

  • filters (mandatory) - An array of filters identifiers. You can look for possible filters identifiers in dnr-rulesets.

  • filteringEnabled (mandatory) - Enable/disable filtering engine.

  • assetsPath (mandatory) - Path to the directory with DNR rule sets. You can use the dnr-rulesets CLI to download DNR rule sets.

  • allowlist (optional) - An array of domains, for which AdGuard won't work.

  • blocklist (optional) - This property completely changes AdGuard behavior. If it is defined, Adguard will work for domains from the blocklist only. All other domains will be ignored. If blocklist is defined, allowlist will be ignored.

  • rules (optional) - An array of custom filtering rules. Here is an [article][filter-rules] describing filtering rules syntax. These custom rules might be created by a user via AdGuard Assistant UI.

Example:

const configuration: Configuration = {
    // Filters identifiers defined in @adguard/dnr-rulesets
    filters: [1, 2, 3, 4, 9, 14],
    filteringEnabled: true,
    assetsPath: 'filters',
    allowlist: ['www.example.com'],
    rules: ['example.org##h1'],
};

![!WARNING] Please note, that we do not allow using filters.adtidy.org other than for testing purposes. You have to use your own server for storing filter files. You can (and actually should) use filters.adtidy.org for periodically updating files on your side.

Static methods

Creates a new AdguardApi instance.

AdguardApi.create

Syntax:

public static async create(): Promise<AdguardApi>

Example:

const adguardApi = await AdguardApi.create();

Methods

adguardApi.getMessageHandler

Gets the message handler for API content script messages.

The API message handler name is a constant that can be exported as MESSAGE_HANDLER_NAME from @adguard/api-mv3.

The list of possible message types is defined in tswebextension

Syntax:

public getMessageHandler(): MessageHandlerMV3

Example:

// get tswebextension message handler
const handleApiMessage = adguardApi.getMessageHandler();

const handleAppMessage = async (message: Message) => {
  // handle your app messages here
};

// route message depending on handler name
browser.runtime.onMessage.addListener(async (message, sender) => {
  if (message?.handlerName === MESSAGE_HANDLER_NAME) {
    return Promise.resolve(handleApiMessage(message, sender));
  }
  return handleAppMessage(message);
});

Returns:

A message handler that will listen to internal messages. For example: messages for get computed css for content-script.

adguardApi.start

Initializes AdGuard API and starts it immediately.

Syntax:

public async start(configuration: Configuration): Promise<Configuration>

Example:

const appliedConfiguration = await adguardApi.start(configuration);

Parameters:

Returns:

A Promise, resolved with applied API Configuration when api is initialized and filtering started

adguardApi.stop

Completely stops AdGuard API.

Syntax:

public async stop(): Promise<void>

Example:

await adguardApi.stop();

Returns:

Promise, resolved when API is completely stopped

adguardApi.configure

This method modifies AdGuard configuration.

Note, that Adguard must be already started (see adguardApi.start).

Syntax:

public async configure(configuration: Configuration): Promise<Configuration>

Example:

const updatedConfiguration = await adguardApi.configure(configuration);

Parameters:

Returns:

A Promise object that is getting resolved with applied API Configuration when the API config is updated.

adguardApi.openAssistant

Opens the AdGuard Assistant UI in the specified tab. You must also subscribe on onAssistantCreateRule event channel for applying rules that are created by Adguard Assistant.

Syntax:

public async openAssistant(tabId: number): Promise<void>

Example:

await adguardApi.openAssistant(tabId);

Parameters:

Returns:

A Promise object that is getting resolved when the Assistant UI is opened in the specified tab.

adguardApi.closeAssistant

Closes AdGuard Assistant in the specified tab.

Syntax:

public async openAssistant(tabId: number): Promise<void>

Example:

await adguardApi.closeAssistant(tabId);

Parameters:

Returns:

A Promise object that is getting resolved when Assistant UI id closed in the specified tab.

adguardApi.getRulesCount

Gets currently loaded rules count.

Syntax:

public getRulesCount(): number

Example:

adguardApi.getRulesCount();

Returns:

rules count number

adguardApi.onAssistantCreateRule

TsWebExtension event channel that receives events when a rule is created via AdGuard Assistant.

Syntax:

public onAssistantCreateRule: EventChannel<string>;

Example:


// update config on Assistant rule apply
const applyRule = async (rule): Promise<void> => {
  console.log(`Rule ${rule} was created by Adguard Assistant`);
  configuration.rules!.push(rule);
  await adguardApi.configure(configuration);
};

// add listener
adguardApi.onAssistantCreateRule.subscribe(applyRule);

// remove listener
adguardApi.onAssistantCreateRule.unsubscribe(applyRule);

adguardApi.onRequestBlocking

API for adding and removing listeners for request blocking events.

[!NOTE] You must have the webRequest permission in your manifest to use.

[!NOTE] Rule calculated by tsurlfilter is not always the same as the declarative rule that has blocked the request. That's why we provide an assumedRule and assumedFilterId properties in the event object. We will improve the rule calculation algorithm to provide more accurate results in future releases.

Syntax:

export interface RequestBlockingLoggerInterface {
    addListener(listener: EventChannelListener<RequestBlockingEvent>): void;
    removeListener(listener: EventChannelListener<RequestBlockingEvent>): void;
}

Callback parameter properties:

type RequestBlockingEvent = {
    /**
     * Tab identifier.
     */
    tabId: number;

    /**
     * Blocked request id.
     */
    requestId: string;

    /**
     * Blocked request URL.
     */
    requestUrl: string;

    /**
     * Referrer URL.
     */
    referrerUrl: string;

    /**
     * Request mime type
     */
    requestType: ContentType;

    /**
     * Assumed Filtering rule index, which has blocked this request. May not be provided if request is blocked by DNR rule.
     */
    assumedRuleIndex?: string;

    /**
     * Assumed rule's filter identifier. May not be provided if request is blocked by DNR rule.
     */
    assumedFilterId?: number;

    /**
     * Company category name for requests blocked by DNR rule. Provided only if request is blocked by DNR rule.
     */
    companyCategoryName?: string;
};

Learn more about companyCategoryName in the list of company categories.

Note that few events can be fired for the same request, e.g., when a request is blocked by a DNR rule, first event is fired during onBeforeRequest with assumedRuleIndex and assumedFilterId properties but no companyCategoryName is provided, and the second event is fired during onErrorOccurred with companyCategoryName property defined but assumedRuleIndex and assumedFilterId are -1. So you can handle such requests by the requestId property.

Example:

// Registers an event listener
adguardApi.onRequestBlocked.addListener(
  callback // function, mandatory
)
// Removes specified event listener
adguardApi.onRequestBlocked.removeListener(
  callback // function, mandatory
)

Supported Request types:

  • DOCUMENT - top-level frame document.
  • SUBDOCUMENT - document loaded in a nested frame.
  • SCRIPT
  • STYLESHEET
  • OBJECT
  • IMAGE
  • XMLHTTPREQUEST
  • MEDIA
  • FONT
  • WEBSOCKET
  • OTHER

Usage

See full sample app project in examples/adguard-api

import browser from 'webextension-polyfill';
import { AdguardApi, type Configuration, MESSAGE_HANDLER_NAME } from '@adguard/api-mv3';

(async (): Promise<void> => {
    // create new AdguardApi instance
    const adguardApi = await AdguardApi.create();

    // console log event on request blocking
    const onRequestBlocked = (event: RequestBlockingEvent) => {
        console.log(event);
    };

    adguardApi.onRequestBlocked.addListener(onRequestBlocked);

    let configuration: Configuration = {
        /**
         * filters identifiers from dnr-rulesets
         * @see https://filters.adtidy.org/extension/chromium/filters.json
         */
        filters: [2, 3, 4],
        filteringEnabled: true,
        allowlist: ['www.example.com'],
        rules: ['example.org##h1'],
        assetsPath: 'filters',
    };

    // console log current rules count, loaded in engine
    const logTotalCount = (): void => {
        console.log('Total rules count:', adguardApi.getRulesCount());
    };

    configuration = await adguardApi.start(configuration);

    console.log('Finished Adguard API initialization.');
    console.log('Applied configuration: ', JSON.stringify(configuration));
    logTotalCount();

    configuration.allowlist!.push('www.google.com');

    await adguardApi.configure(configuration);

    console.log('Finished Adguard API re-configuration');
    logTotalCount();

    const onAssistantCreateRule = async (rule: string) => {
        // update config on assistant rule apply
        console.log(`Rule ${rule} was created by Adguard Assistant`);
        configuration.rules!.push(rule);
        await adguardApi.configure(configuration);
        console.log('Finished Adguard API re-configuration');
        logTotalCount();
    };

    adguardApi.onAssistantCreateRule.subscribe(onAssistantCreateRule);

    // get tswebextension message handler
    const handleApiMessage = adguardApi.getMessageHandler();

    // define custom message handler
    const handleAppMessage = async (message: any) => {
        switch (message.type) {
            case 'OPEN_ASSISTANT': {
                const active = await browser.tabs.query({ active: true });
                if (active[0]?.id) {
                    await adguardApi.openAssistant(active[0].id);
                }
                break;
            }
            default:
            // do nothing
        }
    };

    browser.runtime.onMessage.addListener(async (message, sender) => {
        // route message depending on handler name
        if (message?.handlerName === MESSAGE_HANDLER_NAME) {
            return Promise.resolve(handleApiMessage(message, sender));
        }
        return handleAppMessage(message);
    });

    // Disable Adguard in 1 minute
    setTimeout(async () => {
        adguardApi.onRequestBlocked.removeListener(onRequestBlocked);
        adguardApi.onAssistantCreateRule.unsubscribe(onAssistantCreateRule);
        await adguardApi.stop();
        console.log('Adguard API MV3 has been disabled.');
    }, 60 * 1000);
})();

Minimum supported browser versions

| Browser | Version | | ----------------------- | :-----: | | Chromium Based Browsers | 84 |

Development

Install dependencies

pnpm install

Build

npx lerna run build --scope @adguard/api-mv3 --include-dependencies

Lint

pnpm run lint