chore: remove bunch of usages of any (#27512)
This commit is contained in:
parent
c7aa35a519
commit
79b3393768
16 changed files with 101 additions and 81 deletions
|
@ -639,8 +639,10 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||||
|
|
||||||
fs.promises.readdir = util.promisify(fs.readdir);
|
fs.promises.readdir = util.promisify(fs.readdir);
|
||||||
|
|
||||||
|
type ReaddirSyncOptions = { encoding: BufferEncoding | null; withFileTypes?: false };
|
||||||
|
|
||||||
const { readdirSync } = fs;
|
const { readdirSync } = fs;
|
||||||
fs.readdirSync = function (pathArgument: string, options: { encoding: BufferEncoding | null; withFileTypes?: false } | BufferEncoding | null) {
|
fs.readdirSync = function (pathArgument: string, options: ReaddirSyncOptions | BufferEncoding | null) {
|
||||||
const pathInfo = splitPath(pathArgument);
|
const pathInfo = splitPath(pathArgument);
|
||||||
if (!pathInfo.isAsar) return readdirSync.apply(this, arguments);
|
if (!pathInfo.isAsar) return readdirSync.apply(this, arguments);
|
||||||
const { asarPath, filePath } = pathInfo;
|
const { asarPath, filePath } = pathInfo;
|
||||||
|
@ -655,7 +657,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
|
throw createError(AsarError.NOT_FOUND, { asarPath, filePath });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options && (options as any).withFileTypes) {
|
if (options && (options as ReaddirSyncOptions).withFileTypes) {
|
||||||
const dirents = [];
|
const dirents = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const childPath = path.join(filePath, file);
|
const childPath = path.join(filePath, file);
|
||||||
|
|
|
@ -231,12 +231,12 @@ function sortTemplate (template: (MenuItemConstructorOptions | MenuItem)[]) {
|
||||||
function generateGroupId (items: (MenuItemConstructorOptions | MenuItem)[], pos: number) {
|
function generateGroupId (items: (MenuItemConstructorOptions | MenuItem)[], pos: number) {
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
for (let idx = pos - 1; idx >= 0; idx--) {
|
for (let idx = pos - 1; idx >= 0; idx--) {
|
||||||
if (items[idx].type === 'radio') return (items[idx] as any).groupId;
|
if (items[idx].type === 'radio') return (items[idx] as MenuItem).groupId;
|
||||||
if (items[idx].type === 'separator') break;
|
if (items[idx].type === 'separator') break;
|
||||||
}
|
}
|
||||||
} else if (pos < items.length) {
|
} else if (pos < items.length) {
|
||||||
for (let idx = pos; idx <= items.length - 1; idx++) {
|
for (let idx = pos; idx <= items.length - 1; idx++) {
|
||||||
if (items[idx].type === 'radio') return (items[idx] as any).groupId;
|
if (items[idx].type === 'radio') return (items[idx] as MenuItem).groupId;
|
||||||
if (items[idx].type === 'separator') break;
|
if (items[idx].type === 'separator') break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,14 @@ const extendConstructHook = (target: any, hook: Function) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const ImmutableProperty = <T extends TouchBarItem<any>>(def: (config: T extends TouchBarItem<infer C> ? C : never, setInternalProp: <K extends keyof T>(k: K, v: T[K]) => void) => any) => (target: T, propertyKey: keyof T) => {
|
const ImmutableProperty = <T extends TouchBarItem<any>>(def: (config: T extends TouchBarItem<infer C> ? C : never, setInternalProp: <K extends keyof T>(k: K, v: T[K]) => void) => any) => (target: T, propertyKey: keyof T) => {
|
||||||
extendConstructHook(target as any, function (this: T) {
|
extendConstructHook(target, function (this: T) {
|
||||||
(this as any)[hiddenProperties][propertyKey] = def((this as any)._config, (k, v) => {
|
(this as any)[hiddenProperties][propertyKey] = def((this as any)._config, (k, v) => {
|
||||||
(this as any)[hiddenProperties][k] = v;
|
(this as any)[hiddenProperties][k] = v;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Object.defineProperty(target, propertyKey, {
|
Object.defineProperty(target, propertyKey, {
|
||||||
get: function () {
|
get: function () {
|
||||||
return (this as any)[hiddenProperties][propertyKey];
|
return this[hiddenProperties][propertyKey];
|
||||||
},
|
},
|
||||||
set: function () {
|
set: function () {
|
||||||
throw new Error(`Cannot override property ${name}`);
|
throw new Error(`Cannot override property ${name}`);
|
||||||
|
@ -31,7 +31,7 @@ const ImmutableProperty = <T extends TouchBarItem<any>>(def: (config: T extends
|
||||||
};
|
};
|
||||||
|
|
||||||
const LiveProperty = <T extends TouchBarItem<any>>(def: (config: T extends TouchBarItem<infer C> ? C : never) => any, onMutate?: (self: T, newValue: any) => void) => (target: T, propertyKey: keyof T) => {
|
const LiveProperty = <T extends TouchBarItem<any>>(def: (config: T extends TouchBarItem<infer C> ? C : never) => any, onMutate?: (self: T, newValue: any) => void) => (target: T, propertyKey: keyof T) => {
|
||||||
extendConstructHook(target as any, function (this: T) {
|
extendConstructHook(target, function (this: T) {
|
||||||
(this as any)[hiddenProperties][propertyKey] = def((this as any)._config);
|
(this as any)[hiddenProperties][propertyKey] = def((this as any)._config);
|
||||||
if (onMutate) onMutate((this as any), (this as any)[hiddenProperties][propertyKey]);
|
if (onMutate) onMutate((this as any), (this as any)[hiddenProperties][propertyKey]);
|
||||||
});
|
});
|
||||||
|
@ -59,7 +59,7 @@ abstract class TouchBarItem<ConfigType> extends EventEmitter {
|
||||||
|
|
||||||
constructor (config: ConfigType) {
|
constructor (config: ConfigType) {
|
||||||
super();
|
super();
|
||||||
this._config = this._config || config || {} as any;
|
this._config = this._config || config || {} as ConfigType;
|
||||||
(this as any)[hiddenProperties] = {};
|
(this as any)[hiddenProperties] = {};
|
||||||
const hook = (this as any)._hook;
|
const hook = (this as any)._hook;
|
||||||
if (hook) hook.call(this);
|
if (hook) hook.call(this);
|
||||||
|
|
|
@ -22,18 +22,8 @@ const getNextId = function () {
|
||||||
|
|
||||||
type PostData = LoadURLOptions['postData']
|
type PostData = LoadURLOptions['postData']
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
type MediaSize = {
|
|
||||||
name: string,
|
|
||||||
custom_display_name: string,
|
|
||||||
height_microns: number,
|
|
||||||
width_microns: number,
|
|
||||||
is_default?: 'true',
|
|
||||||
}
|
|
||||||
/* eslint-enable camelcase */
|
|
||||||
|
|
||||||
// Stock page sizes
|
// Stock page sizes
|
||||||
const PDFPageSizes: Record<string, MediaSize> = {
|
const PDFPageSizes: Record<string, ElectronInternal.MediaSize> = {
|
||||||
A5: {
|
A5: {
|
||||||
custom_display_name: 'A5',
|
custom_display_name: 'A5',
|
||||||
height_microns: 210000,
|
height_microns: 210000,
|
||||||
|
@ -90,7 +80,7 @@ const isValidCustomPageSize = (width: number, height: number) => {
|
||||||
const defaultPrintingSetting = {
|
const defaultPrintingSetting = {
|
||||||
// Customizable.
|
// Customizable.
|
||||||
pageRange: [] as {from: number, to: number}[],
|
pageRange: [] as {from: number, to: number}[],
|
||||||
mediaSize: {} as MediaSize,
|
mediaSize: {} as ElectronInternal.MediaSize,
|
||||||
landscape: false,
|
landscape: false,
|
||||||
headerFooterEnabled: false,
|
headerFooterEnabled: false,
|
||||||
marginsType: 0,
|
marginsType: 0,
|
||||||
|
@ -353,7 +343,7 @@ WebContents.prototype.printToPDF = async function (options) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
WebContents.prototype.print = function (options = {}, callback) {
|
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions = {}, callback) {
|
||||||
// TODO(codebytere): deduplicate argument sanitization by moving rest of
|
// TODO(codebytere): deduplicate argument sanitization by moving rest of
|
||||||
// print param logic into new file shared between printToPDF and print
|
// print param logic into new file shared between printToPDF and print
|
||||||
if (typeof options === 'object') {
|
if (typeof options === 'object') {
|
||||||
|
@ -372,14 +362,14 @@ WebContents.prototype.print = function (options = {}, callback) {
|
||||||
throw new Error('height and width properties must be minimum 352 microns.');
|
throw new Error('height and width properties must be minimum 352 microns.');
|
||||||
}
|
}
|
||||||
|
|
||||||
(options as any).mediaSize = {
|
options.mediaSize = {
|
||||||
name: 'CUSTOM',
|
name: 'CUSTOM',
|
||||||
custom_display_name: 'Custom',
|
custom_display_name: 'Custom',
|
||||||
height_microns: height,
|
height_microns: height,
|
||||||
width_microns: width
|
width_microns: width
|
||||||
};
|
};
|
||||||
} else if (PDFPageSizes[pageSize]) {
|
} else if (PDFPageSizes[pageSize]) {
|
||||||
(options as any).mediaSize = PDFPageSizes[pageSize];
|
options.mediaSize = PDFPageSizes[pageSize];
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unsupported pageSize: ${pageSize}`);
|
throw new Error(`Unsupported pageSize: ${pageSize}`);
|
||||||
}
|
}
|
||||||
|
@ -428,7 +418,7 @@ WebContents.prototype.setWindowOpenHandler = function (handler: (details: Electr
|
||||||
this._windowOpenHandler = handler;
|
this._windowOpenHandler = handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
WebContents.prototype._callWindowOpenHandler = function (event: any, url: string, frameName: string, rawFeatures: string): BrowserWindowConstructorOptions | null {
|
WebContents.prototype._callWindowOpenHandler = function (event: Electron.Event, url: string, frameName: string, rawFeatures: string): BrowserWindowConstructorOptions | null {
|
||||||
if (!this._windowOpenHandler) {
|
if (!this._windowOpenHandler) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -458,21 +448,21 @@ WebContents.prototype._callWindowOpenHandler = function (event: any, url: string
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const addReplyToEvent = (event: any) => {
|
const addReplyToEvent = (event: Electron.IpcMainEvent) => {
|
||||||
const { processId, frameId } = event;
|
const { processId, frameId } = event;
|
||||||
event.reply = (...args: any[]) => {
|
event.reply = (channel: string, ...args: any[]) => {
|
||||||
event.sender.sendToFrame([processId, frameId], ...args);
|
event.sender.sendToFrame([processId, frameId], channel, ...args);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const addSenderFrameToEvent = (event: any) => {
|
const addSenderFrameToEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent) => {
|
||||||
const { processId, frameId } = event;
|
const { processId, frameId } = event;
|
||||||
Object.defineProperty(event, 'senderFrame', {
|
Object.defineProperty(event, 'senderFrame', {
|
||||||
get: () => webFrameMain.fromId(processId, frameId)
|
get: () => webFrameMain.fromId(processId, frameId)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const addReturnValueToEvent = (event: any) => {
|
const addReturnValueToEvent = (event: Electron.IpcMainEvent) => {
|
||||||
Object.defineProperty(event, 'returnValue', {
|
Object.defineProperty(event, 'returnValue', {
|
||||||
set: (value) => event.sendReply(value),
|
set: (value) => event.sendReply(value),
|
||||||
get: () => {}
|
get: () => {}
|
||||||
|
@ -521,7 +511,7 @@ WebContents.prototype._init = function () {
|
||||||
this.setMaxListeners(0);
|
this.setMaxListeners(0);
|
||||||
|
|
||||||
// Dispatch IPC messages to the ipc module.
|
// Dispatch IPC messages to the ipc module.
|
||||||
this.on('-ipc-message' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
|
this.on('-ipc-message' as any, function (this: Electron.WebContents, event: Electron.IpcMainEvent, internal: boolean, channel: string, args: any[]) {
|
||||||
addSenderFrameToEvent(event);
|
addSenderFrameToEvent(event);
|
||||||
if (internal) {
|
if (internal) {
|
||||||
ipcMainInternal.emit(channel, event, ...args);
|
ipcMainInternal.emit(channel, event, ...args);
|
||||||
|
@ -532,7 +522,7 @@ WebContents.prototype._init = function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('-ipc-invoke' as any, function (event: any, internal: boolean, channel: string, args: any[]) {
|
this.on('-ipc-invoke' as any, function (event: Electron.IpcMainInvokeEvent, internal: boolean, channel: string, args: any[]) {
|
||||||
addSenderFrameToEvent(event);
|
addSenderFrameToEvent(event);
|
||||||
event._reply = (result: any) => event.sendReply({ result });
|
event._reply = (result: any) => event.sendReply({ result });
|
||||||
event._throw = (error: Error) => {
|
event._throw = (error: Error) => {
|
||||||
|
@ -547,7 +537,7 @@ WebContents.prototype._init = function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('-ipc-message-sync' as any, function (this: Electron.WebContents, event: any, internal: boolean, channel: string, args: any[]) {
|
this.on('-ipc-message-sync' as any, function (this: Electron.WebContents, event: Electron.IpcMainEvent, internal: boolean, channel: string, args: any[]) {
|
||||||
addSenderFrameToEvent(event);
|
addSenderFrameToEvent(event);
|
||||||
addReturnValueToEvent(event);
|
addReturnValueToEvent(event);
|
||||||
if (internal) {
|
if (internal) {
|
||||||
|
@ -559,13 +549,13 @@ WebContents.prototype._init = function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('-ipc-ports' as any, function (event: any, internal: boolean, channel: string, message: any, ports: any[]) {
|
this.on('-ipc-ports' as any, function (event: Electron.IpcMainEvent, internal: boolean, channel: string, message: any, ports: any[]) {
|
||||||
event.ports = ports.map(p => new MessagePortMain(p));
|
event.ports = ports.map(p => new MessagePortMain(p));
|
||||||
ipcMain.emit(channel, event, message);
|
ipcMain.emit(channel, event, message);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle context menu action request from pepper plugin.
|
// Handle context menu action request from pepper plugin.
|
||||||
this.on('pepper-context-menu' as any, function (event: any, params: {x: number, y: number, menu: Array<(MenuItemConstructorOptions) | (MenuItem)>}, callback: () => void) {
|
this.on('pepper-context-menu' as any, function (event: ElectronInternal.Event, params: {x: number, y: number, menu: Array<(MenuItemConstructorOptions) | (MenuItem)>}, callback: () => void) {
|
||||||
// Access Menu via electron.Menu to prevent circular require.
|
// Access Menu via electron.Menu to prevent circular require.
|
||||||
const menu = require('electron').Menu.buildFromTemplate(params.menu);
|
const menu = require('electron').Menu.buildFromTemplate(params.menu);
|
||||||
menu.popup({
|
menu.popup({
|
||||||
|
@ -596,8 +586,8 @@ WebContents.prototype._init = function () {
|
||||||
|
|
||||||
if (this.getType() !== 'remote') {
|
if (this.getType() !== 'remote') {
|
||||||
// Make new windows requested by links behave like "window.open".
|
// Make new windows requested by links behave like "window.open".
|
||||||
this.on('-new-window' as any, (event: any, url: string, frameName: string, disposition: string,
|
this.on('-new-window' as any, (event: ElectronInternal.Event, url: string, frameName: string, disposition: string,
|
||||||
rawFeatures: string, referrer: any, postData: PostData) => {
|
rawFeatures: string, referrer: Electron.Referrer, postData: PostData) => {
|
||||||
openGuestWindow({
|
openGuestWindow({
|
||||||
event,
|
event,
|
||||||
embedder: event.sender,
|
embedder: event.sender,
|
||||||
|
@ -614,7 +604,7 @@ WebContents.prototype._init = function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
let windowOpenOverriddenOptions: BrowserWindowConstructorOptions | null = null;
|
let windowOpenOverriddenOptions: BrowserWindowConstructorOptions | null = null;
|
||||||
this.on('-will-add-new-contents' as any, (event: any, url: string, frameName: string, rawFeatures: string) => {
|
this.on('-will-add-new-contents' as any, (event: ElectronInternal.Event, url: string, frameName: string, rawFeatures: string) => {
|
||||||
windowOpenOverriddenOptions = this._callWindowOpenHandler(event, url, frameName, rawFeatures);
|
windowOpenOverriddenOptions = this._callWindowOpenHandler(event, url, frameName, rawFeatures);
|
||||||
if (!event.defaultPrevented) {
|
if (!event.defaultPrevented) {
|
||||||
const secureOverrideWebPreferences = windowOpenOverriddenOptions ? {
|
const secureOverrideWebPreferences = windowOpenOverriddenOptions ? {
|
||||||
|
@ -632,7 +622,7 @@ WebContents.prototype._init = function () {
|
||||||
|
|
||||||
// Create a new browser window for the native implementation of
|
// Create a new browser window for the native implementation of
|
||||||
// "window.open", used in sandbox and nativeWindowOpen mode.
|
// "window.open", used in sandbox and nativeWindowOpen mode.
|
||||||
this.on('-add-new-contents' as any, (event: any, webContents: Electron.WebContents, disposition: string,
|
this.on('-add-new-contents' as any, (event: ElectronInternal.Event, webContents: Electron.WebContents, disposition: string,
|
||||||
_userGesture: boolean, _left: number, _top: number, _width: number, _height: number, url: string, frameName: string,
|
_userGesture: boolean, _left: number, _top: number, _width: number, _height: number, url: string, frameName: string,
|
||||||
referrer: Electron.Referrer, rawFeatures: string, postData: PostData) => {
|
referrer: Electron.Referrer, rawFeatures: string, postData: PostData) => {
|
||||||
const overriddenOptions = windowOpenOverriddenOptions || undefined;
|
const overriddenOptions = windowOpenOverriddenOptions || undefined;
|
||||||
|
|
|
@ -197,7 +197,7 @@ const attachGuest = function (event: Electron.IpcMainInvokeEvent,
|
||||||
// Inherit certain option values from embedder
|
// Inherit certain option values from embedder
|
||||||
const lastWebPreferences = embedder.getLastWebPreferences();
|
const lastWebPreferences = embedder.getLastWebPreferences();
|
||||||
for (const [name, value] of inheritedWebPreferences) {
|
for (const [name, value] of inheritedWebPreferences) {
|
||||||
if ((lastWebPreferences as any)[name] === value) {
|
if (lastWebPreferences[name as keyof Electron.WebPreferences] === value) {
|
||||||
(webPreferences as any)[name] = value;
|
(webPreferences as any)[name] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
|
||||||
httpReferrer: referrer,
|
httpReferrer: referrer,
|
||||||
...(postData && {
|
...(postData && {
|
||||||
postData,
|
postData,
|
||||||
extraHeaders: formatPostDataHeaders(postData)
|
extraHeaders: formatPostDataHeaders(postData as Electron.UploadRawData[])
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ const handleWindowLifecycleEvents = function ({ embedder, guest, frameName }: {
|
||||||
* `did-create-window` in 11.0.0. Will be removed in 12.0.0.
|
* `did-create-window` in 11.0.0. Will be removed in 12.0.0.
|
||||||
*/
|
*/
|
||||||
function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs, browserWindowOptions, additionalFeatures, disposition, referrer, postData }: {
|
function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs, browserWindowOptions, additionalFeatures, disposition, referrer, postData }: {
|
||||||
event: { sender: WebContents, defaultPrevented: boolean },
|
event: { sender: WebContents, defaultPrevented: boolean, newGuest?: BrowserWindow },
|
||||||
embedder: WebContents,
|
embedder: WebContents,
|
||||||
guest?: WebContents,
|
guest?: WebContents,
|
||||||
windowOpenArgs: WindowOpenArgs,
|
windowOpenArgs: WindowOpenArgs,
|
||||||
|
@ -145,10 +145,10 @@ function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs,
|
||||||
postData?: PostData,
|
postData?: PostData,
|
||||||
}): boolean {
|
}): boolean {
|
||||||
const { url, frameName } = windowOpenArgs;
|
const { url, frameName } = windowOpenArgs;
|
||||||
const isWebViewWithPopupsDisabled = embedder.getType() === 'webview' && (embedder as any).getLastWebPreferences().disablePopups;
|
const isWebViewWithPopupsDisabled = embedder.getType() === 'webview' && embedder.getLastWebPreferences().disablePopups;
|
||||||
const postBody = postData ? {
|
const postBody = postData ? {
|
||||||
data: postData,
|
data: postData,
|
||||||
headers: formatPostDataHeaders(postData)
|
headers: formatPostDataHeaders(postData as Electron.UploadRawData[])
|
||||||
} : null;
|
} : null;
|
||||||
|
|
||||||
embedder.emit(
|
embedder.emit(
|
||||||
|
@ -166,14 +166,14 @@ function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs,
|
||||||
postBody
|
postBody
|
||||||
);
|
);
|
||||||
|
|
||||||
const { newGuest } = event as any;
|
const { newGuest } = event;
|
||||||
if (isWebViewWithPopupsDisabled) return true;
|
if (isWebViewWithPopupsDisabled) return true;
|
||||||
if (event.defaultPrevented) {
|
if (event.defaultPrevented) {
|
||||||
if (newGuest) {
|
if (newGuest) {
|
||||||
if (guest === newGuest.webContents) {
|
if (guest === newGuest.webContents) {
|
||||||
// The webContents is not changed, so set defaultPrevented to false to
|
// The webContents is not changed, so set defaultPrevented to false to
|
||||||
// stop the callers of this event from destroying the webContents.
|
// stop the callers of this event from destroying the webContents.
|
||||||
(event as any).defaultPrevented = false;
|
event.defaultPrevented = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleWindowLifecycleEvents({
|
handleWindowLifecycleEvents({
|
||||||
|
@ -224,7 +224,7 @@ function makeBrowserWindowOptions ({ embedder, features, frameName, isNativeWind
|
||||||
...parsedOptions,
|
...parsedOptions,
|
||||||
...overrideOptions,
|
...overrideOptions,
|
||||||
webPreferences: makeWebPreferences({ embedder, insecureParsedWebPreferences: parsedWebPreferences, secureOverrideWebPreferences: overrideOptions && overrideOptions.webPreferences, useDeprecatedBehaviorForOptionInheritance: true })
|
webPreferences: makeWebPreferences({ embedder, insecureParsedWebPreferences: parsedWebPreferences, secureOverrideWebPreferences: overrideOptions && overrideOptions.webPreferences, useDeprecatedBehaviorForOptionInheritance: true })
|
||||||
}
|
} as Electron.BrowserViewConstructorOptions
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,13 +239,13 @@ export function makeWebPreferences ({ embedder, secureOverrideWebPreferences = {
|
||||||
useDeprecatedBehaviorForOptionInheritance?: boolean
|
useDeprecatedBehaviorForOptionInheritance?: boolean
|
||||||
}) {
|
}) {
|
||||||
const deprecatedInheritedOptions = getDeprecatedInheritedOptions(embedder);
|
const deprecatedInheritedOptions = getDeprecatedInheritedOptions(embedder);
|
||||||
const parentWebPreferences = (embedder as any).getLastWebPreferences();
|
const parentWebPreferences = embedder.getLastWebPreferences();
|
||||||
const securityWebPreferencesFromParent = Object.keys(securityWebPreferences).reduce((map, key) => {
|
const securityWebPreferencesFromParent = (Object.keys(securityWebPreferences).reduce((map, key) => {
|
||||||
if (securityWebPreferences[key] === parentWebPreferences[key]) {
|
if (securityWebPreferences[key] === parentWebPreferences[key as keyof Electron.WebPreferences]) {
|
||||||
map[key] = parentWebPreferences[key];
|
(map as any)[key] = parentWebPreferences[key as keyof Electron.WebPreferences];
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}, {} as any);
|
}, {} as Electron.WebPreferences));
|
||||||
const openerId = parentWebPreferences.nativeWindowOpen ? null : embedder.id;
|
const openerId = parentWebPreferences.nativeWindowOpen ? null : embedder.id;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -270,18 +270,18 @@ export function makeWebPreferences ({ embedder, secureOverrideWebPreferences = {
|
||||||
* only critical security preferences will be inherited by default.
|
* only critical security preferences will be inherited by default.
|
||||||
*/
|
*/
|
||||||
function getDeprecatedInheritedOptions (embedder: WebContents) {
|
function getDeprecatedInheritedOptions (embedder: WebContents) {
|
||||||
if (!(embedder as any).browserWindowOptions) {
|
if (!embedder.browserWindowOptions) {
|
||||||
// If it's a webview, return just the webPreferences.
|
// If it's a webview, return just the webPreferences.
|
||||||
return {
|
return {
|
||||||
webPreferences: (embedder as any).getLastWebPreferences()
|
webPreferences: embedder.getLastWebPreferences()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const { type, show, ...inheritableOptions } = (embedder as any).browserWindowOptions;
|
const { type, show, ...inheritableOptions } = embedder.browserWindowOptions;
|
||||||
return inheritableOptions;
|
return inheritableOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPostDataHeaders (postData: any) {
|
function formatPostDataHeaders (postData: Electron.UploadRawData[]) {
|
||||||
if (!postData) return;
|
if (!postData) return;
|
||||||
|
|
||||||
let extraHeaders = 'content-type: application/x-www-form-urlencoded';
|
let extraHeaders = 'content-type: application/x-www-form-urlencoded';
|
||||||
|
|
|
@ -28,7 +28,7 @@ const getGuestWindow = function (guestContents: WebContents) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const isChildWindow = function (sender: WebContents, target: WebContents) {
|
const isChildWindow = function (sender: WebContents, target: WebContents) {
|
||||||
return (target as any).getLastWebPreferences().openerId === sender.id;
|
return target.getLastWebPreferences().openerId === sender.id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const isRelatedWindow = function (sender: WebContents, target: WebContents) {
|
const isRelatedWindow = function (sender: WebContents, target: WebContents) {
|
||||||
|
@ -43,7 +43,7 @@ const isScriptableWindow = function (sender: WebContents, target: WebContents) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const isNodeIntegrationEnabled = function (sender: WebContents) {
|
const isNodeIntegrationEnabled = function (sender: WebContents) {
|
||||||
return (sender as any).getLastWebPreferences().nodeIntegration === true;
|
return sender.getLastWebPreferences().nodeIntegration === true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Checks whether |sender| can access the |target|:
|
// Checks whether |sender| can access the |target|:
|
||||||
|
@ -65,15 +65,15 @@ ipcMainInternal.on(
|
||||||
features: string
|
features: string
|
||||||
) => {
|
) => {
|
||||||
// This should only be allowed for senders that have nativeWindowOpen: false
|
// This should only be allowed for senders that have nativeWindowOpen: false
|
||||||
const lastWebPreferences = (event.sender as any).getLastWebPreferences();
|
const lastWebPreferences = event.sender.getLastWebPreferences();
|
||||||
if (lastWebPreferences.nativeWindowOpen || lastWebPreferences.sandbox) {
|
if (lastWebPreferences.nativeWindowOpen || lastWebPreferences.sandbox) {
|
||||||
(event as any).returnValue = null;
|
event.returnValue = null;
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'GUEST_WINDOW_MANAGER_WINDOW_OPEN denied: expected native window.open'
|
'GUEST_WINDOW_MANAGER_WINDOW_OPEN denied: expected native window.open'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const browserWindowOptions = (event.sender as any)._callWindowOpenHandler(event, url, frameName, features);
|
const browserWindowOptions = event.sender._callWindowOpenHandler(event, url, frameName, features);
|
||||||
if (event.defaultPrevented) {
|
if (event.defaultPrevented) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ ipcMainInternal.on(
|
||||||
embedder: event.sender,
|
embedder: event.sender,
|
||||||
referrer: { url: '', policy: 'default' },
|
referrer: { url: '', policy: 'default' },
|
||||||
disposition: 'new-window',
|
disposition: 'new-window',
|
||||||
overrideBrowserWindowOptions: browserWindowOptions,
|
overrideBrowserWindowOptions: browserWindowOptions!,
|
||||||
windowOpenArgs: {
|
windowOpenArgs: {
|
||||||
url: url || 'about:blank',
|
url: url || 'about:blank',
|
||||||
frameName: frameName || '',
|
frameName: frameName || '',
|
||||||
|
@ -90,7 +90,7 @@ ipcMainInternal.on(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
(event as any).returnValue = guest ? guest.webContents.id : null;
|
event.returnValue = guest ? guest.webContents.id : null;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ const removeRemoteListenersAndLogWarning = (sender: any, callIntoRenderer: (...a
|
||||||
if (remoteEvents.length > 0) {
|
if (remoteEvents.length > 0) {
|
||||||
message += `\nRemote event names: ${remoteEvents.join(', ')}`;
|
message += `\nRemote event names: ${remoteEvents.join(', ')}`;
|
||||||
remoteEvents.forEach((eventName) => {
|
remoteEvents.forEach((eventName) => {
|
||||||
sender.removeListener(eventName as any, callIntoRenderer);
|
sender.removeListener(eventName, callIntoRenderer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ handleRemoteCommand(IPC_MESSAGES.BROWSER_REQUIRE, function (event, contextId, mo
|
||||||
if (customEvent.defaultPrevented) {
|
if (customEvent.defaultPrevented) {
|
||||||
throw new Error(`Blocked remote.require('${moduleName}')`);
|
throw new Error(`Blocked remote.require('${moduleName}')`);
|
||||||
} else {
|
} else {
|
||||||
customEvent.returnValue = (process as any).mainModule.require(moduleName);
|
customEvent.returnValue = process.mainModule.require(moduleName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ const contextBridge: Electron.ContextBridge = {
|
||||||
checkContextIsolationEnabled();
|
checkContextIsolationEnabled();
|
||||||
return binding.exposeAPIInMainWorld(key, api);
|
return binding.exposeAPIInMainWorld(key, api);
|
||||||
}
|
}
|
||||||
} as any;
|
};
|
||||||
|
|
||||||
export default contextBridge;
|
export default contextBridge;
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ if (nodeIntegration) {
|
||||||
// We do not want to add `uncaughtException` to our definitions
|
// We do not want to add `uncaughtException` to our definitions
|
||||||
// because we don't want anyone else (anywhere) to throw that kind
|
// because we don't want anyone else (anywhere) to throw that kind
|
||||||
// of error.
|
// of error.
|
||||||
global.process.emit('uncaughtException' as any, error as any);
|
global.process.emit('uncaughtException', error as any);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -79,7 +79,7 @@ const isLocalhost = function () {
|
||||||
*/
|
*/
|
||||||
const isUnsafeEvalEnabled: () => Promise<boolean> = function () {
|
const isUnsafeEvalEnabled: () => Promise<boolean> = function () {
|
||||||
// Call _executeJavaScript to bypass the world-safe deprecation warning
|
// Call _executeJavaScript to bypass the world-safe deprecation warning
|
||||||
return (webFrame as any)._executeJavaScript(`(${(() => {
|
return webFrame._executeJavaScript(`(${(() => {
|
||||||
try {
|
try {
|
||||||
eval(window.trustedTypes.emptyScript); // eslint-disable-line no-eval
|
eval(window.trustedTypes.emptyScript); // eslint-disable-line no-eval
|
||||||
} catch {
|
} catch {
|
||||||
|
|
|
@ -60,7 +60,7 @@ export class WebViewAttribute implements MutationHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the attribute's value changes.
|
// Called when the attribute's value changes.
|
||||||
public handleMutation: MutationHandler['handleMutation'] = () => undefined as any
|
public handleMutation: MutationHandler['handleMutation'] = () => undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
// An attribute that is treated as a Boolean.
|
// An attribute that is treated as a Boolean.
|
||||||
|
|
|
@ -94,7 +94,7 @@ const registerWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeo
|
||||||
// The customElements.define has to be called in a special scope.
|
// The customElements.define has to be called in a special scope.
|
||||||
webViewImpl.webFrame.allowGuestViewElementDefinition(window, () => {
|
webViewImpl.webFrame.allowGuestViewElementDefinition(window, () => {
|
||||||
window.customElements.define('webview', WebViewElement);
|
window.customElements.define('webview', WebViewElement);
|
||||||
(window as any).WebView = WebViewElement;
|
window.WebView = WebViewElement;
|
||||||
|
|
||||||
// Delete the callbacks so developers cannot call them and produce unexpected
|
// Delete the callbacks so developers cannot call them and produce unexpected
|
||||||
// behavior.
|
// behavior.
|
||||||
|
|
|
@ -981,7 +981,7 @@ describe('contextBridge', () => {
|
||||||
describe('overrideGlobalValueFromIsolatedWorld', () => {
|
describe('overrideGlobalValueFromIsolatedWorld', () => {
|
||||||
it('should override top level properties', async () => {
|
it('should override top level properties', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
contextBridge.internalContextBridge.overrideGlobalValueFromIsolatedWorld(['open'], () => ({ you: 'are a wizard' }));
|
contextBridge.internalContextBridge!.overrideGlobalValueFromIsolatedWorld(['open'], () => ({ you: 'are a wizard' }));
|
||||||
});
|
});
|
||||||
const result = await callWithBindings(async (root: any) => {
|
const result = await callWithBindings(async (root: any) => {
|
||||||
return root.open();
|
return root.open();
|
||||||
|
@ -991,7 +991,7 @@ describe('contextBridge', () => {
|
||||||
|
|
||||||
it('should override deep properties', async () => {
|
it('should override deep properties', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
contextBridge.internalContextBridge.overrideGlobalValueFromIsolatedWorld(['document', 'foo'], () => 'I am foo');
|
contextBridge.internalContextBridge!.overrideGlobalValueFromIsolatedWorld(['document', 'foo'], () => 'I am foo');
|
||||||
});
|
});
|
||||||
const result = await callWithBindings(async (root: any) => {
|
const result = await callWithBindings(async (root: any) => {
|
||||||
return root.document.foo();
|
return root.document.foo();
|
||||||
|
@ -1008,7 +1008,7 @@ describe('contextBridge', () => {
|
||||||
callCount++;
|
callCount++;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
contextBridge.internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['isFun'], getter);
|
contextBridge.internalContextBridge!.overrideGlobalPropertyFromIsolatedWorld(['isFun'], getter);
|
||||||
contextBridge.exposeInMainWorld('foo', {
|
contextBridge.exposeInMainWorld('foo', {
|
||||||
callCount: () => callCount
|
callCount: () => callCount
|
||||||
});
|
});
|
||||||
|
@ -1022,7 +1022,7 @@ describe('contextBridge', () => {
|
||||||
|
|
||||||
it('should not make a setter if none is provided', async () => {
|
it('should not make a setter if none is provided', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
contextBridge.internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['isFun'], () => true);
|
contextBridge.internalContextBridge!.overrideGlobalPropertyFromIsolatedWorld(['isFun'], () => true);
|
||||||
});
|
});
|
||||||
const result = await callWithBindings(async (root: any) => {
|
const result = await callWithBindings(async (root: any) => {
|
||||||
root.isFun = 123;
|
root.isFun = 123;
|
||||||
|
@ -1038,7 +1038,7 @@ describe('contextBridge', () => {
|
||||||
callArgs.push(args);
|
callArgs.push(args);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
contextBridge.internalContextBridge.overrideGlobalPropertyFromIsolatedWorld(['isFun'], () => true, setter);
|
contextBridge.internalContextBridge!.overrideGlobalPropertyFromIsolatedWorld(['isFun'], () => true, setter);
|
||||||
contextBridge.exposeInMainWorld('foo', {
|
contextBridge.exposeInMainWorld('foo', {
|
||||||
callArgs: () => callArgs
|
callArgs: () => callArgs
|
||||||
});
|
});
|
||||||
|
@ -1056,7 +1056,7 @@ describe('contextBridge', () => {
|
||||||
describe('overrideGlobalValueWithDynamicPropsFromIsolatedWorld', () => {
|
describe('overrideGlobalValueWithDynamicPropsFromIsolatedWorld', () => {
|
||||||
it('should not affect normal values', async () => {
|
it('should not affect normal values', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
contextBridge.internalContextBridge!.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
||||||
a: 123,
|
a: 123,
|
||||||
b: () => 2,
|
b: () => 2,
|
||||||
c: () => ({ d: 3 })
|
c: () => ({ d: 3 })
|
||||||
|
@ -1070,7 +1070,7 @@ describe('contextBridge', () => {
|
||||||
|
|
||||||
it('should work with getters', async () => {
|
it('should work with getters', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
contextBridge.internalContextBridge!.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
||||||
get foo () {
|
get foo () {
|
||||||
return 'hi there';
|
return 'hi there';
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1085,7 @@ describe('contextBridge', () => {
|
||||||
it('should work with setters', async () => {
|
it('should work with setters', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
let a: any = null;
|
let a: any = null;
|
||||||
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
contextBridge.internalContextBridge!.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
||||||
get foo () {
|
get foo () {
|
||||||
return a;
|
return a;
|
||||||
},
|
},
|
||||||
|
@ -1103,7 +1103,7 @@ describe('contextBridge', () => {
|
||||||
|
|
||||||
it('should work with deep properties', async () => {
|
it('should work with deep properties', async () => {
|
||||||
await makeBindingWindow(() => {
|
await makeBindingWindow(() => {
|
||||||
contextBridge.internalContextBridge.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
contextBridge.internalContextBridge!.overrideGlobalValueWithDynamicPropsFromIsolatedWorld(['thing'], {
|
||||||
a: () => ({
|
a: () => ({
|
||||||
get foo () {
|
get foo () {
|
||||||
return 'still here';
|
return 'still here';
|
||||||
|
|
2
typings/internal-ambient.d.ts
vendored
2
typings/internal-ambient.d.ts
vendored
|
@ -232,6 +232,7 @@ declare namespace NodeJS {
|
||||||
_firstFileName?: string;
|
_firstFileName?: string;
|
||||||
|
|
||||||
helperExecPath: string;
|
helperExecPath: string;
|
||||||
|
mainModule: NodeJS.Module;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +272,7 @@ declare interface Window {
|
||||||
completeURL: (project: string, path: string) => string;
|
completeURL: (project: string, path: string) => string;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
WebView: typeof ElectronInternal.WebViewElement;
|
||||||
ResizeObserver: ResizeObserver;
|
ResizeObserver: ResizeObserver;
|
||||||
trustedTypes: TrustedTypePolicyFactory;
|
trustedTypes: TrustedTypePolicyFactory;
|
||||||
}
|
}
|
||||||
|
|
32
typings/internal-electron.d.ts
vendored
32
typings/internal-electron.d.ts
vendored
|
@ -37,8 +37,12 @@ declare namespace Electron {
|
||||||
removeListener(event: '-touch-bar-interaction', listener: (event: Event, itemID: string, details: any) => void): this;
|
removeListener(event: '-touch-bar-interaction', listener: (event: Event, itemID: string, details: any) => void): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BrowserWindowConstructorOptions {
|
||||||
|
webContents?: WebContents;
|
||||||
|
}
|
||||||
|
|
||||||
interface ContextBridge {
|
interface ContextBridge {
|
||||||
internalContextBridge: {
|
internalContextBridge?: {
|
||||||
contextIsolationEnabled: boolean;
|
contextIsolationEnabled: boolean;
|
||||||
overrideGlobalValueFromIsolatedWorld(keys: string[], value: any): void;
|
overrideGlobalValueFromIsolatedWorld(keys: string[], value: any): void;
|
||||||
overrideGlobalValueWithDynamicPropsFromIsolatedWorld(keys: string[], value: any): void;
|
overrideGlobalValueWithDynamicPropsFromIsolatedWorld(keys: string[], value: any): void;
|
||||||
|
@ -88,6 +92,7 @@ declare namespace Electron {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WebFrame {
|
interface WebFrame {
|
||||||
|
_executeJavaScript(code: string, userGesture?: boolean): Promise<any>;
|
||||||
getWebFrameId(window: Window): number;
|
getWebFrameId(window: Window): number;
|
||||||
allowGuestViewElementDefinition(window: Window, context: any): void;
|
allowGuestViewElementDefinition(window: Window, context: any): void;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +105,7 @@ declare namespace Electron {
|
||||||
|
|
||||||
interface WebPreferences {
|
interface WebPreferences {
|
||||||
guestInstanceId?: number;
|
guestInstanceId?: number;
|
||||||
openerId?: number;
|
openerId?: number | null;
|
||||||
disablePopups?: boolean;
|
disablePopups?: boolean;
|
||||||
preloadURL?: string;
|
preloadURL?: string;
|
||||||
embedder?: Electron.WebContents;
|
embedder?: Electron.WebContents;
|
||||||
|
@ -147,9 +152,14 @@ declare namespace Electron {
|
||||||
acceleratorWorksWhenHidden?: boolean;
|
acceleratorWorksWhenHidden?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IpcMainEvent {
|
||||||
|
sendReply(value: any): void;
|
||||||
|
}
|
||||||
|
|
||||||
interface IpcMainInvokeEvent {
|
interface IpcMainInvokeEvent {
|
||||||
|
sendReply(value: any): void;
|
||||||
_reply(value: any): void;
|
_reply(value: any): void;
|
||||||
_throw(error: Error): void;
|
_throw(error: Error | string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const deprecate: ElectronInternal.DeprecationUtil;
|
const deprecate: ElectronInternal.DeprecationUtil;
|
||||||
|
@ -250,10 +260,26 @@ declare namespace ElectronInternal {
|
||||||
once(channel: string, listener: (event: IpcMainInternalEvent, ...args: any[]) => void): this;
|
once(channel: string, listener: (event: IpcMainInternalEvent, ...args: any[]) => void): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Event extends Electron.Event {
|
||||||
|
sender: WebContents;
|
||||||
|
}
|
||||||
|
|
||||||
interface LoadURLOptions extends Electron.LoadURLOptions {
|
interface LoadURLOptions extends Electron.LoadURLOptions {
|
||||||
reloadIgnoringCache?: boolean;
|
reloadIgnoringCache?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface WebContentsPrintOptions extends Electron.WebContentsPrintOptions {
|
||||||
|
mediaSize?: MediaSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaSize = {
|
||||||
|
name: string,
|
||||||
|
custom_display_name: string,
|
||||||
|
height_microns: number,
|
||||||
|
width_microns: number,
|
||||||
|
is_default?: 'true',
|
||||||
|
}
|
||||||
|
|
||||||
type ModuleLoader = () => any;
|
type ModuleLoader = () => any;
|
||||||
|
|
||||||
interface ModuleEntry {
|
interface ModuleEntry {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue