dbgate-api-premium 5.5.7-alpha.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +19 -0
- package/.yarnrc +2 -0
- package/README.md +1 -0
- package/env/dblogin/.env +14 -0
- package/env/portal/.env +70 -0
- package/env/singledb/.env +17 -0
- package/env/storage/.env +43 -0
- package/package.json +89 -0
- package/src/auth/authCommon.js +16 -0
- package/src/auth/authProvider.js +343 -0
- package/src/auth/storageAuthProvider.js +393 -0
- package/src/controllers/apps.js +280 -0
- package/src/controllers/archive.js +217 -0
- package/src/controllers/auth.js +136 -0
- package/src/controllers/config.js +271 -0
- package/src/controllers/connections.js +486 -0
- package/src/controllers/databaseConnections.js +561 -0
- package/src/controllers/files.js +222 -0
- package/src/controllers/jsldata.js +296 -0
- package/src/controllers/metadata.js +47 -0
- package/src/controllers/plugins.js +216 -0
- package/src/controllers/queryHistory.js +54 -0
- package/src/controllers/runners.js +234 -0
- package/src/controllers/scheduler.js +46 -0
- package/src/controllers/serverConnections.js +271 -0
- package/src/controllers/sessions.js +243 -0
- package/src/controllers/storage.js +380 -0
- package/src/controllers/storageDb.js +215 -0
- package/src/controllers/uploads.js +133 -0
- package/src/currentVersion.js +5 -0
- package/src/gistSecret.js +2 -0
- package/src/index.js +139 -0
- package/src/main.js +202 -0
- package/src/packagedPluginsContent.js +1 -0
- package/src/proc/connectProcess.js +38 -0
- package/src/proc/databaseConnectionProcess.js +431 -0
- package/src/proc/index.js +15 -0
- package/src/proc/jslDatastoreProcess.js +60 -0
- package/src/proc/serverConnectionProcess.js +188 -0
- package/src/proc/sessionProcess.js +390 -0
- package/src/proc/sshForwardProcess.js +75 -0
- package/src/shell/archiveReader.js +11 -0
- package/src/shell/archiveWriter.js +22 -0
- package/src/shell/autoIndexForeignKeysTransform.js +19 -0
- package/src/shell/collectorWriter.js +33 -0
- package/src/shell/consoleObjectWriter.js +16 -0
- package/src/shell/copyStream.js +48 -0
- package/src/shell/dataDuplicator.js +63 -0
- package/src/shell/dataTypeMapperTransform.js +21 -0
- package/src/shell/dbModelToJson.js +16 -0
- package/src/shell/deployDb.js +56 -0
- package/src/shell/download.js +15 -0
- package/src/shell/dropAllDbObjects.js +42 -0
- package/src/shell/dumpDatabase.js +49 -0
- package/src/shell/executeQuery.js +39 -0
- package/src/shell/fakeObjectReader.js +35 -0
- package/src/shell/finalizer.js +12 -0
- package/src/shell/generateDeploySql.js +95 -0
- package/src/shell/generateModelSql.js +30 -0
- package/src/shell/importDatabase.js +85 -0
- package/src/shell/index.js +80 -0
- package/src/shell/initializeApiEnvironment.js +9 -0
- package/src/shell/jslDataReader.js +9 -0
- package/src/shell/jsonLinesReader.js +52 -0
- package/src/shell/jsonLinesWriter.js +36 -0
- package/src/shell/jsonReader.js +84 -0
- package/src/shell/jsonToDbModel.js +9 -0
- package/src/shell/jsonWriter.js +97 -0
- package/src/shell/loadDatabase.js +27 -0
- package/src/shell/loadFile.js +10 -0
- package/src/shell/modifyJsonLinesReader.js +148 -0
- package/src/shell/queryReader.js +30 -0
- package/src/shell/registerPlugins.js +9 -0
- package/src/shell/requirePlugin.js +43 -0
- package/src/shell/runScript.js +19 -0
- package/src/shell/sqlDataWriter.js +52 -0
- package/src/shell/sqlTextReplacementTransform.js +32 -0
- package/src/shell/tableReader.js +39 -0
- package/src/shell/tableWriter.js +18 -0
- package/src/storageModel.js +819 -0
- package/src/utility/ColumnMapTransformStream.js +21 -0
- package/src/utility/DatastoreProxy.js +106 -0
- package/src/utility/EnsureStreamHeaderStream.js +31 -0
- package/src/utility/JsonLinesDatabase.js +148 -0
- package/src/utility/JsonLinesDatastore.js +232 -0
- package/src/utility/LineReader.js +88 -0
- package/src/utility/SSHConnection.js +251 -0
- package/src/utility/authProxy.js +133 -0
- package/src/utility/checkLicense.js +186 -0
- package/src/utility/childProcessChecker.js +21 -0
- package/src/utility/cleanDirectory.js +24 -0
- package/src/utility/cloudUpgrade.js +61 -0
- package/src/utility/connectUtility.js +111 -0
- package/src/utility/crypting.js +105 -0
- package/src/utility/diff2htmlPage.js +8 -0
- package/src/utility/directories.js +179 -0
- package/src/utility/downloadPackage.js +51 -0
- package/src/utility/downloader.js +25 -0
- package/src/utility/exceptions.js +9 -0
- package/src/utility/exportDbModel.js +31 -0
- package/src/utility/exportDbModelSql.js +80 -0
- package/src/utility/getChartExport.js +55 -0
- package/src/utility/getDiagramExport.js +25 -0
- package/src/utility/getExpressPath.js +10 -0
- package/src/utility/getJslFileName.js +16 -0
- package/src/utility/getMapExport.js +77 -0
- package/src/utility/hardwareFingerprint.js +89 -0
- package/src/utility/hasPermission.js +101 -0
- package/src/utility/importDbModel.js +9 -0
- package/src/utility/loadFilesRecursive.js +20 -0
- package/src/utility/loadModelFolder.js +29 -0
- package/src/utility/loadModelTransform.js +36 -0
- package/src/utility/pipeForkLogs.js +19 -0
- package/src/utility/platformInfo.js +62 -0
- package/src/utility/processArgs.js +39 -0
- package/src/utility/processComm.js +18 -0
- package/src/utility/requireEngineDriver.js +26 -0
- package/src/utility/requirePluginFunction.js +16 -0
- package/src/utility/socket.js +68 -0
- package/src/utility/sshTunnel.js +106 -0
- package/src/utility/sshTunnelProxy.js +36 -0
- package/src/utility/timingSafeCheckToken.js +9 -0
- package/src/utility/useController.js +99 -0
- package/tsconfig.json +13 -0
- package/webpack.config.js +55 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const getDiagramExport = (html, css, themeType, themeClassName) => {
|
|
2
|
+
return `<html>
|
|
3
|
+
<meta charset='utf-8'>
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<style>
|
|
7
|
+
${css}
|
|
8
|
+
|
|
9
|
+
body {
|
|
10
|
+
background: var(--theme-bg-1);
|
|
11
|
+
color: var(--theme-font-1);
|
|
12
|
+
}
|
|
13
|
+
</style>
|
|
14
|
+
|
|
15
|
+
<link rel="stylesheet" href='https://cdn.jsdelivr.net/npm/@mdi/font@6.5.95/css/materialdesignicons.css' />
|
|
16
|
+
</head>
|
|
17
|
+
|
|
18
|
+
<body class='${themeType == 'dark' ? 'theme-type-dark' : 'theme-type-light'} ${themeClassName}'>
|
|
19
|
+
${html}
|
|
20
|
+
</body>
|
|
21
|
+
|
|
22
|
+
</html>`;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = getDiagramExport;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function getExpressPath(path) {
|
|
2
|
+
path = path.replace(/\/*$/, '').replace(/^\/*/, '');
|
|
3
|
+
const root = (process.env.WEB_ROOT || '').replace(/^\/*/, '').replace(/\/*$/, '');
|
|
4
|
+
if (root) {
|
|
5
|
+
return `/${root}/${path}`;
|
|
6
|
+
}
|
|
7
|
+
return `/${path}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
module.exports = getExpressPath;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { jsldir, archivedir, resolveArchiveFolder } = require('./directories');
|
|
3
|
+
|
|
4
|
+
function getJslFileName(jslid) {
|
|
5
|
+
const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/);
|
|
6
|
+
if (archiveMatch) {
|
|
7
|
+
return path.join(resolveArchiveFolder(archiveMatch[1]), `${archiveMatch[2]}.jsonl`);
|
|
8
|
+
}
|
|
9
|
+
const fileMatch = jslid.match(/^file:\/\/(.*)$/);
|
|
10
|
+
if (fileMatch) {
|
|
11
|
+
return fileMatch[1];
|
|
12
|
+
}
|
|
13
|
+
return path.join(jsldir(), `${jslid}.jsonl`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = getJslFileName;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const getMapExport = (geoJson) => {
|
|
2
|
+
return `<html>
|
|
3
|
+
<meta charset='utf-8'>
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css"
|
|
7
|
+
integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
|
|
8
|
+
crossorigin=""/>
|
|
9
|
+
|
|
10
|
+
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js"
|
|
11
|
+
integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
|
|
12
|
+
crossorigin=""></script>
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
function createMap() {
|
|
16
|
+
map = leaflet.map('map').setView([50, 15], 13);
|
|
17
|
+
|
|
18
|
+
leaflet
|
|
19
|
+
.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
20
|
+
maxZoom: 19,
|
|
21
|
+
attribution: '<a href="https://dbgate.org" title="Exported from DbGate">DbGate</a> | © OpenStreetMap',
|
|
22
|
+
})
|
|
23
|
+
.addTo(map);
|
|
24
|
+
|
|
25
|
+
const geoJsonObj = leaflet
|
|
26
|
+
.geoJSON(${JSON.stringify(geoJson)}, {
|
|
27
|
+
style: function () {
|
|
28
|
+
return {
|
|
29
|
+
weight: 2,
|
|
30
|
+
fillColor: '#ff7800',
|
|
31
|
+
color: '#ff7800',
|
|
32
|
+
opacity: 0.8,
|
|
33
|
+
fillOpacity: 0.4,
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
pointToLayer: (feature, latlng) => {
|
|
37
|
+
return leaflet.circleMarker(latlng, {
|
|
38
|
+
radius: 7,
|
|
39
|
+
weight: 2,
|
|
40
|
+
fillColor: '#ff0000',
|
|
41
|
+
color: '#ff0000',
|
|
42
|
+
opacity: 0.9,
|
|
43
|
+
fillOpacity: 0.9,
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
onEachFeature: (feature, layer) => {
|
|
47
|
+
// does this feature have a property named popupContent?
|
|
48
|
+
if (feature.properties && feature.properties.popupContent) {
|
|
49
|
+
layer.bindPopup(feature.properties.popupContent);
|
|
50
|
+
layer.bindTooltip(feature.properties.popupContent);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
.addTo(map);
|
|
55
|
+
map.fitBounds(geoJsonObj.getBounds());
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<style>
|
|
60
|
+
#map {
|
|
61
|
+
position: fixed;
|
|
62
|
+
left: 0;
|
|
63
|
+
top: 0;
|
|
64
|
+
right: 0;
|
|
65
|
+
bottom: 0;
|
|
66
|
+
}
|
|
67
|
+
</style>
|
|
68
|
+
</head>
|
|
69
|
+
|
|
70
|
+
<body onload='createMap()'>
|
|
71
|
+
<div id='map'></div>
|
|
72
|
+
</body>
|
|
73
|
+
|
|
74
|
+
</html>`;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
module.exports = getMapExport;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const os = require('os');
|
|
3
|
+
const crypto = require('crypto');
|
|
4
|
+
const platformInfo = require('./platformInfo');
|
|
5
|
+
|
|
6
|
+
async function getPublicIpInfo() {
|
|
7
|
+
try {
|
|
8
|
+
const resp = await axios.default.get('https://ipinfo.io/json');
|
|
9
|
+
if (!resp.data?.ip) {
|
|
10
|
+
return { ip: 'unknown-ip' };
|
|
11
|
+
}
|
|
12
|
+
return resp.data;
|
|
13
|
+
} catch (err) {
|
|
14
|
+
return { ip: 'unknown-ip' };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getMacAddress() {
|
|
19
|
+
try {
|
|
20
|
+
const interfaces = os.networkInterfaces();
|
|
21
|
+
for (let iface of Object.values(interfaces)) {
|
|
22
|
+
for (let config of iface) {
|
|
23
|
+
if (config.mac && config.mac !== '00:00:00:00:00:00') {
|
|
24
|
+
return config.mac;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return '00:00:00:00:00:00';
|
|
29
|
+
} catch (err) {
|
|
30
|
+
return '00:00:00:00:00:00';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function getHardwareFingerprint() {
|
|
35
|
+
const publicIpInfo = await getPublicIpInfo();
|
|
36
|
+
const macAddress = getMacAddress();
|
|
37
|
+
const platform = os.platform();
|
|
38
|
+
const release = os.release();
|
|
39
|
+
const hostname = os.hostname();
|
|
40
|
+
const totalMemory = os.totalmem();
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
publicIp: publicIpInfo.ip,
|
|
44
|
+
country: publicIpInfo.country,
|
|
45
|
+
region: publicIpInfo.region,
|
|
46
|
+
city: publicIpInfo.city,
|
|
47
|
+
macAddress,
|
|
48
|
+
platform,
|
|
49
|
+
release,
|
|
50
|
+
hostname,
|
|
51
|
+
totalMemory,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function getHardwareFingerprintHash(data = undefined) {
|
|
56
|
+
if (!data) {
|
|
57
|
+
data = await getHardwareFingerprint();
|
|
58
|
+
}
|
|
59
|
+
const fingerprintData = JSON.stringify(data);
|
|
60
|
+
const hash = crypto.createHash('sha256').update(fingerprintData).digest('hex');
|
|
61
|
+
return hash;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function getPublicHardwareFingerprint() {
|
|
65
|
+
const fingerprint = await getHardwareFingerprint();
|
|
66
|
+
const hash = await getHardwareFingerprintHash(fingerprint);
|
|
67
|
+
return {
|
|
68
|
+
hash,
|
|
69
|
+
payload: {
|
|
70
|
+
platform: fingerprint.platform,
|
|
71
|
+
city: fingerprint.city,
|
|
72
|
+
country: fingerprint.country,
|
|
73
|
+
region: fingerprint.region,
|
|
74
|
+
isDocker: platformInfo.isDocker,
|
|
75
|
+
isAwsUbuntuLayout: platformInfo.isAwsUbuntuLayout,
|
|
76
|
+
isElectron: platformInfo.isElectron,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// getHardwareFingerprint().then(console.log);
|
|
82
|
+
// getHardwareFingerprintHash().then(console.log);
|
|
83
|
+
// getPublicHardwareFingerprint().then(console.log);
|
|
84
|
+
|
|
85
|
+
module.exports = {
|
|
86
|
+
getHardwareFingerprint,
|
|
87
|
+
getHardwareFingerprintHash,
|
|
88
|
+
getPublicHardwareFingerprint,
|
|
89
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const { compilePermissions, testPermission } = require('dbgate-tools');
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
const { getAuthProviderFromReq } = require('../auth/authProvider');
|
|
4
|
+
|
|
5
|
+
const cachedPermissions = {};
|
|
6
|
+
|
|
7
|
+
function hasPermission(tested, req) {
|
|
8
|
+
if (!req) {
|
|
9
|
+
// request object not available, allow all
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const permissions = getAuthProviderFromReq(req).getCurrentPermissions(req);
|
|
14
|
+
|
|
15
|
+
if (!cachedPermissions[permissions]) {
|
|
16
|
+
cachedPermissions[permissions] = compilePermissions(permissions);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return testPermission(tested, cachedPermissions[permissions]);
|
|
20
|
+
|
|
21
|
+
// const { user } = (req && req.auth) || {};
|
|
22
|
+
// const { login } = (process.env.OAUTH_PERMISSIONS && req && req.user) || {};
|
|
23
|
+
// const key = user || login || '';
|
|
24
|
+
// const logins = getLogins();
|
|
25
|
+
|
|
26
|
+
// if (!userPermissions[key]) {
|
|
27
|
+
// if (logins) {
|
|
28
|
+
// const login = logins.find(x => x.login == user);
|
|
29
|
+
// userPermissions[key] = compilePermissions(login ? login.permissions : null);
|
|
30
|
+
// } else {
|
|
31
|
+
// userPermissions[key] = compilePermissions(process.env.PERMISSIONS);
|
|
32
|
+
// }
|
|
33
|
+
// }
|
|
34
|
+
// return testPermission(tested, userPermissions[key]);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// let loginsCache = null;
|
|
38
|
+
// let loginsLoaded = false;
|
|
39
|
+
|
|
40
|
+
// function getLogins() {
|
|
41
|
+
// if (loginsLoaded) {
|
|
42
|
+
// return loginsCache;
|
|
43
|
+
// }
|
|
44
|
+
|
|
45
|
+
// const res = [];
|
|
46
|
+
// if (process.env.LOGIN && process.env.PASSWORD) {
|
|
47
|
+
// res.push({
|
|
48
|
+
// login: process.env.LOGIN,
|
|
49
|
+
// password: process.env.PASSWORD,
|
|
50
|
+
// permissions: process.env.PERMISSIONS,
|
|
51
|
+
// });
|
|
52
|
+
// }
|
|
53
|
+
// if (process.env.LOGINS) {
|
|
54
|
+
// const logins = _.compact(process.env.LOGINS.split(',').map(x => x.trim()));
|
|
55
|
+
// for (const login of logins) {
|
|
56
|
+
// const password = process.env[`LOGIN_PASSWORD_${login}`];
|
|
57
|
+
// const permissions = process.env[`LOGIN_PERMISSIONS_${login}`];
|
|
58
|
+
// if (password) {
|
|
59
|
+
// res.push({
|
|
60
|
+
// login,
|
|
61
|
+
// password,
|
|
62
|
+
// permissions,
|
|
63
|
+
// });
|
|
64
|
+
// }
|
|
65
|
+
// }
|
|
66
|
+
// } else if (process.env.OAUTH_PERMISSIONS) {
|
|
67
|
+
// const login_permission_keys = Object.keys(process.env).filter(key => _.startsWith(key, 'LOGIN_PERMISSIONS_'));
|
|
68
|
+
// for (const permissions_key of login_permission_keys) {
|
|
69
|
+
// const login = permissions_key.replace('LOGIN_PERMISSIONS_', '');
|
|
70
|
+
// const permissions = process.env[permissions_key];
|
|
71
|
+
// userPermissions[login] = compilePermissions(permissions);
|
|
72
|
+
// }
|
|
73
|
+
// }
|
|
74
|
+
|
|
75
|
+
// loginsCache = res.length > 0 ? res : null;
|
|
76
|
+
// loginsLoaded = true;
|
|
77
|
+
// return loginsCache;
|
|
78
|
+
// }
|
|
79
|
+
|
|
80
|
+
function connectionHasPermission(connection, req) {
|
|
81
|
+
if (!connection) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
if (_.isString(connection)) {
|
|
85
|
+
return hasPermission(`connections/${connection}`, req);
|
|
86
|
+
} else {
|
|
87
|
+
return hasPermission(`connections/${connection._id}`, req);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function testConnectionPermission(connection, req) {
|
|
92
|
+
if (!connectionHasPermission(connection, req)) {
|
|
93
|
+
throw new Error('Connection permission not granted');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
hasPermission,
|
|
99
|
+
connectionHasPermission,
|
|
100
|
+
testConnectionPermission,
|
|
101
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const { databaseInfoFromYamlModel, DatabaseAnalyser } = require('dbgate-tools');
|
|
2
|
+
const loadModelFolder = require('./loadModelFolder');
|
|
3
|
+
|
|
4
|
+
async function importDbModel(inputDir) {
|
|
5
|
+
const files = await loadModelFolder(inputDir);
|
|
6
|
+
return databaseInfoFromYamlModel(files);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
module.exports = importDbModel;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const stream = require('stream');
|
|
3
|
+
const readline = require('readline');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
async function loadFilesRecursive(dir, root = null) {
|
|
7
|
+
if (!root) root = dir;
|
|
8
|
+
if (!root.endsWith(path.sep)) root += path.sep;
|
|
9
|
+
const dirents = await fs.readdir(dir, { withFileTypes: true });
|
|
10
|
+
const files = await Promise.all(
|
|
11
|
+
dirents.map(dirent => {
|
|
12
|
+
const res = path.join(dir, dirent.name);
|
|
13
|
+
return dirent.isDirectory() ? loadFilesRecursive(res, root) : res;
|
|
14
|
+
})
|
|
15
|
+
);
|
|
16
|
+
const flatten = Array.prototype.concat(...files);
|
|
17
|
+
return flatten.map(file => (file.startsWith(root) ? file.substr(root.length) : file));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = loadFilesRecursive;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const yaml = require('js-yaml');
|
|
4
|
+
const { resolveArchiveFolder } = require('./directories');
|
|
5
|
+
const loadFilesRecursive = require('./loadFilesRecursive');
|
|
6
|
+
|
|
7
|
+
async function loadModelFolder(inputDir) {
|
|
8
|
+
const files = [];
|
|
9
|
+
|
|
10
|
+
const dir = inputDir.startsWith('archive:')
|
|
11
|
+
? resolveArchiveFolder(inputDir.substring('archive:'.length))
|
|
12
|
+
: path.resolve(inputDir);
|
|
13
|
+
|
|
14
|
+
for (const name of await loadFilesRecursive(dir)) {
|
|
15
|
+
if (name.endsWith('.table.yaml') || name.endsWith('.sql')) {
|
|
16
|
+
const text = await fs.readFile(path.join(dir, name), { encoding: 'utf-8' });
|
|
17
|
+
|
|
18
|
+
files.push({
|
|
19
|
+
name: path.parse(name).base,
|
|
20
|
+
text,
|
|
21
|
+
json: name.endsWith('.yaml') ? yaml.load(text) : null,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return files;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = loadModelFolder;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const { filesdir } = require('./directories');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const _ = require('lodash');
|
|
5
|
+
const dbgateApi = require('../shell');
|
|
6
|
+
const { getLogger, extractErrorLogData } = require('dbgate-tools');
|
|
7
|
+
const logger = getLogger('loadModelTransform');
|
|
8
|
+
|
|
9
|
+
function modelTransformFromJson(json) {
|
|
10
|
+
if (!dbgateApi[json.transform]) return null;
|
|
11
|
+
const creator = dbgateApi[json.transform];
|
|
12
|
+
return creator(...json.arguments);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function loadModelTransform(file) {
|
|
16
|
+
if (!file) return null;
|
|
17
|
+
try {
|
|
18
|
+
const dir = filesdir();
|
|
19
|
+
const fullPath = path.join(dir, 'modtrans', file);
|
|
20
|
+
const text = await fs.readFile(fullPath, { encoding: 'utf-8' });
|
|
21
|
+
const json = JSON.parse(text);
|
|
22
|
+
if (_.isArray(json)) {
|
|
23
|
+
const array = _.compact(json.map(x => modelTransformFromJson(x)));
|
|
24
|
+
return array.length ? structure => array.reduce((acc, val) => val(acc), structure) : null;
|
|
25
|
+
}
|
|
26
|
+
if (_.isPlainObject(json)) {
|
|
27
|
+
return modelTransformFromJson(json);
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
} catch (err) {
|
|
31
|
+
logger.error(extractErrorLogData(err), `Error loading model transform ${file}`);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = loadModelTransform;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const byline = require('byline');
|
|
2
|
+
const { safeJsonParse, getLogger } = require('dbgate-tools');
|
|
3
|
+
const logger = getLogger();
|
|
4
|
+
|
|
5
|
+
const logDispatcher = method => data => {
|
|
6
|
+
const json = safeJsonParse(data.toString());
|
|
7
|
+
if (json && json.level) {
|
|
8
|
+
logger.log(json);
|
|
9
|
+
} else {
|
|
10
|
+
logger[method](json || data.toString());
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function pipeForkLogs(subprocess) {
|
|
15
|
+
byline(subprocess.stdout).on('data', logDispatcher('info'));
|
|
16
|
+
byline(subprocess.stderr).on('data', logDispatcher('error'));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = pipeForkLogs;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const os = require('os');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const processArgs = require('./processArgs');
|
|
5
|
+
const isElectron = require('is-electron');
|
|
6
|
+
|
|
7
|
+
const platform = process.env.OS_OVERRIDE ? process.env.OS_OVERRIDE : process.platform;
|
|
8
|
+
const isWindows = platform === 'win32';
|
|
9
|
+
const isMac = platform === 'darwin';
|
|
10
|
+
const isLinux = platform === 'linux';
|
|
11
|
+
const isDocker = fs.existsSync('/home/dbgate-docker/public');
|
|
12
|
+
const isDevMode = process.env.DEVMODE == '1';
|
|
13
|
+
const isBuiltWebMode = process.env.BUILTWEBMODE == '1';
|
|
14
|
+
const isNpmDist = !!global['IS_NPM_DIST'];
|
|
15
|
+
const isDbModel = !!global['IS_DB_MODEL'];
|
|
16
|
+
const isForkedApi = processArgs.isForkedApi;
|
|
17
|
+
const isAwsUbuntuLayout = fs.existsSync('/home/ubuntu/build/public');
|
|
18
|
+
|
|
19
|
+
// function moduleAvailable(name) {
|
|
20
|
+
// try {
|
|
21
|
+
// require.resolve(name);
|
|
22
|
+
// return true;
|
|
23
|
+
// } catch (e) {
|
|
24
|
+
// return false;
|
|
25
|
+
// }
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
const platformInfo = {
|
|
29
|
+
isWindows,
|
|
30
|
+
isMac,
|
|
31
|
+
isLinux,
|
|
32
|
+
isDocker,
|
|
33
|
+
isElectronBundle: isElectron() && !isDevMode,
|
|
34
|
+
isForkedApi,
|
|
35
|
+
isElectron: isElectron(),
|
|
36
|
+
isDevMode,
|
|
37
|
+
isNpmDist,
|
|
38
|
+
isSnap: process.env.ELECTRON_SNAP == 'true',
|
|
39
|
+
isPortable: isWindows && process.env.PORTABLE_EXECUTABLE_DIR,
|
|
40
|
+
isAppImage: process.env.DESKTOPINTEGRATION === 'AppImageLauncher',
|
|
41
|
+
sshAuthSock: process.env.SSH_AUTH_SOCK,
|
|
42
|
+
environment: process.env.NODE_ENV,
|
|
43
|
+
platform,
|
|
44
|
+
runningInWebpack: !!process.env.WEBPACK_DEV_SERVER_URL,
|
|
45
|
+
allowShellConnection:
|
|
46
|
+
(!processArgs.listenApiChild && !isNpmDist) ||
|
|
47
|
+
!!process.env.SHELL_CONNECTION ||
|
|
48
|
+
!!isElectron() ||
|
|
49
|
+
!!isDbModel ||
|
|
50
|
+
isDevMode,
|
|
51
|
+
allowShellScripting:
|
|
52
|
+
(!processArgs.listenApiChild && !isNpmDist) ||
|
|
53
|
+
!!process.env.SHELL_SCRIPTING ||
|
|
54
|
+
!!isElectron() ||
|
|
55
|
+
!!isDbModel ||
|
|
56
|
+
isDevMode,
|
|
57
|
+
allowConnectionFromEnvVariables: !!isDbModel,
|
|
58
|
+
defaultKeyfile: path.join(os.homedir(), '.ssh/id_rsa'),
|
|
59
|
+
isAwsUbuntuLayout,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
module.exports = platformInfo;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
function getNamedArg(name) {
|
|
2
|
+
const argIndex = process.argv.indexOf(name);
|
|
3
|
+
if (argIndex > 0) {
|
|
4
|
+
return process.argv[argIndex + 1];
|
|
5
|
+
}
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const checkParent = process.argv.includes('--checkParent');
|
|
10
|
+
const startProcess = getNamedArg('--start-process');
|
|
11
|
+
const isForkedApi = process.argv.includes('--is-forked-api');
|
|
12
|
+
const pluginsDir = getNamedArg('--plugins-dir');
|
|
13
|
+
const workspaceDir = getNamedArg('--workspace-dir');
|
|
14
|
+
const processDisplayName = getNamedArg('--process-display-name');
|
|
15
|
+
const listenApi = process.argv.includes('--listen-api');
|
|
16
|
+
const listenApiChild = process.argv.includes('--listen-api-child') || listenApi;
|
|
17
|
+
|
|
18
|
+
function getPassArgs() {
|
|
19
|
+
const res = [];
|
|
20
|
+
if (global['PLUGINS_DIR']) {
|
|
21
|
+
res.push('--plugins-dir', global['PLUGINS_DIR']);
|
|
22
|
+
}
|
|
23
|
+
if (listenApiChild) {
|
|
24
|
+
res.push('listen-api-child');
|
|
25
|
+
}
|
|
26
|
+
return res;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
checkParent,
|
|
31
|
+
startProcess,
|
|
32
|
+
isForkedApi,
|
|
33
|
+
getPassArgs,
|
|
34
|
+
pluginsDir,
|
|
35
|
+
workspaceDir,
|
|
36
|
+
listenApi,
|
|
37
|
+
listenApiChild,
|
|
38
|
+
processDisplayName,
|
|
39
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { handleGetSshTunnelRequest, handleGetSshTunnelResponse } = require('./sshTunnelProxy');
|
|
2
|
+
|
|
3
|
+
function handleProcessCommunication(message, subprocess) {
|
|
4
|
+
const { msgtype } = message;
|
|
5
|
+
if (msgtype == 'getsshtunnel-request') {
|
|
6
|
+
handleGetSshTunnelRequest(message, subprocess);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (msgtype == 'getsshtunnel-response') {
|
|
10
|
+
handleGetSshTunnelResponse(message, subprocess);
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
handleProcessCommunication,
|
|
18
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
const requirePlugin = require('../shell/requirePlugin');
|
|
3
|
+
const { pickSafeConnectionInfo } = require('./crypting');
|
|
4
|
+
|
|
5
|
+
/** @returns {import('dbgate-types').EngineDriver} */
|
|
6
|
+
function requireEngineDriver(connection) {
|
|
7
|
+
let engine = null;
|
|
8
|
+
if (_.isString(connection)) {
|
|
9
|
+
engine = connection;
|
|
10
|
+
} else if (_.isPlainObject(connection)) {
|
|
11
|
+
engine = connection.engine;
|
|
12
|
+
}
|
|
13
|
+
if (!engine) {
|
|
14
|
+
throw new Error(`Could not get driver from connection ${JSON.stringify(pickSafeConnectionInfo(connection))}`);
|
|
15
|
+
}
|
|
16
|
+
if (engine.includes('@')) {
|
|
17
|
+
const [shortName, packageName] = engine.split('@');
|
|
18
|
+
const plugin = requirePlugin(packageName);
|
|
19
|
+
if (plugin.drivers) {
|
|
20
|
+
return plugin.drivers.find(x => x.engine == engine);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`Could not find engine driver ${engine}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = requireEngineDriver;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
const requirePlugin = require('../shell/requirePlugin');
|
|
3
|
+
|
|
4
|
+
function requirePluginFunction(functionName) {
|
|
5
|
+
if (!functionName) return null;
|
|
6
|
+
if (functionName.includes('@')) {
|
|
7
|
+
const [shortName, packageName] = functionName.split('@');
|
|
8
|
+
const plugin = requirePlugin(packageName);
|
|
9
|
+
if (plugin.functions) {
|
|
10
|
+
return plugin.functions[shortName];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = requirePluginFunction;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const _ = require('lodash');
|
|
2
|
+
const stableStringify = require('json-stable-stringify');
|
|
3
|
+
|
|
4
|
+
const sseResponses = {};
|
|
5
|
+
let electronSender = null;
|
|
6
|
+
let pingConfigured = false;
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
ensurePing() {
|
|
10
|
+
if (!pingConfigured) {
|
|
11
|
+
setInterval(() => this.emit('ping'), 29 * 1000);
|
|
12
|
+
pingConfigured = true;
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
addSseResponse(value, strmid) {
|
|
16
|
+
sseResponses[strmid] = {
|
|
17
|
+
...sseResponses[strmid],
|
|
18
|
+
response: value,
|
|
19
|
+
};
|
|
20
|
+
this.ensurePing();
|
|
21
|
+
},
|
|
22
|
+
removeSseResponse(strmid) {
|
|
23
|
+
delete sseResponses[strmid];
|
|
24
|
+
},
|
|
25
|
+
setElectronSender(value) {
|
|
26
|
+
electronSender = value;
|
|
27
|
+
this.ensurePing();
|
|
28
|
+
},
|
|
29
|
+
emit(message, data) {
|
|
30
|
+
if (electronSender) {
|
|
31
|
+
electronSender.send(message, data == null ? null : data);
|
|
32
|
+
}
|
|
33
|
+
for (const strmid in sseResponses) {
|
|
34
|
+
if (data?.strmid && data?.strmid != strmid) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
let skipThisStream = false;
|
|
38
|
+
if (sseResponses[strmid].filter) {
|
|
39
|
+
for (const key in sseResponses[strmid].filter) {
|
|
40
|
+
if (data && data[key]) {
|
|
41
|
+
if (!sseResponses[strmid].filter[key].includes(data[key])) {
|
|
42
|
+
skipThisStream = true;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (skipThisStream) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
sseResponses[strmid].response?.write(
|
|
53
|
+
`event: ${message}\ndata: ${stableStringify(data == null ? null : _.omit(data, ['strmid']))}\n\n`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
emitChanged(key, params = undefined) {
|
|
58
|
+
// console.log('EMIT CHANGED', key);
|
|
59
|
+
this.emit('changed-cache', { key, ...params });
|
|
60
|
+
// this.emit(key);
|
|
61
|
+
},
|
|
62
|
+
setStreamIdFilter(strmid, filter) {
|
|
63
|
+
sseResponses[strmid] = {
|
|
64
|
+
...sseResponses[strmid],
|
|
65
|
+
filter,
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
};
|