From 3d16884db56468688ae587e4edc19a4f15e3f981 Mon Sep 17 00:00:00 2001 From: Tomislav Jovanovic Date: Tue, 13 May 2025 23:17:04 +0000 Subject: [PATCH] Bug 1965726 - Fixup type issues raised from all modules being fully typed r=robwu Differential Revision: https://phabricator.services.mozilla.com/D248719 --- services/common/observers.sys.mjs | 18 +++---- services/crypto/modules/utils.sys.mjs | 9 ++-- .../components/extensions/Extension.sys.mjs | 5 +- .../extensions/ExtensionParent.sys.mjs | 1 + .../extensions/ExtensionPermissions.sys.mjs | 2 +- .../extensions/ExtensionSettingsStore.sys.mjs | 2 +- .../extensions/ExtensionStorage.sys.mjs | 8 +-- .../extensions/ExtensionStorageIDB.sys.mjs | 12 +++-- .../ExtensionStorageSyncKinto.sys.mjs | 1 + .../extensions/ProxyChannelFilter.sys.mjs | 2 +- .../extensions/WebNavigation.sys.mjs | 4 +- .../components/extensions/types/extensions.ts | 50 +++++++++++++++++-- .../components/extensions/types/globals.ts | 32 ------------ toolkit/modules/FinderHighlighter.sys.mjs | 10 ++-- toolkit/modules/FinderIterator.sys.mjs | 1 + toolkit/modules/IndexedDB.sys.mjs | 11 ++-- .../extensions/internal/XPIDatabase.sys.mjs | 6 +-- 17 files changed, 96 insertions(+), 78 deletions(-) delete mode 100644 toolkit/components/extensions/types/globals.ts diff --git a/services/common/observers.sys.mjs b/services/common/observers.sys.mjs index c79b2b1bf21d..5de4b76ca1a7 100644 --- a/services/common/observers.sys.mjs +++ b/services/common/observers.sys.mjs @@ -12,14 +12,14 @@ export var Observers = { /** * Register the given callback as an observer of the given topic. * - * @param topic {String} + * @param {string} topic * the topic to observe * - * @param callback {Object} + * @param {object} callback * the callback; an Object that implements nsIObserver or a Function * that gets called when the notification occurs * - * @param thisObject {Object} [optional] + * @param {object} [thisObject] * the object to use as |this| when calling a Function callback * * @returns the observer @@ -35,13 +35,13 @@ export var Observers = { /** * Unregister the given callback as an observer of the given topic. * - * @param topic {String} + * @param {string} topic * the topic being observed * - * @param callback {Object} + * @param {object} callback * the callback doing the observing * - * @param thisObject {Object} [optional] + * @param {object} [thisObject] * the object being used as |this| when calling a Function callback */ remove(topic, callback, thisObject) { @@ -64,13 +64,13 @@ export var Observers = { /** * Notify observers about something. * - * @param topic {String} + * @param {string} topic * the topic to notify observers about * - * @param subject {Object} [optional] + * @param {object} [subject] * some information about the topic; can be any JS object or primitive * - * @param data {String} [optional] [deprecated] + * @param {string} [data] [deprecated] * some more information about the topic; deprecated as the subject * is sufficient to pass all needed information to the JS observers * that this module targets; if you have multiple values to pass to diff --git a/services/crypto/modules/utils.sys.mjs b/services/crypto/modules/utils.sys.mjs index 3aa3db32d13a..24cd5047162e 100644 --- a/services/crypto/modules/utils.sys.mjs +++ b/services/crypto/modules/utils.sys.mjs @@ -134,11 +134,10 @@ export var CryptoUtils = { }, /** - * @param {String} alg Hash algorithm (common values are SHA-1 or SHA-256) - * @param {ArrayBuffer} key - * @param {ArrayBuffer} data - * @param {Number} len Desired output length in bytes. - * @returns {Uint8Array} + * @param {string} alg Hash algorithm (common values are SHA-1 or SHA-256) + * @param {BufferSource} key + * @param {BufferSource} data + * @returns {Promise} */ async hmac(alg, key, data) { const hmacKey = await crypto.subtle.importKey( diff --git a/toolkit/components/extensions/Extension.sys.mjs b/toolkit/components/extensions/Extension.sys.mjs index 22b105329a12..c045c0f1f7c7 100644 --- a/toolkit/components/extensions/Extension.sys.mjs +++ b/toolkit/components/extensions/Extension.sys.mjs @@ -3091,7 +3091,7 @@ export class ExtensionData { /** * @param {Array} dataPermissions An array of data collection permissions. * - * @returns {{msg: string, collectsTechnicalAndInteractionData: boolean, hasNone: boolean}} An + * @returns {{msg?: string, collectsTechnicalAndInteractionData?: boolean, hasNone: boolean}} An * object with information about data collection permissions for the UI. */ static _formatDataCollectionPermissions(dataPermissions, type) { @@ -3158,10 +3158,11 @@ export class ExtensionData { * @param {Array} permissions A list of optional data collection * permissions. * - * @returns {Record} A map of permission names to localized + * Returns an object mapping permission names to localized * strings representing the optional data collection permissions. */ static _formatOptionalDataCollectionPermissions(permissions) { + /** @type {Record} */ const optionalDataCollectionPermissions = {}; const odcKeys = []; diff --git a/toolkit/components/extensions/ExtensionParent.sys.mjs b/toolkit/components/extensions/ExtensionParent.sys.mjs index 77b07b2f2bb1..94b7c6898498 100644 --- a/toolkit/components/extensions/ExtensionParent.sys.mjs +++ b/toolkit/components/extensions/ExtensionParent.sys.mjs @@ -362,6 +362,7 @@ const ProxyMessenger = { async recvPortConnect(arg, { sender }) { if (arg.native) { + /** @type {ParentPort} */ let port = this.openNative(arg.name, sender).onConnect(arg.portId, this); port.senderChildId = sender.childId; port.native = true; diff --git a/toolkit/components/extensions/ExtensionPermissions.sys.mjs b/toolkit/components/extensions/ExtensionPermissions.sys.mjs index 544a15ff1935..6976341babb2 100644 --- a/toolkit/components/extensions/ExtensionPermissions.sys.mjs +++ b/toolkit/components/extensions/ExtensionPermissions.sys.mjs @@ -367,7 +367,7 @@ export var ExtensionPermissions = { * @typedef {object} Perms * @property {string[]} origins * @property {string[]} permissions - * @property {string[]} data_collection + * @property {string[]} [data_collection] * * @param {Perms} perms api permissions and origins to be added/removed. * @param {Perms} optional permissions and origins from the manifest. diff --git a/toolkit/components/extensions/ExtensionSettingsStore.sys.mjs b/toolkit/components/extensions/ExtensionSettingsStore.sys.mjs index 751b10bf5d80..926857646cb9 100644 --- a/toolkit/components/extensions/ExtensionSettingsStore.sys.mjs +++ b/toolkit/components/extensions/ExtensionSettingsStore.sys.mjs @@ -545,7 +545,7 @@ export var ExtensionSettingsStore = { * * @param {string} type The type of setting to be returned. * @param {string} key A string that uniquely identifies the setting. - * @param {string} id + * @param {string} [id] * The id of the extension for which the setting is being retrieved. * Defaults to undefined, in which case the top setting is returned. * diff --git a/toolkit/components/extensions/ExtensionStorage.sys.mjs b/toolkit/components/extensions/ExtensionStorage.sys.mjs index 1bbec7abd712..21cc21572b6f 100644 --- a/toolkit/components/extensions/ExtensionStorage.sys.mjs +++ b/toolkit/components/extensions/ExtensionStorage.sys.mjs @@ -92,8 +92,10 @@ function serialize(name, anonymizedName, value) { return value; } +/** @import {JSONFile} from "resource://gre/modules/JSONFile.sys.mjs" */ + export var ExtensionStorage = { - /** @type {Map>} */ + /** @type {Map>} */ jsonFilePromises: new Map(), listeners: new Map(), @@ -104,7 +106,7 @@ export var ExtensionStorage = { * * @param {string} extensionId * The ID of the extension for which to return a file. - * @returns {Promise>} + * @returns {Promise} */ async _readFile(extensionId) { await IOUtils.makeDirectory(this.getExtensionDir(extensionId)); @@ -128,7 +130,7 @@ export var ExtensionStorage = { * * @param {string} extensionId * The ID of the extension for which to return a file. - * @returns {Promise>} + * @returns {Promise} */ getFile(extensionId) { let promise = this.jsonFilePromises.get(extensionId); diff --git a/toolkit/components/extensions/ExtensionStorageIDB.sys.mjs b/toolkit/components/extensions/ExtensionStorageIDB.sys.mjs index 61b125f12137..e9eaa2c3b7a2 100644 --- a/toolkit/components/extensions/ExtensionStorageIDB.sys.mjs +++ b/toolkit/components/extensions/ExtensionStorageIDB.sys.mjs @@ -1,14 +1,12 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* eslint-disable mozilla/valid-lazy */ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; import { IndexedDB } from "resource://gre/modules/IndexedDB.sys.mjs"; -/** @type {Lazy} */ -const lazy = {}; - -ChromeUtils.defineESModuleGetters(lazy, { +const lazy = XPCOMUtils.declareLazy({ ExtensionStorage: "resource://gre/modules/ExtensionStorage.sys.mjs", ExtensionUtils: "resource://gre/modules/ExtensionUtils.sys.mjs", getTrimmedString: "resource://gre/modules/ExtensionTelemetry.sys.mjs", @@ -170,7 +168,11 @@ class ExtensionStorageLocalIDB extends IndexedDB { static openForPrincipal(storagePrincipal) { // The db is opened using an extension principal isolated in a reserved user context id. - return super.openForPrincipal(storagePrincipal, IDB_NAME, IDB_VERSION); + return /** @type {Promise} */ ( + super.openForPrincipal(storagePrincipal, IDB_NAME, { + version: IDB_VERSION, + }) + ); } async isEmpty() { diff --git a/toolkit/components/extensions/ExtensionStorageSyncKinto.sys.mjs b/toolkit/components/extensions/ExtensionStorageSyncKinto.sys.mjs index 29b71dcef50f..2d2b0e7eea8f 100644 --- a/toolkit/components/extensions/ExtensionStorageSyncKinto.sys.mjs +++ b/toolkit/components/extensions/ExtensionStorageSyncKinto.sys.mjs @@ -579,6 +579,7 @@ class CryptoCollection { */ async getKeyRing() { const cryptoKeyRecord = await this.getKeyRingRecord(); + /** @type {CollectionKeyManager & {uuid?}} */ const collectionKeys = new lazy.CollectionKeyManager(); if (cryptoKeyRecord.keys) { collectionKeys.setContents( diff --git a/toolkit/components/extensions/ProxyChannelFilter.sys.mjs b/toolkit/components/extensions/ProxyChannelFilter.sys.mjs index f943668cfc41..f7d58a95cee2 100644 --- a/toolkit/components/extensions/ProxyChannelFilter.sys.mjs +++ b/toolkit/components/extensions/ProxyChannelFilter.sys.mjs @@ -337,7 +337,7 @@ export class ProxyChannelFilter { let wrapper = ChannelWrapper.get(channel); let browserData = { tabId: -1, windowId: -1 }; - if (wrapper.browserElement) { + if (XULElement.isInstance(wrapper.browserElement)) { browserData = lazy.tabTracker.getBrowserData(wrapper.browserElement); } diff --git a/toolkit/components/extensions/WebNavigation.sys.mjs b/toolkit/components/extensions/WebNavigation.sys.mjs index be27edfd072b..b1be429d91c1 100644 --- a/toolkit/components/extensions/WebNavigation.sys.mjs +++ b/toolkit/components/extensions/WebNavigation.sys.mjs @@ -127,9 +127,9 @@ export var WebNavigationManager = { * The data for the autocompleted item. * @param {object} [acData.result] * The result information associated with the navigation action. - * @param {typeof lazy.UrlbarUtils.RESULT_TYPE} [acData.result.type] + * @param {Items} [acData.result.type] * The result type associated with the navigation action. - * @param {typeof lazy.UrlbarUtils.RESULT_SOURCE} [acData.result.source] + * @param {Items} [acData.result.source] * The result source associated with the navigation action. */ onURLBarUserStartNavigation(acData) { diff --git a/toolkit/components/extensions/types/extensions.ts b/toolkit/components/extensions/types/extensions.ts index 29e6fa68c44c..5e345aad5911 100644 --- a/toolkit/components/extensions/types/extensions.ts +++ b/toolkit/components/extensions/types/extensions.ts @@ -2,10 +2,11 @@ * Types specific to toolkit/extensions code. */ declare global { - type BaseContext = import("ExtensionCommon.sys.mjs").BaseContext; - type ExtensionChild = import("ExtensionChild.sys.mjs").ExtensionChild; - type Extension = import("Extension.sys.mjs").Extension; + type BaseContext = import("../ExtensionCommon.sys.mjs").BaseContext; + type ExtensionChild = import("../ExtensionChild.sys.mjs").ExtensionChild; + type Extension = import("../Extension.sys.mjs").Extension; type callback = (...any) => any; + type DOMWindow = Window; interface nsIDOMProcessChild { getActor(name: "ProcessConduits"): ProcessConduitsChild; @@ -33,3 +34,46 @@ import { ConduitAddress } from "ConduitsParent.sys.mjs"; type Conduit = PointConduit & { [s in `send${Items}`]: callback }; type Init = ConduitAddress & { send: Send }; + +type PreferencesNS = + typeof import("resource://gre/modules/Preferences.sys.mjs").Preferences; + +declare module "resource://gre/modules/Preferences.sys.mjs" { + class Preferences { + get: PreferencesNS["get"]; + } +} + +declare module "resource://testing-common/Assert.sys.mjs" { + namespace Assert { + var equal: Assert["equal"]; + var ok: Assert["ok"]; + } +} + +declare module "resource://gre/modules/addons/XPIDatabase.sys.mjs" { + interface AddonWrapper { + id: string; + version: string; + } +} + +declare module "resource://gre/modules/IndexedDB.sys.mjs" { + interface Cursor extends IDBCursor {} + + interface CursorWithValue { + value: IDBCursorWithValue["value"]; + } + + interface ObjectStore { + clear: IDBObjectStore["clear"]; + delete: IDBObjectStore["delete"]; + get: IDBObjectStore["get"]; + getKey: (...args: Parameters) => Promise; + put: IDBObjectStore["put"]; + } + + interface Transaction { + abort: IDBTransaction["abort"]; + } +} diff --git a/toolkit/components/extensions/types/globals.ts b/toolkit/components/extensions/types/globals.ts deleted file mode 100644 index 4b7aa8ee8de1..000000000000 --- a/toolkit/components/extensions/types/globals.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Exports for all modules redirected here by a catch-all rule in tsconfig.json. -export var AddonManager, - AddonManagerPrivate, - AddonSettings, - AddonWrapper, - AsyncShutdown, - ExtensionMenus, - ExtensionProcessScript, - ExtensionScriptingStore, - ExtensionUserScripts, - NetUtil, - E10SUtils, - LightweightThemeManager, - ServiceWorkerCleanUp, - GeckoViewConnection, - GeckoViewWebExtension, - IndexedDB, - JSONFile, - Log, - UrlbarUtils, - WebExtensionDescriptorActor; - -/** - * A stub type for the "class" from EventEmitter.sys.mjs. - * TODO: Convert EventEmitter.sys.mjs into a proper class. - */ -export declare class EventEmitter { - emit(event: string, ...args: any[]): void; - on(event: string, listener: callback): void; - once(event: string, listener: callback): Promise; - off(event: string, listener: callback): void; -} diff --git a/toolkit/modules/FinderHighlighter.sys.mjs b/toolkit/modules/FinderHighlighter.sys.mjs index 655792e49809..d7a8639f7789 100644 --- a/toolkit/modules/FinderHighlighter.sys.mjs +++ b/toolkit/modules/FinderHighlighter.sys.mjs @@ -249,11 +249,11 @@ FinderHighlighter.prototype = { * Toggle highlighting all occurrences of a word in a page. This method will * be called recursively for each (i)frame inside a page. * - * @param {Booolean} highlight Whether highlighting should be turned on - * @param {String} word Needle to search for and highlight when found - * @param {Boolean} linksOnly Only consider nodes that are links for the search - * @param {Boolean} drawOutline Whether found links should be outlined. - * @param {Boolean} useSubFrames Whether to iterate over subframes. + * @param {Booolean} highlight Whether highlighting should be turned on + * @param {String} [word] Needle to search for and highlight when found + * @param {Boolean} [linksOnly] Only consider nodes that are links for the search + * @param {Boolean} [drawOutline] Whether found links should be outlined. + * @param {Boolean} [useSubFrames] Whether to iterate over subframes. * @yield {Promise} that resolves once the operation has finished */ async highlight(highlight, word, linksOnly, drawOutline, useSubFrames) { diff --git a/toolkit/modules/FinderIterator.sys.mjs b/toolkit/modules/FinderIterator.sys.mjs index f09873bed8fb..12601b670ac8 100644 --- a/toolkit/modules/FinderIterator.sys.mjs +++ b/toolkit/modules/FinderIterator.sys.mjs @@ -62,6 +62,7 @@ export class FinderIterator { * The returned promise is resolved when 1) the limit is reached, 2) when all * the ranges have been found or 3) when `stop()` is called whilst iterating. * + * @param {object} options * @param {Number} [options.allowDistance] Allowed edit distance between the * current word and `options.word` * when the iterator is already running diff --git a/toolkit/modules/IndexedDB.sys.mjs b/toolkit/modules/IndexedDB.sys.mjs index 21c434f1fe63..776409b04fb6 100644 --- a/toolkit/modules/IndexedDB.sys.mjs +++ b/toolkit/modules/IndexedDB.sys.mjs @@ -116,7 +116,7 @@ function forwardMethods(cls, target, methods) { } } -class Cursor { +export class Cursor { constructor(cursorRequest, source) { this.cursorRequest = cursorRequest; this.source = source; @@ -166,7 +166,7 @@ defineCursorUpdateMethods(Cursor, [ forwardGetters(Cursor, "cursor", ["direction", "key", "primaryKey"]); wrapMethods(Cursor, "cursor", ["delete", "update"]); -class CursorWithValue extends Cursor {} +export class CursorWithValue extends Cursor {} forwardGetters(CursorWithValue, "cursor", ["value"]); @@ -212,7 +212,7 @@ forwardGetters(Index, "index", [ "unique", ]); -class ObjectStore extends Cursed { +export class ObjectStore extends Cursed { constructor(store) { super(store); @@ -232,7 +232,7 @@ wrapMethods(ObjectStore, "store", ["add", "clear", "delete", "put"]); forwardMethods(ObjectStore, "store", ["deleteIndex"]); -class Transaction { +export class Transaction { constructor(transaction) { this.transaction = transaction; @@ -339,6 +339,7 @@ export class IndexedDB { } constructor(db) { + /** @type {IDBDatabase} */ this.db = db; } @@ -347,7 +348,7 @@ export class IndexedDB { /** * Opens a transaction for the given object stores. * - * @param {Array} storeNames + * @param {string | string[]} storeNames * The names of the object stores for which to open a transaction. * @param {string} [mode = "readonly"] * The mode in which to open the transaction. diff --git a/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs b/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs index 56178693b917..31decf510676 100644 --- a/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs +++ b/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs @@ -249,8 +249,6 @@ let addonFor = wrapper => wrapperMap.get(wrapper); const EMPTY_ARRAY = Object.freeze([]); -let AddonWrapper; - /** * The AddonInternal is an internal only representation of add-ons. It * may have come from the database or an extension manifest. @@ -882,7 +880,7 @@ export class AddonInternal { * @param {AddonInternal} aAddon * The add-on object to wrap. */ -AddonWrapper = class { +export class AddonWrapper { constructor(aAddon) { wrapperMap.set(this, aAddon); } @@ -1525,7 +1523,7 @@ AddonWrapper = class { } return url; } -}; +} function chooseValue(aAddon, aObj, aProp) { let repositoryAddon = aAddon._repositoryAddon;