Skip to content

Commit

Permalink
AG-35594 Update AGTree to v2
Browse files Browse the repository at this point in the history
Merge in ADGUARD-FILTERS/aglint from fix/AG-35594 to master

Squashed commit of the following:

commit 446cf59
Author: scripthunter7 <[email protected]>
Date:   Wed Sep 11 11:55:00 2024 +0200

    add date to changelog

commit e37600d
Author: scripthunter7 <[email protected]>
Date:   Tue Sep 10 19:40:02 2024 +0200

    add rule to tests

commit 0914676
Author: scripthunter7 <[email protected]>
Date:   Tue Sep 10 19:36:54 2024 +0200

    update packages

commit 2a03064
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 18:00:58 2024 +0200

    fixes

commit aa961ce
Author: Slava Leleka <[email protected]>
Date:   Mon Sep 9 18:35:49 2024 +0300

    src/linter/helpers/css-generate.ts edited online with Bitbucket

commit 4082945
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 13:37:36 2024 +0200

    make message consistent

commit 3294981
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 12:25:08 2024 +0200

    add quotes to parsing error message

commit 2eccd9e
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 12:07:04 2024 +0200

    change parsing error message

commit 458aec7
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 10:51:23 2024 +0200

    rename fn

commit 0a0828c
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 10:48:48 2024 +0200

    enable decl validator

commit 23c741c
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 10:03:16 2024 +0200

    fix nits

commit db82770
Author: Slava Leleka <[email protected]>
Date:   Mon Sep 9 10:44:39 2024 +0300

    CHANGELOG.md edited online with Bitbucket

commit 11ffc40
Author: scripthunter7 <[email protected]>
Date:   Mon Sep 9 09:42:38 2024 +0200

    finalize

commit 593ca32
Author: scripthunter7 <[email protected]>
Date:   Fri Sep 6 19:11:06 2024 +0200

    update changelog

commit a02f4b4
Author: scripthunter7 <[email protected]>
Date:   Fri Sep 6 19:10:44 2024 +0200

    update readme

commit bea4753
Author: scripthunter7 <[email protected]>
Date:   Fri Sep 6 18:49:33 2024 +0200

    Update AGTree to v2
  • Loading branch information
scripthunter7 committed Sep 11, 2024
1 parent f6f1f80 commit 12b72d8
Show file tree
Hide file tree
Showing 36 changed files with 2,029 additions and 198 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,13 @@ module.exports = {
fixMixedExportsWithInlineTypeSpecifier: true,
},
],
'jsdoc/check-tag-names': [
'warn',
{
// Define additional tags
// https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-tag-names.md#definedtags
definedTags: ['note'],
},
],
},
};
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,33 @@ The format is based on [Keep a Changelog][keepachangelog], and this project adhe
[keepachangelog]: https://keepachangelog.com/en/1.0.0/
[semver]: https://semver.org/spec/v2.0.0.html

## [2.1.0] - 2024-09-11

### Added

- Various CSSTree utilities.
- [`@adguard/ecss-tree`][ecss-tree] library to work with CSS and Extended CSS syntax.
- `no-invalid-css-syntax` linter rule to check CSS syntax in `adblock` rules.
- `no-invalid-css-declaration` linter rule to check valid CSS declarations in `adblock` rules.

### Changed

- Since AGTree v2 no longer parses the full CSS syntax as AGTree v1 did,
we now use the [@adguard/ecss-tree][ecss-tree] library to maintain the same functionality.
Additionally, we provide a special layer for CSS handling in the linter core.
- More semantic parsing error messages.
- Changed module type to CJS.
- Updated [@adguard/agtree] to `v2.0.2` [#215]. From this major version, AGTree no longer parses all CSS syntax,
so we need to use a separate library for this purpose in the linter.

### Fixed

- Improved exports in `package.json`.

[#215]: https://github.com/AdguardTeam/AGLint/issues/215
[ecss-tree]: https://github.com/AdguardTeam/ecsstree
[2.1.0]: https://github.com/AdguardTeam/AGLint/compare/v2.0.10...v2.1.0

## [2.0.10] - 2024-09-04

### Added
Expand Down
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ Table of Contents:
- [`inconsistent-hint-platforms`](#inconsistent-hint-platforms)
- [`no-short-rules`](#no-short-rules)
- [`no-excluded-rules`](#no-excluded-rules)
- [`no-invalid-css-syntax`](#no-invalid-css-syntax)
- [`no-invalid-css-declaration`](#no-invalid-css-declaration)
- [Compatibility](#compatibility)
- [Use programmatically](#use-programmatically)
- [Development \& Contribution](#development--contribution)
Expand Down Expand Up @@ -834,6 +836,48 @@ Requested in https://github.com/AdguardTeam/AGLint/issues/214
- example\.com\/bad\/query\/
```

### `no-invalid-css-syntax`

Check if a rule contains syntactically invalid CSS.
It uses the [ECSSTree][ecss-tree] parser internally to check the CSS syntax.

- **Severity:** `error` (2)
- **Fixable:** no
- **Options:** none
- **Example:**
```adblock
##.#bar
```
will be reported as error:
```txt
1:4 error Cannot parse CSS due to the following error: Name is expected
```
since the `##.#bar` rule contains invalid CSS syntax, `.` should be followed by a valid class name.
Also works with CSS injection rules and their declaration lists.

[ecss-tree]: https://github.com/AdguardTeam/ecsstree

### `no-invalid-css-declaration`

Checks whether a CSS injection rule contains any unknown properties or invalid values.
This process utilizes the [CSSTree][css-tree] lexer, which is based on the [MDN Data][mdn-data] database.

- **Severity:** `error` (2)
- **Fixable:** no
- **Options:** none
- **Example:**
```adblock
#$#.foo { color: bar; }
```
will be reported as error:
```txt
1:17 error Invalid value for `color` property, mismatch with syntax <color>
```
since `bar` is not a valid color value.

[css-tree]: https://github.com/csstree/csstree
[mdn-data]: https://github.com/mdn/data/tree/main

## Compatibility

The linter is compatible with all modern browsers and Node.js versions. Minimum required versions are:
Expand Down
31 changes: 19 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adguard/aglint",
"version": "2.0.10",
"version": "2.1.0",
"description": "Universal adblock filter list linter.",
"keywords": [
"adblock",
Expand All @@ -20,18 +20,25 @@
"url": "https://github.com/AdguardTeam/AGLint/issues"
},
"homepage": "https://github.com/AdguardTeam/AGLint#readme",
"type": "module",
"main": "dist/aglint.cjs",
"module": "dist/aglint.esm.js",
"browser": "dist/aglint.umd.min.js",
"main": "dist/aglint.js",
"module": "dist/aglint.esm.mjs",
"types": "dist/aglint.d.ts",
"bin": "dist/aglint.cli.js",
"exports": {
".": {
"types": "./dist/aglint.d.ts",
"import": "./dist/aglint.esm.mjs",
"require": "./dist/aglint.js"
},
"./es": "./dist/aglint.esm.mjs",
"./iife": "./dist/aglint.iife.min.js",
"./umd": "./dist/aglint.umd.min.js"
},
"files": [
"dist",
"src"
"dist"
],
"engines": {
"node": ">=14"
"node": ">=17"
},
"scripts": {
"build": "yarn clean && yarn build-txt && yarn build-types && yarn rollup --config rollup.config.ts --configPlugin @rollup/plugin-json --configPlugin @rollup/plugin-typescript && yarn clean-types",
Expand All @@ -41,7 +48,7 @@
"clean": "rimraf dist",
"clean-types": "rimraf dist/types",
"coverage": "jest --coverage",
"lint": "yarn lint:ts && yarn lint:md",
"lint": "yarn check-types && yarn lint:ts && yarn lint:md",
"lint:md": "markdownlint .",
"lint:ts": "eslint . --cache --ext .ts",
"prepare": "node .husky/install.mjs",
Expand All @@ -51,11 +58,10 @@
"devDependencies": {
"@babel/core": "^7.22.5",
"@babel/preset-env": "^7.22.5",
"@rollup/plugin-alias": "^5.0.0",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^25.0.2",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.3",
"@rollup/plugin-typescript": "^11.1.1",
"@swc/core": "^1.3.74",
Expand Down Expand Up @@ -89,7 +95,8 @@
"typescript": "^4.9.5"
},
"dependencies": {
"@adguard/agtree": "^1.1.8",
"@adguard/agtree": "^2.0.2",
"@adguard/ecss-tree": "^1.1.0",
"@inquirer/checkbox": "^1.3.7",
"@inquirer/select": "^1.2.7",
"chalk": "4.1.2",
Expand Down
32 changes: 13 additions & 19 deletions rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import commonjs from '@rollup/plugin-commonjs';
import externals from 'rollup-plugin-node-externals';
import dtsPlugin from 'rollup-plugin-dts';
import nodePolyfills from 'rollup-plugin-polyfill-node';
import alias from '@rollup/plugin-alias';
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
import json from '@rollup/plugin-json';
import terser from '@rollup/plugin-terser';
Expand Down Expand Up @@ -72,32 +71,24 @@ const typeScriptPlugin = typescript({
const commonPlugins = [
json({ preferConst: true }),
commonjs({ sourceMap: false }),
resolve({ preferBuiltins: false }),
typeScriptPlugin,
];

// Plugins for Node.js builds
const nodePlugins = [
...commonPlugins,
resolve({ preferBuiltins: false }),
externals(),
];

// Plugins for browser builds
const browserPlugins = [
...commonPlugins,
nodePolyfills(),
// The build of CSSTree is a bit complicated (patches, require "emulation", etc.),
// so here we only specify the pre-built version by an alias
alias({
entries: [
{
find: '@adguard/ecss-tree',
replacement: path.join(
'node_modules/@adguard/ecss-tree/dist/ecsstree.umd.min.js',
),
},
],
resolve({
browser: true,
preferBuiltins: false,
}),
nodePolyfills(),
// Provide better browser compatibility with Babel
getBabelOutputPlugin({
presets: [
Expand Down Expand Up @@ -139,7 +130,7 @@ const cjs = {
input: path.join(ROOT_DIR, 'src', 'index.node.ts'),
output: [
{
file: path.join(distDirLocation, `${BASE_FILE_NAME}.cjs`),
file: path.join(distDirLocation, `${BASE_FILE_NAME}.js`),
format: 'cjs',
exports: 'auto',
sourcemap: false,
Expand All @@ -154,7 +145,10 @@ const cjs = {
[
'@babel/preset-env',
{
targets: 'node >= 14',
// at least Node.js 17
targets: {
node: '17',
},
},
],
],
Expand All @@ -169,7 +163,7 @@ const esm = {
input: path.join(ROOT_DIR, 'src', 'index.node.ts'),
output: [
{
file: path.join(distDirLocation, `${BASE_FILE_NAME}.esm.js`),
file: path.join(distDirLocation, `${BASE_FILE_NAME}.esm.mjs`),
format: 'esm',
sourcemap: false,
banner: BANNER,
Expand All @@ -192,11 +186,11 @@ const cli = {
output: [
{
file: path.join(distDirLocation, `${BASE_FILE_NAME}.cli.js`),
format: 'esm',
format: 'cjs',
sourcemap: false,
// Replace import './index.node' with './aglint.esm.js'
paths: {
[linterIndex]: path.join('./', `${BASE_FILE_NAME}.esm.js`),
[linterIndex]: path.join('./', `${BASE_FILE_NAME}.js`),
},
banner: `${SHEBANG}\n${BANNER}`,
},
Expand Down
54 changes: 52 additions & 2 deletions src/linter/common.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { type Struct } from 'superstruct';
import { type AdblockSyntax, type AnyRule, type Node } from '@adguard/agtree';
import {
type Value,
type AdblockSyntax,
type AnyRule,
type Node,
} from '@adguard/agtree';

import { type AnySeverity } from './severity';
import { type CssTreeParsingContext, type CssTreeParsingContextToNode } from './helpers/css-tree-types';

/**
* Represents any linter rule
Expand Down Expand Up @@ -146,6 +152,19 @@ export interface LinterConfig {
rules?: LinterRuleConfigObject;
}

/**
* Type definition for the linter rule context getter function.
*
* @param rawValueNode The raw value node.
* @param context The context, see {@link CssTreeParsingContext}.
*
* @returns The CSS node or `null` if the CSS could not be parsed.
*/
type CssNodeGetter = <T extends CssTreeParsingContext>(
rawValueNode: Value<string>,
context: T
) => CssTreeParsingContextToNode[T] | null;

/**
* Represents a linter context that is passed to the rules when their events are triggered
*/
Expand Down Expand Up @@ -189,6 +208,21 @@ export interface GenericRuleContext<StorageType = LinterRuleStorage<unknown>, Co
* @param problem - The problem to report
*/
report: (problem: LinterProblemReport) => void;

/**
* Returns the CSS node for the given raw value node and context.
*
* @param rawValueNode - The raw value node
* @param context - The context, see {@link CssTreeParsingContext}.
* For more information, please check https://github.com/csstree/csstree/blob/master/docs/parsing.md#context
*
* @returns The CSS node or `null` if the CSS could not be parsed
*
* @note When you call this function from a rule and it cannot parse the CSS,
* it will automatically report a problem to the linter and marks your linter rule as the source.
* Reported problem will have the same severity as the rule.
*/
getCssNode: CssNodeGetter;
}

/**
Expand Down Expand Up @@ -253,10 +287,26 @@ export interface LinterProblemReport {
message: string;

/**
* Node that caused the problem
* Node that caused the problem. If provided, the linter will use its offsets to determine the problem location.
*/
node?: Node;

/**
* Relative start offset to the start of the node that caused the problem.
* Useful when you do not want to mark the whole node as problematic.
*
* @note Only takes effect when `node` is provided.
*/
relativeNodeStartOffset?: number;

/**
* Relative start offset to the start of the node that caused the problem.
* Useful when you do not want to mark the whole node as problematic.
*
* @note Only takes effect when `node` is provided.
*/
relativeNodeEndOffset?: number;

/**
* The location of the problem
*/
Expand Down
2 changes: 2 additions & 0 deletions src/linter/config-presets/aglint-all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { type LinterConfig } from '../common';
const config: LinterConfig = {
syntax: [AdblockSyntax.Common],
rules: {
'no-invalid-css-syntax': 'error',
'no-invalid-css-declaration': 'error',
'duplicated-hint-platforms': 'error',
'duplicated-hints': 'error',
'duplicated-modifiers': 'error',
Expand Down
2 changes: 2 additions & 0 deletions src/linter/config-presets/aglint-recommended.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { type LinterConfig } from '../common';
const config: LinterConfig = {
syntax: [AdblockSyntax.Common],
rules: {
'no-invalid-css-syntax': 'error',
'no-invalid-css-declaration': 'error',
'duplicated-hint-platforms': 'error',
'duplicated-hints': 'error',
'duplicated-modifiers': 'error',
Expand Down
Loading

0 comments on commit 12b72d8

Please sign in to comment.