@freedomofpress/webcat 0.0.0-stage → 3.0.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.
Files changed (82) hide show
  1. package/Readme.md +45 -0
  2. package/data/block.json +101 -0
  3. package/data/list.json +80 -0
  4. package/dist/hooks/content.js +1 -0
  5. package/dist/lib/browser/chrome.d.ts +86 -0
  6. package/dist/lib/browser/chrome.js +138 -0
  7. package/dist/lib/browser/kvstore.d.ts +70 -0
  8. package/dist/lib/browser/kvstore.js +241 -0
  9. package/dist/lib/browser/permissions.d.ts +113 -0
  10. package/dist/lib/browser/permissions.js +182 -0
  11. package/dist/lib/browser/requests.d.ts +145 -0
  12. package/dist/lib/browser/requests.js +292 -0
  13. package/dist/lib/browser/scripting.d.ts +19 -0
  14. package/dist/lib/browser/scripting.js +92 -0
  15. package/dist/lib/browser/sync.d.ts +68 -0
  16. package/dist/lib/browser/sync.js +114 -0
  17. package/dist/lib/browser/utils.d.ts +5 -0
  18. package/dist/lib/browser/utils.js +11 -0
  19. package/dist/lib/config.d.ts +45 -0
  20. package/dist/lib/config.js +45 -0
  21. package/dist/lib/validator_set.d.ts +4 -0
  22. package/dist/lib/validator_set.js +20 -0
  23. package/dist/lib/webcat/cache.d.ts +200 -0
  24. package/dist/lib/webcat/cache.js +308 -0
  25. package/dist/lib/webcat/canonicalize.d.ts +1 -0
  26. package/dist/lib/webcat/canonicalize.js +58 -0
  27. package/dist/lib/webcat/db.d.ts +30 -0
  28. package/dist/lib/webcat/db.js +131 -0
  29. package/dist/lib/webcat/encoding.d.ts +8 -0
  30. package/dist/lib/webcat/encoding.js +57 -0
  31. package/dist/lib/webcat/handler.d.ts +26 -0
  32. package/dist/lib/webcat/handler.js +419 -0
  33. package/dist/lib/webcat/hookbuilder.d.ts +47 -0
  34. package/dist/lib/webcat/hookbuilder.js +170 -0
  35. package/dist/lib/webcat/interfaces/bundle.d.ts +46 -0
  36. package/dist/lib/webcat/interfaces/bundle.js +8 -0
  37. package/dist/lib/webcat/interfaces/database.d.ts +68 -0
  38. package/dist/lib/webcat/interfaces/database.js +1 -0
  39. package/dist/lib/webcat/interfaces/errors.d.ts +451 -0
  40. package/dist/lib/webcat/interfaces/errors.js +109 -0
  41. package/dist/lib/webcat/interfaces/log.d.ts +14 -0
  42. package/dist/lib/webcat/interfaces/log.js +10 -0
  43. package/dist/lib/webcat/interfaces/originstate.d.ts +40 -0
  44. package/dist/lib/webcat/interfaces/originstate.js +1 -0
  45. package/dist/lib/webcat/interfaces/requeststate.d.ts +10 -0
  46. package/dist/lib/webcat/interfaces/requeststate.js +1 -0
  47. package/dist/lib/webcat/logger.d.ts +64 -0
  48. package/dist/lib/webcat/logger.js +112 -0
  49. package/dist/lib/webcat/originstate.d.ts +45 -0
  50. package/dist/lib/webcat/originstate.js +302 -0
  51. package/dist/lib/webcat/parsers.d.ts +21 -0
  52. package/dist/lib/webcat/parsers.js +36 -0
  53. package/dist/lib/webcat/request.d.ts +11 -0
  54. package/dist/lib/webcat/request.js +78 -0
  55. package/dist/lib/webcat/resources.d.ts +3 -0
  56. package/dist/lib/webcat/resources.js +41 -0
  57. package/dist/lib/webcat/response.d.ts +39 -0
  58. package/dist/lib/webcat/response.js +394 -0
  59. package/dist/lib/webcat/ui.d.ts +70 -0
  60. package/dist/lib/webcat/ui.js +282 -0
  61. package/dist/lib/webcat/updater.d.ts +115 -0
  62. package/dist/lib/webcat/updater.js +296 -0
  63. package/dist/lib/webcat/utils.d.ts +8 -0
  64. package/dist/lib/webcat/utils.js +74 -0
  65. package/dist/lib/webcat/validators.d.ts +16 -0
  66. package/dist/lib/webcat/validators.js +457 -0
  67. package/dist/lib/webcat.d.ts +11 -0
  68. package/dist/lib/webcat.js +130 -0
  69. package/icons/dark/webcat-error.SVG +1 -0
  70. package/icons/dark/webcat-ok.SVG +1 -0
  71. package/icons/dark/webcat.SVG +1 -0
  72. package/icons/light/webcat-error.SVG +1 -0
  73. package/icons/light/webcat-ok.SVG +1 -0
  74. package/icons/light/webcat.SVG +1 -0
  75. package/package.json +72 -4
  76. package/pages/error.css +9 -0
  77. package/pages/error.html +70 -0
  78. package/pages/error.js +51 -0
  79. package/pages/popup.css +16 -0
  80. package/pages/popup.html +14 -0
  81. package/pages/popup.js +48 -0
  82. package/README.md +0 -3
