From 8424779906ae33222764db9ed837f55115143e71 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Mon, 15 Aug 2022 10:09:33 +0200 Subject: [PATCH] refactor: don't expose deprecate as an internal module (#35311) --- filenames.auto.gni | 5 +- lib/browser/api/app.ts | 3 +- lib/browser/api/crash-reporter.ts | 3 +- lib/browser/api/web-contents.ts | 3 +- lib/common/api/deprecate.ts | 135 ----------------- lib/common/api/module-list.ts | 4 +- lib/common/define-properties.ts | 2 +- lib/common/deprecate.ts | 139 ++++++++++++++++++ lib/sandboxed_renderer/api/module-list.ts | 6 - ...pi-deprecate-spec.ts => deprecate-spec.ts} | 2 +- typings/internal-electron.d.ts | 21 --- 11 files changed, 149 insertions(+), 174 deletions(-) delete mode 100644 lib/common/api/deprecate.ts create mode 100644 lib/common/deprecate.ts rename spec-main/{api-deprecate-spec.ts => deprecate-spec.ts} (98%) diff --git a/filenames.auto.gni b/filenames.auto.gni index 6cbf6be5d0..df8837bcf3 100644 --- a/filenames.auto.gni +++ b/filenames.auto.gni @@ -136,7 +136,6 @@ auto_filenames = { ] sandbox_bundle_deps = [ - "lib/common/api/deprecate.ts", "lib/common/api/native-image.ts", "lib/common/define-properties.ts", "lib/common/ipc-messages.ts", @@ -238,11 +237,11 @@ auto_filenames = { "lib/browser/rpc-server.ts", "lib/browser/web-view-events.ts", "lib/common/api/clipboard.ts", - "lib/common/api/deprecate.ts", "lib/common/api/module-list.ts", "lib/common/api/native-image.ts", "lib/common/api/shell.ts", "lib/common/define-properties.ts", + "lib/common/deprecate.ts", "lib/common/init.ts", "lib/common/ipc-messages.ts", "lib/common/reset-search-paths.ts", @@ -259,7 +258,6 @@ auto_filenames = { renderer_bundle_deps = [ "lib/common/api/clipboard.ts", - "lib/common/api/deprecate.ts", "lib/common/api/module-list.ts", "lib/common/api/native-image.ts", "lib/common/api/shell.ts", @@ -298,7 +296,6 @@ auto_filenames = { worker_bundle_deps = [ "lib/common/api/clipboard.ts", - "lib/common/api/deprecate.ts", "lib/common/api/module-list.ts", "lib/common/api/native-image.ts", "lib/common/api/shell.ts", diff --git a/lib/browser/api/app.ts b/lib/browser/api/app.ts index 346b48c9fc..c0d34fcfc9 100644 --- a/lib/browser/api/app.ts +++ b/lib/browser/api/app.ts @@ -1,6 +1,7 @@ import * as fs from 'fs'; -import { Menu, deprecate } from 'electron/main'; +import { Menu } from 'electron/main'; +import * as deprecate from '@electron/internal/common/deprecate'; const bindings = process._linkedBinding('electron_browser_app'); const commandLine = process._linkedBinding('electron_common_command_line'); diff --git a/lib/browser/api/crash-reporter.ts b/lib/browser/api/crash-reporter.ts index 16a9b1b5cb..729d9fe53d 100644 --- a/lib/browser/api/crash-reporter.ts +++ b/lib/browser/api/crash-reporter.ts @@ -1,4 +1,5 @@ -import { app, deprecate } from 'electron/main'; +import { app } from 'electron/main'; +import * as deprecate from '@electron/internal/common/deprecate'; const binding = process._linkedBinding('electron_browser_crash_reporter'); diff --git a/lib/browser/api/web-contents.ts b/lib/browser/api/web-contents.ts index f15851b21f..d7bd9d2e34 100644 --- a/lib/browser/api/web-contents.ts +++ b/lib/browser/api/web-contents.ts @@ -1,4 +1,4 @@ -import { app, ipcMain, session, webFrameMain, deprecate } from 'electron/main'; +import { app, ipcMain, session, webFrameMain } from 'electron/main'; import type { BrowserWindowConstructorOptions, LoadURLOptions } from 'electron/main'; import * as url from 'url'; @@ -10,6 +10,7 @@ import * as ipcMainUtils from '@electron/internal/browser/ipc-main-internal-util import { MessagePortMain } from '@electron/internal/browser/message-port-main'; import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; import { IpcMainImpl } from '@electron/internal/browser/ipc-main-impl'; +import * as deprecate from '@electron/internal/common/deprecate'; // session is not used here, the purpose is to make sure session is initialized // before the webContents module. diff --git a/lib/common/api/deprecate.ts b/lib/common/api/deprecate.ts deleted file mode 100644 index 42a881d8a2..0000000000 --- a/lib/common/api/deprecate.ts +++ /dev/null @@ -1,135 +0,0 @@ -let deprecationHandler: ElectronInternal.DeprecationHandler | null = null; - -function warnOnce (oldName: string, newName?: string) { - let warned = false; - const msg = newName - ? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.` - : `'${oldName}' is deprecated and will be removed.`; - return () => { - if (!warned && !process.noDeprecation) { - warned = true; - deprecate.log(msg); - } - }; -} - -const deprecate: ElectronInternal.DeprecationUtil = { - warnOnce, - setHandler: (handler) => { deprecationHandler = handler; }, - getHandler: () => deprecationHandler, - warn: (oldName, newName) => { - if (!process.noDeprecation) { - deprecate.log(`'${oldName}' is deprecated. Use '${newName}' instead.`); - } - }, - log: (message) => { - if (typeof deprecationHandler === 'function') { - deprecationHandler(message); - } else if (process.throwDeprecation) { - throw new Error(message); - } else if (process.traceDeprecation) { - return console.trace(message); - } else { - return console.warn(`(electron) ${message}`); - } - }, - - // remove a function with no replacement - removeFunction: (fn, removedName) => { - if (!fn) { throw Error(`'${removedName} function' is invalid or does not exist.`); } - - // wrap the deprecated function to warn user - const warn = warnOnce(`${fn.name} function`); - return function (this: any) { - warn(); - fn.apply(this, arguments); - } as unknown as typeof fn; - }, - - // change the name of a function - renameFunction: (fn, newName) => { - const warn = warnOnce(`${fn.name} function`, `${newName} function`); - return function (this: any) { - warn(); - return fn.apply(this, arguments); - } as unknown as typeof fn; - }, - - moveAPI (fn: T, oldUsage: string, newUsage: string): T { - const warn = warnOnce(oldUsage, newUsage); - return function (this: any) { - warn(); - return fn.apply(this, arguments); - } as unknown as typeof fn; - }, - - // change the name of an event - event: (emitter, oldName, newName) => { - const warn = newName.startsWith('-') /* internal event */ - ? warnOnce(`${oldName} event`) - : warnOnce(`${oldName} event`, `${newName} event`); - return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) { - if (this.listenerCount(oldName) !== 0) { - warn(); - this.emit(oldName, ...args); - } - }); - }, - - // remove a property with no replacement - removeProperty: (o, removedName, onlyForValues) => { - // if the property's already been removed, warn about it - const info = Object.getOwnPropertyDescriptor((o as any).__proto__, removedName) // eslint-disable-line - if (!info) { - deprecate.log(`Unable to remove property '${removedName}' from an object that lacks it.`); - return o; - } - if (!info.get || !info.set) { - deprecate.log(`Unable to remove property '${removedName}' from an object does not have a getter / setter`); - return o; - } - - // wrap the deprecated property in an accessor to warn - const warn = warnOnce(removedName); - return Object.defineProperty(o, removedName, { - configurable: true, - get: () => { - warn(); - return info.get!.call(o); - }, - set: newVal => { - if (!onlyForValues || onlyForValues.includes(newVal)) { - warn(); - } - return info.set!.call(o, newVal); - } - }); - }, - - // change the name of a property - renameProperty: (o, oldName, newName) => { - const warn = warnOnce(oldName, newName); - - // if the new property isn't there yet, - // inject it and warn about it - if ((oldName in o) && !(newName in o)) { - warn(); - o[newName] = (o as any)[oldName]; - } - - // wrap the deprecated property in an accessor to warn - // and redirect to the new property - return Object.defineProperty(o, oldName, { - get: () => { - warn(); - return o[newName]; - }, - set: value => { - warn(); - o[newName] = value; - } - }); - } -}; - -export default deprecate; diff --git a/lib/common/api/module-list.ts b/lib/common/api/module-list.ts index a5493e552d..629186dc24 100644 --- a/lib/common/api/module-list.ts +++ b/lib/common/api/module-list.ts @@ -2,7 +2,5 @@ export const commonModuleList: ElectronInternal.ModuleEntry[] = [ { name: 'clipboard', loader: () => require('./clipboard') }, { name: 'nativeImage', loader: () => require('./native-image') }, - { name: 'shell', loader: () => require('./shell') }, - // The internal modules, invisible unless you know their names. - { name: 'deprecate', loader: () => require('./deprecate'), private: true } + { name: 'shell', loader: () => require('./shell') } ]; diff --git a/lib/common/define-properties.ts b/lib/common/define-properties.ts index add72cd846..ad9e08d4fd 100644 --- a/lib/common/define-properties.ts +++ b/lib/common/define-properties.ts @@ -9,7 +9,7 @@ export function defineProperties (targetExports: Object, moduleList: ElectronInt const descriptors: PropertyDescriptorMap = {}; for (const module of moduleList) { descriptors[module.name] = { - enumerable: !module.private, + enumerable: true, get: handleESModule(module.loader) }; } diff --git a/lib/common/deprecate.ts b/lib/common/deprecate.ts new file mode 100644 index 0000000000..b9c42c3cc0 --- /dev/null +++ b/lib/common/deprecate.ts @@ -0,0 +1,139 @@ +type DeprecationHandler = (message: string) => void; + +let deprecationHandler: DeprecationHandler | null = null; + +export function warnOnce (oldName: string, newName?: string) { + let warned = false; + const msg = newName + ? `'${oldName}' is deprecated and will be removed. Please use '${newName}' instead.` + : `'${oldName}' is deprecated and will be removed.`; + return () => { + if (!warned && !process.noDeprecation) { + warned = true; + log(msg); + } + }; +} + +export function setHandler (handler: DeprecationHandler | null): void { + deprecationHandler = handler; +} + +export function getHandler (): DeprecationHandler | null { + return deprecationHandler; +} + +export function warn (oldName: string, newName: string): void { + if (!process.noDeprecation) { + log(`'${oldName}' is deprecated. Use '${newName}' instead.`); + } +} + +export function log (message: string): void { + if (typeof deprecationHandler === 'function') { + deprecationHandler(message); + } else if (process.throwDeprecation) { + throw new Error(message); + } else if (process.traceDeprecation) { + return console.trace(message); + } else { + return console.warn(`(electron) ${message}`); + } +} + +// remove a function with no replacement +export function removeFunction (fn: T, removedName: string): T { + if (!fn) { throw Error(`'${removedName} function' is invalid or does not exist.`); } + + // wrap the deprecated function to warn user + const warn = warnOnce(`${fn.name} function`); + return function (this: any) { + warn(); + fn.apply(this, arguments); + } as unknown as typeof fn; +} + +// change the name of a function +export function renameFunction (fn: T, newName: string): T { + const warn = warnOnce(`${fn.name} function`, `${newName} function`); + return function (this: any) { + warn(); + return fn.apply(this, arguments); + } as unknown as typeof fn; +} + +// change the name of an event +export function event (emitter: NodeJS.EventEmitter, oldName: string, newName: string) { + const warn = newName.startsWith('-') /* internal event */ + ? warnOnce(`${oldName} event`) + : warnOnce(`${oldName} event`, `${newName} event`); + return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) { + if (this.listenerCount(oldName) !== 0) { + warn(); + this.emit(oldName, ...args); + } + }); +} + +// remove a property with no replacement +export function removeProperty(object: T, removedName: K, onlyForValues?: any[]): T { + // if the property's already been removed, warn about it + const info = Object.getOwnPropertyDescriptor((object as any).__proto__, removedName) // eslint-disable-line + if (!info) { + log(`Unable to remove property '${removedName}' from an object that lacks it.`); + return object; + } + if (!info.get || !info.set) { + log(`Unable to remove property '${removedName}' from an object does not have a getter / setter`); + return object; + } + + // wrap the deprecated property in an accessor to warn + const warn = warnOnce(removedName); + return Object.defineProperty(object, removedName, { + configurable: true, + get: () => { + warn(); + return info.get!.call(object); + }, + set: newVal => { + if (!onlyForValues || onlyForValues.includes(newVal)) { + warn(); + } + return info.set!.call(object, newVal); + } + }); +} + +// change the name of a property +export function renameProperty(object: T, oldName: string, newName: K): T { + const warn = warnOnce(oldName, newName); + + // if the new property isn't there yet, + // inject it and warn about it + if ((oldName in object) && !(newName in object)) { + warn(); + object[newName] = (object as any)[oldName]; + } + + // wrap the deprecated property in an accessor to warn + // and redirect to the new property + return Object.defineProperty(object, oldName, { + get: () => { + warn(); + return object[newName]; + }, + set: value => { + warn(); + object[newName] = value; + } + }); +} + +export function moveAPI (fn: T, oldUsage: string, newUsage: string): T { + const warn = warnOnce(oldUsage, newUsage); + return function (this: any) { + warn(); + return fn.apply(this, arguments); + } as unknown as typeof fn; +} diff --git a/lib/sandboxed_renderer/api/module-list.ts b/lib/sandboxed_renderer/api/module-list.ts index 91d075eebc..09772fd72e 100644 --- a/lib/sandboxed_renderer/api/module-list.ts +++ b/lib/sandboxed_renderer/api/module-list.ts @@ -18,11 +18,5 @@ export const moduleList: ElectronInternal.ModuleEntry[] = [ { name: 'webFrame', loader: () => require('@electron/internal/renderer/api/web-frame') - }, - // The internal modules, invisible unless you know their names. - { - name: 'deprecate', - loader: () => require('@electron/internal/common/api/deprecate'), - private: true } ]; diff --git a/spec-main/api-deprecate-spec.ts b/spec-main/deprecate-spec.ts similarity index 98% rename from spec-main/api-deprecate-spec.ts rename to spec-main/deprecate-spec.ts index c45c338e26..b8e3ae9b1d 100644 --- a/spec-main/api-deprecate-spec.ts +++ b/spec-main/deprecate-spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { deprecate } from 'electron/main'; +import * as deprecate from '../lib/common/deprecate'; describe('deprecate', () => { let throwing: boolean; diff --git a/typings/internal-electron.d.ts b/typings/internal-electron.d.ts index 7789f297e5..00478dad54 100644 --- a/typings/internal-electron.d.ts +++ b/typings/internal-electron.d.ts @@ -147,12 +147,6 @@ declare namespace Electron { _throw(error: Error | string): void; } - const deprecate: ElectronInternal.DeprecationUtil; - - namespace Main { - const deprecate: ElectronInternal.DeprecationUtil; - } - class View {} // Experimental views API @@ -193,21 +187,6 @@ declare namespace Electron { } declare namespace ElectronInternal { - type DeprecationHandler = (message: string) => void; - interface DeprecationUtil { - warnOnce(oldName: string, newName?: string): () => void; - setHandler(handler: DeprecationHandler | null): void; - getHandler(): DeprecationHandler | null; - warn(oldName: string, newName: string): void; - log(message: string): void; - removeFunction(fn: T, removedName: string): T; - renameFunction(fn: T, newName: string): T; - event(emitter: NodeJS.EventEmitter, oldName: string, newName: string): void; - removeProperty(object: T, propertyName: K, onlyForValues?: any[]): T; - renameProperty(object: T, oldName: string, newName: K): T; - moveAPI(fn: T, oldUsage: string, newUsage: string): T; - } - interface DesktopCapturer { startHandling(captureWindow: boolean, captureScreen: boolean, thumbnailSize: Electron.Size, fetchWindowIcons: boolean): void; _onerror?: (error: string) => void;