mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-18 00:56:02 +00:00
api running in electron main process
This commit is contained in:
@@ -90,7 +90,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "./",
|
"homepage": "./",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cross-env ELECTRON_START_URL=http://localhost:5000 electron .",
|
"start": "cross-env ELECTRON_START_URL=http://localhost:5000 ELECTRON_DEBUG=1 DEVMODE=1 electron .",
|
||||||
"start:local": "cross-env electron .",
|
"start:local": "cross-env electron .",
|
||||||
"dist": "electron-builder",
|
"dist": "electron-builder",
|
||||||
"build": "cd ../packages/api && yarn build && cd ../web && yarn build && cd ../../app && yarn dist",
|
"build": "cd ../packages/api && yarn build && cd ../web && yarn build && cd ../../app && yarn dist",
|
||||||
|
|||||||
@@ -101,25 +101,25 @@ function buildMenu() {
|
|||||||
{
|
{
|
||||||
label: 'dbgate.org',
|
label: 'dbgate.org',
|
||||||
click() {
|
click() {
|
||||||
require('electron').shell.openExternal('https://dbgate.org');
|
electron.shell.openExternal('https://dbgate.org');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'DbGate on GitHub',
|
label: 'DbGate on GitHub',
|
||||||
click() {
|
click() {
|
||||||
require('electron').shell.openExternal('https://github.com/dbgate/dbgate');
|
electron.shell.openExternal('https://github.com/dbgate/dbgate');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'DbGate on docker hub',
|
label: 'DbGate on docker hub',
|
||||||
click() {
|
click() {
|
||||||
require('electron').shell.openExternal('https://hub.docker.com/r/dbgate/dbgate');
|
electron.shell.openExternal('https://hub.docker.com/r/dbgate/dbgate');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Report problem or feature request',
|
label: 'Report problem or feature request',
|
||||||
click() {
|
click() {
|
||||||
require('electron').shell.openExternal('https://github.com/dbgate/dbgate/issues/new');
|
electron.shell.openExternal('https://github.com/dbgate/dbgate/issues/new');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
commandItem('tabs.changelog'),
|
commandItem('tabs.changelog'),
|
||||||
@@ -182,6 +182,7 @@ function createWindow() {
|
|||||||
// enableRemoteModule: true,
|
// enableRemoteModule: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
mainWindow.webContents.openDevTools();
|
||||||
// require('@electron/remote/main').enable(mainWindow.webContents);
|
// require('@electron/remote/main').enable(mainWindow.webContents);
|
||||||
if (store.get('winIsMaximized')) {
|
if (store.get('winIsMaximized')) {
|
||||||
mainWindow.maximize();
|
mainWindow.maximize();
|
||||||
@@ -190,7 +191,7 @@ function createWindow() {
|
|||||||
mainMenu = buildMenu();
|
mainMenu = buildMenu();
|
||||||
mainWindow.setMenu(mainMenu);
|
mainWindow.setMenu(mainMenu);
|
||||||
|
|
||||||
function loadMainWindow(initArgs) {
|
function loadMainWindow() {
|
||||||
const startUrl =
|
const startUrl =
|
||||||
process.env.ELECTRON_START_URL ||
|
process.env.ELECTRON_START_URL ||
|
||||||
url.format({
|
url.format({
|
||||||
@@ -198,18 +199,18 @@ function createWindow() {
|
|||||||
protocol: 'file:',
|
protocol: 'file:',
|
||||||
slashes: true,
|
slashes: true,
|
||||||
});
|
});
|
||||||
mainWindow.webContents.on('did-finish-load', function () {
|
// mainWindow.webContents.on('did-finish-load', function () {
|
||||||
mainWindow.webContents.executeJavaScript(
|
// mainWindow.webContents.executeJavaScript(
|
||||||
`runInit=()=>{
|
// `runInit=()=>{
|
||||||
try{
|
// try{
|
||||||
dbgate_initializeElectron(${JSON.stringify(initArgs)});
|
// dbgate_initializeElectron(${JSON.stringify(initArgs)});
|
||||||
}catch(e){
|
// }catch(e){
|
||||||
setTimeout(runInit,100)
|
// setTimeout(runInit,100)
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
runInit()`
|
// runInit()`
|
||||||
);
|
// );
|
||||||
});
|
// });
|
||||||
mainWindow.on('close', () => {
|
mainWindow.on('close', () => {
|
||||||
store.set('winBounds', mainWindow.getBounds());
|
store.set('winBounds', mainWindow.getBounds());
|
||||||
store.set('winIsMaximized', mainWindow.isMaximized());
|
store.set('winIsMaximized', mainWindow.isMaximized());
|
||||||
@@ -220,27 +221,35 @@ function createWindow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.ELECTRON_START_URL) {
|
const api = require(path.join(
|
||||||
loadMainWindow({});
|
__dirname,
|
||||||
} else {
|
process.env.ELECTRON_DEBUG ? '../../packages/api' : '../packages/api/dist/bundle.js'
|
||||||
const apiProcess = fork(path.join(__dirname, '../packages/api/dist/bundle.js'), [
|
));
|
||||||
'--dynport',
|
api.getMainModule().useAllControllers(null, electron);
|
||||||
'--is-electron-bundle',
|
|
||||||
'--native-modules',
|
|
||||||
path.join(__dirname, 'nativeModules'),
|
|
||||||
// '../../../src/nativeModules'
|
|
||||||
]);
|
|
||||||
apiProcess.on('message', msg => {
|
|
||||||
if (msg.msgtype == 'listening') {
|
|
||||||
const { port, authorization } = msg;
|
|
||||||
|
|
||||||
loadMainWindow({
|
loadMainWindow();
|
||||||
port,
|
|
||||||
authorization,
|
// if (process.env.ELECTRON_START_URL) {
|
||||||
});
|
// loadMainWindow({});
|
||||||
}
|
// } else {
|
||||||
});
|
// const apiProcess = fork(path.join(__dirname, '../packages/api/dist/bundle.js'), [
|
||||||
}
|
// '--dynport',
|
||||||
|
// '--is-electron-bundle',
|
||||||
|
// '--native-modules',
|
||||||
|
// path.join(__dirname, 'nativeModules'),
|
||||||
|
// // '../../../src/nativeModules'
|
||||||
|
// ]);
|
||||||
|
// apiProcess.on('message', msg => {
|
||||||
|
// if (msg.msgtype == 'listening') {
|
||||||
|
// const { port, authorization } = msg;
|
||||||
|
|
||||||
|
// loadMainWindow({
|
||||||
|
// port,
|
||||||
|
// authorization,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
// mainWindow.loadURL('http://localhost:3000');
|
// mainWindow.loadURL('http://localhost:3000');
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
"fs-reverse": "^0.0.3",
|
"fs-reverse": "^0.0.3",
|
||||||
"get-port": "^5.1.1",
|
"get-port": "^5.1.1",
|
||||||
"http": "^0.0.0",
|
"http": "^0.0.0",
|
||||||
|
"is-electron": "^2.2.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json-stable-stringify": "^1.0.1",
|
"json-stable-stringify": "^1.0.1",
|
||||||
"line-reader": "^0.4.0",
|
"line-reader": "^0.4.0",
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ if (processArgs.startProcess) {
|
|||||||
const proc = require('./proc');
|
const proc = require('./proc');
|
||||||
const module = proc[processArgs.startProcess];
|
const module = proc[processArgs.startProcess];
|
||||||
module.start();
|
module.start();
|
||||||
} else if (!module['parent'] && !processArgs.checkParent) {
|
|
||||||
const main = require('./main');
|
|
||||||
|
|
||||||
main.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// else if (!module['parent'] && !processArgs.checkParent) {
|
||||||
|
// const main = require('./main');
|
||||||
|
|
||||||
|
// main.start();
|
||||||
|
// }
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...shell,
|
...shell,
|
||||||
getMainModule: () => require('./main'),
|
getMainModule: () => require('./main'),
|
||||||
|
|||||||
@@ -102,20 +102,7 @@ function start() {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
useController(app, '/connections', connections);
|
useAllControllers(app, null);
|
||||||
useController(app, '/server-connections', serverConnections);
|
|
||||||
useController(app, '/database-connections', databaseConnections);
|
|
||||||
useController(app, '/metadata', metadata);
|
|
||||||
useController(app, '/sessions', sessions);
|
|
||||||
useController(app, '/runners', runners);
|
|
||||||
useController(app, '/jsldata', jsldata);
|
|
||||||
useController(app, '/config', config);
|
|
||||||
useController(app, '/archive', archive);
|
|
||||||
useController(app, '/uploads', uploads);
|
|
||||||
useController(app, '/plugins', plugins);
|
|
||||||
useController(app, '/files', files);
|
|
||||||
useController(app, '/scheduler', scheduler);
|
|
||||||
useController(app, '/query-history', queryHistory);
|
|
||||||
|
|
||||||
// if (process.env.PAGES_DIRECTORY) {
|
// if (process.env.PAGES_DIRECTORY) {
|
||||||
// app.use('/pages', express.static(process.env.PAGES_DIRECTORY));
|
// app.use('/pages', express.static(process.env.PAGES_DIRECTORY));
|
||||||
@@ -158,4 +145,21 @@ function start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { start };
|
function useAllControllers(app, electron) {
|
||||||
|
useController(app, electron, '/connections', connections);
|
||||||
|
useController(app, electron, '/server-connections', serverConnections);
|
||||||
|
useController(app, electron, '/database-connections', databaseConnections);
|
||||||
|
useController(app, electron, '/metadata', metadata);
|
||||||
|
useController(app, electron, '/sessions', sessions);
|
||||||
|
useController(app, electron, '/runners', runners);
|
||||||
|
useController(app, electron, '/jsldata', jsldata);
|
||||||
|
useController(app, electron, '/config', config);
|
||||||
|
useController(app, electron, '/archive', archive);
|
||||||
|
useController(app, electron, '/uploads', uploads);
|
||||||
|
useController(app, electron, '/plugins', plugins);
|
||||||
|
useController(app, electron, '/files', files);
|
||||||
|
useController(app, electron, '/scheduler', scheduler);
|
||||||
|
useController(app, electron, '/query-history', queryHistory);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { start, useAllControllers };
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const fs = require('fs');
|
|||||||
const os = require('os');
|
const os = require('os');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const processArgs = require('./processArgs');
|
const processArgs = require('./processArgs');
|
||||||
|
const isElectron = require('is-electron');
|
||||||
|
|
||||||
const platform = process.env.OS_OVERRIDE ? process.env.OS_OVERRIDE : process.platform;
|
const platform = process.env.OS_OVERRIDE ? process.env.OS_OVERRIDE : process.platform;
|
||||||
const isWindows = platform === 'win32';
|
const isWindows = platform === 'win32';
|
||||||
@@ -28,6 +29,7 @@ const platformInfo = {
|
|||||||
isLinux,
|
isLinux,
|
||||||
isDocker,
|
isDocker,
|
||||||
isElectronBundle,
|
isElectronBundle,
|
||||||
|
isElectron: isElectron(),
|
||||||
isDevMode,
|
isDevMode,
|
||||||
isNpmDist,
|
isNpmDist,
|
||||||
isSnap: process.env.ELECTRON_SNAP == 'true',
|
isSnap: process.env.ELECTRON_SNAP == 'true',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const express = require('express');
|
|||||||
/**
|
/**
|
||||||
* @param {string} route
|
* @param {string} route
|
||||||
*/
|
*/
|
||||||
module.exports = function useController(app, route, controller) {
|
module.exports = function useController(app, electron, route, controller) {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
if (controller._init) {
|
if (controller._init) {
|
||||||
@@ -23,6 +23,21 @@ module.exports = function useController(app, route, controller) {
|
|||||||
const meta = controller[`${key}_meta`];
|
const meta = controller[`${key}_meta`];
|
||||||
if (!meta) continue;
|
if (!meta) continue;
|
||||||
|
|
||||||
|
const routeAction = `/${_.kebabCase(key)}`;
|
||||||
|
|
||||||
|
if (electron) {
|
||||||
|
if (meta === true) {
|
||||||
|
const handler = `${route.substring(1)}-${_.kebabCase(key)}`;
|
||||||
|
console.log('REGISTERING HANDLER', handler);
|
||||||
|
electron.ipcMain.handle(handler, async (event, args) => {
|
||||||
|
const data = await controller[key](args);
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let method = 'post';
|
let method = 'post';
|
||||||
let raw = false;
|
let raw = false;
|
||||||
let rawParams = false;
|
let rawParams = false;
|
||||||
@@ -36,11 +51,10 @@ module.exports = function useController(app, route, controller) {
|
|||||||
rawParams = meta.rawParams;
|
rawParams = meta.rawParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
const route = `/${_.kebabCase(key)}`;
|
|
||||||
if (raw) {
|
if (raw) {
|
||||||
router[method](route, controller[key]);
|
router[method](routeAction, controller[key]);
|
||||||
} else {
|
} else {
|
||||||
router[method](route, async (req, res) => {
|
router[method](routeAction, async (req, res) => {
|
||||||
// if (controller._init && !controller._init_called) {
|
// if (controller._init && !controller._init_called) {
|
||||||
// await controller._init();
|
// await controller._init();
|
||||||
// controller._init_called = true;
|
// controller._init_called = true;
|
||||||
@@ -58,5 +72,7 @@ module.exports = function useController(app, route, controller) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.use(route, router);
|
if (app) {
|
||||||
|
app.use(route, router);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
import { setAppLoaded } from './utility/appLoadManager';
|
import { setAppLoaded } from './utility/appLoadManager';
|
||||||
import ErrorHandler from './utility/ErrorHandler.svelte';
|
import ErrorHandler from './utility/ErrorHandler.svelte';
|
||||||
import OpenTabsOnStartup from './utility/OpenTabsOnStartup.svelte';
|
import OpenTabsOnStartup from './utility/OpenTabsOnStartup.svelte';
|
||||||
import { shouldWaitForElectronInitialize } from './utility/getElectron';
|
// import { shouldWaitForElectronInitialize } from './utility/getElectron';
|
||||||
import { subscribeConnectionPingers } from './utility/connectionsPinger';
|
import { subscribeConnectionPingers } from './utility/connectionsPinger';
|
||||||
import { subscribePermissionCompiler } from './utility/hasPermission';
|
import { subscribePermissionCompiler } from './utility/hasPermission';
|
||||||
import { apiCall } from './utility/api';
|
import { apiCall } from './utility/api';
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
let loadedApi = false;
|
let loadedApi = false;
|
||||||
|
|
||||||
async function loadApi() {
|
async function loadApi() {
|
||||||
if (shouldWaitForElectronInitialize()) {
|
// if (shouldWaitForElectronInitialize()) {
|
||||||
setTimeout(loadApi, 100);
|
// setTimeout(loadApi, 100);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// console.log('************** LOADING API');
|
// console.log('************** LOADING API');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import resolveApi, { resolveApiHeaders } from './resolveApi';
|
import resolveApi, { resolveApiHeaders } from './resolveApi';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import { cacheClean } from './cache';
|
import { cacheClean } from './cache';
|
||||||
|
import getElectron from './getElectron';
|
||||||
// import socket from './socket';
|
// import socket from './socket';
|
||||||
|
|
||||||
let eventSource;
|
let eventSource;
|
||||||
@@ -13,37 +14,53 @@ function wantEventSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function apiCall(route: string, args: {} = undefined) {
|
export async function apiCall(route: string, args: {} = undefined) {
|
||||||
const resp = await fetch(`${resolveApi()}/${route}`, {
|
const electron = getElectron();
|
||||||
method: 'POST',
|
if (electron) {
|
||||||
cache: 'no-cache',
|
const resp = await electron.invoke(route.replace('/', '-'), args);
|
||||||
headers: {
|
return resp;
|
||||||
'Content-Type': 'application/json',
|
} else {
|
||||||
...resolveApiHeaders(),
|
const resp = await fetch(`${resolveApi()}/${route}`, {
|
||||||
},
|
method: 'POST',
|
||||||
body: JSON.stringify(args),
|
cache: 'no-cache',
|
||||||
});
|
headers: {
|
||||||
return resp.json();
|
'Content-Type': 'application/json',
|
||||||
|
...resolveApiHeaders(),
|
||||||
|
},
|
||||||
|
body: JSON.stringify(args),
|
||||||
|
});
|
||||||
|
return resp.json();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiHandlers = new WeakMap();
|
const apiHandlers = new WeakMap();
|
||||||
|
|
||||||
export function apiOn(event: string, handler: Function) {
|
export function apiOn(event: string, handler: Function) {
|
||||||
wantEventSource();
|
const electron = getElectron();
|
||||||
if (!apiHandlers.has(handler)) {
|
if (electron) {
|
||||||
const handlerProxy = e => {
|
electron.addEventListener(event, handler);
|
||||||
// console.log('RECEIVED', e.type, JSON.parse(e.data));
|
} else {
|
||||||
handler(JSON.parse(e.data));
|
wantEventSource();
|
||||||
};
|
if (!apiHandlers.has(handler)) {
|
||||||
apiHandlers.set(handler, handlerProxy);
|
const handlerProxy = e => {
|
||||||
}
|
// console.log('RECEIVED', e.type, JSON.parse(e.data));
|
||||||
|
handler(JSON.parse(e.data));
|
||||||
|
};
|
||||||
|
apiHandlers.set(handler, handlerProxy);
|
||||||
|
}
|
||||||
|
|
||||||
eventSource.addEventListener(event, apiHandlers.get(handler));
|
eventSource.addEventListener(event, apiHandlers.get(handler));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function apiOff(event: string, handler: Function) {
|
export function apiOff(event: string, handler: Function) {
|
||||||
wantEventSource();
|
const electron = getElectron();
|
||||||
if (apiHandlers.has(handler)) {
|
if (electron) {
|
||||||
eventSource.removeEventListener(event, apiHandlers.get(handler));
|
electron.removeEventListener(event, handler);
|
||||||
|
} else {
|
||||||
|
wantEventSource();
|
||||||
|
if (apiHandlers.has(handler)) {
|
||||||
|
eventSource.removeEventListener(event, apiHandlers.get(handler));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
class ElectronApi {
|
class ElectronApi {
|
||||||
public port?: number;
|
// public port?: number;
|
||||||
public authorization?: string;
|
// public authorization?: string;
|
||||||
private ipcRenderer = getIpcRenderer();
|
private ipcRenderer = getIpcRenderer();
|
||||||
|
|
||||||
constructor(args) {
|
constructor() {
|
||||||
this.port = args.port;
|
// this.port = args.port;
|
||||||
this.authorization = args.authorization;
|
// this.authorization = args.authorization;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(msg, args = null) {
|
send(msg, args = null) {
|
||||||
@@ -30,18 +30,29 @@ class ElectronApi {
|
|||||||
async openExternal(url) {
|
async openExternal(url) {
|
||||||
await this.ipcRenderer.invoke('openExternal', url);
|
await this.ipcRenderer.invoke('openExternal', url);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let apiInstance = null;
|
async invoke(route, args) {
|
||||||
|
const res = await this.ipcRenderer.invoke(route, args);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
function initializeElectron(args) {
|
addEventListener(channel: string, listener: Function) {
|
||||||
apiInstance = new ElectronApi(args);
|
this.ipcRenderer.on(channel, listener);
|
||||||
if (window['dbgate_recreateSocket']) {
|
}
|
||||||
window['dbgate_recreateSocket']();
|
|
||||||
|
removeEventListener(channel: string, listener: Function) {
|
||||||
|
this.ipcRenderer.removeEventListener(channel, listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window['dbgate_initializeElectron'] = initializeElectron;
|
// function initializeElectron(args) {
|
||||||
|
// apiInstance = new ElectronApi(args);
|
||||||
|
// if (window['dbgate_recreateSocket']) {
|
||||||
|
// window['dbgate_recreateSocket']();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// window['dbgate_initializeElectron'] = initializeElectron;
|
||||||
|
|
||||||
function getIpcRenderer() {
|
function getIpcRenderer() {
|
||||||
if (window['require']) {
|
if (window['require']) {
|
||||||
@@ -51,14 +62,16 @@ function getIpcRenderer() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldWaitForElectronInitialize() {
|
// export function shouldWaitForElectronInitialize() {
|
||||||
return !!getIpcRenderer() && !apiInstance;
|
// return !!getIpcRenderer() && !apiInstance;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function isElectronAvailable() {
|
export function isElectronAvailable() {
|
||||||
return !!getIpcRenderer();
|
return !!getIpcRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const apiInstance = isElectronAvailable() ? new ElectronApi() : null;
|
||||||
|
|
||||||
export default function getElectron(): ElectronApi {
|
export default function getElectron(): ElectronApi {
|
||||||
return apiInstance;
|
return apiInstance;
|
||||||
// try {
|
// try {
|
||||||
|
|||||||
@@ -5316,6 +5316,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2:
|
|||||||
is-data-descriptor "^1.0.0"
|
is-data-descriptor "^1.0.0"
|
||||||
kind-of "^6.0.2"
|
kind-of "^6.0.2"
|
||||||
|
|
||||||
|
is-electron@^2.2.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.1.tgz#751b1dd8a74907422faa5c35aaa0cf66d98086e9"
|
||||||
|
integrity sha512-r8EEQQsqT+Gn0aXFx7lTFygYQhILLCB+wn0WCDL5LZRINeLH/Rvw1j2oKodELLXYNImQ3CRlVsY8wW4cGOsyuw==
|
||||||
|
|
||||||
is-extendable@^0.1.0, is-extendable@^0.1.1:
|
is-extendable@^0.1.0, is-extendable@^0.1.1:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
|
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
|
||||||
|
|||||||
Reference in New Issue
Block a user