mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-30 15:03:57 +00:00
Merge branch 'master' into sqlite
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "4.1.11",
|
"version": "4.1.12-beta.2",
|
||||||
"name": "dbgate-all",
|
"name": "dbgate-all",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*",
|
"packages/*",
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ const portfinder = require('portfinder');
|
|||||||
const stableStringify = require('json-stable-stringify');
|
const stableStringify = require('json-stable-stringify');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const platformInfo = require('./platformInfo');
|
const platformInfo = require('./platformInfo');
|
||||||
|
const AsyncLock = require('async-lock');
|
||||||
|
const lock = new AsyncLock();
|
||||||
|
|
||||||
const sshConnectionCache = {};
|
const sshConnectionCache = {};
|
||||||
const sshTunnelCache = {};
|
const sshTunnelCache = {};
|
||||||
@@ -45,36 +47,43 @@ async function getSshConnection(connection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getSshTunnel(connection) {
|
async function getSshTunnel(connection) {
|
||||||
const sshConn = await getSshConnection(connection);
|
|
||||||
const tunnelCacheKey = stableStringify(_.pick(connection, TUNNEL_FIELDS));
|
const tunnelCacheKey = stableStringify(_.pick(connection, TUNNEL_FIELDS));
|
||||||
if (sshTunnelCache[tunnelCacheKey]) return sshTunnelCache[tunnelCacheKey];
|
|
||||||
|
|
||||||
const localPort = await portfinder.getPortPromise({ port: 10000, stopPort: 60000 });
|
return await lock.acquire(tunnelCacheKey, async () => {
|
||||||
// workaround for `getPortPromise` not releasing the port quickly enough
|
const sshConn = await getSshConnection(connection);
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
if (sshTunnelCache[tunnelCacheKey]) return sshTunnelCache[tunnelCacheKey];
|
||||||
const tunnelConfig = {
|
|
||||||
fromPort: localPort,
|
|
||||||
toPort: connection.port,
|
|
||||||
toHost: connection.server,
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
const tunnel = await sshConn.forward(tunnelConfig);
|
|
||||||
console.log(
|
|
||||||
`Created SSH tunnel to ${connection.sshHost}-${connection.server}:${connection.port}, using local port ${localPort}`
|
|
||||||
);
|
|
||||||
|
|
||||||
sshTunnelCache[tunnelCacheKey] = {
|
const localPort = await portfinder.getPortPromise({ port: 10000, stopPort: 60000 });
|
||||||
state: 'ok',
|
// workaround for `getPortPromise` not releasing the port quickly enough
|
||||||
localPort,
|
await new Promise(resolve => setTimeout(resolve, 500));
|
||||||
|
const tunnelConfig = {
|
||||||
|
fromPort: localPort,
|
||||||
|
toPort: connection.port,
|
||||||
|
toHost: connection.server,
|
||||||
};
|
};
|
||||||
return sshTunnelCache[tunnelCacheKey];
|
try {
|
||||||
} catch (err) {
|
console.log(
|
||||||
// error is not cached
|
`Creating SSH tunnel to ${connection.sshHost}-${connection.server}:${connection.port}, using local port ${localPort}`
|
||||||
return {
|
);
|
||||||
state: 'error',
|
|
||||||
message: err.message,
|
const tunnel = await sshConn.forward(tunnelConfig);
|
||||||
};
|
console.log(
|
||||||
}
|
`Created SSH tunnel to ${connection.sshHost}-${connection.server}:${connection.port}, using local port ${localPort}`
|
||||||
|
);
|
||||||
|
|
||||||
|
sshTunnelCache[tunnelCacheKey] = {
|
||||||
|
state: 'ok',
|
||||||
|
localPort,
|
||||||
|
};
|
||||||
|
return sshTunnelCache[tunnelCacheKey];
|
||||||
|
} catch (err) {
|
||||||
|
// error is not cached
|
||||||
|
return {
|
||||||
|
state: 'error',
|
||||||
|
message: err.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
import { getFormContext } from './FormProviderCore.svelte';
|
import { getFormContext } from './FormProviderCore.svelte';
|
||||||
import SelectField from './SelectField.svelte';
|
import SelectField from './SelectField.svelte';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
export let name;
|
export let name;
|
||||||
|
export let options;
|
||||||
export let isClearable = false;
|
export let isClearable = false;
|
||||||
|
|
||||||
const { values, setFieldValue } = getFormContext();
|
const { values, setFieldValue } = getFormContext();
|
||||||
@@ -14,6 +16,7 @@
|
|||||||
<SelectField
|
<SelectField
|
||||||
{...$$restProps}
|
{...$$restProps}
|
||||||
value={$values[name]}
|
value={$values[name]}
|
||||||
|
options={_.compact(options)}
|
||||||
on:change={e => {
|
on:change={e => {
|
||||||
setFieldValue(name, e.detail);
|
setFieldValue(name, e.detail);
|
||||||
dispatch('change', e.detail);
|
dispatch('change', e.detail);
|
||||||
|
|||||||
Reference in New Issue
Block a user