chore: type check JS in docs (#38423)

* build(deps): update @electron/lint-roller

* chore: type check JS in docs

* docs: add @ts-check and @ts-expect-error to code blocks

* chore: fix type check errors in docs

* chore: add ts-type to blocks
This commit is contained in:
David Sanders 2023-06-05 15:26:26 +08:00 committed by GitHub
parent 4c89061e0e
commit 905aad9cb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 257 additions and 182 deletions

View file

@ -971,7 +971,7 @@ app.setJumpList([
title: 'Tool A', title: 'Tool A',
program: process.execPath, program: process.execPath,
args: '--run-tool-a', args: '--run-tool-a',
icon: process.execPath, iconPath: process.execPath,
iconIndex: 0, iconIndex: 0,
description: 'Runs Tool A' description: 'Runs Tool A'
}, },
@ -980,7 +980,7 @@ app.setJumpList([
title: 'Tool B', title: 'Tool B',
program: process.execPath, program: process.execPath,
args: '--run-tool-b', args: '--run-tool-b',
icon: process.execPath, iconPath: process.execPath,
iconIndex: 0, iconIndex: 0,
description: 'Runs Tool B' description: 'Runs Tool B'
} }
@ -1418,8 +1418,8 @@ const fs = require('fs')
let filepath let filepath
let bookmark let bookmark
dialog.showOpenDialog(null, { securityScopedBookmarks: true }, (filepaths, bookmarks) => { dialog.showOpenDialog(null, { securityScopedBookmarks: true }).then(({ filePaths, bookmarks }) => {
filepath = filepaths[0] filepath = filePaths[0]
bookmark = bookmarks[0] bookmark = bookmarks[0]
fs.readFileSync(filepath) fs.readFileSync(filepath)
}) })

View file

@ -104,6 +104,7 @@ window, you have to set both `parent` and `modal` options:
```javascript ```javascript
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const top = new BrowserWindow()
const child = new BrowserWindow({ parent: top, modal: true, show: false }) const child = new BrowserWindow({ parent: top, modal: true, show: false })
child.loadURL('https://github.com') child.loadURL('https://github.com')
child.once('ready-to-show', () => { child.once('ready-to-show', () => {
@ -597,7 +598,7 @@ On Linux the setter is a no-op, although the getter returns `true`.
A `boolean` property that determines whether the window is excluded from the applications Windows menu. `false` by default. A `boolean` property that determines whether the window is excluded from the applications Windows menu. `false` by default.
```js ```js @ts-expect-error=[11]
const win = new BrowserWindow({ height: 600, width: 600 }) const win = new BrowserWindow({ height: 600, width: 600 })
const template = [ const template = [
@ -1200,6 +1201,9 @@ Node's [`url.format`](https://nodejs.org/api/url.html#url_url_format_urlobject)
method: method:
```javascript ```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
const url = require('url').format({ const url = require('url').format({
protocol: 'file', protocol: 'file',
slashes: true, slashes: true,
@ -1213,6 +1217,9 @@ You can load a URL using a `POST` request with URL-encoded data by doing
the following: the following:
```javascript ```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.loadURL('http://localhost:8000/post', { win.loadURL('http://localhost:8000/post', {
postData: [{ postData: [{
type: 'rawData', type: 'rawData',

View file

@ -104,7 +104,7 @@ The `callback` function is expected to be called back with user credentials:
* `username` string * `username` string
* `password` string * `password` string
```javascript ```javascript @ts-type={request:Electron.ClientRequest}
request.on('login', (authInfo, callback) => { request.on('login', (authInfo, callback) => {
callback('username', 'password') callback('username', 'password')
}) })
@ -113,7 +113,7 @@ request.on('login', (authInfo, callback) => {
Providing empty credentials will cancel the request and report an authentication Providing empty credentials will cancel the request and report an authentication
error on the response object: error on the response object:
```javascript ```javascript @ts-type={request:Electron.ClientRequest}
request.on('response', (response) => { request.on('response', (response) => {
console.log(`STATUS: ${response.statusCode}`) console.log(`STATUS: ${response.statusCode}`)
response.on('error', (error) => { response.on('error', (error) => {

View file

@ -148,10 +148,7 @@ clipboard.
```js ```js
const { clipboard } = require('electron') const { clipboard } = require('electron')
clipboard.writeBookmark({ clipboard.writeBookmark('Electron Homepage', 'https://electronjs.org')
text: 'https://electronjs.org',
bookmark: 'Electron Homepage'
})
``` ```
### `clipboard.readFindText()` _macOS_ ### `clipboard.readFindText()` _macOS_

View file

@ -18,7 +18,7 @@ contextBridge.exposeInMainWorld(
) )
``` ```
```javascript ```javascript @ts-nocheck
// Renderer (Main World) // Renderer (Main World)
window.electron.doThing() window.electron.doThing()
@ -104,7 +104,7 @@ contextBridge.exposeInIsolatedWorld(
) )
``` ```
```javascript ```javascript @ts-nocheck
// Renderer (In isolated world id1004) // Renderer (In isolated world id1004)
window.electron.doThing() window.electron.doThing()

View file

@ -10,7 +10,9 @@ title is `Electron`:
```javascript ```javascript
// In the main process. // In the main process.
const { desktopCapturer } = require('electron') const { BrowserWindow, desktopCapturer } = require('electron')
const mainWindow = new BrowserWindow()
desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => { desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources => {
for (const source of sources) { for (const source of sources) {
@ -22,7 +24,7 @@ desktopCapturer.getSources({ types: ['window', 'screen'] }).then(async sources =
}) })
``` ```
```javascript ```javascript @ts-nocheck
// In the preload script. // In the preload script.
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')

View file

@ -72,7 +72,7 @@ and a directory selector, so if you set `properties` to
`['openFile', 'openDirectory']` on these platforms, a directory selector will be `['openFile', 'openDirectory']` on these platforms, a directory selector will be
shown. shown.
```js ```js @ts-type={mainWindow:Electron.BrowserWindow}
dialog.showOpenDialogSync(mainWindow, { dialog.showOpenDialogSync(mainWindow, {
properties: ['openFile', 'openDirectory'] properties: ['openFile', 'openDirectory']
}) })
@ -139,7 +139,7 @@ and a directory selector, so if you set `properties` to
`['openFile', 'openDirectory']` on these platforms, a directory selector will be `['openFile', 'openDirectory']` on these platforms, a directory selector will be
shown. shown.
```js ```js @ts-type={mainWindow:Electron.BrowserWindow}
dialog.showOpenDialog(mainWindow, { dialog.showOpenDialog(mainWindow, {
properties: ['openFile', 'openDirectory'] properties: ['openFile', 'openDirectory']
}).then(result => { }).then(result => {

View file

@ -89,7 +89,7 @@ tuples. So, the even-numbered offsets are key values, and the odd-numbered
offsets are the associated values. Header names are not lowercased, and offsets are the associated values. Header names are not lowercased, and
duplicates are not merged. duplicates are not merged.
```javascript ```javascript @ts-type={response:Electron.IncomingMessage}
// Prints something like: // Prints something like:
// //
// [ 'user-agent', // [ 'user-agent',
@ -100,5 +100,5 @@ duplicates are not merged.
// '127.0.0.1:8000', // '127.0.0.1:8000',
// 'ACCEPT', // 'ACCEPT',
// '*/*' ] // '*/*' ]
console.log(request.rawHeaders) console.log(response.rawHeaders)
``` ```

View file

@ -83,14 +83,14 @@ If `listener` returns a Promise, the eventual result of the promise will be
returned as a reply to the remote caller. Otherwise, the return value of the returned as a reply to the remote caller. Otherwise, the return value of the
listener will be used as the value of the reply. listener will be used as the value of the reply.
```js title='Main Process' ```js title='Main Process' @ts-type={somePromise:(...args:unknown[])=>Promise<unknown>}
ipcMain.handle('my-invokable-ipc', async (event, ...args) => { ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
const result = await somePromise(...args) const result = await somePromise(...args)
return result return result
}) })
``` ```
```js title='Renderer Process' ```js title='Renderer Process' @ts-type={arg1:unknown} @ts-type={arg2:unknown}
async () => { async () => {
const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2) const result = await ipcRenderer.invoke('my-invokable-ipc', arg1, arg2)
// ... // ...

View file

@ -101,7 +101,7 @@ The main process should listen for `channel` with
For example: For example:
```javascript ```javascript @ts-type={someArgument:unknown} @ts-type={doSomeWork:(arg:unknown)=>Promise<unknown>}
// Renderer process // Renderer process
ipcRenderer.invoke('some-name', someArgument).then((result) => { ipcRenderer.invoke('some-name', someArgument).then((result) => {
// ... // ...

View file

@ -147,7 +147,7 @@ can have a submenu.
An example of creating the application menu with the simple template API: An example of creating the application menu with the simple template API:
```javascript ```javascript @ts-expect-error=[107]
const { app, Menu } = require('electron') const { app, Menu } = require('electron')
const isMac = process.platform === 'darwin' const isMac = process.platform === 'darwin'
@ -267,7 +267,7 @@ menu on behalf of the renderer.
Below is an example of showing a menu when the user right clicks the page: Below is an example of showing a menu when the user right clicks the page:
```js ```js @ts-expect-error=[21]
// renderer // renderer
window.addEventListener('contextmenu', (e) => { window.addEventListener('contextmenu', (e) => {
e.preventDefault() e.preventDefault()
@ -289,7 +289,7 @@ ipcMain.on('show-context-menu', (event) => {
{ label: 'Menu Item 2', type: 'checkbox', checked: true } { label: 'Menu Item 2', type: 'checkbox', checked: true }
] ]
const menu = Menu.buildFromTemplate(template) const menu = Menu.buildFromTemplate(template)
menu.popup(BrowserWindow.fromWebContents(event.sender)) menu.popup({ window: BrowserWindow.fromWebContents(event.sender) })
}) })
``` ```

View file

@ -17,7 +17,8 @@ Example:
```js ```js
// Main process // Main process
const { MessageChannelMain } = require('electron') const { BrowserWindow, MessageChannelMain } = require('electron')
const w = new BrowserWindow()
const { port1, port2 } = new MessageChannelMain() const { port1, port2 } = new MessageChannelMain()
w.webContents.postMessage('port', null, [port2]) w.webContents.postMessage('port', null, [port2])
port1.postMessage({ some: 'message' }) port1.postMessage({ some: 'message' })
@ -26,9 +27,9 @@ port1.postMessage({ some: 'message' })
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
ipcRenderer.on('port', (e) => { ipcRenderer.on('port', (e) => {
// e.ports is a list of ports sent along with this message // e.ports is a list of ports sent along with this message
e.ports[0].on('message', (messageEvent) => { e.ports[0].onmessage = (messageEvent) => {
console.log(messageEvent.data) console.log(messageEvent.data)
}) }
}) })
``` ```

View file

@ -5,7 +5,7 @@
Process: [Main](../glossary.md#main-process) Process: [Main](../glossary.md#main-process)
```javascript ```javascript
const { netLog } = require('electron') const { app, netLog } = require('electron')
app.whenReady().then(async () => { app.whenReady().then(async () => {
await netLog.startLogging('/path/to/net-log') await netLog.startLogging('/path/to/net-log')

View file

@ -32,7 +32,7 @@ To have your custom protocol work in combination with a custom session, you need
to register it to that session explicitly. to register it to that session explicitly.
```javascript ```javascript
const { session, app, protocol } = require('electron') const { app, BrowserWindow, net, protocol, session } = require('electron')
const path = require('path') const path = require('path')
const url = require('url') const url = require('url')
@ -41,11 +41,11 @@ app.whenReady().then(() => {
const ses = session.fromPartition(partition) const ses = session.fromPartition(partition)
ses.protocol.handle('atom', (request) => { ses.protocol.handle('atom', (request) => {
const path = request.url.slice('atom://'.length) const filePath = request.url.slice('atom://'.length)
return net.fetch(url.pathToFileURL(path.join(__dirname, path))) return net.fetch(url.pathToFileURL(path.join(__dirname, filePath)).toString())
}) })
mainWindow = new BrowserWindow({ webPreferences: { partition } }) const mainWindow = new BrowserWindow({ webPreferences: { partition } })
}) })
``` ```
@ -121,9 +121,9 @@ Either a `Response` or a `Promise<Response>` can be returned.
Example: Example:
```js ```js
import { app, protocol } from 'electron' const { app, net, protocol } = require('electron')
import { join } from 'path' const { join } = require('path')
import { pathToFileURL } from 'url' const { pathToFileURL } = require('url')
protocol.registerSchemesAsPrivileged([ protocol.registerSchemesAsPrivileged([
{ {
@ -131,7 +131,7 @@ protocol.registerSchemesAsPrivileged([
privileges: { privileges: {
standard: true, standard: true,
secure: true, secure: true,
supportsFetchAPI: true supportFetchAPI: true
} }
} }
]) ])
@ -147,7 +147,7 @@ app.whenReady().then(() => {
} }
// NB, this does not check for paths that escape the bundle, e.g. // NB, this does not check for paths that escape the bundle, e.g.
// app://bundle/../../secret_file.txt // app://bundle/../../secret_file.txt
return net.fetch(pathToFileURL(join(__dirname, pathname))) return net.fetch(pathToFileURL(join(__dirname, pathname)).toString())
} else if (host === 'api') { } else if (host === 'api') {
return net.fetch('https://api.my-server.com/' + pathname, { return net.fetch('https://api.my-server.com/' + pathname, {
method: req.method, method: req.method,

View file

@ -98,7 +98,7 @@ Emitted when Electron is about to download `item` in `webContents`.
Calling `event.preventDefault()` will cancel the download and `item` will not be Calling `event.preventDefault()` will cancel the download and `item` will not be
available from next tick of the process. available from next tick of the process.
```javascript ```javascript @ts-expect-error=[4]
const { session } = require('electron') const { session } = require('electron')
session.defaultSession.on('will-download', (event, item, webContents) => { session.defaultSession.on('will-download', (event, item, webContents) => {
event.preventDefault() event.preventDefault()
@ -214,7 +214,7 @@ cancel the request. Additionally, permissioning on `navigator.hid` can
be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler) be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler). and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
```javascript ```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@ -253,7 +253,7 @@ app.whenReady().then(() => {
win.webContents.session.on('select-hid-device', (event, details, callback) => { win.webContents.session.on('select-hid-device', (event, details, callback) => {
event.preventDefault() event.preventDefault()
const selectedDevice = details.deviceList.find((device) => { const selectedDevice = details.deviceList.find((device) => {
return device.vendorId === '9025' && device.productId === '67' return device.vendorId === 9025 && device.productId === 67
}) })
callback(selectedDevice?.deviceId) callback(selectedDevice?.deviceId)
}) })
@ -320,7 +320,7 @@ cancel the request. Additionally, permissioning on `navigator.serial` can
be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler) be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler)
with the `serial` permission. with the `serial` permission.
```javascript ```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@ -463,7 +463,7 @@ cancel the request. Additionally, permissioning on `navigator.usb` can
be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler) be further managed by using [`ses.setPermissionCheckHandler(handler)`](#sessetpermissioncheckhandlerhandler)
and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler). and [`ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
```javascript ```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)} @ts-type={updateGrantedDevices:(devices:Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)=>void}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@ -502,7 +502,7 @@ app.whenReady().then(() => {
win.webContents.session.on('select-usb-device', (event, details, callback) => { win.webContents.session.on('select-usb-device', (event, details, callback) => {
event.preventDefault() event.preventDefault()
const selectedDevice = details.deviceList.find((device) => { const selectedDevice = details.deviceList.find((device) => {
return device.vendorId === '9025' && device.productId === '67' return device.vendorId === 9025 && device.productId === 67
}) })
if (selectedDevice) { if (selectedDevice) {
// Optionally, add this to the persisted devices (updateGrantedDevices needs to be implemented by developer to persist permissions) // Optionally, add this to the persisted devices (updateGrantedDevices needs to be implemented by developer to persist permissions)
@ -755,15 +755,17 @@ Sets download saving directory. By default, the download directory will be the
Emulates network with the given configuration for the `session`. Emulates network with the given configuration for the `session`.
```javascript ```javascript
const win = new BrowserWindow()
// To emulate a GPRS connection with 50kbps throughput and 500 ms latency. // To emulate a GPRS connection with 50kbps throughput and 500 ms latency.
window.webContents.session.enableNetworkEmulation({ win.webContents.session.enableNetworkEmulation({
latency: 500, latency: 500,
downloadThroughput: 6400, downloadThroughput: 6400,
uploadThroughput: 6400 uploadThroughput: 6400
}) })
// To emulate a network outage. // To emulate a network outage.
window.webContents.session.enableNetworkEmulation({ offline: true }) win.webContents.session.enableNetworkEmulation({ offline: true })
``` ```
#### `ses.preconnect(options)` #### `ses.preconnect(options)`
@ -1036,7 +1038,7 @@ Additionally, the default behavior of Electron is to store granted device permis
If longer term storage is needed, a developer can store granted device If longer term storage is needed, a developer can store granted device
permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`. permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`.
```javascript ```javascript @ts-type={fetchGrantedDevices:()=>(Array<Electron.DevicePermissionHandlerHandlerDetails['device']>)}
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let win = null let win = null
@ -1084,9 +1086,9 @@ app.whenReady().then(() => {
win.webContents.session.on('select-hid-device', (event, details, callback) => { win.webContents.session.on('select-hid-device', (event, details, callback) => {
event.preventDefault() event.preventDefault()
const selectedDevice = details.deviceList.find((device) => { const selectedDevice = details.deviceList.find((device) => {
return device.vendorId === '9025' && device.productId === '67' return device.vendorId === 9025 && device.productId === 67
}) })
callback(selectedPort?.deviceId) callback(selectedDevice?.deviceId)
}) })
}) })
``` ```
@ -1174,23 +1176,17 @@ macOS does not require a handler because macOS handles the pairing
automatically. To clear the handler, call `setBluetoothPairingHandler(null)`. automatically. To clear the handler, call `setBluetoothPairingHandler(null)`.
```javascript ```javascript
const { app, BrowserWindow, session } = require('electron')
const { app, BrowserWindow, ipcMain, session } = require('electron') const path = require('path')
let bluetoothPinCallback = null
function createWindow () { function createWindow () {
let bluetoothPinCallback = null
const mainWindow = new BrowserWindow({ const mainWindow = new BrowserWindow({
webPreferences: { webPreferences: {
preload: path.join(__dirname, 'preload.js') preload: path.join(__dirname, 'preload.js')
} }
}) })
}
// Listen for an IPC message from the renderer to get the response for the Bluetooth pairing.
ipcMain.on('bluetooth-pairing-response', (event, response) => {
bluetoothPinCallback(response)
})
mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => { mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
bluetoothPinCallback = callback bluetoothPinCallback = callback
@ -1200,6 +1196,12 @@ mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) =>
mainWindow.webContents.send('bluetooth-pairing-request', details) mainWindow.webContents.send('bluetooth-pairing-request', details)
}) })
// Listen for an IPC message from the renderer to get the response for the Bluetooth pairing.
mainWindow.webContents.ipc.on('bluetooth-pairing-response', (event, response) => {
bluetoothPinCallback(response)
})
}
app.whenReady().then(() => { app.whenReady().then(() => {
createWindow() createWindow()
}) })

View file

@ -87,12 +87,12 @@ const { TouchBarLabel, TouchBarButton, TouchBarSpacer } = TouchBar
let spinning = false let spinning = false
// Reel labels // Reel labels
const reel1 = new TouchBarLabel() const reel1 = new TouchBarLabel({ label: '' })
const reel2 = new TouchBarLabel() const reel2 = new TouchBarLabel({ label: '' })
const reel3 = new TouchBarLabel() const reel3 = new TouchBarLabel({ label: '' })
// Spin result label // Spin result label
const result = new TouchBarLabel() const result = new TouchBarLabel({ label: '' })
// Spin button // Spin button
const spin = new TouchBarButton({ const spin = new TouchBarButton({

View file

@ -98,7 +98,7 @@ async function lookupTargetId (browserWindow) {
await wc.debugger.attach('1.3') await wc.debugger.attach('1.3')
const { targetInfo } = await wc.debugger.sendCommand('Target.getTargetInfo') const { targetInfo } = await wc.debugger.sendCommand('Target.getTargetInfo')
const { targetId } = targetInfo const { targetId } = targetInfo
const targetWebContents = await webContents.fromDevToolsTargetId(targetId) const targetWebContents = await wc.fromDevToolsTargetId(targetId)
} }
``` ```
@ -1020,9 +1020,9 @@ e.g. the `http://` or `file://`. If the load should bypass http cache then
use the `pragma` header to achieve it. use the `pragma` header to achieve it.
```javascript ```javascript
const { webContents } = require('electron') const win = new BrowserWindow()
const options = { extraHeaders: 'pragma: no-cache\n' } const options = { extraHeaders: 'pragma: no-cache\n' }
webContents.loadURL('https://github.com', options) win.webContents.loadURL('https://github.com', options)
``` ```
#### `contents.loadFile(filePath[, options])` #### `contents.loadFile(filePath[, options])`
@ -1052,6 +1052,7 @@ an app structure like this:
Would require code like this Would require code like this
```js ```js
const win = new BrowserWindow()
win.loadFile('src/index.html') win.loadFile('src/index.html')
``` ```
@ -1188,7 +1189,9 @@ when this process is unstable or unusable, for instance in order to recover
from the `unresponsive` event. from the `unresponsive` event.
```js ```js
contents.on('unresponsive', async () => { const win = new BrowserWindow()
win.webContents.on('unresponsive', async () => {
const { response } = await dialog.showMessageBox({ const { response } = await dialog.showMessageBox({
message: 'App X has become unresponsive', message: 'App X has become unresponsive',
title: 'Do you want to try forcefully reloading the app?', title: 'Do you want to try forcefully reloading the app?',
@ -1196,8 +1199,8 @@ contents.on('unresponsive', async () => {
cancelId: 1 cancelId: 1
}) })
if (response === 0) { if (response === 0) {
contents.forcefullyCrashRenderer() win.webContents.forcefullyCrashRenderer()
contents.reload() win.webContents.reload()
} }
}) })
``` ```
@ -1224,8 +1227,9 @@ Injects CSS into the current web page and returns a unique key for the inserted
stylesheet. stylesheet.
```js ```js
contents.on('did-finish-load', () => { const win = new BrowserWindow()
contents.insertCSS('html, body { background-color: #f00; }') win.webContents.on('did-finish-load', () => {
win.webContents.insertCSS('html, body { background-color: #f00; }')
}) })
``` ```
@ -1239,9 +1243,11 @@ Removes the inserted CSS from the current web page. The stylesheet is identified
by its key, which is returned from `contents.insertCSS(css)`. by its key, which is returned from `contents.insertCSS(css)`.
```js ```js
contents.on('did-finish-load', async () => { const win = new BrowserWindow()
const key = await contents.insertCSS('html, body { background-color: #f00; }')
contents.removeInsertedCSS(key) win.webContents.on('did-finish-load', async () => {
const key = await win.webContents.insertCSS('html, body { background-color: #f00; }')
win.webContents.removeInsertedCSS(key)
}) })
``` ```
@ -1262,7 +1268,9 @@ this limitation.
Code execution will be suspended until web page stop loading. Code execution will be suspended until web page stop loading.
```js ```js
contents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1").then(resp => resp.json())', true) const win = new BrowserWindow()
win.webContents.executeJavaScript('fetch("https://jsonplaceholder.typicode.com/users/1").then(resp => resp.json())', true)
.then((result) => { .then((result) => {
console.log(result) // Will be the JSON object from the fetch call console.log(result) // Will be the JSON object from the fetch call
}) })
@ -1373,7 +1381,8 @@ Sets the maximum and minimum pinch-to-zoom level.
> **NOTE**: Visual zoom is disabled by default in Electron. To re-enable it, call: > **NOTE**: Visual zoom is disabled by default in Electron. To re-enable it, call:
> >
> ```js > ```js
> contents.setVisualZoomLevelLimits(1, 3) > const win = new BrowserWindow()
> win.webContents.setVisualZoomLevelLimits(1, 3)
> ``` > ```
#### `contents.undo()` #### `contents.undo()`
@ -1508,12 +1517,12 @@ can be obtained by subscribing to [`found-in-page`](web-contents.md#event-found-
Stops any `findInPage` request for the `webContents` with the provided `action`. Stops any `findInPage` request for the `webContents` with the provided `action`.
```javascript ```javascript
const { webContents } = require('electron') const win = new BrowserWindow()
webContents.on('found-in-page', (event, result) => { win.webContents.on('found-in-page', (event, result) => {
if (result.finalUpdate) webContents.stopFindInPage('clearSelection') if (result.finalUpdate) win.webContents.stopFindInPage('clearSelection')
}) })
const requestId = webContents.findInPage('api') const requestId = win.webContents.findInPage('api')
console.log(requestId) console.log(requestId)
``` ```
@ -1593,6 +1602,7 @@ Use `page-break-before: always;` CSS style to force to print to a new page.
Example usage: Example usage:
```js ```js
const win = new BrowserWindow()
const options = { const options = {
silent: true, silent: true,
deviceName: 'My-Printer', deviceName: 'My-Printer',
@ -1889,8 +1899,9 @@ For example:
```js ```js
// Main process // Main process
const win = new BrowserWindow()
const { port1, port2 } = new MessageChannelMain() const { port1, port2 } = new MessageChannelMain()
webContents.postMessage('port', { message: 'hello' }, [port1]) win.webContents.postMessage('port', { message: 'hello' }, [port1])
// Renderer process // Renderer process
ipcRenderer.on('port', (e, msg) => { ipcRenderer.on('port', (e, msg) => {

View file

@ -128,8 +128,9 @@ For example:
```js ```js
// Main process // Main process
const win = new BrowserWindow()
const { port1, port2 } = new MessageChannelMain() const { port1, port2 } = new MessageChannelMain()
webContents.mainFrame.postMessage('port', { message: 'hello' }, [port1]) win.webContents.mainFrame.postMessage('port', { message: 'hello' }, [port1])
// Renderer process // Renderer process
ipcRenderer.on('port', (e, msg) => { ipcRenderer.on('port', (e, msg) => {

View file

@ -96,13 +96,12 @@ with an array of misspelt words when complete.
An example of using [node-spellchecker][spellchecker] as provider: An example of using [node-spellchecker][spellchecker] as provider:
```javascript ```javascript @ts-expect-error=[2,6]
const { webFrame } = require('electron') const { webFrame } = require('electron')
const spellChecker = require('spellchecker') const spellChecker = require('spellchecker')
webFrame.setSpellCheckProvider('en-US', { webFrame.setSpellCheckProvider('en-US', {
spellCheck (words, callback) { spellCheck (words, callback) {
setTimeout(() => { setTimeout(() => {
const spellchecker = require('spellchecker')
const misspelled = words.filter(x => spellchecker.isMisspelled(x)) const misspelled = words.filter(x => spellchecker.isMisspelled(x))
callback(misspelled) callback(misspelled)
}, 0) }, 0)

View file

@ -255,7 +255,7 @@ The `webview` tag has the following methods:
**Example** **Example**
```javascript ```javascript @ts-expect-error=[3]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('dom-ready', () => { webview.addEventListener('dom-ready', () => {
webview.openDevTools() webview.openDevTools()
@ -799,7 +799,7 @@ Fired when the guest window logs a console message.
The following example code forwards all log messages to the embedder's console The following example code forwards all log messages to the embedder's console
without regard for log level or other properties. without regard for log level or other properties.
```javascript ```javascript @ts-expect-error=[3]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('console-message', (e) => { webview.addEventListener('console-message', (e) => {
console.log('Guest page logged a message:', e.message) console.log('Guest page logged a message:', e.message)
@ -820,7 +820,7 @@ Returns:
Fired when a result is available for Fired when a result is available for
[`webview.findInPage`](#webviewfindinpagetext-options) request. [`webview.findInPage`](#webviewfindinpagetext-options) request.
```javascript ```javascript @ts-expect-error=[3,6]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('found-in-page', (e) => { webview.addEventListener('found-in-page', (e) => {
webview.stopFindInPage('keepSelection') webview.stopFindInPage('keepSelection')
@ -945,7 +945,7 @@ Fired when the guest page attempts to close itself.
The following example code navigates the `webview` to `about:blank` when the The following example code navigates the `webview` to `about:blank` when the
guest attempts to close itself. guest attempts to close itself.
```javascript ```javascript @ts-expect-error=[3]
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('close', () => { webview.addEventListener('close', () => {
webview.src = 'about:blank' webview.src = 'about:blank'
@ -965,7 +965,7 @@ Fired when the guest page has sent an asynchronous message to embedder page.
With `sendToHost` method and `ipc-message` event you can communicate With `sendToHost` method and `ipc-message` event you can communicate
between guest page and embedder page: between guest page and embedder page:
```javascript ```javascript @ts-expect-error=[4,7]
// In embedder page. // In embedder page.
const webview = document.querySelector('webview') const webview = document.querySelector('webview')
webview.addEventListener('ipc-message', (event) => { webview.addEventListener('ipc-message', (event) => {

View file

@ -55,7 +55,7 @@ fs.readdirSync('/path/to/example.asar')
Use a module from the archive: Use a module from the archive:
```javascript ```javascript @ts-nocheck
require('./path/to/example.asar/dir/module.js') require('./path/to/example.asar/dir/module.js')
``` ```

View file

@ -40,7 +40,7 @@ Valid `algorithm` values are currently `SHA256` only. The `hash` is a hash of t
ASAR integrity checking is currently disabled by default and can be enabled by toggling a fuse. See [Electron Fuses](fuses.md) for more information on what Electron Fuses are and how they work. When enabling this fuse you typically also want to enable the `onlyLoadAppFromAsar` fuse otherwise the validity checking can be bypassed via the Electron app code search path. ASAR integrity checking is currently disabled by default and can be enabled by toggling a fuse. See [Electron Fuses](fuses.md) for more information on what Electron Fuses are and how they work. When enabling this fuse you typically also want to enable the `onlyLoadAppFromAsar` fuse otherwise the validity checking can be bypassed via the Electron app code search path.
```js ```js @ts-nocheck
require('@electron/fuses').flipFuses( require('@electron/fuses').flipFuses(
// E.g. /a/b/Foo.app // E.g. /a/b/Foo.app
pathToPackagedApp, pathToPackagedApp,

View file

@ -90,7 +90,7 @@ Usage of `selenium-webdriver` with Electron is the same as with
normal websites, except that you have to manually specify how to connect normal websites, except that you have to manually specify how to connect
ChromeDriver and where to find the binary of your Electron app: ChromeDriver and where to find the binary of your Electron app:
```js title='test.js' ```js title='test.js' @ts-expect-error=[1]
const webdriver = require('selenium-webdriver') const webdriver = require('selenium-webdriver')
const driver = new webdriver.Builder() const driver = new webdriver.Builder()
// The "9515" is the port opened by ChromeDriver. // The "9515" is the port opened by ChromeDriver.
@ -155,7 +155,7 @@ Playwright launches your app in development mode through the `_electron.launch`
To point this API to your Electron app, you can pass the path to your main process To point this API to your Electron app, you can pass the path to your main process
entry point (here, it is `main.js`). entry point (here, it is `main.js`).
```js {5} ```js {5} @ts-nocheck
const { _electron: electron } = require('playwright') const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test') const { test } = require('@playwright/test')
@ -169,7 +169,7 @@ test('launch app', async () => {
After that, you will access to an instance of Playwright's `ElectronApp` class. This After that, you will access to an instance of Playwright's `ElectronApp` class. This
is a powerful class that has access to main process modules for example: is a powerful class that has access to main process modules for example:
```js {6-11} ```js {6-11} @ts-nocheck
const { _electron: electron } = require('playwright') const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test') const { test } = require('@playwright/test')
@ -189,7 +189,7 @@ test('get isPackaged', async () => {
It can also create individual [Page][playwright-page] objects from Electron BrowserWindow instances. It can also create individual [Page][playwright-page] objects from Electron BrowserWindow instances.
For example, to grab the first BrowserWindow and save a screenshot: For example, to grab the first BrowserWindow and save a screenshot:
```js {6-7} ```js {6-7} @ts-nocheck
const { _electron: electron } = require('playwright') const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test') const { test } = require('@playwright/test')
@ -205,7 +205,7 @@ test('save screenshot', async () => {
Putting all this together using the PlayWright Test runner, let's create a `example.spec.js` Putting all this together using the PlayWright Test runner, let's create a `example.spec.js`
test file with a single test and assertion: test file with a single test and assertion:
```js title='example.spec.js' ```js title='example.spec.js' @ts-nocheck
const { _electron: electron } = require('playwright') const { _electron: electron } = require('playwright')
const { test, expect } = require('@playwright/test') const { test, expect } = require('@playwright/test')
@ -259,7 +259,7 @@ expose custom methods to your test suite.
To create a custom driver, we'll use Node.js' [`child_process`](https://nodejs.org/api/child_process.html) API. To create a custom driver, we'll use Node.js' [`child_process`](https://nodejs.org/api/child_process.html) API.
The test suite will spawn the Electron process, then establish a simple messaging protocol: The test suite will spawn the Electron process, then establish a simple messaging protocol:
```js title='testDriver.js' ```js title='testDriver.js' @ts-nocheck
const childProcess = require('child_process') const childProcess = require('child_process')
const electronPath = require('electron') const electronPath = require('electron')
@ -296,7 +296,7 @@ For convenience, you may want to wrap `appProcess` in a driver object that provi
high-level functions. Here is an example of how you can do this. Let's start by creating high-level functions. Here is an example of how you can do this. Let's start by creating
a `TestDriver` class: a `TestDriver` class:
```js title='testDriver.js' ```js title='testDriver.js' @ts-nocheck
class TestDriver { class TestDriver {
constructor ({ path, args, env }) { constructor ({ path, args, env }) {
this.rpcCalls = [] this.rpcCalls = []
@ -378,7 +378,7 @@ framework of your choosing. The following example uses
[`ava`](https://www.npmjs.com/package/ava), but other popular choices like Jest [`ava`](https://www.npmjs.com/package/ava), but other popular choices like Jest
or Mocha would work as well: or Mocha would work as well:
```js title='test.js' ```js title='test.js' @ts-nocheck
const test = require('ava') const test = require('ava')
const electronPath = require('electron') const electronPath = require('electron')
const { TestDriver } = require('./testDriver') const { TestDriver } = require('./testDriver')

View file

@ -67,7 +67,7 @@ are likely using [`electron-packager`][], which includes [`@electron/osx-sign`][
If you're using Packager's API, you can pass [in configuration that both signs If you're using Packager's API, you can pass [in configuration that both signs
and notarizes your application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html). and notarizes your application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html).
```js ```js @ts-nocheck
const packager = require('electron-packager') const packager = require('electron-packager')
packager({ packager({
@ -116,7 +116,7 @@ Electron app. This is the tool used under the hood by Electron Forge's
`electron-winstaller` directly, use the `certificateFile` and `certificatePassword` configuration `electron-winstaller` directly, use the `certificateFile` and `certificatePassword` configuration
options when creating your installer. options when creating your installer.
```js {10-11} ```js {10-11} @ts-nocheck
const electronInstaller = require('electron-winstaller') const electronInstaller = require('electron-winstaller')
// NB: Use this syntax within an async function, Node does not have support for // NB: Use this syntax within an async function, Node does not have support for
// top-level await as of Node 12. // top-level await as of Node 12.
@ -146,7 +146,7 @@ If you're not using Electron Forge and want to use `electron-wix-msi` directly,
`certificateFile` and `certificatePassword` configuration options `certificateFile` and `certificatePassword` configuration options
or pass in parameters directly to [SignTool.exe][] with the `signWithParams` option. or pass in parameters directly to [SignTool.exe][] with the `signWithParams` option.
```js {12-13} ```js {12-13} @ts-nocheck
import { MSICreator } from 'electron-wix-msi' import { MSICreator } from 'electron-wix-msi'
// Step 1: Instantiate the MSICreator // Step 1: Instantiate the MSICreator

View file

@ -16,7 +16,7 @@ Context isolation has been enabled by default since Electron 12, and it is a rec
Exposing APIs from your preload script to a loaded website in the renderer process is a common use-case. With context isolation disabled, your preload script would share a common global `window` object with the renderer. You could then attach arbitrary properties to a preload script: Exposing APIs from your preload script to a loaded website in the renderer process is a common use-case. With context isolation disabled, your preload script would share a common global `window` object with the renderer. You could then attach arbitrary properties to a preload script:
```javascript title='preload.js' ```javascript title='preload.js' @ts-nocheck
// preload with contextIsolation disabled // preload with contextIsolation disabled
window.myAPI = { window.myAPI = {
doAThing: () => {} doAThing: () => {}
@ -25,7 +25,7 @@ window.myAPI = {
The `doAThing()` function could then be used directly in the renderer process: The `doAThing()` function could then be used directly in the renderer process:
```javascript title='renderer.js' ```javascript title='renderer.js' @ts-nocheck
// use the exposed API in the renderer // use the exposed API in the renderer
window.myAPI.doAThing() window.myAPI.doAThing()
``` ```
@ -43,7 +43,7 @@ contextBridge.exposeInMainWorld('myAPI', {
}) })
``` ```
```javascript title='renderer.js' ```javascript title='renderer.js' @ts-nocheck
// use the exposed API in the renderer // use the exposed API in the renderer
window.myAPI.doAThing() window.myAPI.doAThing()
``` ```
@ -98,7 +98,7 @@ declare global {
Doing so will ensure that the TypeScript compiler will know about the `electronAPI` property on your global `window` object when writing scripts in your renderer process: Doing so will ensure that the TypeScript compiler will know about the `electronAPI` property on your global `window` object when writing scripts in your renderer process:
```typescript title='renderer.ts' ```typescript title='renderer.ts' @ts-nocheck
window.electronAPI.loadPreferences() window.electronAPI.loadPreferences()
``` ```

View file

@ -116,7 +116,7 @@ Now the renderer process can communicate with the main process securely and perf
The `renderer.js` file is responsible for controlling the `<button>` functionality. The `renderer.js` file is responsible for controlling the `<button>` functionality.
```js title='renderer.js' ```js title='renderer.js' @ts-expect-error=[2,7]
document.getElementById('toggle-dark-mode').addEventListener('click', async () => { document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
const isDarkMode = await window.darkMode.toggle() const isDarkMode = await window.darkMode.toggle()
document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light' document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'

View file

@ -67,7 +67,7 @@ The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is
We've made a handy module, [`@electron/fuses`](https://npmjs.com/package/@electron/fuses), to make flipping these fuses easy. Check out the README of that module for more details on usage and potential error cases. We've made a handy module, [`@electron/fuses`](https://npmjs.com/package/@electron/fuses), to make flipping these fuses easy. Check out the README of that module for more details on usage and potential error cases.
```js ```js @ts-nocheck
require('@electron/fuses').flipFuses( require('@electron/fuses').flipFuses(
// Path to electron // Path to electron
require('electron'), require('electron'),

View file

@ -66,7 +66,7 @@ You can use environment variables to override the base URL, the path at which to
look for Electron binaries, and the binary filename. The URL used by `@electron/get` look for Electron binaries, and the binary filename. The URL used by `@electron/get`
is composed as follows: is composed as follows:
```javascript ```javascript @ts-nocheck
url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME url = ELECTRON_MIRROR + ELECTRON_CUSTOM_DIR + '/' + ELECTRON_CUSTOM_FILENAME
``` ```

View file

@ -138,7 +138,7 @@ To make these elements interactive, we'll be adding a few lines of code in the i
`renderer.js` file that leverages the `window.electronAPI` functionality exposed from the preload `renderer.js` file that leverages the `window.electronAPI` functionality exposed from the preload
script: script:
```javascript title='renderer.js (Renderer Process)' ```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[4,5]
const setButton = document.getElementById('btn') const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title') const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => { setButton.addEventListener('click', () => {
@ -182,13 +182,13 @@ provided to the renderer process. Please refer to
::: :::
```javascript {6-13,25} title='main.js (Main Process)' ```javascript {6-13,25} title='main.js (Main Process)'
const { BrowserWindow, dialog, ipcMain } = require('electron') const { app, BrowserWindow, dialog, ipcMain } = require('electron')
const path = require('path') const path = require('path')
// ... // ...
async function handleFileOpen () { async function handleFileOpen () {
const { canceled, filePaths } = await dialog.showOpenDialog() const { canceled, filePaths } = await dialog.showOpenDialog({})
if (!canceled) { if (!canceled) {
return filePaths[0] return filePaths[0]
} }
@ -203,7 +203,7 @@ function createWindow () {
mainWindow.loadFile('index.html') mainWindow.loadFile('index.html')
} }
app.whenReady(() => { app.whenReady().then(() => {
ipcMain.handle('dialog:openFile', handleFileOpen) ipcMain.handle('dialog:openFile', handleFileOpen)
createWindow() createWindow()
}) })
@ -263,7 +263,7 @@ The UI consists of a single `#btn` button element that will be used to trigger o
a `#filePath` element that will be used to display the path of the selected file. Making these a `#filePath` element that will be used to display the path of the selected file. Making these
pieces work will take a few lines of code in the renderer process script: pieces work will take a few lines of code in the renderer process script:
```javascript title='renderer.js (Renderer Process)' ```javascript title='renderer.js (Renderer Process)' @ts-expect-error=[5]
const btn = document.getElementById('btn') const btn = document.getElementById('btn')
const filePathElement = document.getElementById('filePath') const filePathElement = document.getElementById('filePath')
@ -412,7 +412,7 @@ function createWindow () {
For the purposes of the tutorial, it's important to note that the `click` handler For the purposes of the tutorial, it's important to note that the `click` handler
sends a message (either `1` or `-1`) to the renderer process through the `update-counter` channel. sends a message (either `1` or `-1`) to the renderer process through the `update-counter` channel.
```javascript ```javascript @ts-nocheck
click: () => mainWindow.webContents.send('update-counter', -1) click: () => mainWindow.webContents.send('update-counter', -1)
``` ```
@ -486,7 +486,7 @@ To tie it all together, we'll create an interface in the loaded HTML file that c
Finally, to make the values update in the HTML document, we'll add a few lines of DOM manipulation Finally, to make the values update in the HTML document, we'll add a few lines of DOM manipulation
so that the value of the `#counter` element is updated whenever we fire an `update-counter` event. so that the value of the `#counter` element is updated whenever we fire an `update-counter` event.
```javascript title='renderer.js (Renderer Process)' ```javascript title='renderer.js (Renderer Process)' @ts-nocheck
const counter = document.getElementById('counter') const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((_event, value) => { window.electronAPI.onUpdateCounter((_event, value) => {
@ -509,7 +509,7 @@ We can demonstrate this with slight modifications to the code from the previous
renderer process, use the `event` parameter to send a reply back to the main process through the renderer process, use the `event` parameter to send a reply back to the main process through the
`counter-value` channel. `counter-value` channel.
```javascript title='renderer.js (Renderer Process)' ```javascript title='renderer.js (Renderer Process)' @ts-nocheck
const counter = document.getElementById('counter') const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((event, value) => { window.electronAPI.onUpdateCounter((event, value) => {

View file

@ -56,7 +56,7 @@ Starting with a working application from the
[Quick Start Guide](quick-start.md), update the `main.js` file with the [Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines: following lines:
```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/global' ```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/global' @ts-type={createWindow:()=>void}
const { app, globalShortcut } = require('electron') const { app, globalShortcut } = require('electron')
app.whenReady().then(() => { app.whenReady().then(() => {
@ -131,7 +131,7 @@ If you don't want to do manual shortcut parsing, there are libraries that do
advanced key detection, such as [mousetrap][]. Below are examples of usage of the advanced key detection, such as [mousetrap][]. Below are examples of usage of the
`mousetrap` running in the Renderer process: `mousetrap` running in the Renderer process:
```js ```js @ts-nocheck
Mousetrap.bind('4', () => { console.log('4') }) Mousetrap.bind('4', () => { console.log('4') })
Mousetrap.bind('?', () => { console.log('show shortcuts!') }) Mousetrap.bind('?', () => { console.log('show shortcuts!') })
Mousetrap.bind('esc', () => { console.log('escape') }, 'keyup') Mousetrap.bind('esc', () => { console.log('escape') }, 'keyup')

View file

@ -45,6 +45,8 @@ if (process.defaultApp) {
We will now define the function in charge of creating our browser window and load our application's `index.html` file. We will now define the function in charge of creating our browser window and load our application's `index.html` file.
```javascript ```javascript
let mainWindow
const createWindow = () => { const createWindow = () => {
// Create the browser window. // Create the browser window.
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
@ -65,7 +67,7 @@ This code will be different in Windows compared to MacOS and Linux. This is due
#### Windows code: #### Windows code:
```javascript ```javascript @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
const gotTheLock = app.requestSingleInstanceLock() const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) { if (!gotTheLock) {
@ -91,7 +93,7 @@ if (!gotTheLock) {
#### MacOS and Linux code: #### MacOS and Linux code:
```javascript ```javascript @ts-type={createWindow:()=>void}
// This method will be called when Electron has finished // This method will be called when Electron has finished
// initialization and is ready to create browser windows. // initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs. // Some APIs can only be used after this event occurs.
@ -166,7 +168,7 @@ If you're using Electron Packager's API, adding support for protocol handlers is
Electron Forge is handled, except Electron Forge is handled, except
`protocols` is part of the Packager options passed to the `packager` function. `protocols` is part of the Packager options passed to the `packager` function.
```javascript ```javascript @ts-nocheck
const packager = require('electron-packager') const packager = require('electron-packager')
packager({ packager({

View file

@ -126,7 +126,7 @@ app.whenReady().then(async () => {
Then, in your preload scripts you receive the port through IPC and set up the Then, in your preload scripts you receive the port through IPC and set up the
listeners. listeners.
```js title='preloadMain.js and preloadSecondary.js (Preload scripts)' ```js title='preloadMain.js and preloadSecondary.js (Preload scripts)' @ts-nocheck
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
ipcRenderer.on('port', e => { ipcRenderer.on('port', e => {
@ -148,7 +148,7 @@ That means window.electronMessagePort is globally available and you can call
`postMessage` on it from anywhere in your app to send a message to the other `postMessage` on it from anywhere in your app to send a message to the other
renderer. renderer.
```js title='renderer.js (Renderer Process)' ```js title='renderer.js (Renderer Process)' @ts-nocheck
// elsewhere in your code to send a message to the other renderers message handler // elsewhere in your code to send a message to the other renderers message handler
window.electronMessagePort.postmessage('ping') window.electronMessagePort.postmessage('ping')
``` ```
@ -181,7 +181,7 @@ app.whenReady().then(async () => {
// We can't use ipcMain.handle() here, because the reply needs to transfer a // We can't use ipcMain.handle() here, because the reply needs to transfer a
// MessagePort. // MessagePort.
// Listen for message sent from the top-level frame // Listen for message sent from the top-level frame
mainWindow.webContents.mainFrame.on('request-worker-channel', (event) => { mainWindow.webContents.mainFrame.ipc.on('request-worker-channel', (event) => {
// Create a new channel ... // Create a new channel ...
const { port1, port2 } = new MessageChannelMain() const { port1, port2 } = new MessageChannelMain()
// ... send one end to the worker ... // ... send one end to the worker ...
@ -245,7 +245,7 @@ Electron's built-in IPC methods only support two modes: fire-and-forget
can implement a "response stream", where a single request responds with a can implement a "response stream", where a single request responds with a
stream of data. stream of data.
```js title='renderer.js (Renderer Process)' ```js title='renderer.js (Renderer Process)' @ts-expect-error=[18]
const makeStreamingRequest = (element, callback) => { const makeStreamingRequest = (element, callback) => {
// MessageChannels are lightweight--it's cheap to create a new one for each // MessageChannels are lightweight--it's cheap to create a new one for each
// request. // request.

View file

@ -42,7 +42,7 @@ safe.
The only way to load a native module safely for now, is to make sure the app The only way to load a native module safely for now, is to make sure the app
loads no native modules after the Web Workers get started. loads no native modules after the Web Workers get started.
```javascript ```javascript @ts-expect-error=[1]
process.dlopen = () => { process.dlopen = () => {
throw new Error('Load native module is not safe') throw new Error('Load native module is not safe')
} }

View file

@ -22,6 +22,7 @@ In `preload.js` use the [`contextBridge`][] to inject a method `window.electron.
```js ```js
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
const path = require('path')
contextBridge.exposeInMainWorld('electron', { contextBridge.exposeInMainWorld('electron', {
startDrag: (fileName) => { startDrag: (fileName) => {
@ -43,7 +44,7 @@ Add a draggable element to `index.html`, and reference your renderer script:
In `renderer.js` set up the renderer process to handle drag events by calling the method you added via the [`contextBridge`][] above. In `renderer.js` set up the renderer process to handle drag events by calling the method you added via the [`contextBridge`][] above.
```javascript ```javascript @ts-expect-error=[3]
document.getElementById('drag').ondragstart = (event) => { document.getElementById('drag').ondragstart = (event) => {
event.preventDefault() event.preventDefault()
window.electron.startDrag('drag-and-drop.md') window.electron.startDrag('drag-and-drop.md')

View file

@ -173,7 +173,7 @@ in the fictitious `.foo` format. In order to do that, it relies on the
equally fictitious `foo-parser` module. In traditional Node.js development, equally fictitious `foo-parser` module. In traditional Node.js development,
you might write code that eagerly loads dependencies: you might write code that eagerly loads dependencies:
```js title='parser.js' ```js title='parser.js' @ts-expect-error=[2]
const fs = require('fs') const fs = require('fs')
const fooParser = require('foo-parser') const fooParser = require('foo-parser')
@ -196,7 +196,7 @@ In the above example, we're doing a lot of work that's being executed as soon
as the file is loaded. Do we need to get parsed files right away? Could we as the file is loaded. Do we need to get parsed files right away? Could we
do this work a little later, when `getParsedFiles()` is actually called? do this work a little later, when `getParsedFiles()` is actually called?
```js title='parser.js' ```js title='parser.js' @ts-expect-error=[20]
// "fs" is likely already being loaded, so the `require()` call is cheap // "fs" is likely already being loaded, so the `require()` call is cheap
const fs = require('fs') const fs = require('fs')
@ -205,7 +205,7 @@ class Parser {
// Touch the disk as soon as `getFiles` is called, not sooner. // Touch the disk as soon as `getFiles` is called, not sooner.
// Also, ensure that we're not blocking other operations by using // Also, ensure that we're not blocking other operations by using
// the asynchronous version. // the asynchronous version.
this.files = this.files || await fs.readdir('.') this.files = this.files || await fs.promises.readdir('.')
return this.files return this.files
} }

View file

@ -175,13 +175,13 @@ Although preload scripts share a `window` global with the renderer they're attac
you cannot directly attach any variables from the preload script to `window` because of you cannot directly attach any variables from the preload script to `window` because of
the [`contextIsolation`][context-isolation] default. the [`contextIsolation`][context-isolation] default.
```js title='preload.js' ```js title='preload.js' @ts-nocheck
window.myAPI = { window.myAPI = {
desktop: true desktop: true
} }
``` ```
```js title='renderer.js' ```js title='renderer.js' @ts-nocheck
console.log(window.myAPI) console.log(window.myAPI)
// => undefined // => undefined
``` ```
@ -200,7 +200,7 @@ contextBridge.exposeInMainWorld('myAPI', {
}) })
``` ```
```js title='renderer.js' ```js title='renderer.js' @ts-nocheck
console.log(window.myAPI) console.log(window.myAPI)
// => { desktop: true } // => { desktop: true }
``` ```

View file

@ -182,7 +182,7 @@ In Electron, browser windows can only be created after the `app` module's
[`app.whenReady()`][app-when-ready] API. Call `createWindow()` after `whenReady()` [`app.whenReady()`][app-when-ready] API. Call `createWindow()` after `whenReady()`
resolves its Promise. resolves its Promise.
```js ```js @ts-type={createWindow:()=>void}
app.whenReady().then(() => { app.whenReady().then(() => {
createWindow() createWindow()
}) })
@ -239,7 +239,7 @@ from within your existing `whenReady()` callback.
[activate]: ../api/app.md#event-activate-macos [activate]: ../api/app.md#event-activate-macos
```js ```js @ts-type={createWindow:()=>void}
app.whenReady().then(() => { app.whenReady().then(() => {
createWindow() createWindow()
@ -290,6 +290,7 @@ To attach this script to your renderer process, pass in the path to your preload
to the `webPreferences.preload` option in your existing `BrowserWindow` constructor. to the `webPreferences.preload` option in your existing `BrowserWindow` constructor.
```js ```js
const { app, BrowserWindow } = require('electron')
// include the Node.js 'path' module at the top of your file // include the Node.js 'path' module at the top of your file
const path = require('path') const path = require('path')

View file

@ -141,7 +141,7 @@ like `HTTP`. Similarly, we recommend the use of `WSS` over `WS`, `FTPS` over
#### How? #### How?
```js title='main.js (Main Process)' ```js title='main.js (Main Process)' @ts-type={browserWindow:Electron.BrowserWindow}
// Bad // Bad
browserWindow.loadURL('http://example.com') browserWindow.loadURL('http://example.com')
@ -278,7 +278,7 @@ security-conscious developers might want to assume the very opposite.
```js title='main.js (Main Process)' ```js title='main.js (Main Process)'
const { session } = require('electron') const { session } = require('electron')
const URL = require('url').URL const { URL } = require('url')
session session
.fromPartition('some-partition') .fromPartition('some-partition')
@ -608,7 +608,8 @@ sometimes be fooled - a `startsWith('https://example.com')` test would let
`https://example.com.attacker.com` through. `https://example.com.attacker.com` through.
```js title='main.js (Main Process)' ```js title='main.js (Main Process)'
const URL = require('url').URL const { URL } = require('url')
const { app } = require('electron')
app.on('web-contents-created', (event, contents) => { app.on('web-contents-created', (event, contents) => {
contents.on('will-navigate', (event, navigationUrl) => { contents.on('will-navigate', (event, navigationUrl) => {
@ -647,8 +648,8 @@ receive, amongst other parameters, the `url` the window was requested to open
and the options used to create it. We recommend that you register a handler to and the options used to create it. We recommend that you register a handler to
monitor the creation of windows, and deny any unexpected window creation. monitor the creation of windows, and deny any unexpected window creation.
```js title='main.js (Main Process)' ```js title='main.js (Main Process)' @ts-type={isSafeForExternalOpen:(url:string)=>boolean}
const { shell } = require('electron') const { app, shell } = require('electron')
app.on('web-contents-created', (event, contents) => { app.on('web-contents-created', (event, contents) => {
contents.setWindowOpenHandler(({ url }) => { contents.setWindowOpenHandler(({ url }) => {
@ -683,7 +684,7 @@ leveraged to execute arbitrary commands.
#### How? #### How?
```js title='main.js (Main Process)' ```js title='main.js (Main Process)' @ts-type={USER_CONTROLLED_DATA_HERE:string}
// Bad // Bad
const { shell } = require('electron') const { shell } = require('electron')
shell.openExternal(USER_CONTROLLED_DATA_HERE) shell.openExternal(USER_CONTROLLED_DATA_HERE)
@ -739,7 +740,7 @@ You should be validating the `sender` of **all** IPC messages by default.
#### How? #### How?
```js title='main.js (Main Process)' ```js title='main.js (Main Process)' @ts-type={getSecrets:()=>unknown}
// Bad // Bad
ipcMain.handle('get-secrets', () => { ipcMain.handle('get-secrets', () => {
return getSecrets() return getSecrets()

View file

@ -72,7 +72,7 @@ npx electron-installer-snap --src=out/myappname-linux-x64
If you have an existing build pipeline, you can use `electron-installer-snap` If you have an existing build pipeline, you can use `electron-installer-snap`
programmatically. For more information, see the [Snapcraft API docs][snapcraft-syntax]. programmatically. For more information, see the [Snapcraft API docs][snapcraft-syntax].
```js ```js @ts-nocheck
const snap = require('electron-installer-snap') const snap = require('electron-installer-snap')
snap(options) snap(options)

View file

@ -20,12 +20,12 @@ On macOS as we use the native APIs there is no way to set the language that the
For Windows and Linux there are a few Electron APIs you should use to set the languages for the spellchecker. For Windows and Linux there are a few Electron APIs you should use to set the languages for the spellchecker.
```js ```js @ts-type={myWindow:Electron.BrowserWindow}
// Sets the spellchecker to check English US and French // Sets the spellchecker to check English US and French
myWindow.session.setSpellCheckerLanguages(['en-US', 'fr']) myWindow.webContents.session.setSpellCheckerLanguages(['en-US', 'fr'])
// An array of all available language codes // An array of all available language codes
const possibleLanguages = myWindow.session.availableSpellCheckerLanguages const possibleLanguages = myWindow.webContents.session.availableSpellCheckerLanguages
``` ```
By default the spellchecker will enable the language matching the current OS locale. By default the spellchecker will enable the language matching the current OS locale.
@ -35,7 +35,7 @@ By default the spellchecker will enable the language matching the current OS loc
All the required information to generate a context menu is provided in the [`context-menu`](../api/web-contents.md#event-context-menu) event on each `webContents` instance. A small example All the required information to generate a context menu is provided in the [`context-menu`](../api/web-contents.md#event-context-menu) event on each `webContents` instance. A small example
of how to make a context menu with this information is provided below. of how to make a context menu with this information is provided below.
```js ```js @ts-type={myWindow:Electron.BrowserWindow}
const { Menu, MenuItem } = require('electron') const { Menu, MenuItem } = require('electron')
myWindow.webContents.on('context-menu', (event, params) => { myWindow.webContents.on('context-menu', (event, params) => {
@ -45,7 +45,7 @@ myWindow.webContents.on('context-menu', (event, params) => {
for (const suggestion of params.dictionarySuggestions) { for (const suggestion of params.dictionarySuggestions) {
menu.append(new MenuItem({ menu.append(new MenuItem({
label: suggestion, label: suggestion,
click: () => mainWindow.webContents.replaceMisspelling(suggestion) click: () => myWindow.webContents.replaceMisspelling(suggestion)
})) }))
} }
@ -54,7 +54,7 @@ myWindow.webContents.on('context-menu', (event, params) => {
menu.append( menu.append(
new MenuItem({ new MenuItem({
label: 'Add to dictionary', label: 'Add to dictionary',
click: () => mainWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord) click: () => myWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord)
}) })
) )
} }
@ -67,8 +67,8 @@ myWindow.webContents.on('context-menu', (event, params) => {
Although the spellchecker itself does not send any typings, words or user input to Google services the hunspell dictionary files are downloaded from a Google CDN by default. If you want to avoid this you can provide an alternative URL to download the dictionaries from. Although the spellchecker itself does not send any typings, words or user input to Google services the hunspell dictionary files are downloaded from a Google CDN by default. If you want to avoid this you can provide an alternative URL to download the dictionaries from.
```js ```js @ts-type={myWindow:Electron.BrowserWindow}
myWindow.session.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/') myWindow.webContents.session.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/')
``` ```
Check out the docs for [`session.setSpellCheckerDictionaryDownloadURL`](../api/session.md#sessetspellcheckerdictionarydownloadurlurl) for more information on where to get the dictionary files from and how you need to host them. Check out the docs for [`session.setSpellCheckerDictionaryDownloadURL`](../api/session.md#sessetspellcheckerdictionarydownloadurlurl) for more information on where to get the dictionary files from and how you need to host them.

View file

@ -51,7 +51,7 @@ app.whenReady().then(() => {
Great! Now we can start attaching a context menu to our Tray, like so: Great! Now we can start attaching a context menu to our Tray, like so:
```js ```js @ts-expect-error=[8]
const contextMenu = Menu.buildFromTemplate([ const contextMenu = Menu.buildFromTemplate([
{ label: 'Item1', type: 'radio' }, { label: 'Item1', type: 'radio' },
{ label: 'Item2', type: 'radio' }, { label: 'Item2', type: 'radio' },
@ -68,7 +68,7 @@ To read more about constructing native menus, click
Finally, let's give our tray a tooltip and a title. Finally, let's give our tray a tooltip and a title.
```js ```js @ts-type={tray:Electron.Tray}
tray.setToolTip('This is my application') tray.setToolTip('This is my application')
tray.setTitle('This is my title') tray.setTitle('This is my title')
``` ```

View file

@ -256,7 +256,7 @@ const createWindow = () => {
### Calling your function when the app is ready ### Calling your function when the app is ready
```js title='main.js (Lines 12-14)' ```js title='main.js (Lines 12-14)' @ts-type={createWindow:()=>void}
app.whenReady().then(() => { app.whenReady().then(() => {
createWindow() createWindow()
}) })
@ -336,7 +336,7 @@ Because windows cannot be created before the `ready` event, you should only list
`activate` events after your app is initialized. Do this by only listening for activate `activate` events after your app is initialized. Do this by only listening for activate
events inside your existing `whenReady()` callback. events inside your existing `whenReady()` callback.
```js ```js @ts-type={createWindow:()=>void}
app.whenReady().then(() => { app.whenReady().then(() => {
createWindow() createWindow()

View file

@ -118,7 +118,7 @@ information in the window. This variable can be accessed via `window.versions` o
`versions`. Create a `renderer.js` script that uses the [`document.getElementById`][] `versions`. Create a `renderer.js` script that uses the [`document.getElementById`][]
DOM API to replace the displayed text for the HTML element with `info` as its `id` property. DOM API to replace the displayed text for the HTML element with `info` as its `id` property.
```js title="renderer.js" ```js title="renderer.js" @ts-nocheck
const information = document.getElementById('info') const information = document.getElementById('info')
information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})` information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})`
``` ```
@ -225,7 +225,7 @@ app.whenReady().then(() => {
Once you have the sender and receiver set up, you can now send messages from the renderer Once you have the sender and receiver set up, you can now send messages from the renderer
to the main process through the `'ping'` channel you just defined. to the main process through the `'ping'` channel you just defined.
```js title='renderer.js' ```js title='renderer.js' @ts-expect-error=[2]
const func = async () => { const func = async () => {
const response = await window.versions.ping() const response = await window.versions.ping()
console.log(response) // prints out 'pong' console.log(response) // prints out 'pong'

View file

@ -188,7 +188,7 @@ npm install update-electron-app
Then, import the module and call it immediately in the main process. Then, import the module and call it immediately in the main process.
```js title='main.js' ```js title='main.js' @ts-nocheck
require('update-electron-app')() require('update-electron-app')()
``` ```

View file

@ -32,7 +32,7 @@ npm install update-electron-app
Then, invoke the updater from your app's main process file: Then, invoke the updater from your app's main process file:
```js title="main.js" ```js title="main.js" @ts-nocheck
require('update-electron-app')() require('update-electron-app')()
``` ```
@ -113,7 +113,7 @@ Now that you've configured the basic update mechanism for your application, you
need to ensure that the user will get notified when there's an update. This need to ensure that the user will get notified when there's an update. This
can be achieved using the [autoUpdater API events](../api/auto-updater.md#events): can be achieved using the [autoUpdater API events](../api/auto-updater.md#events):
```javascript title="main.js" ```javascript title="main.js" @ts-expect-error=[11]
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => { autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = { const dialogOpts = {
type: 'info', type: 'info',

View file

@ -196,9 +196,9 @@ const win = new BrowserWindow({
} }
}) })
ipcMain.on('set-ignore-mouse-events', (event, ...args) => { ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
const win = BrowserWindow.fromWebContents(event.sender) const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(...args) win.setIgnoreMouseEvents(ignore, options)
}) })
``` ```

View file

@ -125,7 +125,7 @@ Starting with a working application from the
following lines: following lines:
```javascript ```javascript
const { BrowserWindow } = require('electron') const { BrowserWindow, nativeImage } = require('electron')
const path = require('path') const path = require('path')
const win = new BrowserWindow() const win = new BrowserWindow()
@ -133,11 +133,11 @@ const win = new BrowserWindow()
win.setThumbarButtons([ win.setThumbarButtons([
{ {
tooltip: 'button1', tooltip: 'button1',
icon: path.join(__dirname, 'button1.png'), icon: nativeImage.createFromPath(path.join(__dirname, 'button1.png')),
click () { console.log('button1 clicked') } click () { console.log('button1 clicked') }
}, { }, {
tooltip: 'button2', tooltip: 'button2',
icon: path.join(__dirname, 'button2.png'), icon: nativeImage.createFromPath(path.join(__dirname, 'button2.png')),
flags: ['enabled', 'dismissonclick'], flags: ['enabled', 'dismissonclick'],
click () { console.log('button2 clicked.') } click () { console.log('button2 clicked.') }
} }
@ -189,11 +189,11 @@ Starting with a working application from the
following lines: following lines:
```javascript ```javascript
const { BrowserWindow } = require('electron') const { BrowserWindow, nativeImage } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
win.setOverlayIcon('path/to/overlay.png', 'Description for overlay') win.setOverlayIcon(nativeImage.createFromPath('path/to/overlay.png'), 'Description for overlay')
``` ```
[msdn-icon-overlay]: https://learn.microsoft.com/en-us/windows/win32/shell/taskbar-extensions#icon-overlays [msdn-icon-overlay]: https://learn.microsoft.com/en-us/windows/win32/shell/taskbar-extensions#icon-overlays

View file

@ -9,7 +9,7 @@
"@electron/docs-parser": "^1.1.0", "@electron/docs-parser": "^1.1.0",
"@electron/fiddle-core": "^1.0.4", "@electron/fiddle-core": "^1.0.4",
"@electron/github-app-auth": "^2.0.0", "@electron/github-app-auth": "^2.0.0",
"@electron/lint-roller": "^1.2.1", "@electron/lint-roller": "^1.5.0",
"@electron/typescript-definitions": "^8.14.0", "@electron/typescript-definitions": "^8.14.0",
"@octokit/rest": "^19.0.7", "@octokit/rest": "^19.0.7",
"@primer/octicons": "^10.0.0", "@primer/octicons": "^10.0.0",
@ -30,6 +30,7 @@
"@types/stream-json": "^1.5.1", "@types/stream-json": "^1.5.1",
"@types/temp": "^0.8.34", "@types/temp": "^0.8.34",
"@types/uuid": "^3.4.6", "@types/uuid": "^3.4.6",
"@types/w3c-web-serial": "^1.0.3",
"@types/webpack": "^5.28.0", "@types/webpack": "^5.28.0",
"@types/webpack-env": "^1.17.0", "@types/webpack-env": "^1.17.0",
"@typescript-eslint/eslint-plugin": "^5.59.7", "@typescript-eslint/eslint-plugin": "^5.59.7",
@ -87,10 +88,11 @@
"lint:objc": "node ./script/lint.js --objc", "lint:objc": "node ./script/lint.js --objc",
"lint:py": "node ./script/lint.js --py", "lint:py": "node ./script/lint.js --py",
"lint:gn": "node ./script/lint.js --gn", "lint:gn": "node ./script/lint.js --gn",
"lint:docs": "remark docs -qf && npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:docs-fiddles && npm run lint:docs-relative-links && npm run lint:markdownlint", "lint:docs": "remark docs -qf && npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:ts-check-js-in-markdown && npm run lint:docs-fiddles && npm run lint:docs-relative-links && npm run lint:markdownlint",
"lint:docs-fiddles": "standard \"docs/fiddles/**/*.js\"", "lint:docs-fiddles": "standard \"docs/fiddles/**/*.js\"",
"lint:docs-relative-links": "electron-lint-markdown-links --root docs \"**/*.md\"", "lint:docs-relative-links": "electron-lint-markdown-links --root docs \"**/*.md\"",
"lint:markdownlint": "electron-markdownlint \"*.md\" \"docs/**/*.md\"", "lint:markdownlint": "electron-markdownlint \"*.md\" \"docs/**/*.md\"",
"lint:ts-check-js-in-markdown": "electron-lint-markdown-ts-check --root docs \"**/*.md\" --ignore \"breaking-changes.md\"",
"lint:js-in-markdown": "electron-lint-markdown-standard --root docs \"**/*.md\"", "lint:js-in-markdown": "electron-lint-markdown-standard --root docs \"**/*.md\"",
"create-api-json": "node script/create-api-json.js", "create-api-json": "node script/create-api-json.js",
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --api=electron-api.json && node spec/ts-smoke/runner.js", "create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --api=electron-api.json && node spec/ts-smoke/runner.js",

View file

@ -194,10 +194,10 @@
"@octokit/auth-app" "^4.0.13" "@octokit/auth-app" "^4.0.13"
"@octokit/rest" "^19.0.11" "@octokit/rest" "^19.0.11"
"@electron/lint-roller@^1.2.1": "@electron/lint-roller@^1.5.0":
version "1.2.1" version "1.5.0"
resolved "https://registry.yarnpkg.com/@electron/lint-roller/-/lint-roller-1.2.1.tgz#9f9d99b0a8975646e0a0131ab1b21a2ec62e80d8" resolved "https://registry.yarnpkg.com/@electron/lint-roller/-/lint-roller-1.5.0.tgz#9b743979e1b03327e475fa696bb781eb2ea05ef2"
integrity sha512-w9PelpTBX8ClAv2iVa8fYqK77dnN0zWiHW98Utf8D83nmxkCMQNrKdRupSyiuIttbic1Nao8FhTScppmzOz0gw== integrity sha512-205UxwJEx8zv5wLwPq4wMA0OYrJ7d1GuqOhPav0Uy2HWe4K+DZbSP50safCvZCSpI6Op3DMo79tp5i8VppuPWA==
dependencies: dependencies:
"@dsanders11/vscode-markdown-languageservice" "^0.3.0" "@dsanders11/vscode-markdown-languageservice" "^0.3.0"
glob "^8.1.0" glob "^8.1.0"
@ -206,6 +206,7 @@
mdast-util-from-markdown "^1.3.0" mdast-util-from-markdown "^1.3.0"
minimist "^1.2.8" minimist "^1.2.8"
node-fetch "^2.6.9" node-fetch "^2.6.9"
rimraf "^4.4.1"
standard "^17.0.0" standard "^17.0.0"
unist-util-visit "^4.1.2" unist-util-visit "^4.1.2"
vscode-languageserver "^8.1.0" vscode-languageserver "^8.1.0"
@ -1066,6 +1067,11 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/w3c-web-serial@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/w3c-web-serial/-/w3c-web-serial-1.0.3.tgz#9fd5e8542f74e464bb1715b384b5c0dcbf2fb2c3"
integrity sha512-R4J/OjqKAUFQoXVIkaUTfzb/sl6hLh/ZhDTfowJTRMa7LhgEmI/jXV4zsL1u8HpNa853BxwNmDIr0pauizzwSQ==
"@types/webpack-env@^1.17.0": "@types/webpack-env@^1.17.0":
version "1.17.0" version "1.17.0"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.17.0.tgz#f99ce359f1bfd87da90cc4a57cab0a18f34a48d0" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.17.0.tgz#f99ce359f1bfd87da90cc4a57cab0a18f34a48d0"
@ -3156,6 +3162,16 @@ glob@^8.1.0:
minimatch "^5.0.1" minimatch "^5.0.1"
once "^1.3.0" once "^1.3.0"
glob@^9.2.0:
version "9.3.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21"
integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==
dependencies:
fs.realpath "^1.0.0"
minimatch "^8.0.2"
minipass "^4.2.4"
path-scurry "^1.6.1"
glob@~8.0.3: glob@~8.0.3:
version "8.0.3" version "8.0.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e"
@ -4078,7 +4094,7 @@ lru-cache@^6.0.0:
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
lru-cache@^9.0.0: lru-cache@^9.0.0, lru-cache@^9.1.1:
version "9.1.1" version "9.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.1.tgz#c58a93de58630b688de39ad04ef02ef26f1902f1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.1.tgz#c58a93de58630b688de39ad04ef02ef26f1902f1"
integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A== integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==
@ -4514,6 +4530,13 @@ minimatch@^5.0.1:
dependencies: dependencies:
brace-expansion "^2.0.1" brace-expansion "^2.0.1"
minimatch@^8.0.2:
version "8.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229"
integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==
dependencies:
brace-expansion "^2.0.1"
minimatch@~5.1.2: minimatch@~5.1.2:
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff"
@ -4543,6 +4566,16 @@ minipass@^4.0.0:
resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.1.tgz#2b9408c6e81bb8b338d600fb3685e375a370a057" resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.0.1.tgz#2b9408c6e81bb8b338d600fb3685e375a370a057"
integrity sha512-V9esFpNbK0arbN3fm2sxDKqMYgIp7XtVdE4Esj+PE4Qaaxdg1wIw48ITQIOn1sc8xXSmUviVL3cyjMqPlrVkiA== integrity sha512-V9esFpNbK0arbN3fm2sxDKqMYgIp7XtVdE4Esj+PE4Qaaxdg1wIw48ITQIOn1sc8xXSmUviVL3cyjMqPlrVkiA==
minipass@^4.2.4:
version "4.2.8"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a"
integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==
"minipass@^5.0.0 || ^6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81"
integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==
minizlib@^2.1.1: minizlib@^2.1.1:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
@ -4933,6 +4966,14 @@ path-parse@^1.0.6, path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-scurry@^1.6.1:
version "1.9.2"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.9.2.tgz#90f9d296ac5e37e608028e28a447b11d385b3f63"
integrity sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==
dependencies:
lru-cache "^9.1.1"
minipass "^5.0.0 || ^6.0.2"
path-to-regexp@0.1.7: path-to-regexp@0.1.7:
version "0.1.7" version "0.1.7"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
@ -5830,6 +5871,13 @@ rimraf@^3.0.2:
dependencies: dependencies:
glob "^7.1.3" glob "^7.1.3"
rimraf@^4.4.1:
version "4.4.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755"
integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==
dependencies:
glob "^9.2.0"
rimraf@~2.2.6: rimraf@~2.2.6:
version "2.2.8" version "2.2.8"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"