webext-patterns 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +4 -0
- package/index.js +47 -13
- package/package.json +14 -10
- package/readme.md +60 -4
package/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export declare const patternValidationRegex: RegExp;
|
|
2
2
|
export declare const allStarsRegex: RegExp;
|
|
3
3
|
export declare const allUrlsRegex: RegExp;
|
|
4
|
+
export declare function assertValidPattern(matchPattern: string): void;
|
|
5
|
+
export declare function isValidPattern(matchPattern: string): boolean;
|
|
6
|
+
export declare function doesUrlMatchPatterns(url: string, ...matchPattern: string[]): boolean;
|
|
4
7
|
export declare function patternToRegex(...matchPatterns: readonly string[]): RegExp;
|
|
5
8
|
export declare function globToRegex(...globs: readonly string[]): RegExp;
|
|
9
|
+
export declare function excludeDuplicatePatterns(matchPatterns: readonly string[]): string[];
|
package/index.js
CHANGED
|
@@ -1,28 +1,53 @@
|
|
|
1
1
|
import escapeStringRegexp from 'escape-string-regexp';
|
|
2
2
|
// Copied from https://github.com/mozilla/gecko-dev/blob/073cc24f53d0cf31403121d768812146e597cc9d/toolkit/components/extensions/schemas/manifest.json#L487-L491
|
|
3
3
|
export const patternValidationRegex = /^(https?|wss?|file|ftp|\*):\/\/(\*|\*\.[^*/]+|[^*/]+)\/.*$|^file:\/\/\/.*$|^resource:\/\/(\*|\*\.[^*/]+|[^*/]+)\/.*$|^about:/;
|
|
4
|
-
const isFirefox =
|
|
4
|
+
const isFirefox = globalThis.navigator?.userAgent.includes('Firefox/');
|
|
5
5
|
export const allStarsRegex = isFirefox
|
|
6
6
|
? /^(https?|wss?):[/][/][^/]+([/].*)?$/
|
|
7
7
|
: /^https?:[/][/][^/]+([/].*)?$/;
|
|
8
8
|
export const allUrlsRegex = /^(https?|file|ftp):[/]+/;
|
|
9
|
-
function
|
|
10
|
-
if (!
|
|
9
|
+
export function assertValidPattern(matchPattern) {
|
|
10
|
+
if (!isValidPattern(matchPattern)) {
|
|
11
11
|
throw new Error(matchPattern + ' is an invalid pattern, it must match ' + String(patternValidationRegex));
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
}
|
|
14
|
+
export function isValidPattern(matchPattern) {
|
|
15
|
+
return matchPattern === '<all_urls>' || patternValidationRegex.test(matchPattern);
|
|
16
|
+
}
|
|
17
|
+
export function doesUrlMatchPatterns(url, ...matchPattern) {
|
|
18
|
+
if (matchPattern.includes('<all_urls>') && allUrlsRegex.test(url)) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
if (matchPattern.includes('*://*/*') && allStarsRegex.test(url)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
for (const pattern of matchPattern) {
|
|
25
|
+
if (patternToRegex(pattern).test(url)) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
function getRawPatternRegex(matchPattern) {
|
|
32
|
+
assertValidPattern(matchPattern);
|
|
33
|
+
// Host undefined for file:///
|
|
34
|
+
let [, protocol, host = '', pathname] = matchPattern.split(/(^[^:]+:[/][/])([^/]+)?/);
|
|
14
35
|
protocol = protocol
|
|
15
36
|
.replace('*', isFirefox ? '(https?|wss?)' : 'https?') // Protocol wildcard
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
37
|
+
.replaceAll(/[/]/g, '[/]'); // Escape slashes
|
|
38
|
+
if (host === '*') {
|
|
39
|
+
host = '[^/]+';
|
|
40
|
+
}
|
|
41
|
+
else if (host) {
|
|
42
|
+
host = host
|
|
43
|
+
.replace(/^[*][.]/, '([^/]+.)*') // Initial wildcard
|
|
44
|
+
.replaceAll(/[.]/g, '[.]') // Escape dots
|
|
45
|
+
.replace(/[*]$/, '[^.]+'); // Last wildcard
|
|
46
|
+
}
|
|
22
47
|
pathname = pathname
|
|
23
|
-
.
|
|
24
|
-
.
|
|
25
|
-
.
|
|
48
|
+
.replaceAll(/[/]/g, '[/]') // Escape slashes
|
|
49
|
+
.replaceAll(/[.]/g, '[.]') // Escape dots
|
|
50
|
+
.replaceAll(/[*]/g, '.*'); // Any wildcard
|
|
26
51
|
return '^' + protocol + host + '(' + pathname + ')?$';
|
|
27
52
|
}
|
|
28
53
|
export function patternToRegex(...matchPatterns) {
|
|
@@ -74,3 +99,12 @@ export function globToRegex(...globs) {
|
|
|
74
99
|
}
|
|
75
100
|
return new RegExp(globs.map(x => getRawGlobRegex(x)).join('|'));
|
|
76
101
|
}
|
|
102
|
+
export function excludeDuplicatePatterns(matchPatterns) {
|
|
103
|
+
if (matchPatterns.includes('<all_urls>')) {
|
|
104
|
+
return ['<all_urls>'];
|
|
105
|
+
}
|
|
106
|
+
if (matchPatterns.includes('*://*/*')) {
|
|
107
|
+
return ['*://*/*'];
|
|
108
|
+
}
|
|
109
|
+
return matchPatterns.filter(possibleSubset => !matchPatterns.some(possibleSuperset => possibleSubset !== possibleSuperset && patternToRegex(possibleSuperset).test(possibleSubset)));
|
|
110
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webext-patterns",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Tool to convert the patterns and globs of your WebExtension manifest to regex",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"browser",
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
"webext"
|
|
18
18
|
],
|
|
19
19
|
"repository": "fregante/webext-patterns",
|
|
20
|
+
"funding": "https://github.com/sponsors/fregante",
|
|
20
21
|
"license": "MIT",
|
|
21
22
|
"author": "Federico Brigante <me@fregante.com> (https://fregante.com)",
|
|
22
23
|
"type": "module",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
24
|
+
"exports": "./index.js",
|
|
25
|
+
"types": "./index.d.ts",
|
|
25
26
|
"files": [
|
|
26
27
|
"index.js",
|
|
27
28
|
"index.d.ts"
|
|
@@ -47,13 +48,16 @@
|
|
|
47
48
|
"escape-string-regexp": "^5.0.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@sindresorhus/tsconfig": "^
|
|
51
|
-
"@types/chrome": "0.0.
|
|
52
|
-
"ava": "^
|
|
53
|
-
"sinon": "^
|
|
54
|
-
"type-fest": "^
|
|
55
|
-
"typescript": "^
|
|
56
|
-
"xo": "^0.
|
|
51
|
+
"@sindresorhus/tsconfig": "^5.0.0",
|
|
52
|
+
"@types/chrome": "0.0.256",
|
|
53
|
+
"ava": "^6.0.1",
|
|
54
|
+
"sinon": "^17.0.1",
|
|
55
|
+
"type-fest": "^4.9.0",
|
|
56
|
+
"typescript": "^5.3.3",
|
|
57
|
+
"xo": "^0.56.0"
|
|
58
|
+
},
|
|
59
|
+
"engines": {
|
|
60
|
+
"node": ">=18"
|
|
57
61
|
},
|
|
58
62
|
"webExt": {
|
|
59
63
|
"sourceDir": "demo-extension",
|
package/readme.md
CHANGED
|
@@ -19,22 +19,38 @@ npm install webext-patterns
|
|
|
19
19
|
|
|
20
20
|
```js
|
|
21
21
|
// This module is only offered as a ES Module
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
patternToRegex,
|
|
24
|
+
globToRegex,
|
|
25
|
+
excludeDuplicatePatterns
|
|
26
|
+
doesUrlMatchPatterns,
|
|
27
|
+
assertValidPattern,
|
|
28
|
+
isValidPattern,
|
|
29
|
+
} from 'webext-patterns';
|
|
23
30
|
```
|
|
24
31
|
|
|
25
32
|
## Usage
|
|
26
33
|
|
|
27
|
-
> **Note**
|
|
28
|
-
> Firefox and Chrome handle globs very slighly differently. `webext-patterns` defaults to Chrome’s logic, but if it detects a Firefox userAgent it will produce a Firefox-compatible regex.
|
|
29
|
-
|
|
30
34
|
```js
|
|
31
35
|
patternToRegex('http://*/*');
|
|
32
36
|
// Returns /^http:[/][/][^/]+[/].+$/
|
|
33
37
|
|
|
34
38
|
globToRegex('*.example.com');
|
|
35
39
|
// Returns /\.example\.com$/
|
|
40
|
+
|
|
41
|
+
excludeDuplicatePatterns(['https://*.google.com/*', 'https://google.com/*']);
|
|
42
|
+
// Returns ['https://*.google.com/*']
|
|
43
|
+
|
|
44
|
+
assertValidPattern('https://google.*/*');
|
|
45
|
+
// Throws an error because the pattern is invalid
|
|
46
|
+
|
|
47
|
+
isValidPattern('https://*.google.com/*');
|
|
48
|
+
// Returns true
|
|
36
49
|
```
|
|
37
50
|
|
|
51
|
+
> **Note**
|
|
52
|
+
> Firefox and Chrome handle patterns very slighly differently. `webext-patterns` defaults to Chrome’s logic, but if it detects a Firefox userAgent it will produce a Firefox-compatible regex.
|
|
53
|
+
|
|
38
54
|
## API
|
|
39
55
|
|
|
40
56
|
#### patternToRegex(pattern1, pattern2, etc)
|
|
@@ -84,6 +100,46 @@ googleRegex.test('https://google.it/search'); // -> true
|
|
|
84
100
|
googleRegex.test('https://google.de/search'); // -> false
|
|
85
101
|
```
|
|
86
102
|
|
|
103
|
+
#### excludeDuplicatePatterns([pattern1, pattern2, etc])
|
|
104
|
+
|
|
105
|
+
Accepts an array of patterns and returns a filtered array without the patterns that are already covered by others. For example `"https://*/*"` already covers all "https" URLs, so having `"https://google.com/*"` in the array won't make any difference and therefore it's dropped.
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
excludeDuplicatePatterns([
|
|
109
|
+
"https://*/*",
|
|
110
|
+
"https://google.com/*",
|
|
111
|
+
"https://*.example.com/*",
|
|
112
|
+
]);
|
|
113
|
+
// Returns ["https://*/*"]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### doesUrlMatchPatterns(url, ...patterns)
|
|
117
|
+
|
|
118
|
+
Accepts a URL and any number of patterns and returns `true` if the URL matches any of the patterns. This is a convenience method that wraps `patternToRegex` for single use. If you plan on testing multiple URLs to the same pattern, it's better to convert the patterns to a regex once and reuse that.
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
doesUrlMatchPatterns('https://google.com/', ['https://*.google.com/*', '*://example.com/*']);
|
|
122
|
+
// Returns true
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### assertValidPattern(pattern)
|
|
126
|
+
|
|
127
|
+
Accepts a pattern and throws an error if it's invalid.
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
assertValidPattern('https://google.*/*');
|
|
131
|
+
// Throws an error because the pattern is invalid
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### isValidPattern(pattern)
|
|
135
|
+
|
|
136
|
+
Accepts a pattern and returns `true` if it's valid.
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
isValidPattern('https://google.*/*');
|
|
140
|
+
// Returns false
|
|
141
|
+
```
|
|
142
|
+
|
|
87
143
|
## Related
|
|
88
144
|
|
|
89
145
|
### Permissions
|