@@ -0,0 +1,241 @@
1
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
2
+ var __typeError = (msg) => {
3
+ throw TypeError(msg);
4
+ };
5
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
6
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
7
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
8
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
9
+ var __using = (stack, value, async) => {
10
+ if (value != null) {
11
+ if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
12
+ var dispose, inner;
13
+ if (async) dispose = value[__knownSymbol("asyncDispose")];
14
+ if (dispose === void 0) {
15
+ dispose = value[__knownSymbol("dispose")];
16
+ if (async) inner = dispose;
17
+ }
18
+ if (typeof dispose !== "function") __typeError("Object not disposable");
19
+ if (inner) dispose = function() {
20
+ try {
21
+ inner.call(this);
22
+ } catch (e) {
23
+ return Promise.reject(e);
24
+ }
25
+ };
26
+ stack.push([async, dispose, value]);
27
+ } else if (async) {
28
+ stack.push([async]);
29
+ }
30
+ return value;
31
+ };
32
+ var __callDispose = (stack, error, hasError) => {
33
+ var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
34
+ return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
35
+ };
36
+ var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
37
+ var next = (it) => {
38
+ while (it = stack.pop()) {
39
+ try {
40
+ var result = it[1] && it[1].call(it[2]);
41
+ if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
42
+ } catch (e) {
43
+ fail(e);
44
+ }
45
+ }
46
+ if (hasError) throw error;
47
+ };
48
+ return next();
49
+ };
50
+ var _mutex, _namespace, _store;
51
+ import permissions from "./permissions.js";
52
+ import { Mutex } from "./sync.js";
53
+ var __create = Object.create;
54
+ var __defProp = Object.defineProperty;
55
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
56
+ var __knownSymbol2 = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
57
+ var __typeError2 = (msg) => {
58
+ throw TypeError(msg);
59
+ };
60
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
61
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
62
+ var __decoratorStart = (base) => [, , , __create(null)];
63
+ var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
64
+ var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError2("Function expected") : fn;
65
+ var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError2("Already initialized") : fns.push(__expectFn(fn || null)) });
66
+ var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol2("metadata"), array[3]);
67
+ var __runInitializers = (array, flags, self, value) => {
68
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) fns[i].call(self);
69
+ return value;
70
+ };
71
+ var __decorateElement = (array, flags, name, decorators, target, extra) => {
72
+ var it, done, ctx, k = flags & 7, p = false;
73
+ var j = 0;
74
+ var extraInitializers = array[j] || (array[j] = []);
75
+ var desc = k && (target = target.prototype, k < 5 && (k > 3 || !p) && __getOwnPropDesc(target, name));
76
+ __name(target, name);
77
+ for (var i = decorators.length - 1; i >= 0; i--) {
78
+ ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
79
+ it = (0, decorators[i])(target, ctx), done._ = 1;
80
+ __expectFn(it) && (target = it);
81
+ }
82
+ return __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
83
+ };
84
+ var _KVStore_decorators, _init;
85
+ _KVStore_decorators = [permissions.require("storage")];
86
+ class KVStore {
87
+ /**
88
+ * Reads a persisted value.
89
+ *
90
+ * @param key The key to read.
91
+ * @param area The name of the {@link browser.storage.StorageArea | storage area} to read from.
92
+ * @returns A Promise that resolves to the value read.
93
+ */
94
+ async get(key, area = "local") {
95
+ const item = await browser.storage[area].get(key);
96
+ return item[key];
97
+ }
98
+ /**
99
+ * Stores values.
100
+ *
101
+ * @param items An object consisting of one or more key/value pairs to store.
102
+ * @param area The name of the {@link browser.storage.StorageArea | storage area} to use.
103
+ */
104
+ async set(items, area = "local") {
105
+ return browser.storage[area].set(items);
106
+ }
107
+ /**
108
+ * Clears all values whose key matches the specified prefix.
109
+ *
110
+ * @param prefix The prefix to match against.
111
+ * @param area The name of the {@link browser.storage.StorageArea | storage area} to use.
112
+ */
113
+ async clear(prefix = "", area = "local") {
114
+ const keys = await this.getKeys(prefix, area);
115
+ return browser.storage[area].remove(keys);
116
+ }
117
+ /**
118
+ * Retrieves a list of stored keys matching the specified prefix.
119
+ *
120
+ * @param prefix The prefix to match against.
121
+ * @param area The name of the {@link browser.storage.StorageArea | storage area} to read from.
122
+ * @returns A Promise that resolves to an array of matching keys.
123
+ */
124
+ async getKeys(prefix = "", area = "local") {
125
+ let keys;
126
+ if (browser.storage[area]["getKeys"]) {
127
+ keys = await browser.storage[area].getKeys();
128
+ } else {
129
+ keys = Object.keys(await browser.storage[area].get(null));
130
+ }
131
+ return keys.filter((key) => key.startsWith(`${prefix}`));
132
+ }
133
+ /**
134
+ * Clears a single persisted value.
135
+ *
136
+ * @param key The key to clear.
137
+ * @param area The name of the {@link browser.storage.StorageArea | storage area} to use.
138
+ */
139
+ async remove(key, area = "local") {
140
+ return browser.storage[area].remove(key);
141
+ }
142
+ }
143
+ _init = __decoratorStart();
144
+ KVStore = __decorateElement(_init, 0, "KVStore", _KVStore_decorators, KVStore);
145
+ __runInitializers(_init, 1, KVStore);
146
+ const _NamespacedKVStore = class _NamespacedKVStore {
147
+ /**
148
+ * @param namespace The namespace prefix to use for this store.
149
+ * @param store A backing {@link KVStore} instance to use for persistence.
150
+ */
151
+ constructor(namespace, store = new KVStore()) {
152
+ __privateAdd(this, _mutex, new Mutex());
153
+ __privateAdd(this, _namespace);
154
+ __privateAdd(this, _store);
155
+ __privateSet(this, _namespace, namespace);
156
+ __privateSet(this, _store, store);
157
+ }
158
+ async get(key, area = "local") {
159
+ var _stack = [];
160
+ try {
161
+ const _lock = __using(_stack, await __privateGet(this, _mutex).acquire());
162
+ const namespacedKey = `${__privateGet(this, _namespace)}:${key}`;
163
+ return await __privateGet(this, _store).get(namespacedKey, area);
164
+ } catch (_) {
165
+ var _error = _, _hasError = true;
166
+ } finally {
167
+ __callDispose(_stack, _error, _hasError);
168
+ }
169
+ }
170
+ async set(items, area = "local") {
171
+ var _stack = [];
172
+ try {
173
+ const _lock = __using(_stack, await __privateGet(this, _mutex).acquire());
174
+ const namespacedItems = {};
175
+ for (const key in items) {
176
+ namespacedItems[`${__privateGet(this, _namespace)}:${key}`] = items[key];
177
+ }
178
+ return await __privateGet(this, _store).set(namespacedItems, area);
179
+ } catch (_) {
180
+ var _error = _, _hasError = true;
181
+ } finally {
182
+ __callDispose(_stack, _error, _hasError);
183
+ }
184
+ }
185
+ async clear(prefix = "", area = "local") {
186
+ var _stack = [];
187
+ try {
188
+ const _lock = __using(_stack, await __privateGet(this, _mutex).acquire());
189
+ return await __privateGet(this, _store).clear(`${__privateGet(this, _namespace)}:${prefix}`, area);
190
+ } catch (_) {
191
+ var _error = _, _hasError = true;
192
+ } finally {
193
+ __callDispose(_stack, _error, _hasError);
194
+ }
195
+ }
196
+ async getKeys(prefix = "", area = "local") {
197
+ var _stack = [];
198
+ try {
199
+ const _lock = __using(_stack, await __privateGet(this, _mutex).acquire());
200
+ const namespacedKeys = await __privateGet(this, _store).getKeys(
201
+ `${__privateGet(this, _namespace)}:${prefix}`,
202
+ area
203
+ );
204
+ return namespacedKeys.map(
205
+ (key) => key.substring(__privateGet(this, _namespace).length + 1)
206
+ );
207
+ } catch (_) {
208
+ var _error = _, _hasError = true;
209
+ } finally {
210
+ __callDispose(_stack, _error, _hasError);
211
+ }
212
+ }
213
+ async remove(key, area) {
214
+ var _stack = [];
215
+ try {
216
+ const _lock = __using(_stack, await __privateGet(this, _mutex).acquire());
217
+ const namespacedKey = `${__privateGet(this, _namespace)}:${key}`;
218
+ return await __privateGet(this, _store).remove(namespacedKey, area);
219
+ } catch (_) {
220
+ var _error = _, _hasError = true;
221
+ } finally {
222
+ __callDispose(_stack, _error, _hasError);
223
+ }
224
+ }
225
+ /**
226
+ * Creates a new subnamespace within this namespace.
227
+ *
228
+ * @param namespace A new namespace prefix to append to the existing prefix.
229
+ */
230
+ namespace(namespace) {
231
+ return new _NamespacedKVStore(namespace, this);
232
+ }
233
+ };
234
+ _mutex = new WeakMap();
235
+ _namespace = new WeakMap();
236
+ _store = new WeakMap();
237
+ let NamespacedKVStore = _NamespacedKVStore;
238
+ export {
239
+ KVStore,
240
+ NamespacedKVStore
241
+ };
@@ -0,0 +1,113 @@
1
+ /**
2
+ * The subject of a permission check. Typically a class or a method, but may
3
+ * also be a function or any object with a name property.
4
+ */
5
+ export interface Subject {
6
+ /** The name of the subject. */
7
+ name: string;
8
+ }
9
+ /**
10
+ * The `permissionerror` event. Notifies the consumer of a missing permission.
11
+ */
12
+ export declare class PermissionErrorEvent extends Event {
13
+ /**
14
+ * The subject of the missing permission passed to the decorator returned by
15
+ * {@link PermissionChecker.require}.
16
+ */
17
+ readonly subject: Subject;
18
+ /**
19
+ * The missing permission, as declared via {@link PermissionChecker.require}.
20
+ */
21
+ readonly permission: string;
22
+ /** @internal */
23
+ constructor(subject: Subject, permission: string);
24
+ }
25
+ /**
26
+ * The `permissionrestored` event. Notifies the consumer of a required
27
+ * permission gained by a subject.
28
+ */
29
+ export declare class PermissionRestoredEvent extends Event {
30
+ /** The subject that required the permission. */
31
+ readonly subject: Subject;
32
+ /**
33
+ * The required permission, as declared via
34
+ * {@link PermissionChecker.require}.
35
+ */
36
+ readonly permission: string;
37
+ /** @internal */
38
+ constructor(subject: Subject, permission: string);
39
+ }
40
+ export interface PermissionChecker {
41
+ /** @group Methods */
42
+ addEventListener: EventTarget["addEventListener"] & ((type: "permissionerror", callback: (event: PermissionErrorEvent) => void) => void) & ((type: "permissionrestored", callback: (event: PermissionRestoredEvent) => void) => void);
43
+ }
44
+ /**
45
+ * Checks extension permissions and triggers warnings for missing ones. For
46
+ * an example, {@link PermissionChecker.require}.
47
+ */
48
+ export declare class PermissionChecker extends EventTarget {
49
+ #private;
50
+ constructor();
51
+ /**
52
+ * Creates a decorator that checks for an extension permission. For a class
53
+ * or method that requires multiple permissions, use multiple decorators.
54
+ *
55
+ * Permissions are checked at declaration time, not at instantiation or call
56
+ * time. Permission checks are asynchronous, best-effort, and do not block
57
+ * any code from running.
58
+ *
59
+ * Permission warnings in the console may be suppressed by calling
60
+ * {@link PermissionErrorEvent.preventDefault}.
61
+ *
62
+ * @param permission The extension permission to require. May be either a
63
+ * {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#api_permissions | named permission}
64
+ * or a {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns | match pattern}
65
+ * for a {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions | host permission}.
66
+ * @returns
67
+ *
68
+ * @example
69
+ * import permissions from "@freedomofpress/webcat/browser/permissions";
70
+ *
71
+ * @permissions.require("webRequest")
72
+ * @permissions.require("webRequestBlocking")
73
+ * @permissions.require("https://example.com/*")
74
+ * class ExampleBlocker {
75
+ * ...
76
+ * }
77
+ */
78
+ require(permission: string): (subject: Subject) => void;
79
+ /**
80
+ * Reads the required permissions for a subject. If subject is omitted,
81
+ * reads the required permissions across all subjects.
82
+ *
83
+ * @param subject The subject of the permissions.
84
+ * @returns The set of permissions declared for the subject via
85
+ * {@link require}, or if no subject is given, permissions across all
86
+ * subjects.
87
+ */
88
+ getRequired(subject?: Subject): Set<string>;
89
+ /**
90
+ * Reads the missing permissions for a subject. If subject is omitted, reads
91
+ * the missing permissions across all subjects.
92
+ *
93
+ * @param subject The subject of the permissions.
94
+ * @returns The set of missing permissions required by the subject via
95
+ * {@link require}, or if no subject is given, missing permissions across
96
+ * all subjects.
97
+ */
98
+ getMissing(subject?: Subject): Set<string>;
99
+ /**
100
+ * Checks the permissions of a given subject.
101
+ *
102
+ * @param subject The subject of the permissions.
103
+ * @returns A Promise that resolves to true if the subject has all the
104
+ * permissions required.
105
+ */
106
+ check(subject: Subject): Promise<boolean>;
107
+ }
108
+ /**
109
+ * The default {@link PermissionChecker} instance. For an example, see
110
+ * {@link PermissionChecker.require}.
111
+ */
112
+ declare const _default: PermissionChecker;
113
+ export default _default;
@@ -0,0 +1,182 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
8
+ var _requirements, _missing, _PermissionChecker_instances, checkOne_fn, handleAdded_fn, handleRemoved_fn;
9
+ class PermissionErrorEvent extends Event {
10
+ /** @internal */
11
+ constructor(subject, permission) {
12
+ super("permissionerror", { cancelable: true });
13
+ this.subject = subject;
14
+ this.permission = permission;
15
+ }
16
+ }
17
+ class PermissionRestoredEvent extends Event {
18
+ /** @internal */
19
+ constructor(subject, permission) {
20
+ super("permissionrestored", { cancelable: true });
21
+ this.subject = subject;
22
+ this.permission = permission;
23
+ }
24
+ }
25
+ class PermissionChecker extends EventTarget {
26
+ constructor() {
27
+ super();
28
+ __privateAdd(this, _PermissionChecker_instances);
29
+ __privateAdd(this, _requirements, /* @__PURE__ */ new Map());
30
+ __privateAdd(this, _missing, /* @__PURE__ */ new Map());
31
+ browser.permissions.onAdded.addListener(__privateMethod(this, _PermissionChecker_instances, handleAdded_fn).bind(this));
32
+ browser.permissions.onRemoved.addListener(__privateMethod(this, _PermissionChecker_instances, handleRemoved_fn).bind(this));
33
+ }
34
+ /**
35
+ * Creates a decorator that checks for an extension permission. For a class
36
+ * or method that requires multiple permissions, use multiple decorators.
37
+ *
38
+ * Permissions are checked at declaration time, not at instantiation or call
39
+ * time. Permission checks are asynchronous, best-effort, and do not block
40
+ * any code from running.
41
+ *
42
+ * Permission warnings in the console may be suppressed by calling
43
+ * {@link PermissionErrorEvent.preventDefault}.
44
+ *
45
+ * @param permission The extension permission to require. May be either a
46
+ * {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#api_permissions | named permission}
47
+ * or a {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns | match pattern}
48
+ * for a {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions | host permission}.
49
+ * @returns
50
+ *
51
+ * @example
52
+ * import permissions from "@freedomofpress/webcat/browser/permissions";
53
+ *
54
+ * @permissions.require("webRequest")
55
+ * @permissions.require("webRequestBlocking")
56
+ * @permissions.require("https://example.com/*")
57
+ * class ExampleBlocker {
58
+ * ...
59
+ * }
60
+ */
61
+ require(permission) {
62
+ return (subject) => {
63
+ let requirements = __privateGet(this, _requirements).get(subject);
64
+ if (!requirements) {
65
+ requirements = /* @__PURE__ */ new Set();
66
+ __privateGet(this, _requirements).set(subject, requirements);
67
+ }
68
+ requirements.add(permission);
69
+ __privateMethod(this, _PermissionChecker_instances, checkOne_fn).call(this, subject, permission);
70
+ };
71
+ }
72
+ /**
73
+ * Reads the required permissions for a subject. If subject is omitted,
74
+ * reads the required permissions across all subjects.
75
+ *
76
+ * @param subject The subject of the permissions.
77
+ * @returns The set of permissions declared for the subject via
78
+ * {@link require}, or if no subject is given, permissions across all
79
+ * subjects.
80
+ */
81
+ getRequired(subject) {
82
+ if (subject) {
83
+ return new Set(__privateGet(this, _requirements).get(subject));
84
+ }
85
+ return __privateGet(this, _requirements).values().reduce((all, permissions2) => {
86
+ return all.union(permissions2);
87
+ }, /* @__PURE__ */ new Set());
88
+ }
89
+ /**
90
+ * Reads the missing permissions for a subject. If subject is omitted, reads
91
+ * the missing permissions across all subjects.
92
+ *
93
+ * @param subject The subject of the permissions.
94
+ * @returns The set of missing permissions required by the subject via
95
+ * {@link require}, or if no subject is given, missing permissions across
96
+ * all subjects.
97
+ */
98
+ getMissing(subject) {
99
+ if (subject) {
100
+ return new Set(__privateGet(this, _missing).get(subject));
101
+ }
102
+ return __privateGet(this, _missing).values().reduce((all, missing) => {
103
+ return all.union(missing);
104
+ }, /* @__PURE__ */ new Set());
105
+ }
106
+ /**
107
+ * Checks the permissions of a given subject.
108
+ *
109
+ * @param subject The subject of the permissions.
110
+ * @returns A Promise that resolves to true if the subject has all the
111
+ * permissions required.
112
+ */
113
+ async check(subject) {
114
+ const requirements = __privateGet(this, _requirements).get(subject) ?? /* @__PURE__ */ new Set();
115
+ const checks = Array.from(requirements).map(
116
+ (r) => __privateMethod(this, _PermissionChecker_instances, checkOne_fn).call(this, subject, r)
117
+ );
118
+ const results = await Promise.all(checks);
119
+ return results.every((ok) => ok);
120
+ }
121
+ }
122
+ _requirements = new WeakMap();
123
+ _missing = new WeakMap();
124
+ _PermissionChecker_instances = new WeakSet();
125
+ checkOne_fn = async function(subject, permission) {
126
+ const permissions2 = new Array();
127
+ const origins = new Array();
128
+ if (permission.includes("://") || permission === "<all_urls>") {
129
+ origins.push(permission);
130
+ } else {
131
+ permissions2.push(permission);
132
+ }
133
+ return browser.permissions.contains({ permissions: permissions2, origins }).then((ok) => {
134
+ if (ok) {
135
+ const missing = __privateGet(this, _missing).get(subject);
136
+ if (missing) {
137
+ if (missing.delete(permission)) {
138
+ const event = new PermissionRestoredEvent(subject, permission);
139
+ this.dispatchEvent(event);
140
+ }
141
+ }
142
+ } else {
143
+ let missing = __privateGet(this, _missing).get(subject);
144
+ if (!missing) {
145
+ missing = /* @__PURE__ */ new Set();
146
+ __privateGet(this, _missing).set(subject, missing);
147
+ }
148
+ if (!missing.has(permission)) {
149
+ missing.add(permission);
150
+ const event = new PermissionErrorEvent(subject, permission);
151
+ this.dispatchEvent(event);
152
+ if (!event.defaultPrevented) {
153
+ console.warn(
154
+ "Extension permission requirements not fulfilled for %s. The '%s' permission is required.",
155
+ subject.name,
156
+ permission
157
+ );
158
+ }
159
+ }
160
+ }
161
+ return ok;
162
+ });
163
+ };
164
+ handleAdded_fn = function() {
165
+ for (const [subject, set] of __privateGet(this, _missing)) {
166
+ if (set.size > 0) {
167
+ this.check(subject);
168
+ }
169
+ }
170
+ };
171
+ handleRemoved_fn = function() {
172
+ for (const [subject, _] of __privateGet(this, _requirements)) {
173
+ this.check(subject);
174
+ }
175
+ };
176
+ const permissions = new PermissionChecker();
177
+ export {
178
+ PermissionChecker,
179
+ PermissionErrorEvent,
180
+ PermissionRestoredEvent,
181
+ permissions as default
182
+ };
@@ -0,0 +1,145 @@
1
+ /** @internal */
2
+ export declare class RequestDetailsBase {
3
+ #private;
4
+ /**
5
+ * Resolved when the request completes or rejected if a network error occurs.
6
+ */
7
+ readonly completed: Promise<void>;
8
+ constructor();
9
+ /** @internal */
10
+ complete(): void;
11
+ /** @internal */
12
+ fail(): void;
13
+ }
14
+ /** @interface */
15
+ export type BeforeRequestDetails = RequestDetailsBase & browser.webRequest._OnBeforeRequestDetails;
16
+ /** @interface */
17
+ export type BeforeHeadersDetails = BeforeRequestDetails & browser.webRequest._OnBeforeSendHeadersDetails;
18
+ /** @interface */
19
+ export type HeadersReceivedDetails = BeforeHeadersDetails & browser.webRequest._OnHeadersReceivedDetails;
20
+ /** @interface */
21
+ export type ErrorOccurredDetails = BeforeRequestDetails & browser.webRequest._OnErrorOccurredDetails;
22
+ /** @interface */
23
+ export type CompletedDetails = HeadersReceivedDetails & browser.webRequest._OnCompletedDetails;
24
+ export type RequestDetails = BeforeHeadersDetails | BeforeHeadersDetails | HeadersReceivedDetails | ErrorOccurredDetails | CompletedDetails;
25
+ declare const dispose: typeof Symbol.dispose;
26
+ /**
27
+ * The response of a single listener to a blocking {@link RequestEvent},
28
+ * created with {@link RequestEvent.createBlockingResponse}. Implements the
29
+ * {@link Disposable} interface. A new BlockingResponse cancels the request;
30
+ * a listener signals successful completion by setting {@link cancel} to
31
+ * false, either by assigning to it directly or with the {@link set} method.
32
+ * A listener must create it with a
33
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/using using declaration}
34
+ * before its first await expression; the response is reported on disposal.
35
+ *
36
+ * @example
37
+ * handler.addEventListener("beforeheaders", async (event) => {
38
+ * using blockingResponse = event.createBlockingResponse();
39
+ * await doSomething(event.details);
40
+ * blockingResponse.cancel = false;
41
+ * });
42
+ */
43
+ export declare class BlockingResponse implements browser.webRequest.BlockingResponse, Disposable {
44
+ #private;
45
+ /**
46
+ * Whether to cancel the request. Defaults to true, so that a listener that
47
+ * throws, or never completes its checks, cancels the request. Set to false
48
+ * to signal successful completion.
49
+ */
50
+ cancel: boolean | undefined;
51
+ redirectUrl?: string | undefined;
52
+ upgradeToSecure?: boolean | undefined;
53
+ requestHeaders?: browser.webRequest.HttpHeaders | undefined;
54
+ responseHeaders?: browser.webRequest.HttpHeaders | undefined;
55
+ authCredentials?: browser.webRequest._BlockingResponseAuthCredentials | undefined;
56
+ constructor(details?: RequestDetails);
57
+ /**
58
+ * Implements the {@link Disposable} interface.
59
+ */
60
+ [dispose](): void;
61
+ /**
62
+ * @returns A Promise that resolves to this BlockingResponse after disposal.
63
+ */
64
+ ready(): Promise<BlockingResponse>;
65
+ /**
66
+ * @param value An object whose properties are copied to this BlockingResponse.
67
+ */
68
+ set(value: browser.webRequest.BlockingResponse): void;
69
+ /**
70
+ * Sets the response header `name` to `value`, replacing any existing
71
+ * occurrences. Starts from the response's original headers, so the rest
72
+ * pass through unchanged.
73
+ */
74
+ setHeader(name: string, value: string): void;
75
+ }
76
+ /**
77
+ * Event type for events dispatched by RequestHandlers.
78
+ */
79
+ export declare class RequestEvent<T extends RequestDetails> extends Event {
80
+ #private;
81
+ /**
82
+ * Details of the request this event concerns.
83
+ */
84
+ readonly details: T;
85
+ /** @internal */
86
+ constructor(type: string, details: T);
87
+ /**
88
+ * Creates a {@link BlockingResponse} for this event. Each listener creates
89
+ * its own before its first await expression, so that listeners respond
90
+ * independently of each other; see {@link ready} for how the responses are
91
+ * combined.
92
+ *
93
+ * @returns A new BlockingResponse that cancels the request unless the
94
+ * listener sets {@link BlockingResponse.cancel} to false.
95
+ */
96
+ createBlockingResponse(): BlockingResponse;
97
+ /**
98
+ * Awaits all BlockingResponses created for this event and merges them into
99
+ * a single response. If any of them cancels the request, so does the
100
+ * result; otherwise, their other properties are combined. With no
101
+ * BlockingResponses, the request proceeds unchanged.
102
+ *
103
+ * @returns A Promise that resolves to the merged response.
104
+ * @internal
105
+ */
106
+ ready(): Promise<browser.webRequest.BlockingResponse>;
107
+ }
108
+ export interface RequestHandler extends EventTarget {
109
+ /** @group Methods */
110
+ addEventListener: EventTarget["addEventListener"] & ((type: "beforerequest", callback: (event: RequestEvent<BeforeRequestDetails>) => void) => void) & ((type: "beforeheaders", callback: (event: RequestEvent<BeforeHeadersDetails>) => void) => void) & ((type: "headersreceived", callback: (event: RequestEvent<HeadersReceivedDetails>) => void) => void) & ((type: "erroroccurred", callback: (event: RequestEvent<ErrorOccurredDetails>) => void) => void) & ((type: "completed", callback: (event: RequestEvent<CompletedDetails>) => void) => void);
111
+ }
112
+ /**
113
+ * Handles web requests and responses for specific FQDNs. Manages the entire
114
+ * lifecycle of a request and aggregates details such as request headers and
115
+ * response headers to make them available in later stages.
116
+ */
117
+ export declare class RequestHandler extends EventTarget {
118
+ #private;
119
+ /**
120
+ * Binds the handler to the given list of FQDNs. When called, the handler
121
+ * starts handling requests for the FQDNs in the list and stops handling
122
+ * requests for any previously bound FQDNs that are not in the new list.
123
+ *
124
+ * @param fqdns A list of fully-qualified domain names to bind to.
125
+ */
126
+ bind(fqdns: string[]): void;
127
+ /** @internal */
128
+ protected getListenerOptions(fqdns: string[], type: "beforerequest"): [browser.webRequest.RequestFilter, browser.webRequest.OnBeforeRequestOptions[]];
129
+ /** @internal */
130
+ protected getListenerOptions(fqdns: string[], type: "beforeheaders"): [browser.webRequest.RequestFilter, browser.webRequest.OnBeforeSendHeadersOptions[]];
131
+ /** @internal */
132
+ protected getListenerOptions(fqdns: string[], type: "headersreceived"): [browser.webRequest.RequestFilter, browser.webRequest.OnHeadersReceivedOptions[]];
133
+ /** @internal */
134
+ protected getListenerOptions(fqdns: string[], type: "erroroccurred" | "completed"): [browser.webRequest.RequestFilter];
135
+ /**
136
+ * Returns a tuple consisting of a request filter and an optional options
137
+ * array, used when registering webRequest listeners. Overriding this method
138
+ * allows changing the registration behavior.
139
+ *
140
+ * @param fqdns Fully-qualified domain names to handle requests for.
141
+ * @param type The type of event to handle.
142
+ */
143
+ protected getListenerOptions(fqdns: string[], type: string): [browser.webRequest.RequestFilter] | [browser.webRequest.RequestFilter, (browser.webRequest.OnBeforeRequestOptions[] | browser.webRequest.OnBeforeSendHeadersOptions[] | browser.webRequest.OnHeadersReceivedOptions[])];
144
+ }
145
+ export {};