Compare commits

..

4 Commits

Author SHA1 Message Date
SPRINX0\prochazka 0ff830f5b0 changed query workflow 2025-11-05 13:32:04 +01:00
SPRINX0\prochazka 7214516950 _t 2025-11-05 13:12:09 +01:00
SPRINX0\prochazka c6cbd77b88 Merge branch 'master' into feature/result-query 2025-11-05 13:07:39 +01:00
SPRINX0\prochazka 5535bf91a1 Show executed query on log #1236 2025-11-05 12:11:19 +01:00
446 changed files with 6319 additions and 28229 deletions
-4
View File
@@ -21,10 +21,6 @@ jobs:
- windows-2022
- ubuntu-22.04
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: python -m pip install --upgrade pip setuptools
- name: Install python 3.11 (MacOS)
if: matrix.os == 'macos-14'
run: |
-4
View File
@@ -21,10 +21,6 @@ jobs:
- windows-2022
- ubuntu-22.04
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: python -m pip install --upgrade pip setuptools
- name: Install python 3.11 (MacOS)
if: matrix.os == 'macos-14'
run: |
+1 -5
View File
@@ -21,10 +21,6 @@ jobs:
- windows-2022
- ubuntu-22.04
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: python -m pip install --upgrade pip setuptools
- name: Install python 3.11 (MacOS)
if: matrix.os == 'macos-14'
run: |
@@ -47,7 +43,7 @@ jobs:
repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro
ref: a5f52768cea7e98cae5e5b1f5fef3c47a475b8a6
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
- name: Merge dbgate/dbgate-pro
run: |
mkdir ../dbgate-pro
+1 -5
View File
@@ -21,10 +21,6 @@ jobs:
- windows-2022
- ubuntu-22.04
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: python -m pip install --upgrade pip setuptools
- name: Install python 3.11 (MacOS)
if: matrix.os == 'macos-14'
run: |
@@ -47,7 +43,7 @@ jobs:
repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro
ref: a5f52768cea7e98cae5e5b1f5fef3c47a475b8a6
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
- name: Merge dbgate/dbgate-pro
run: |
mkdir ../dbgate-pro
-4
View File
@@ -21,10 +21,6 @@ jobs:
- windows-2022
- ubuntu-22.04
steps:
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: python -m pip install --upgrade pip setuptools
- name: Install python 3.11 (MacOS)
if: matrix.os == 'macos-14'
run: |
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro
ref: a5f52768cea7e98cae5e5b1f5fef3c47a475b8a6
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
- name: Merge dbgate/dbgate-pro
run: |
mkdir ../dbgate-pro
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro
ref: a5f52768cea7e98cae5e5b1f5fef3c47a475b8a6
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
- name: Merge dbgate/dbgate-pro
run: |
mkdir ../dbgate-pro
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro
ref: a5f52768cea7e98cae5e5b1f5fef3c47a475b8a6
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
- name: Merge dbgate/dbgate-pro
run: |
mkdir ../dbgate-pro
+3 -18
View File
@@ -5,14 +5,10 @@ name: Cypress tests with screenshots PREMIUM
'on':
push:
branches:
- stable
- master
- develop
- feature/**
- hotfix/**
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
e2e-tests:
runs-on: ubuntu-latest
@@ -30,7 +26,7 @@ jobs:
repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro
ref: a5f52768cea7e98cae5e5b1f5fef3c47a475b8a6
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
- name: Merge dbgate/dbgate-pro
run: |
mkdir ../dbgate-pro
@@ -73,8 +69,8 @@ jobs:
with:
name: screenshots
path: screenshots
- name: Push E2E screenshots - stable
if: ${{ github.ref_name == 'stable' }}
- name: Push E2E screenshots
if: ${{ github.ref_name == 'master' }}
run: |
git config --global user.email "info@dbgate.info"
git config --global user.name "GitHub Actions"
@@ -84,17 +80,6 @@ jobs:
git add .
git commit --amend --no-edit
git push --force
- name: Push E2E screenshots - master
if: ${{ github.ref_name == 'master' }}
run: |
git config --global user.email "info@dbgate.info"
git config --global user.name "GitHub Actions"
git clone https://${{ secrets.DIFLOW_GIT_SECRET }}@github.com/dbgate/dbgate-img.git
cp ../dbgate-merged/e2e-tests/screenshots/*.png dbgate-img/static/img-dev
cd dbgate-img/static/img-dev
git add .
git commit --amend --no-edit
git push --force
services:
postgres-cypress:
image: postgres
+18 -3
View File
@@ -9,9 +9,6 @@ name: Integration and unit tests
- develop
- feature/**
- hotfix/**
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
all-tests:
runs-on: ubuntu-latest
@@ -45,6 +42,24 @@ jobs:
run: |
cd packages/tools
yarn test:ci
- uses: tanmen/jest-reporter@v1
if: always()
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-file: integration-tests/result.json
action-name: Integration tests
- uses: tanmen/jest-reporter@v1
if: always()
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-file: packages/filterparser/result.json
action-name: Filter parser test results
- uses: tanmen/jest-reporter@v1
if: always()
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
result-file: packages/datalib/result.json
action-name: Datalib (perspectives) test results
services:
postgres-integr:
image: postgres
-1
View File
@@ -24,7 +24,6 @@ docker/plugins
.env.development.local
.env.test.local
.env.production.local
.env.translation
npm-debug.log*
yarn-debug.log*
+1 -81
View File
@@ -8,86 +8,6 @@ Builds:
- linux - application for linux
- win - application for Windows
## 6.8.2
- FIXED: Initialize storage database from envoronment variables failed with PostgreSQL
## 6.8.1
- FIXED: Won't navigate to the relevant field on click of a field in columns #1303
## 6.8.0
- ADDED: Form cell view for detailed data inspection and editing in data grids, with multi-row bulk editing support
- CHANGED: Cell data sidebar moved to right side, now is part of data grid
- FIXED: Improved widget resizing algorithm
- FIXED: Word wrap feature in SQL editor
- CHANGED: Data grid keyboard navigation improvements
- CHANGED: Improved PostgreSQL decimal type support in data grid #1214
- ADDED: Retrieve number of databases from Redis configuration #1278
- ADDED: Run macro context menu (Premium)
- ADDED: Support for skip update columns in replicator
- FIXED: UTF-8 BOM handling in CSV input
- CHANGED: Advanced export is now part of Community edition
- FIXED: SQLite foreign key constraint types
- FIXED: Double drop constraint issue
- CHANGED: Improved map view lat/lon field autodetection
- FIXED: Alter table operations and constraint sanitization
- ADDED: Import connections from environment variables (Team Premium)
## 6.7.3
- FIXED: Fixed problem in analyser core - in PostgreSQL, after dropping table, dropped table still appeared in structure
- FIXED: PostgreSQL numeric columns do not align right #1254
- ADDED: Custom thousands separator #1213
## 6.7.2
- CHANGED: Settings modal redesign - now is settings opened in tab instead of modal, similarily as in VSCode
- FIXED: Fixed search in table shortcuts #1273
- CHANGED: Improved foreign key editor UX
- FIXED: Fixed incremental DB structure refresh for PostgreSQL, optimalized slow loading primary keys in PostgreSQL
- CHANGED: You could now choose, how to refresh structure, added ability to disconnect or reconnect
- ADDED: Better processing of table backups, generate table restore script #1274
- CHANGED: Improved storage of settings, especially for Team Premium edition
## 6.7.1
- ADDED: LANGUAGE environment variable for the web version. #1266
- ADDED: New localizations (Italian, Portugese (Brazil), Japanese)
- ADDED: Option to detect language from browser settings in web version
- FIXED: Check updates option no longer available in 6.7.0 #1263
- FIXED: A MERGE statement must be terminated by a semi-colon (;), but dbgate stripped it. #1257
- ADDED: Show table size #552
- ADDED: Sort tables by size and by row count
- ADDED: Connect to Legacy MongoDB (Premium) #540
- FIXED: Fixed problems in saving team files in Team Premium edition
- CHANGED: Files are by default saved to team folders in Team Premium edition
- ADDED: Other files types supported in Team Premium edition (diagrams, query design, perspectives, import/export jobs, shell scripts, database compare jobs)
## 6.7.0
- ADDED: Added localization support, now you can use DbGate in multiple languages (French, Spanish, German, Czech, Slovak, Simplified Chinese) #347 #705 #939 #1079
- CHANGED: Solved many issues with binary fields, huge performance improvements in binary fields processing
- FIXED: Export to CSV produces empty file #1247
- CHANGED: Upgraded electron to version 38 #1243
- FIXED: PostgreSQL export to SQL and XML doesn't include bytea field contents #1228
- FIXED: Export CSV broken #1080
- FIXED: Inconsistent handling of hex-like strings #680
- FIXED: Export mongodb binary cell as binary file #292
- CHANGED: SSL is used automatically for connections to Azure databases
- ADDED: New export formats CSV for Excel, TSV
- FIXED: Horizontal scrolling on macOS trackpad/Magic Mouse #1250
## 6.6.12
- FIXED: Cannot paste license key on Mac (special commands like copy/paste were disabled on license screen)
## 6.6.11
- FIXED: Fixed theming on application startup
- CHANGED: Improved licensing page
## 6.6.10
- FIXED: License from environment variable is not refreshed #1245
- FIXED: connection closing / reconnecting #1237
- ADDED: retain history across multiple queries #1236
- ADDED: load CSVs to temp tables #1235
- FIXED: Not possible to scroll the data view horizontally by pressing shift and scroll mouse middle button on Mac #453
- FIXED: Expired trial workflow (Premium)
- ADDED: Column name collision resolving #1234 (MySQL)
## 6.6.8
- CHANGED: Windows executable now uses Azure trusted signing certificate
- CHANGED: NPM packages now use GitHub OIDC provenance signing for better security
@@ -103,7 +23,7 @@ Builds:
- ADDED: SQL AI assistant - powered by database chat, could help you to write SQL queries (Premium)
- ADDED: Explain SQL error (powered by AI) (Premium)
- ADDED: Database chat (and SQL AI Assistant) now supports showing charts (Premium)
- FIXED: Fixed editing new files and roles (Team Premium)
- FIXED: Fxied editing new files and roles (Team Premium)
- FIXED: Connection to standalone database could be now pinned
- FIXED: Cannot open up large JSON file #1215
+1 -1
View File
@@ -128,7 +128,7 @@
"devDependencies": {
"copyfiles": "^2.2.0",
"cross-env": "^6.0.3",
"electron": "38.6.0",
"electron": "30.0.2",
"electron-builder": "25.1.8"
}
}
+13 -41
View File
@@ -31,16 +31,6 @@ let mainModule;
let appUpdateStatus = '';
let settingsJson = {};
function getTranslated(key) {
if (typeof key === 'string' && global.TRANSLATION_DATA?.[key]) {
return global.TRANSLATION_DATA?.[key];
}
if (typeof key?._transKey === 'string') {
return global.TRANSLATION_DATA?.[key._transKey] ?? key._transOptions?.defaultMessage;
}
return key;
}
process.on('uncaughtException', function (error) {
console.error('uncaughtException', error);
});
@@ -73,7 +63,6 @@ try {
let mainWindow;
let mainMenu;
let runCommandOnLoad = null;
let mainWindowMenuSet = false;
log.transports.file.level = 'debug';
autoUpdater.logger = log;
@@ -96,22 +85,17 @@ function formatKeyText(keyText) {
return keyText.replace('CtrlOrCommand+', 'Ctrl+');
}
function commandItem(item, disableAll = false) {
function commandItem(item) {
const id = item.command;
const command = commands[id];
if (item.skipInApp) {
return { skip: true };
}
if (!command) {
return { skip: true };
}
return {
id,
label: command
? getTranslated(command.menuName) || getTranslated(command.toolbarName) || getTranslated(command.name)
: id,
label: command ? command.menuName || command.toolbarName || command.name : id,
accelerator: formatKeyText(command ? command.keyText : undefined),
enabled: command ? command.enabled && (!disableAll || command.systemCommand) : false,
enabled: command ? command.enabled : false,
click() {
if (mainWindow) {
mainWindow.webContents.send('run-command', id);
@@ -123,14 +107,14 @@ function commandItem(item, disableAll = false) {
};
}
function buildMenu(disableAll = false) {
function buildMenu() {
let template = _cloneDeepWith(mainMenuDefinition({ editMenu: true, isMac: isMac() }), item => {
if (item.divider) {
return { type: 'separator' };
}
if (item.command) {
return commandItem(item, disableAll);
return commandItem(item);
}
});
@@ -145,7 +129,7 @@ function buildMenu(disableAll = false) {
{
label: 'DbGate',
submenu: [
commandItem({ command: 'about.show' }, disableAll),
commandItem({ command: 'about.show' }),
{ role: 'services' },
{ role: 'hide' },
{ role: 'hideOthers' },
@@ -161,28 +145,22 @@ function buildMenu(disableAll = false) {
}
ipcMain.on('update-commands', async (event, arg) => {
const parsed = JSON.parse(arg);
commands = parsed.commands;
const isModalOpened = parsed.isModalOpened;
const dbgatePage = parsed.dbgatePage;
commands = JSON.parse(arg);
for (const key of Object.keys(commands)) {
const menu = mainMenu.getMenuItemById(key);
if (!menu) continue;
const command = commands[key];
// rebuild menu
if (global.TRANSLATION_DATA && (menu.label != command.text || menu.accelerator != command.keyText)) {
mainMenu = buildMenu(isModalOpened || !!dbgatePage);
if (menu.label != command.text || menu.accelerator != command.keyText) {
mainMenu = buildMenu();
Menu.setApplicationMenu(mainMenu);
if (!mainWindowMenuSet) {
mainWindow.setMenu(mainMenu);
mainWindowMenuSet = true;
}
// mainWindow.setMenu(mainMenu);
return;
}
menu.enabled = command.enabled && !isModalOpened && !dbgatePage;
menu.enabled = command.enabled;
}
});
ipcMain.on('quit-app', async (event, arg) => {
@@ -325,12 +303,6 @@ ipcMain.on('check-for-updates', async (event, url) => {
autoUpdater.autoDownload = false;
autoUpdater.checkForUpdates();
});
ipcMain.on('translation-data', async (event, arg) => {
global.TRANSLATION_DATA = JSON.parse(arg);
mainMenu = buildMenu();
Menu.setApplicationMenu(mainMenu);
mainWindow.setMenu(mainMenu);
});
function fillMissingSettings(value) {
const res = {
@@ -407,8 +379,8 @@ function createWindow() {
mainWindow.setFullScreen(true);
}
// mainMenu = buildMenu();
// mainWindow.setMenu(mainMenu);
mainMenu = buildMenu();
mainWindow.setMenu(mainMenu);
function loadMainWindow() {
const startUrl =
+7 -15
View File
@@ -1,10 +1,6 @@
function _t(key, { defaultMessage, currentTranslations } = {}) {
return (currentTranslations || global.TRANSLATION_DATA)?.[key] || defaultMessage;
}
module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
module.exports = ({ editMenu, isMac }) => [
{
label: _t('menu.file', { defaultMessage: 'File', currentTranslations }),
label: 'File',
submenu: [
{ command: 'new.connection', hideDisabled: true },
{ command: 'new.sqliteDatabase', hideDisabled: true },
@@ -32,7 +28,7 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
},
editMenu
? {
label: _t('menu.edit', { defaultMessage: 'Edit', currentTranslations }),
label: 'Edit',
submenu: [
{ command: 'edit.undo' },
{ command: 'edit.redo' },
@@ -57,7 +53,7 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
// ],
// },
{
label: _t('menu.view', { defaultMessage: 'View', currentTranslations }),
label: 'View',
submenu: [
{ command: 'app.reload', hideDisabled: true },
{ command: 'app.toggleDevTools', hideDisabled: true },
@@ -76,12 +72,10 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
{ command: 'app.zoomIn', hideDisabled: true },
{ command: 'app.zoomOut', hideDisabled: true },
{ command: 'app.zoomReset', hideDisabled: true },
{ divider: true },
{ command: 'app.showLogs', hideDisabled: true },
],
},
{
label: _t('menu.tools', { defaultMessage: 'Tools', currentTranslations }),
label: 'Tools',
submenu: [
{ command: 'database.search', hideDisabled: true },
{ command: 'commandPalette.show', hideDisabled: true },
@@ -97,8 +91,6 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
{ divider: true },
{ command: 'app.exportConnections', hideDisabled: true },
{ command: 'app.importConnections', hideDisabled: true },
{ divider: true },
{ command: 'app.managePlugins', hideDisabled: true },
],
},
...(isMac
@@ -110,7 +102,7 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
]
: []),
{
label: _t('menu.help', { defaultMessage: 'Help', currentTranslations }),
label: 'Help',
submenu: [
{ command: 'app.openDocs', hideDisabled: true },
{ command: 'app.openWeb', hideDisabled: true },
@@ -122,7 +114,7 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
{ command: 'tabs.changelog', hideDisabled: true },
{ command: 'about.show', hideDisabled: true },
{ divider: true },
{ command: 'app.checkForUpdates', hideDisabled: true },
{ command: 'file.checkForUpdates', hideDisabled: true },
],
},
];
+224 -279
View File
@@ -16,9 +16,9 @@
ajv-keywords "^3.4.1"
"@electron/asar@^3.2.7":
version "3.4.1"
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.4.1.tgz#4e9196a4b54fba18c56cd8d5cac67c5bdc588065"
integrity sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==
version "3.2.17"
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.17.tgz#91d28087aad80d1a1c8cc4e667c6476edf50f949"
integrity sha512-OcWImUI686w8LkghQj9R2ynZ2ME693Ek6L1SiaAgqGKzBaTIZw3fHDqN82Rcl+EU1Gm9EgkJ5KLIY/q5DCRbbA==
dependencies:
commander "^5.0.0"
glob "^7.1.6"
@@ -98,18 +98,6 @@
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
"@isaacs/balanced-match@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29"
integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==
"@isaacs/brace-expansion@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3"
integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==
dependencies:
"@isaacs/balanced-match" "^4.0.1"
"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
@@ -214,23 +202,16 @@
"@types/node" "*"
"@types/ms@*":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78"
integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==
version "0.7.34"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
"@types/node@*":
version "24.10.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.0.tgz#6b79086b0dfc54e775a34ba8114dcc4e0221f31f"
integrity sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==
"@types/node@*", "@types/node@^20.9.0":
version "20.12.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.10.tgz#8f0c3f12b0f075eee1fe20c1afb417e9765bef76"
integrity sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==
dependencies:
undici-types "~7.16.0"
"@types/node@^22.7.7":
version "22.19.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.0.tgz#849606ef3920850583a4e7ee0930987c35ad80be"
integrity sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==
dependencies:
undici-types "~6.21.0"
undici-types "~5.26.4"
"@types/plist@^3.0.1":
version "3.0.5"
@@ -248,9 +229,9 @@
"@types/node" "*"
"@types/verror@^1.10.3":
version "1.10.11"
resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.11.tgz#d3d6b418978c8aa202d41e5bb3483227b6ecc1bb"
integrity sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==
version "1.10.10"
resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.10.tgz#d5a4b56abac169bfbc8b23d291363a682e6fa087"
integrity sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==
"@types/yauzl@^2.9.1":
version "2.10.3"
@@ -260,9 +241,9 @@
"@types/node" "*"
"@xmldom/xmldom@^0.8.8":
version "0.8.11"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608"
integrity sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==
version "0.8.10"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
"@yarnpkg/lockfile@^1.1.0":
version "1.1.0"
@@ -282,14 +263,14 @@ agent-base@6, agent-base@^6.0.2:
debug "4"
agent-base@^7.1.0, agent-base@^7.1.2:
version "7.1.4"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8"
integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==
version "7.1.3"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1"
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
agentkeepalive@^4.2.1:
version "4.6.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a"
integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==
version "4.5.0"
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
dependencies:
humanize-ms "^1.2.1"
@@ -322,9 +303,9 @@ ansi-regex@^5.0.1:
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-regex@^6.0.1:
version "6.2.2"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1"
integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==
version "6.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654"
integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
@@ -334,9 +315,9 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
color-convert "^2.0.1"
ansi-styles@^6.1.0:
version "6.2.3"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041"
integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==
version "6.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
app-builder-bin@5.0.0-alpha.10:
version "5.0.0-alpha.10"
@@ -382,9 +363,9 @@ app-builder-lib@25.1.8:
temp-file "^3.4.0"
"aproba@^1.0.3 || ^2.0.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.1.0.tgz#75500a190313d95c64e871e7e4284c6ac219f0b1"
integrity sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==
version "2.0.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==
are-we-there-yet@^3.0.0:
version "3.0.1"
@@ -414,10 +395,10 @@ async-exit-hook@^2.0.1:
resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3"
integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==
async@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
async@^3.2.3:
version "3.2.5"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66"
integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==
asynckit@^0.4.0:
version "0.4.0"
@@ -466,33 +447,33 @@ boolean@^3.0.1:
integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
brace-expansion@^1.1.7:
version "1.1.12"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843"
integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7"
integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
braces@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
dependencies:
fill-range "^7.1.1"
fill-range "^7.0.1"
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
buffer-equal-constant-time@^1.0.1:
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==
@@ -518,10 +499,10 @@ builder-util-runtime@9.2.10:
debug "^4.3.4"
sax "^1.2.4"
builder-util-runtime@9.3.1:
version "9.3.1"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz#0daedde0f6d381f2a00a50a407b166fe7dca1a67"
integrity sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==
builder-util-runtime@9.2.5:
version "9.2.5"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.2.5.tgz#0afdffa0adb5c84c14926c7dd2cf3c6e96e9be83"
integrity sha512-HjIDfhvqx/8B3TDN4GbABQcgpewTU4LMRTQPkVpKYV3lsuxEJoIfvg09GyWTNmfVNSUAYf+fbTN//JX4TH20pg==
dependencies:
debug "^4.3.4"
sax "^1.2.4"
@@ -590,15 +571,7 @@ cacheable-request@^7.0.2:
normalize-url "^6.0.1"
responselike "^2.0.0"
call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -771,9 +744,9 @@ cross-env@^6.0.3:
cross-spawn "^7.0.0"
cross-spawn@^6.0.5:
version "6.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57"
integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
dependencies:
nice-try "^1.0.4"
path-key "^2.0.1"
@@ -781,19 +754,26 @@ cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3, cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4:
version "4.4.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@^4.3.3:
version "4.4.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
dependencies:
ms "^2.1.3"
@@ -845,9 +825,9 @@ delegates@^1.0.0:
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
detect-libc@^2.0.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"
integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
version "2.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
detect-node@^2.0.4:
version "2.1.0"
@@ -898,18 +878,9 @@ dotenv-expand@^11.0.6:
dotenv "^16.4.5"
dotenv@^16.4.5:
version "16.6.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.6.1.tgz#773f0e69527a8315c7285d5ee73c4459d20a8020"
integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==
dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-errors "^1.3.0"
gopd "^1.2.0"
version "16.4.7"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
eastasianwidth@^0.2.0:
version "0.2.0"
@@ -965,11 +936,11 @@ electron-publish@25.1.7:
mime "^2.5.2"
electron-updater@^6.3.4:
version "6.6.2"
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.6.2.tgz#3e65e044f1a99b00d61e200e24de8e709c69ce99"
integrity sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==
version "6.3.4"
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.3.4.tgz#3934bc89875bb524c2cbbd11041114e97c0c2496"
integrity sha512-uZUo7p1Y53G4tl6Cgw07X1yF8Jlz6zhaL7CQJDZ1fVVkOaBfE2cWtx80avwDVi8jHp+I/FWawrMgTAeCCNIfAg==
dependencies:
builder-util-runtime "9.3.1"
builder-util-runtime "9.2.5"
fs-extra "^10.1.0"
js-yaml "^4.1.0"
lazy-val "^1.0.5"
@@ -978,13 +949,13 @@ electron-updater@^6.3.4:
semver "^7.6.3"
tiny-typed-emitter "^2.1.0"
electron@38.6.0:
version "38.6.0"
resolved "https://registry.yarnpkg.com/electron/-/electron-38.6.0.tgz#c862bff41d42776e307bf5cc92503dda23612339"
integrity sha512-68OFNxJlrEStA+t8k5atzf4frJddvRR1N1oalr49Ll8YZ0+0nEsDhw4UNhTCoZKTjSYcxFF/4rt+sco+OlnB3g==
electron@30.0.2:
version "30.0.2"
resolved "https://registry.yarnpkg.com/electron/-/electron-30.0.2.tgz#95ba019216bf8be9f3097580123e33ea37497733"
integrity sha512-zv7T+GG89J/hyWVkQsLH4Y/rVEfqJG5M/wOBIGNaDdqd8UV9/YZPdS7CuFeaIj0H9LhCt95xkIQNpYB/3svOkQ==
dependencies:
"@electron/get" "^2.0.0"
"@types/node" "^22.7.7"
"@types/node" "^20.9.0"
extract-zip "^2.0.1"
emoji-regex@^8.0.0:
@@ -1005,9 +976,9 @@ encoding@^0.1.13:
iconv-lite "^0.6.2"
end-of-stream@^1.1.0:
version "1.4.5"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c"
integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
dependencies:
once "^1.4.0"
@@ -1021,42 +992,27 @@ err-code@^2.0.2:
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==
es-define-property@^1.0.0, es-define-property@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
es-define-property@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
dependencies:
get-intrinsic "^1.2.4"
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
dependencies:
es-errors "^1.3.0"
es-set-tostringtag@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d"
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
dependencies:
es-errors "^1.3.0"
get-intrinsic "^1.2.6"
has-tostringtag "^1.0.2"
hasown "^2.0.2"
es6-error@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
escalade@^3.1.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
version "3.1.2"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
escape-string-regexp@^4.0.0:
version "4.0.0"
@@ -1064,9 +1020,9 @@ escape-string-regexp@^4.0.0:
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
exponential-backoff@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6"
integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==
version "3.1.1"
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==
extract-zip@^2.0.1:
version "2.0.1"
@@ -1108,10 +1064,10 @@ filelist@^1.0.4:
dependencies:
minimatch "^5.0.1"
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
dependencies:
to-regex-range "^5.0.1"
@@ -1123,22 +1079,20 @@ find-yarn-workspace-root@^2.0.0:
micromatch "^4.0.2"
foreground-child@^3.1.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f"
integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==
version "3.3.0"
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77"
integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==
dependencies:
cross-spawn "^7.0.6"
cross-spawn "^7.0.0"
signal-exit "^4.0.1"
form-data@^4.0.0:
version "4.0.4"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
es-set-tostringtag "^2.1.0"
hasown "^2.0.2"
mime-types "^2.1.12"
fs-extra@^10.0.0, fs-extra@^10.1.0:
@@ -1151,9 +1105,9 @@ fs-extra@^10.0.0, fs-extra@^10.1.0:
universalify "^2.0.0"
fs-extra@^11.1.1:
version "11.3.2"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4"
integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==
version "11.2.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b"
integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
@@ -1214,29 +1168,16 @@ get-caller-file@^2.0.5:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.2.6:
version "1.3.0"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
dependencies:
call-bind-apply-helpers "^1.0.2"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.1.1"
function-bind "^1.1.2"
get-proto "^1.0.1"
gopd "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
math-intrinsics "^1.1.0"
get-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
dependencies:
dunder-proto "^1.0.1"
es-object-atoms "^1.0.0"
has-proto "^1.0.1"
has-symbols "^1.0.3"
hasown "^2.0.0"
get-stream@^5.1.0:
version "5.2.0"
@@ -1300,10 +1241,12 @@ globalthis@^1.0.1:
define-properties "^1.2.1"
gopd "^1.0.1"
gopd@^1.0.1, gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
dependencies:
get-intrinsic "^1.1.3"
got@^11.7.0, got@^11.8.5:
version "11.8.6"
@@ -1339,24 +1282,22 @@ has-property-descriptors@^1.0.0:
dependencies:
es-define-property "^1.0.0"
has-symbols@^1.0.3, has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
has-proto@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
has-tostringtag@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
dependencies:
has-symbols "^1.0.3"
has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
has-unicode@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==
hasown@^2.0.2:
hasown@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
@@ -1371,9 +1312,9 @@ hosted-git-info@^4.1.0:
lru-cache "^6.0.0"
http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5"
integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==
version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
http-proxy-agent@^5.0.0:
version "5.0.0"
@@ -1471,10 +1412,13 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1,
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ip-address@^10.0.1:
version "10.1.0"
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4"
integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==
ip-address@^9.0.5:
version "9.0.5"
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a"
integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==
dependencies:
jsbn "1.1.0"
sprintf-js "^1.1.3"
is-ci@^2.0.0:
version "2.0.0"
@@ -1543,9 +1487,9 @@ isbinaryfile@^4.0.8:
integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==
isbinaryfile@^5.0.0:
version "5.0.6"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.6.tgz#01eac28867aeffaebaee7eaf21d1dd3a67d7c0c7"
integrity sha512-I+NmIfBHUl+r2wcDd6JwE9yWje/PIVY/R5/CmV8dXLZd5K+L9X2klAOwfAHNnondLXkbHyTAleQAWonpTJBTtw==
version "5.0.4"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.4.tgz#2a2edefa76cafa66613fe4c1ea52f7f031017bdf"
integrity sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==
isexe@^2.0.0:
version "2.0.0"
@@ -1562,13 +1506,14 @@ jackspeak@^3.1.2:
"@pkgjs/parseargs" "^0.11.0"
jake@^10.8.5:
version "10.9.4"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.4.tgz#d626da108c63d5cfb00ab5c25fadc7e0084af8e6"
integrity sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==
version "10.9.1"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.1.tgz#8dc96b7fcc41cb19aa502af506da4e1d56f5e62b"
integrity sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==
dependencies:
async "^3.2.6"
async "^3.2.3"
chalk "^4.0.2"
filelist "^1.0.4"
picocolors "^1.1.1"
minimatch "^3.1.2"
js-yaml@^4.1.0:
version "4.1.0"
@@ -1577,6 +1522,11 @@ js-yaml@^4.1.0:
dependencies:
argparse "^2.0.1"
jsbn@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==
json-buffer@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
@@ -1605,9 +1555,9 @@ jsonfile@^4.0.0:
graceful-fs "^4.1.6"
jsonfile@^6.0.1:
version "6.2.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62"
integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
dependencies:
universalify "^2.0.0"
optionalDependencies:
@@ -1630,11 +1580,11 @@ jsonwebtoken@^9.0.2:
semver "^7.5.4"
jwa@^1.4.1:
version "1.4.2"
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.2.tgz#16011ac6db48de7b102777e57897901520eec7b9"
integrity sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==
version "1.4.1"
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
dependencies:
buffer-equal-constant-time "^1.0.1"
buffer-equal-constant-time "1.0.1"
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
@@ -1779,17 +1729,12 @@ matcher@^3.0.0:
dependencies:
escape-string-regexp "^4.0.0"
math-intrinsics@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
micromatch@^4.0.2:
version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
dependencies:
braces "^3.0.3"
braces "^3.0.2"
picomatch "^2.3.1"
mime-db@1.52.0:
@@ -1825,13 +1770,13 @@ mimic-response@^3.1.0:
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
minimatch@^10.0.0:
version "10.1.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.1.1.tgz#e6e61b9b0c1dcab116b5a7d1458e8b6ae9e73a55"
integrity sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==
version "10.0.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b"
integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==
dependencies:
"@isaacs/brace-expansion" "^5.0.0"
brace-expansion "^2.0.1"
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1:
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
@@ -1926,6 +1871,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@^2.0.0, ms@^2.1.1, ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
@@ -1942,9 +1892,9 @@ nice-try@^1.0.4:
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
node-abi@^3.45.0:
version "3.80.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.80.0.tgz#d7390951f27caa129cceeec01e1c20fc9f07581c"
integrity sha512-LyPuZJcI9HVwzXK1GPxWNzrr+vr8Hp/3UqlmWxxh8p54U1ZbclOqbSog9lWHaCX+dBaiGi6n/hIX+mKu74GmPA==
version "3.71.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.71.0.tgz#52d84bbcd8575efb71468fbaa1f9a49b2c242038"
integrity sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==
dependencies:
semver "^7.3.5"
@@ -1954,9 +1904,9 @@ node-addon-api@^1.6.3:
integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==
node-api-version@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.1.tgz#19bad54f6d65628cbee4e607a325e4488ace2de9"
integrity sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==
version "0.2.0"
resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.0.tgz#5177441da2b1046a4d4547ab9e0972eed7b1ac1d"
integrity sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==
dependencies:
semver "^7.3.5"
@@ -2131,11 +2081,6 @@ pend@~1.2.0:
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
@@ -2174,9 +2119,9 @@ promise-retry@^2.0.1:
retry "^0.12.0"
pump@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d"
integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
@@ -2316,9 +2261,9 @@ sanitize-filename@^1.6.3:
truncate-utf8-bytes "^1.0.0"
sax@^1.2.4:
version "1.4.3"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.3.tgz#fcebae3b756cdc8428321805f4b70f16ec0ab5db"
integrity sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==
version "1.3.0"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==
semver-compare@^1.0.0:
version "1.0.0"
@@ -2335,10 +2280,15 @@ semver@^6.2.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
version "7.7.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946"
integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==
semver@^7.3.2:
version "7.6.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2"
integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==
semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
version "7.6.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
serialize-error@^7.0.1:
version "7.0.1"
@@ -2422,11 +2372,11 @@ socks-proxy-agent@^7.0.0:
socks "^2.6.2"
socks@^2.6.2:
version "2.8.7"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea"
integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==
version "2.8.3"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5"
integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==
dependencies:
ip-address "^10.0.1"
ip-address "^9.0.5"
smart-buffer "^4.2.0"
source-map-support@^0.5.19:
@@ -2442,7 +2392,7 @@ source-map@^0.6.0:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
sprintf-js@^1.1.2:
sprintf-js@^1.1.2, sprintf-js@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
@@ -2504,9 +2454,9 @@ string_decoder@~1.1.1:
ansi-regex "^5.0.1"
strip-ansi@^7.0.1:
version "7.1.2"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba"
integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
dependencies:
ansi-regex "^6.0.1"
@@ -2572,9 +2522,9 @@ tmp@^0.0.33:
os-tmpdir "~1.0.2"
tmp@^0.2.0:
version "0.2.5"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8"
integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==
version "0.2.3"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae"
integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==
to-regex-range@^5.0.1:
version "5.0.1"
@@ -2596,19 +2546,14 @@ type-fest@^0.13.1:
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
typescript@^5.4.3:
version "5.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
version "5.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6"
integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==
undici-types@~6.21.0:
version "6.21.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
undici-types@~7.16.0:
version "7.16.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46"
integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
unique-filename@^2.0.0:
version "2.0.1"
@@ -2647,9 +2592,9 @@ uri-js@^4.2.2:
punycode "^2.1.0"
utf8-byte-length@^1.0.1:
version "1.0.5"
resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz#f9f63910d15536ee2b2d5dd4665389715eac5c1e"
integrity sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==
version "1.0.4"
resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
-27
View File
@@ -160,31 +160,4 @@ program
}
});
program
.command('sort')
.description('Sort translation files by keys')
.action(() => {
try {
const languages = getAllNonDefaultLanguages();
for (const language of languages) {
const filePath = `./translations/${language}.json`;
const content = fs.readFileSync(filePath, 'utf-8');
const translations = JSON.parse(content);
const sortedTranslations = {};
Object.keys(translations)
.sort()
.forEach(key => {
// @ts-ignore
sortedTranslations[key] = translations[key];
});
fs.writeFileSync(filePath, JSON.stringify(sortedTranslations, null, 2), 'utf-8');
console.log(`Sorted translations for language: ${language}`);
}
} catch (error) {
console.error(error);
console.error('Error during sort:', error.message);
process.exit(1);
}
});
module.exports = { program };
-132
View File
@@ -1,132 +0,0 @@
require('dotenv').config({ path: '.env.translation' });
const fs = require('fs');
const path = require('path');
const OpenAI = require('openai');
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const translationsDir = path.join(__dirname, '../../translations');
const enFilePath = path.join(translationsDir, 'en.json');
const languageNames = {
'cs.json': 'Czech',
'de.json': 'German',
'es.json': 'Spanish',
'fr.json': 'French',
'it.json': 'Italian',
'ja.json': 'Japanese',
'pt.json': 'Portuguese',
'sk.json': 'Slovak',
'zh.json': 'Chinese'
};
// Read source (english)
const enTranslations = JSON.parse(fs.readFileSync(enFilePath, 'utf8'));
const enKeys = Object.keys(enTranslations);
// Get all translation files
const translationFiles = fs.readdirSync(translationsDir)
.filter(file => file.endsWith('.json') && file !== 'en.json')
.sort();
console.log(`Found ${enKeys.length} keys in en.json\n`);
console.log('='.repeat(80));
async function translateMissingIds({file, translations, missingIds}){
const languageName = languageNames[file];
if (!languageName) {
console.log(`No language name mapping for file: ${file}`);
return;
}
// Build object with only missing translations
const needed = {};
missingIds.forEach(key => {
needed[key] = enTranslations[key];
});
// Get all existing translations as style examples
const existingTranslations = {};
Object.keys(translations).forEach(key => {
if (translations[key] && !translations[key].startsWith('***')) {
existingTranslations[key] = {
en: enTranslations[key],
translated: translations[key]
};
}
});
const prompt = `You are a professional translator for DbGate, a database management application.
Translate the following English UI strings to ${languageName}.
IMPORTANT RULES:
1. Preserve ALL placeholders exactly as they appear: {plugin}, {columnNumber}, {0}, {1}, etc.
2. Maintain technical terminology appropriately for database software
3. Match the translation style, tone, and formality of the existing translations shown below
4. Keep the same level of brevity or verbosity as the existing translations
5. Return ONLY valid JSON - no markdown, no explanations, no code blocks
6. Use the same keys as provided
EXISTING TRANSLATIONS (for style reference):
${JSON.stringify(existingTranslations, null, 2)}
STRINGS TO TRANSLATE:
${JSON.stringify(needed, null, 2)}
Return format: {"key": "translated value", ...}`;
const response = await client.chat.completions.create({
model: 'gpt-5.1',
messages: [
{ role: 'system', content: 'You are a professional translator specializing in software localization. Match the style and tone of existing translations. Return only valid JSON.' },
{ role: 'user', content: prompt }
],
temperature: 0.2
});
let translatedJson = response.choices[0].message.content.trim();
// Remove markdown code blocks if present
translatedJson = translatedJson.replace(/^```json\n?/, '').replace(/\n?```$/, '');
return JSON.parse(translatedJson);
}
(async () => {
for (const file of translationFiles) {
const filePath = path.join(translationsDir, file);
const translations = JSON.parse(fs.readFileSync(filePath, 'utf8'));
const missingIds = enKeys.filter(key => !translations.hasOwnProperty(key) || (typeof translations[key] === 'string' && translations[key].startsWith('***')));
console.log(`\n${file.toUpperCase()}`);
console.log('-'.repeat(80));
if (missingIds.length === 0) {
console.log('✓ All translations complete!');
continue;
} else {
console.log(`Found ${missingIds.length} untranslated IDs\n`);
}
const newTranslations = await translateMissingIds({file, translations, missingIds});
if (!newTranslations) {
console.log(`Skipping file due to translation error: ${file}`);
continue;
}
for (const [key, value] of Object.entries(newTranslations)) {
translations[key] = value;
console.log(`Translated: ${key} => ${value}`);
}
fs.writeFileSync(filePath, JSON.stringify(translations, null, 2) + '\n', 'utf8');
console.log(`\n✓ Updated translations written to ${file}`);
}
console.log('\n' + '='.repeat(80));
console.log('Translation complete!\n');
})();
-1
View File
@@ -4,7 +4,6 @@ const volatilePackages = [
'@clickhouse/client',
'bson', // this package is already bundled and is used in mongodb
'mongodb',
'mongodb-old',
'mongodb-client-encryption',
'tedious',
'msnodesqlv8',
-1
View File
@@ -10,7 +10,6 @@ module.exports = defineConfig({
// baseUrl: 'http://localhost:3000',
// trashAssetsBeforeRuns: false,
chromeWebSecurity: false,
reporter: process.env.CI ? 'mocha-reporter-gha' : 'spec',
setupNodeEvents(on, config) {
// implement node event listeners here
@@ -113,18 +113,6 @@ describe('Add connection', () => {
cy.contains('performance_schema');
});
it('Plugin tab', () => {
cy.testid('WidgetIconPanel_menu').click();
cy.contains('Tools').click();
cy.contains('Manage plugins').click();
cy.contains('dbgate-plugin-theme-total-white').click();
// text from plugin markdown
cy.contains('Total white theme');
// wait for load logos
cy.wait(2000);
cy.themeshot('view-plugin-tab');
});
it('export connections', () => {
cy.testid('WidgetIconPanel_menu').click();
cy.contains('Tools').click();
+22 -51
View File
@@ -60,7 +60,7 @@ describe('Data browser data', () => {
cy.contains('MyChinook').click();
cy.testid('SqlObjectList_search').clear().type('album');
cy.contains('Tables (1/11)');
cy.contains('347 rows, 65.5 KB, InnoDB');
cy.contains('347 rows, InnoDB');
cy.testid('SqlObjectList_searchMenuDropDown').click();
cy.contains('Column name').click();
cy.contains('Tables (2/11)');
@@ -85,16 +85,14 @@ describe('Data browser data', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.contains('Album').click();
// hide what is not needed
cy.testid('WidgetIconPanel_database').click();
cy.testid('DataGrid_itemReferences').click();
cy.testid('DataFilterControl_input_Title').type('Rock{enter}');
cy.contains('Rows: 7');
cy.testid('DataFilterControl_input_AlbumId').type('>10xxx{enter}');
cy.contains('Rows: 7');
cy.testid('DataFilterControl_filtermenu_ArtistId').click();
cy.testid('DataFilterControl_filtermenu_Title').click();
// hide what is not needed
cy.testid('WidgetIconPanel_database').click();
cy.testid('DataGrid_itemReferences').click();
cy.themeshot('data-browser-filter');
cy.testid('DataGridCore_button_clearFilters').click();
cy.contains('Rows: 347');
@@ -204,7 +202,7 @@ describe('Data browser data', () => {
cy.themeshot('query-editor-join-wizard');
});
it('Mongo query JSON data view', () => {
it('Mongo JSON data view', () => {
cy.contains('Mongo-connection').click();
cy.contains('MgChinook').click();
cy.contains('Customer').click();
@@ -215,10 +213,9 @@ describe('Data browser data', () => {
cy.contains('Open query').click();
cy.wait(1000);
cy.contains('Execute').click();
cy.testid('TabContent_1').contains('Leonie').rightclick();
cy.contains('Show cell data').click();
cy.testid('WidgetIconPanel_cell-data').click();
// test JSON view
cy.contains('Country: "Germany"');
cy.contains('Country: "Brazil"');
cy.themeshot('mongo-query-json-view');
});
@@ -296,8 +293,7 @@ describe('Data browser data', () => {
// cy.contains('location').click();
cy.contains('14.2').click();
cy.contains('13.9').click({ shiftKey: true });
cy.testid('WidgetIconPanel_database').click();
cy.testid('TableDataTab_toggleCellDataView').click();
cy.testid('WidgetIconPanel_cell-data').click();
cy.wait(2000);
cy.themeshot('cell-map-view');
});
@@ -314,6 +310,17 @@ describe('Data browser data', () => {
cy.themeshot('search-in-connections');
});
it('Plugin tab', () => {
cy.testid('WidgetIconPanel_settings').click();
cy.contains('Manage plugins').click();
cy.contains('dbgate-plugin-theme-total-white').click();
// text from plugin markdown
cy.contains('Total white theme');
// wait for load logos
cy.wait(2000);
cy.themeshot('view-plugin-tab');
});
it('Edit mongo data JSON', () => {
// TODO FIX: Missing button+ctx menu Revert all changes, missing button+ctx menu add document
// TODO: Dark theme - not visible changed and deleted document
@@ -341,7 +348,7 @@ describe('Data browser data', () => {
cy.themeshot('save-changes-mongodb');
});
it('Mongo JSON cell view', () => {
it('Edit mongo data JSON', () => {
// TODO FIX: Auto expand cell view
cy.contains('Mongo-connection').click();
cy.contains('MgRivers').click();
@@ -351,8 +358,7 @@ describe('Data browser data', () => {
cy.testid('ColumnManagerRow_checkbox_countries.1').click();
cy.testid('ColumnManagerRow_checkbox__id').click();
cy.testid('DataFilterControl_input_countries.1').type('EXISTS{enter}');
cy.contains('Austria').click();
cy.testid('CollectionDataTab_toggleCellDataView').click();
cy.testid('WidgetIconPanel_cell-data').click();
cy.themeshot('mongodb-json-cell-view');
});
@@ -477,39 +483,4 @@ describe('Data browser data', () => {
cy.testid('DataDeployTab_importIntoDb').click();
cy.themeshot('data-replicator');
});
it('Form cell view', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.contains('Invoice').click();
cy.contains('Rows: 412');
cy.get('[data-row="0"][data-col="header"]').click();
cy.get('[data-row="1"][data-col="header"]').click();
cy.get('[data-row="0"][data-col="header"]').click();
cy.contains('Autodetect - Form');
cy.themeshot('form-cell-view');
});
it('Group by', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.contains('Album').click();
cy.testid('WidgetIconPanel_database').click();
cy.testid('ColumnHeaderControl_dropdown_ArtistId').click();
cy.contains('Group by').click();
cy.testid('ColumnHeaderControl_dropdown_Title').first().click();
cy.themeshot('data-browser-group-by');
});
it('Filter by expanded column', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.contains('Album').click();
cy.testid('WidgetIconPanel_database').click();
cy.testid('ColumnManagerRow_expand_ArtistId').click();
cy.testid('ColumnManagerRow_checkbox_ArtistId.Name').click();
cy.testid('ColumnManagerRow_checkbox_ArtistId').click();
cy.testid('DataFilterControl_input_ArtistId.Name').type('mich{enter}');
cy.themeshot('data-browser-filter-by-expanded');
});
});
+13 -113
View File
@@ -110,7 +110,7 @@ describe('Charts', () => {
cy.themeshot('new-object-window');
});
it.skip('Database chat - charts', () => {
it.only('Database chat - charts', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.testid('TabsPanel_buttonNewObject').click();
@@ -119,13 +119,11 @@ describe('Charts', () => {
cy.get('body').realType('show me chart of most popular genres');
cy.get('body').realPress('{enter}');
cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
cy.testid('chart-canvas', { timeout: 30000 }).should($c =>
expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/)
);
cy.testid('chart-canvas', { timeout: 30000 }).should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
cy.themeshot('database-chat-chart');
});
it.skip('Database chat', () => {
it('Database chat', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.testid('TabsPanel_buttonNewObject').click();
@@ -146,7 +144,7 @@ describe('Charts', () => {
// cy.themeshot('database-chat');
});
it.skip('Explain query error', () => {
it('Explain query error', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.testid('TabsPanel_buttonNewObject').click();
@@ -157,113 +155,15 @@ describe('Charts', () => {
cy.testid('MessageViewRow-explainErrorButton-1').click();
cy.testid('ChatCodeRenderer_useSqlButton', { timeout: 30000 });
cy.themeshot('explain-query-error');
});
it('Switch language', () => {
cy.contains('MySql-connection').click();
cy.contains('MyChinook').click();
cy.testid('WidgetIconPanel_settings').click();
cy.testid('SettingsModal_languageSelect').select('Deutsch');
cy.testid('ConfirmModal_okButton').click();
cy.testid('WidgetIconPanel_settings').click();
cy.contains('Sprache');
cy.themeshot('switch-language-de');
cy.testid('SettingsModal_languageSelect').select('Français');
cy.testid('ConfirmModal_okButton').click();
cy.testid('WidgetIconPanel_settings').click();
cy.contains('Langue');
cy.themeshot('switch-language-fr');
cy.testid('SettingsModal_languageSelect').select('Español');
cy.testid('ConfirmModal_okButton').click();
cy.testid('WidgetIconPanel_settings').click();
cy.contains('Idioma');
cy.themeshot('switch-language-es');
cy.testid('SettingsModal_languageSelect').select('Čeština');
cy.testid('ConfirmModal_okButton').click();
cy.testid('WidgetIconPanel_settings').click();
cy.contains('Jazyk');
cy.themeshot('switch-language-cs');
cy.testid('SettingsModal_languageSelect').select('中文');
cy.testid('ConfirmModal_okButton').click();
cy.testid('WidgetIconPanel_settings').click();
cy.contains('语言');
cy.themeshot('switch-language-zh');
cy.testid('SettingsModal_languageSelect').select('English');
cy.testid('ConfirmModal_okButton').click();
cy.testid('WidgetIconPanel_settings');
});
it('Settings', () => {
cy.testid('WidgetIconPanel_settings').click();
cy.themeshot('app-settings-general');
cy.contains('Behaviour').click();
cy.themeshot('app-settings-behaviour');
cy.get('[data-testid=BehaviourSettings_useTabPreviewMode]').uncheck();
// SQL Editor
cy.contains('SQL Editor').click();
cy.get('[data-testid=SQLEditorSettings_sqlCommandsCase]').select('lowerCase');
cy.contains('MySql-connection').click();
cy.contains('charts_sample').click();
cy.contains('employees').click();
cy.contains('MyChinook').click();
cy.contains('Customer').rightclick();
cy.contains('SQL template').click();
cy.contains('CREATE TABLE').click();
cy.contains('create table');
// Default Actions
cy.testid('WidgetIconPanel_settings').click();
cy.contains('Default Actions').click();
cy.get('[data-testid=DefaultActionsSettings_useLastUsedAction]').uncheck();
// Themes
cy.contains('Themes').click();
cy.themeshot('app-settings-themes');
cy.testid('ThemeSkeleton-Dark-built-in').click();
cy.testid('ThemeSkeleton-Light-built-in').click();
// General
cy.contains(/^General$/).click();
cy.contains('charts_sample');
cy.get('[data-testid=GeneralSettings_lockedDatabaseMode]').check();
cy.contains('Connections').click();
cy.contains('charts_sample').should('not.exist');
// Datagrid
cy.contains('Data grid').click();
cy.get('[data-testid=DataGridSettings_showHintColumns]').uncheck();
cy.wait(500);
cy.contains('Album').click();
cy.contains('AC/DC').should('not.exist');
cy.testid('WidgetIconPanel_settings').click();
cy.contains('Keyboard shortcuts').click();
cy.themeshot('app-settings-keyboard-shortcuts');
cy.contains('Chart').click();
cy.testid('CommandModal_keyboardButton').click();
cy.realPress(['Control', 'g']);
cy.realPress('Enter');
cy.contains('OK').click();
cy.contains('Ctrl+G');
cy.contains('AI').click();
cy.themeshot('app-settings-ai');
cy.get('[data-testid=AISettings_addProviderButton]').click();
cy.contains('Provider 1');
cy.get('[data-testid=AiProviderCard_removeButton]').click();
cy.contains('Are you sure you want to remove Provider 1 provider?');
cy.contains('OK').click();
cy.contains('Provider 1').should('not.exist');
// cy.testid('TabsPanel_buttonNewObject').click();
// cy.testid('NewObjectModal_databaseChat').click();
// cy.wait(1000);
// cy.get('body').realType('show me chart of most popular genres');
// cy.get('body').realPress('{enter}');
// cy.testid('DatabaseChatTab_executeAllQueries', { timeout: 30000 }).click();
// cy.wait(5000);
// cy.testid('chart-canvas').should($c => expect($c[0].toDataURL()).to.match(/^data:image\/png;base64/));
// cy.themeshot('database-chat-chart');
});
});
+7 -68
View File
@@ -3,8 +3,6 @@ const { formatQueryWithoutParams } = require('dbgate-tools');
global.DBGATE_PACKAGES = {
'dbgate-tools': require('dbgate-tools'),
'dbgate-sqltree': require('dbgate-sqltree'),
'dbgate-datalib': require('dbgate-datalib'),
};
function requireEngineDriver(engine) {
@@ -105,70 +103,13 @@ describe('Transactions', () => {
describe('Backup table', () => {
multiTest({ skipMongo: true }, (connectionName, databaseName, engine, options = {}) => {
const implicitTransactions = options.implicitTransactions ?? false;
cy.contains(connectionName).click();
if (databaseName) cy.contains(databaseName).click();
cy.contains('addresses').rightclick();
cy.contains('customers').rightclick();
cy.contains('Create table backup').click();
cy.testid('ConfirmSqlModal_okButton').click();
cy.testid('app-object-group-items-table-backups').contains('addresses').click();
cy.contains('Rows: 12').should('be.visible');
cy.testid('app-object-group-items-tables').contains('addresses').click();
cy.contains('Ridgewood').click();
cy.testid('TableDataTab_deleteSelectedRows').click();
cy.contains('Rosewood').click();
cy.testid('TableDataTab_deleteSelectedRows').click();
cy.contains('Vermont').click();
cy.get('body').realType('Wermont{enter}');
cy.testid('TableDataTab_insertNewRow').click();
cy.get('body').realType('Modranska{enter}');
cy.realPress(['ArrowLeft']);
cy.realPress(['ArrowLeft']);
cy.get('body').realType('13{enter}');
cy.realPress(['ArrowRight']);
cy.get('body').realType('1{enter}');
cy.realPress(['ArrowRight']);
cy.realPress(['ArrowRight']);
cy.realPress(['ArrowRight']);
cy.get('body').realType('Prague{enter}');
cy.realPress(['ArrowRight']);
cy.get('body').realType('CZ{enter}');
cy.realPress(['ArrowRight']);
cy.get('body').realType('10000{enter}');
cy.realPress(['ArrowRight']);
cy.get('body').realType('111222333{enter}');
cy.testid('TableDataTab_save').click();
cy.testid('ConfirmSqlModal_okButton', { timeout: 10000 }).click();
cy.contains('Rows: 11').should('be.visible'); // wait for save
cy.testid('app-object-group-items-table-backups').contains('addresses').rightclick();
cy.contains('restore script').click();
cy.contains('UPDATE'); // wait for query
cy.testid('QueryTab_executeButton').click();
cy.contains('Query execution finished');
if (implicitTransactions) {
cy.testid('QueryTab_commitTransactionButton').click();
cy.contains('Commit Transaction finished');
}
cy.realPress('F1');
cy.realType('Close all');
cy.realPress('Enter');
// cy.testid('CloseTabModal_buttonConfirm').click();
cy.wait(1000);
cy.testid('app-object-group-items-tables').contains('addresses', { timeout: 10000 }).click();
// check whether data was successfully restored
cy.contains('Rows: 12').should('be.visible');
cy.contains('Ridgewood');
cy.contains('Vermont');
cy.contains('_customers').click();
cy.contains('Rows: 8').should('be.visible');
});
});
@@ -205,15 +146,13 @@ describe('Import CSV', () => {
cy.contains('Import').click();
cy.get('input[type=file]').selectFile('cypress/fixtures/customers-20.csv', { force: true });
cy.testid('ImportExportConfigurator_tableMappingSection').contains('customers-20');
cy.contains('customers-20');
cy.testid('ImportExportTab_preview_content').contains('50ddd99fAdF48B3').should('be.visible');
cy.testid('ImportExportTab_executeButton').click();
cy.testid('ImportExportConfigurator_tableMappingSection').contains('20 rows written').should('be.visible');
cy.contains('20 rows written').should('be.visible');
cy.testid('SqlObjectList_refreshButton').click();
cy.testid('DatabasStatusMenu_refreshFull').click();
// cy.contains('Refresh DB structure (incremental)').click();
cy.testid('SqlObjectList_container').contains('customers-20').click();
cy.contains('Rows: 20').should('be.visible');
@@ -239,7 +178,7 @@ describe('Import CSV - source error', () => {
cy.testid('ImportExportTab_preview_content').contains('Invalid Closing Quote').should('be.visible');
cy.testid('ImportExportTab_executeButton').click();
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20-err', { timeout: 10000 }).click();
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20-err').click();
cy.testid('ErrorMessageModal_message').contains('Invalid Closing Quote').should('be.visible');
});
@@ -258,7 +197,7 @@ describe('Import CSV - target error', () => {
cy.contains('customers-20');
cy.testid('ImportExportConfigurator_targetName_customers-20').clear().type('system."]`');
cy.testid('ImportExportTab_executeButton').click();
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20', { timeout: 10000 }).click();
cy.testid('ImportExportConfigurator_errorInfoIcon_customers-20').click();
cy.testid('ErrorMessageModal_message').should('be.visible');
});
});
+2 -2
View File
@@ -37,7 +37,7 @@ Cypress.Commands.add(
},
(subject, file, options) => {
cy.window().then(win => {
win.__changeCurrentTheme('dark');
win.__changeCurrentTheme('theme-dark');
});
// cy.screenshot(`${file}-dark`, {
@@ -64,7 +64,7 @@ Cypress.Commands.add(
// });
cy.window().then(win => {
win.__changeCurrentTheme('light');
win.__changeCurrentTheme('theme-light');
});
if (subject) {
+4 -1
View File
@@ -10,11 +10,11 @@
"cypress-real-events": "^1.13.0",
"env-cmd": "^10.1.0",
"kill-port": "^2.0.1",
"mocha-reporter-gha": "^1.1.1",
"start-server-and-test": "^2.0.8"
},
"scripts": {
"cy:open": "cypress open --config experimentalInteractiveRunEvents=true",
"cy:run:add-connection": "cypress run --spec cypress/e2e/add-connection.cy.js",
"cy:run:portal": "cypress run --spec cypress/e2e/portal.cy.js",
"cy:run:oauth": "cypress run --spec cypress/e2e/oauth.cy.js",
@@ -23,6 +23,7 @@
"cy:run:multi-sql": "cypress run --spec cypress/e2e/multi-sql.cy.js",
"cy:run:cloud": "cypress run --spec cypress/e2e/cloud.cy.js",
"cy:run:charts": "cypress run --spec cypress/e2e/charts.cy.js",
"start:add-connection": "node clearTestingData && cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:portal": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:oauth": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
@@ -31,6 +32,7 @@
"start:multi-sql": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/multi-sql/.env node e2e-tests/init/multi-sql.js && env-cmd -f e2e-tests/env/multi-sql/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:cloud": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/cloud/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:charts": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/charts/.env node e2e-tests/init/charts.js && env-cmd -f e2e-tests/env/charts/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"test:add-connection": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection",
"test:portal": "start-server-and-test start:portal http://localhost:3000 cy:run:portal",
"test:oauth": "start-server-and-test start:oauth http://localhost:3000 cy:run:oauth",
@@ -39,6 +41,7 @@
"test:multi-sql": "start-server-and-test start:multi-sql http://localhost:3000 cy:run:multi-sql",
"test:cloud": "start-server-and-test start:cloud http://localhost:3000 cy:run:cloud",
"test:charts": "start-server-and-test start:charts http://localhost:3000 cy:run:charts",
"test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team && yarn test:multi-sql && yarn test:cloud && yarn test:charts",
"test:ci": "yarn test"
},
-52
View File
@@ -2,34 +2,6 @@
# yarn lockfile v1
"@actions/core@^1.10.1":
version "1.11.1"
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.11.1.tgz#ae683aac5112438021588030efb53b1adb86f172"
integrity sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==
dependencies:
"@actions/exec" "^1.1.1"
"@actions/http-client" "^2.0.1"
"@actions/exec@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@actions/exec/-/exec-1.1.1.tgz#2e43f28c54022537172819a7cf886c844221a611"
integrity sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==
dependencies:
"@actions/io" "^1.0.1"
"@actions/http-client@^2.0.1":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.2.3.tgz#31fc0b25c0e665754ed39a9f19a8611fc6dab674"
integrity sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==
dependencies:
tunnel "^0.0.6"
undici "^5.25.4"
"@actions/io@^1.0.1":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.1.3.tgz#4cdb6254da7962b07473ff5c335f3da485d94d71"
integrity sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
@@ -67,11 +39,6 @@
debug "^3.1.0"
lodash.once "^4.1.1"
"@fastify/busboy@^2.0.0":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d"
integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==
"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0":
version "9.3.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"
@@ -980,13 +947,6 @@ minimist@^1.2.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
mocha-reporter-gha@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/mocha-reporter-gha/-/mocha-reporter-gha-1.1.1.tgz#e1248abd0769f55b57b36ccd7db2b0b6573d5adf"
integrity sha512-CFbcgM56V4yWlbF91XuwrE6a5X/IqjVXTPefO7m8cY8Es8G1UhJ2KKOrk16AcSemRzVWXp2Fdy3bWJ7j45snWw==
dependencies:
"@actions/core" "^1.10.1"
ms@^2.1.1, ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
@@ -1332,11 +1292,6 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@@ -1352,13 +1307,6 @@ undici-types@~6.20.0:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
undici@^5.25.4:
version "5.29.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.29.0.tgz#419595449ae3f2cdcba3580a2e8903399bd1f5a3"
integrity sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==
dependencies:
"@fastify/busboy" "^2.0.0"
universalify@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
@@ -12,7 +12,6 @@ const {
} = require('dbgate-tools');
function pickImportantTableInfo(engine, table) {
if (!table) return table;
const props = ['columnName', 'defaultValue'];
if (!engine.skipNullability) props.push('notNull');
if (!engine.skipAutoIncrement) props.push('autoIncrement');
@@ -26,15 +25,6 @@ function pickImportantTableInfo(engine, table) {
.map(props =>
_.omitBy(props, (v, k) => k == 'defaultValue' && v == 'NULL' && engine.setNullDefaultInsteadOfDrop)
),
// TODO:
foreignKeys: table.foreignKeys
.sort((a, b) => a.refTableName.localeCompare(b.refTableName))
.map(fk => ({
constraintType: fk.constraintType,
refTableName: fk.refTableName,
columns: fk.columns.map(col => ({ columnName: col.columnName, refColumnName: col.refColumnName })),
})),
};
}
@@ -43,7 +33,7 @@ function checkTableStructure(engine, t1, t2) {
expect(pickImportantTableInfo(engine, t1)).toEqual(pickImportantTableInfo(engine, t2));
}
async function testTableDiff(engine, conn, driver, mangle, changedTable = 't1') {
async function testTableDiff(engine, conn, driver, mangle) {
const initQuery = formatQueryWithoutParams(driver, `create table ~t0 (~id int not null primary key)`);
await driver.query(conn, transformSqlForEngine(engine, initQuery));
@@ -78,39 +68,17 @@ async function testTableDiff(engine, conn, driver, mangle, changedTable = 't1')
await driver.query(conn, transformSqlForEngine(engine, query));
}
if (!engine.skipReferences) {
const query = formatQueryWithoutParams(
driver,
`create table ~t3 (~id int not null primary key, ~fkval int ${
driver.dialect.implicitNullDeclaration ? '' : 'null'
})`
);
await driver.query(conn, transformSqlForEngine(engine, query));
}
const tget = x => x?.tables?.find(y => y.pureName == changedTable);
const structure1Source = await driver.analyseFull(conn);
const structure1 = generateDbPairingId(extendDatabaseInfo(structure1Source));
const tget = x => x.tables.find(y => y.pureName == 't1');
const structure1 = generateDbPairingId(extendDatabaseInfo(await driver.analyseFull(conn)));
let structure2 = _.cloneDeep(structure1);
mangle(tget(structure2));
structure2 = extendDatabaseInfo(structure2);
const { sql } = getAlterTableScript(tget(structure1), tget(structure2), {}, structure1, structure2, driver);
// sleep 1s - some engines have update datetime precision only to seconds
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('RUNNING ALTER SQL', driver.engine, ':', sql);
await driver.script(conn, sql);
// TODO:
// if (!engine.skipIncrementalAnalysis) {
// const structure2RealIncremental = await driver.analyseIncremental(conn, structure1Source);
// checkTableStructure(engine, tget(structure2RealIncremental), tget(structure2));
// }
const structure2Real = extendDatabaseInfo(await driver.analyseFull(conn));
checkTableStructure(engine, tget(structure2Real), tget(structure2));
@@ -119,7 +87,6 @@ async function testTableDiff(engine, conn, driver, mangle, changedTable = 't1')
const TESTED_COLUMNS = ['col_pk', 'col_std', 'col_def', 'col_fk', 'col_ref', 'col_idx', 'col_uq'];
// const TESTED_COLUMNS = ['col_pk'];
// const TESTED_COLUMNS = ['col_fk'];
// const TESTED_COLUMNS = ['col_idx'];
// const TESTED_COLUMNS = ['col_def'];
// const TESTED_COLUMNS = ['col_std'];
@@ -183,25 +150,11 @@ describe('Alter table', () => {
)(
'Drop column - %s - %s',
testWrapper(async (conn, driver, column, engine) => {
await testTableDiff(engine, conn, driver,
tbl => {
tbl.columns = tbl.columns.filter(x => x.columnName != column);
tbl.foreignKeys = tbl.foreignKeys
.map(fk => ({
...fk,
columns: fk.columns.filter(col => col.columnName != column)
}))
.filter(fk => fk.columns.length > 0);
}
);
await testTableDiff(engine, conn, driver, tbl => (tbl.columns = tbl.columns.filter(x => x.columnName != column)));
})
);
test.each(
createEnginesColumnsSource(engines.filter(x => !x.skipNullability && !x.skipChangeNullability)).filter(
([_label, col]) => !col.endsWith('_pk')
)
)(
test.each(createEnginesColumnsSource(engines.filter(x => !x.skipNullable && !x.skipChangeNullability)))(
'Change nullability - %s - %s',
testWrapper(async (conn, driver, column, engine) => {
await testTableDiff(
@@ -220,11 +173,7 @@ describe('Alter table', () => {
engine,
conn,
driver,
tbl => {
tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, columnName: 'col_renamed' } : x));
tbl.foreignKeys = tbl.foreignKeys.map(fk => ({...fk, columns: fk.columns.map(col => col.columnName == column ? { ...col, columnName: 'col_renamed' } : col)
}));
}
tbl => (tbl.columns = tbl.columns.map(x => (x.columnName == column ? { ...x, columnName: 'col_renamed' } : x)))
);
})
);
@@ -265,48 +214,6 @@ describe('Alter table', () => {
})
);
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
'Drop FK - %s',
testWrapper(async (conn, driver, engine) => {
await testTableDiff(
engine,
conn,
driver,
tbl => {
tbl.foreignKeys = [];
},
't2'
);
})
);
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
'Create FK - %s',
testWrapper(async (conn, driver, engine) => {
await testTableDiff(
engine,
conn,
driver,
tbl => {
tbl.foreignKeys = [
{
constraintType: 'foreignKey',
pureName: 't3',
refTableName: 't1',
columns: [
{
columnName: 'fkval',
refColumnName: 'col_ref',
},
],
},
];
},
't3'
);
})
);
// test.each(engines.map(engine => [engine.label, engine]))(
// 'Change autoincrement - %s',
// testWrapper(async (conn, driver, engine) => {
@@ -303,52 +303,4 @@ describe('Data replicator', () => {
}),
15 * 1000
);
test.each(engines.filter(x => !x.skipDataReplicator).map(engine => [engine.label, engine]))(
'Skip columns for update - %s',
testWrapper(async (conn, driver, engine) => {
runCommandOnDriver(conn, driver, dmp =>
dmp.createTable({
pureName: 't1',
columns: [
{ columnName: 'id', dataType: 'int', autoIncrement: true, notNull: true },
{ columnName: 'key', dataType: 'varchar(50)', notNull: true },
{ columnName: 'val', dataType: 'varchar(50)' },
],
primaryKey: {
columns: [{ columnName: 'id' }],
},
})
);
const getcfg = (v1 = 'v1') => ({
systemConnection: conn,
driver,
items: [
{
name: 't1',
matchColumns: ['key'],
skipUpdateColumns: ['val'],
findExisting: true,
updateExisting: true,
createNew: true,
jsonArray: [
{ key: '1', val: v1 },
{ key: '2', val: 'v2' },
{ key: '3', val: 'v3' },
],
},
],
});
await dataReplicator(getcfg('v1'));
const res1 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select ~val from ~t1 where ~key='1'`));
expect(res1.rows[0].val).toEqual('v1');
await dataReplicator(getcfg('v2'));
const res2 = await runQueryOnDriver(conn, driver, dmp => dmp.put(`select ~val from ~t1 where ~key='1'`));
expect(res2.rows[0].val).toEqual('v1');
})
);
});
-73
View File
@@ -49,32 +49,6 @@ class StreamHandler {
}
}
class BinaryTestStreamHandler {
constructor(resolve, reject, expectedValue) {
this.resolve = resolve;
this.reject = reject;
this.expectedValue = expectedValue;
this.rowsReceived = [];
}
row(row) {
try {
this.rowsReceived.push(row);
if (this.expectedValue) {
expect(row).toEqual(this.expectedValue);
}
} catch (error) {
this.reject(error);
return;
}
}
recordset(columns) {}
done(result) {
this.resolve(this.rowsReceived);
}
info(msg) {}
}
function executeStreamItem(driver, conn, sql) {
return new Promise(resolve => {
const handler = new StreamHandler(resolve);
@@ -249,51 +223,4 @@ describe('Query', () => {
expect(row[keys[0]] == 1).toBeTruthy();
})
);
test.each(engines.filter(x => x.binaryDataType).map(engine => [engine.label, engine]))(
'Binary - %s',
testWrapper(async (dbhan, driver, engine) => {
await runCommandOnDriver(dbhan, driver, dmp =>
dmp.createTable({
pureName: 't1',
columns: [
{ columnName: 'id', dataType: 'int', notNull: true, autoIncrement: true },
{ columnName: 'val', dataType: engine.binaryDataType },
],
primaryKey: {
columns: [{ columnName: 'id' }],
},
})
);
const structure = await driver.analyseFull(dbhan);
const table = structure.tables.find(x => x.pureName == 't1');
const dmp = driver.createDumper();
dmp.putCmd("INSERT INTO ~t1 (~val) VALUES (%v)", {
$binary: { base64: 'iVBORw0KWgo=' },
});
await driver.query(dbhan, dmp.s, {discardResult: true});
const dmp2 = driver.createDumper();
dmp2.put('SELECT ~val FROM ~t1');
const res = await driver.query(dbhan, dmp2.s);
const row = res.rows[0];
const keys = Object.keys(row);
expect(keys.length).toEqual(1);
expect(row[keys[0]]).toEqual({$binary: {base64: 'iVBORw0KWgo='}});
const res2 = await driver.readQuery(dbhan, dmp2.s);
const rows = await Array.fromAsync(res2);
const rowsVal = rows.filter(r => r.val != null);
expect(rowsVal.length).toEqual(1);
expect(rowsVal[0].val).toEqual({$binary: {base64: 'iVBORw0KWgo='}});
const res3 = await new Promise((resolve, reject) => {
const handler = new BinaryTestStreamHandler(resolve, reject, {val: {$binary: {base64: 'iVBORw0KWgo='}}});
driver.stream(dbhan, dmp2.s, handler);
});
})
);
});
@@ -33,9 +33,7 @@ describe('Schema tests', () => {
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeTruthy();
expect(schemas2.length).toEqual(count + 1);
expect(schemas2.find(x => x.isDefault).schemaName).toEqual(engine.defaultSchemaName);
if (!engine.skipIncrementalAnalysis) {
expect(structure2).toBeNull();
}
expect(structure2).toBeNull();
})
);
@@ -53,9 +51,7 @@ describe('Schema tests', () => {
const structure2 = await driver.analyseIncremental(conn, structure1);
const schemas2 = await driver.listSchemas(conn);
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeFalsy();
if (!engine.skipIncrementalAnalysis) {
expect(structure2).toBeNull();
}
expect(structure2).toBeNull();
})
);
@@ -94,7 +94,7 @@ describe('Table analyse', () => {
})
);
test.each(engines.map(engine => [engine.label, engine]))(
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
'Table add - incremental analysis - %s',
testWrapper(async (conn, driver, engine) => {
await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine)));
@@ -112,7 +112,7 @@ describe('Table analyse', () => {
})
);
test.each(engines.map(engine => [engine.label, engine]))(
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
'Table remove - incremental analysis - %s',
testWrapper(async (conn, driver, engine) => {
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
@@ -130,7 +130,7 @@ describe('Table analyse', () => {
})
);
test.each(engines.map(engine => [engine.label, engine]))(
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))(
'Table change - incremental analysis - %s',
testWrapper(async (conn, driver, engine) => {
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
+1 -1
View File
@@ -44,7 +44,7 @@ services:
# - 15942:9042
#
# clickhouse:
# image: bitnamilegacy/clickhouse:24.8.4
# image: bitnami/clickhouse:24.8.4
# restart: always
# ports:
# - 15005:8123
+4 -10
View File
@@ -44,7 +44,6 @@ const mysqlEngine = {
supportRenameSqlObject: false,
dbSnapshotBySeconds: true,
dumpFile: 'data/chinook-mysql.sql',
binaryDataType: 'blob',
dumpChecks: [
{
sql: 'select count(*) as res from genre',
@@ -187,7 +186,6 @@ const mariaDbEngine = {
/** @type {import('dbgate-types').TestEngineInfo} */
const postgreSqlEngine = {
label: 'PostgreSQL',
skipIncrementalAnalysis: true,
connection: {
engine: 'postgres@dbgate-plugin-postgres',
password: 'Pwd2020Db',
@@ -218,7 +216,6 @@ const postgreSqlEngine = {
supportSchemas: true,
supportRenameSqlObject: true,
defaultSchemaName: 'public',
binaryDataType: 'bytea',
dumpFile: 'data/chinook-postgre.sql',
dumpChecks: [
{
@@ -449,7 +446,6 @@ const sqlServerEngine = {
supportTableComments: true,
supportColumnComments: true,
// skipSeparateSchemas: true,
binaryDataType: 'varbinary(100)',
triggers: [
{
testName: 'triggers before each row',
@@ -510,7 +506,6 @@ const sqliteEngine = {
},
},
],
binaryDataType: 'blob',
};
const libsqlFileEngine = {
@@ -624,7 +619,6 @@ const oracleEngine = {
},
},
],
binaryDataType: 'blob',
};
/** @type {import('dbgate-types').TestEngineInfo} */
@@ -760,16 +754,16 @@ const enginesOnLocal = [
// cassandraEngine,
// mysqlEngine,
// mariaDbEngine,
postgreSqlEngine,
//sqlServerEngine,
// postgreSqlEngine,
// sqlServerEngine,
// sqliteEngine,
// cockroachDbEngine,
// clickhouseEngine,
// libsqlFileEngine,
// libsqlWsEngine,
//oracleEngine,
// oracleEngine,
// duckdbEngine,
//firebirdEngine,
firebirdEngine,
];
/** @type {import('dbgate-types').TestEngineInfo[] & Record<string, import('dbgate-types').TestEngineInfo>} */
-1
View File
@@ -1,4 +1,3 @@
module.exports = {
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
reporters: ['default', 'github-actions'],
};
+1 -1
View File
@@ -18,7 +18,7 @@
},
"devDependencies": {
"cross-env": "^7.0.3",
"jest": "^28.1.3",
"jest": "^27.0.1",
"pino-pretty": "^11.2.2",
"tmp": "^0.2.3"
}
-1
View File
@@ -1,7 +1,6 @@
global.DBGATE_PACKAGES = {
'dbgate-tools': require('dbgate-tools'),
'dbgate-sqltree': require('dbgate-sqltree'),
'dbgate-datalib': require('dbgate-datalib'),
};
const { prettyFactory } = require('pino-pretty');
+1 -3
View File
@@ -22,9 +22,7 @@ async function connect(engine, database) {
if (engine.generateDbFile) {
const conn = await driver.connect({
...connection,
databaseFile:
(engine.databaseFileLocationOnServer ?? (process.env.CITEST ? 'dbtemp/' : 'integration-tests/dbtemp/')) +
database,
databaseFile: (engine.databaseFileLocationOnServer ?? 'dbtemp/') + database,
});
return conn;
} else {
-1
View File
@@ -3,7 +3,6 @@ const engines = require('./engines');
global.DBGATE_PACKAGES = {
'dbgate-tools': require('dbgate-tools'),
'dbgate-sqltree': require('dbgate-sqltree'),
'dbgate-datalib': require('dbgate-datalib'),
};
async function connectEngine(engine) {
+1 -4
View File
@@ -1,6 +1,6 @@
{
"private": true,
"version": "7.0.0-premium-beta.5",
"version": "6.6.9",
"name": "dbgate-all",
"workspaces": [
"packages/*",
@@ -22,7 +22,6 @@
"start:api:auth": "yarn workspace dbgate-api start:auth | pino-pretty",
"start:api:dblogin": "yarn workspace dbgate-api start:dblogin | pino-pretty",
"start:api:storage": "yarn workspace dbgate-api start:storage | pino-pretty",
"start:api:sfill": "yarn workspace dbgate-api start:sfill | pino-pretty",
"start:api:storage:built": "yarn workspace dbgate-api start:storage:built | pino-pretty",
"start:api:azure": "yarn workspace dbgate-api start:azure | pino-pretty",
"start:api:e2e:team": "yarn workspace dbgate-api start:e2e:team | pino-pretty",
@@ -75,8 +74,6 @@
"translations:add-missing": "node common/translations-cli/index.js add-missing",
"translations:remove-unused": "node common/translations-cli/index.js remove-unused",
"translations:check": "node common/translations-cli/index.js check",
"translations:sort": "node common/translations-cli/index.js sort",
"translations:translate": "node common/translations-cli/translate.js",
"errors": "node common/assign-dbgm-codes.mjs ."
},
"dependencies": {
+1 -1
View File
@@ -2,7 +2,7 @@ DEVMODE=1
SHELL_SCRIPTING=1
ALLOW_DBGATE_PRIVATE_CLOUD=1
DEVWEB=1
# LOCAL_AUTH_PROXY=1
LOCAL_AUTH_PROXY=1
# LOCAL_AI_GATEWAY=true
# REDIRECT_TO_DBGATE_CLOUD_LOGIN=1
-54
View File
@@ -1,54 +0,0 @@
DEVMODE=1
DEVWEB=1
# STORAGE_SERVER=localhost
# STORAGE_USER=root
# STORAGE_PASSWORD=Pwd2020Db
# STORAGE_PORT=3306
# STORAGE_DATABASE=dbgate-filled
# STORAGE_ENGINE=mysql@dbgate-plugin-mysql
STORAGE_SERVER=localhost
STORAGE_USER=postgres
STORAGE_PASSWORD=Pwd2020Db
STORAGE_PORT=5432
STORAGE_DATABASE=dbgate_sfill
STORAGE_ENGINE=postgres@dbgate-plugin-postgres
CONNECTIONS=mysql,postgres,mongo,redis
LABEL_mysql=MySql
SERVER_mysql=dbgatedckstage1.sprinx.cz
USER_mysql=root
PASSWORD_mysql=Pwd2020Db
PORT_mysql=3306
ENGINE_mysql=mysql@dbgate-plugin-mysql
LABEL_postgres=Postgres
SERVER_postgres=dbgatedckstage1.sprinx.cz
USER_postgres=postgres
PASSWORD_postgres=Pwd2020Db
PORT_postgres=5432
ENGINE_postgres=postgres@dbgate-plugin-postgres
LABEL_mongo=Mongo
SERVER_mongo=dbgatedckstage1.sprinx.cz
USER_mongo=root
PASSWORD_mongo=Pwd2020Db
PORT_mongo=27017
ENGINE_mongo=mongo@dbgate-plugin-mongo
LABEL_redis=Redis
SERVER_redis=dbgatedckstage1.sprinx.cz
ENGINE_redis=redis@dbgate-plugin-redis
PORT_redis=6379
ROLE_test1_CONNECTIONS=mysql
ROLE_test1_PERMISSIONS=widgets/*
ROLE_test1_DATABASES_db1_CONNECTION=mysql
ROLE_test1_DATABASES_db1_PERMISSION=run_script
ROLE_test1_DATABASES_db1_DATABASES=db1
ROLE_test1_DATABASES_db2_CONNECTION=redis
ROLE_test1_DATABASES_db2_PERMISSION=run_script
ROLE_test1_DATABASES_db2_DATABASES=db2
+1 -2
View File
@@ -31,7 +31,7 @@
"cors": "^2.8.5",
"cross-env": "^6.0.3",
"dbgate-datalib": "^6.0.0-alpha.1",
"dbgate-query-splitter": "^4.11.9",
"dbgate-query-splitter": "^4.11.7",
"dbgate-sqltree": "^6.0.0-alpha.1",
"dbgate-tools": "^6.0.0-alpha.1",
"debug": "^4.3.4",
@@ -75,7 +75,6 @@
"start:dblogin": "env-cmd -f env/dblogin/.env node src/index.js --listen-api",
"start:filedb": "env-cmd node src/index.js /home/jena/test/chinook/Chinook.db --listen-api",
"start:storage": "env-cmd -f env/storage/.env node src/index.js --listen-api",
"start:sfill": "env-cmd -f env/sfill/.env node src/index.js --listen-api",
"start:storage:built": "env-cmd -f env/storage/.env cross-env DEVMODE= BUILTWEBMODE=1 node dist/bundle.js --listen-api",
"start:singleconn": "env-cmd node src/index.js --server localhost --user root --port 3307 --engine mysql@dbgate-plugin-mysql --password test --listen-api",
"start:azure": "env-cmd -f env/azure/.env node src/index.js --listen-api",
+2 -2
View File
@@ -35,8 +35,8 @@ module.exports = {
},
refreshPublicFiles_meta: true,
async refreshPublicFiles({ isRefresh }, req) {
await refreshPublicFiles(isRefresh, req?.headers?.['x-ui-language']);
async refreshPublicFiles({ isRefresh }) {
await refreshPublicFiles(isRefresh);
return {
status: 'ok',
};
+9 -6
View File
@@ -71,7 +71,6 @@ module.exports = {
const isLicenseValid = checkedLicense?.status == 'ok';
const logoutUrl = storageConnectionError ? null : await authProvider.getLogoutUrl();
const adminConfig = storageConnectionError ? null : await storage.readConfig({ group: 'admin' });
const settingsConfig = storageConnectionError ? null : await storage.readConfig({ group: 'settings' });
storage.startRefreshLicense();
@@ -122,7 +121,6 @@ module.exports = {
allowPrivateCloud: platformInfo.isElectron || !!process.env.ALLOW_DBGATE_PRIVATE_CLOUD,
...currentVersion,
redirectToDbGateCloudLogin: !!process.env.REDIRECT_TO_DBGATE_CLOUD_LOGIN,
preferrendLanguage: settingsConfig?.['storage.language'] || process.env.LANGUAGE || null,
};
return configResult;
@@ -289,11 +287,16 @@ module.exports = {
const res = await lock.acquire('settings', async () => {
const currentValue = await this.loadSettings();
try {
let updated = {
...currentValue,
...values,
};
let updated = currentValue;
if (process.env.STORAGE_DATABASE) {
updated = {
...currentValue,
..._.mapValues(values, v => {
if (v === true) return 'true';
if (v === false) return 'false';
return v;
}),
};
await storage.writeConfig({
group: 'settings',
config: updated,
+52 -25
View File
@@ -14,16 +14,11 @@ const JsonLinesDatabase = require('../utility/JsonLinesDatabase');
const processArgs = require('../utility/processArgs');
const { safeJsonParse, getLogger, extractErrorLogData } = require('dbgate-tools');
const platformInfo = require('../utility/platformInfo');
const {
connectionHasPermission,
testConnectionPermission,
loadPermissionsFromRequest,
} = require('../utility/hasPermission');
const { connectionHasPermission, testConnectionPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
const pipeForkLogs = require('../utility/pipeForkLogs');
const requireEngineDriver = require('../utility/requireEngineDriver');
const { getAuthProviderById } = require('../auth/authProvider');
const { startTokenChecking } = require('../utility/authProxy');
const { extractConnectionsFromEnv } = require('../utility/envtools');
const logger = getLogger('connections');
@@ -62,7 +57,55 @@ function getDatabaseFileLabel(databaseFile) {
function getPortalCollections() {
if (process.env.CONNECTIONS) {
const connections = extractConnectionsFromEnv(process.env);
const connections = _.compact(process.env.CONNECTIONS.split(',')).map(id => ({
_id: id,
engine: process.env[`ENGINE_${id}`],
server: process.env[`SERVER_${id}`],
user: process.env[`USER_${id}`],
password: process.env[`PASSWORD_${id}`],
passwordMode: process.env[`PASSWORD_MODE_${id}`],
port: process.env[`PORT_${id}`],
databaseUrl: process.env[`URL_${id}`],
useDatabaseUrl: !!process.env[`URL_${id}`],
databaseFile: process.env[`FILE_${id}`]?.replace(
'%%E2E_TEST_DATA_DIRECTORY%%',
path.join(path.dirname(path.dirname(__dirname)), 'e2e-tests', 'tmpdata')
),
socketPath: process.env[`SOCKET_PATH_${id}`],
serviceName: process.env[`SERVICE_NAME_${id}`],
authType: process.env[`AUTH_TYPE_${id}`] || (process.env[`SOCKET_PATH_${id}`] ? 'socket' : undefined),
defaultDatabase:
process.env[`DATABASE_${id}`] ||
(process.env[`FILE_${id}`] ? getDatabaseFileLabel(process.env[`FILE_${id}`]) : null),
singleDatabase: !!process.env[`DATABASE_${id}`] || !!process.env[`FILE_${id}`],
displayName: process.env[`LABEL_${id}`],
isReadOnly: process.env[`READONLY_${id}`],
databases: process.env[`DBCONFIG_${id}`] ? safeJsonParse(process.env[`DBCONFIG_${id}`]) : null,
allowedDatabases: process.env[`ALLOWED_DATABASES_${id}`]?.replace(/\|/g, '\n'),
allowedDatabasesRegex: process.env[`ALLOWED_DATABASES_REGEX_${id}`],
parent: process.env[`PARENT_${id}`] || undefined,
useSeparateSchemas: !!process.env[`USE_SEPARATE_SCHEMAS_${id}`],
localDataCenter: process.env[`LOCAL_DATA_CENTER_${id}`],
// SSH tunnel
useSshTunnel: process.env[`USE_SSH_${id}`],
sshHost: process.env[`SSH_HOST_${id}`],
sshPort: process.env[`SSH_PORT_${id}`],
sshMode: process.env[`SSH_MODE_${id}`],
sshLogin: process.env[`SSH_LOGIN_${id}`],
sshPassword: process.env[`SSH_PASSWORD_${id}`],
sshKeyfile: process.env[`SSH_KEY_FILE_${id}`],
sshKeyfilePassword: process.env[`SSH_KEY_FILE_PASSWORD_${id}`],
// SSL
useSsl: process.env[`USE_SSL_${id}`],
sslCaFile: process.env[`SSL_CA_FILE_${id}`],
sslCertFile: process.env[`SSL_CERT_FILE_${id}`],
sslCertFilePassword: process.env[`SSL_CERT_FILE_PASSWORD_${id}`],
sslKeyFile: process.env[`SSL_KEY_FILE_${id}`],
sslRejectUnauthorized: process.env[`SSL_REJECT_UNAUTHORIZED_${id}`],
trustServerCertificate: process.env[`SSL_TRUST_CERTIFICATE_${id}`],
}));
for (const conn of connections) {
for (const prop in process.env) {
@@ -73,10 +116,7 @@ function getPortalCollections() {
}
}
logger.info(
{ connections: connections.map(pickSafeConnectionInfo) },
'DBGM-00005 Using connections from ENV variables'
);
logger.info({ connections: connections.map(pickSafeConnectionInfo) }, 'DBGM-00005 Using connections from ENV variables');
const noengine = connections.filter(x => !x.engine);
if (noengine.length > 0) {
logger.warn(
@@ -182,15 +222,6 @@ module.exports = {
);
}
await this.checkUnsavedConnectionsLimit();
if (process.env.STORAGE_DATABASE && process.env.CONNECTIONS) {
const storage = require('./storage');
try {
await storage.fillStorageConnectionsFromEnv();
} catch (err) {
logger.error(extractErrorLogData(err), 'DBGM-00268 Error filling storage connections from env');
}
}
},
list_meta: true,
@@ -471,11 +502,7 @@ module.exports = {
state,
client: 'web',
});
if (authResp?.url) {
res.redirect(authResp.url);
return;
}
res.json({ error: 'No URL returned from auth provider' });
res.redirect(authResp.url);
},
dbloginApp_meta: true,
@@ -494,20 +494,6 @@ module.exports = {
return res.result || null;
},
multiCallMethod_meta: true,
async multiCallMethod({ conid, database, callList }, req) {
await testConnectionPermission(conid, req);
const opened = await this.ensureOpened(conid, database);
const res = await this.sendRequest(opened, { msgtype: 'multiCallMethod', callList });
if (res.errorMessage) {
return {
errorMessage: res.errorMessage,
};
}
return res.result || null;
},
status_meta: true,
async status({ conid, database }, req) {
if (!conid) {
+2 -30
View File
@@ -68,7 +68,6 @@ module.exports = {
await fs.unlink(path.join(filesdir(), folder, file));
socket.emitChanged(`files-changed`, { folder });
socket.emitChanged(`all-files-changed`);
this.emitChangedFolder(folder);
return true;
},
@@ -141,15 +140,6 @@ module.exports = {
return deserialize(format, text);
},
emitChangedFolder(folder) {
if (folder == 'themes') {
socket.emitChanged(`file-themes-changed`);
}
if (folder == 'favorites') {
socket.emitChanged('files-changed-favorites');
}
},
save_meta: true,
async save({ folder, file, data, format }, req) {
const loadedPermissions = await loadPermissionsFromRequest(req);
@@ -183,8 +173,6 @@ module.exports = {
if (folder == 'shell') {
scheduler.reload();
}
this.emitChangedFolder(folder);
return true;
}
},
@@ -252,8 +240,8 @@ module.exports = {
},
exportDiagram_meta: true,
async exportDiagram({ filePath, html, css, themeType, themeVariables, watermark }) {
await fs.writeFile(filePath, getDiagramExport(html, css, themeType, themeVariables, watermark));
async exportDiagram({ filePath, html, css, themeType, themeClassName, watermark }) {
await fs.writeFile(filePath, getDiagramExport(html, css, themeType, themeClassName, watermark));
return true;
},
@@ -358,20 +346,4 @@ module.exports = {
}
return res;
},
getFileThemes_meta: true,
async getFileThemes(_params, req) {
const loadedPermissions = await loadPermissionsFromRequest(req);
if (!hasPermission(`files/themes/read`, loadedPermissions)) return [];
const dir = path.join(filesdir(), 'themes');
if (!(await fs.exists(dir))) return [];
const files = await fs.readdir(dir);
const res = [];
for (const file of files) {
const filePath = path.join(dir, file);
const text = await fs.readFile(filePath, { encoding: 'utf-8' });
res.push(JSON.parse(text));
}
return res;
},
};
-10
View File
@@ -83,16 +83,6 @@ module.exports = {
socket.emit(`session-recordset-${sesid}`, { jslid, resultIndex });
},
handle_endrecordset(sesid, props) {
const { jslid, rowCount, durationMs } = props;
this.dispatchMessage(sesid, {
message: `Query returned ${rowCount} rows in ${durationMs} ms`,
rowCount,
durationMs,
jslid,
});
},
handle_stats(sesid, stats) {
jsldata.notifyChangedStats(stats);
},
-1
View File
@@ -147,7 +147,6 @@ const shell = require('./shell/index');
global.DBGATE_PACKAGES = {
'dbgate-tools': require('dbgate-tools'),
'dbgate-sqltree': require('dbgate-sqltree'),
'dbgate-datalib': require('dbgate-datalib'),
};
if (processArgs.startProcess) {
@@ -368,107 +368,6 @@ async function handleSaveTableData({ msgid, changeSet }) {
}
}
async function handleMultiCallMethod({ msgid, callList }) {
try {
const driver = requireEngineDriver(storedConnection);
await driver.invokeMethodCallList(dbhan, callList);
// for (const change of changeSet.changes) {
// if (change.type === 'string') {
// await driver.query(dbhan, `SET "${change.key}" "${change.value}"`);
// } else if (change.type === 'json') {
// await driver.query(dbhan, `JSON.SET "${change.key}" $ '${change.value.replace(/'/g, "\\'")}'`);
// } else if (change.type === 'hash') {
// if (change.updates && Array.isArray(change.updates)) {
// for (const update of change.updates) {
// await driver.query(dbhan, `HSET "${change.key}" "${update.key}" "${update.value}"`);
// if (update.ttl !== undefined && update.ttl !== null && update.ttl !== -1) {
// try {
// await dbhan.client.call('HEXPIRE', change.key, update.ttl, 'FIELDS', 1, update.key);
// } catch (e) {}
// }
// }
// }
// if (change.inserts && Array.isArray(change.inserts)) {
// for (const insert of change.inserts) {
// await driver.query(dbhan, `HSET "${change.key}" "${insert.key}" "${insert.value}"`);
// if (insert.ttl !== undefined && insert.ttl !== null && insert.ttl !== -1) {
// try {
// await dbhan.client.call('HEXPIRE', change.key, insert.ttl, 'FIELDS', 1, insert.key);
// } catch (e) {}
// }
// }
// }
// if (change.deletes && Array.isArray(change.deletes)) {
// for (const delKey of change.deletes) {
// await driver.query(dbhan, `HDEL "${change.key}" "${delKey}"`);
// }
// }
// } else if (change.type === 'zset') {
// if (change.updates && Array.isArray(change.updates)) {
// for (const update of change.updates) {
// await driver.query(dbhan, `ZADD "${change.key}" ${update.score} "${update.member}"`);
// }
// }
// if (change.inserts && Array.isArray(change.inserts)) {
// for (const insert of change.inserts) {
// await driver.query(dbhan, `ZADD "${change.key}" ${insert.score} "${insert.member}"`);
// }
// }
// if (change.deletes && Array.isArray(change.deletes)) {
// for (const delMember of change.deletes) {
// await driver.query(dbhan, `ZREM "${change.key}" "${delMember}"`);
// }
// }
// } else if (change.type === 'list') {
// if (change.updates && Array.isArray(change.updates)) {
// for (const update of change.updates) {
// await driver.query(dbhan, `LSET "${change.key}" ${update.index} "${update.value}"`);
// }
// }
// if (change.inserts && Array.isArray(change.inserts)) {
// for (const insert of change.inserts) {
// await driver.query(dbhan, `RPUSH "${change.key}" "${insert.value}"`);
// }
// }
// } else if (change.type === 'set') {
// if (change.inserts && Array.isArray(change.inserts)) {
// for (const insert of change.inserts) {
// await driver.query(dbhan, `SADD "${change.key}" "${insert.value}"`);
// }
// }
// if (change.deletes && Array.isArray(change.deletes)) {
// for (const delValue of change.deletes) {
// await driver.query(dbhan, `SREM "${change.key}" "${delValue}"`);
// }
// }
// } else if (change.type === 'stream') {
// if (change.inserts && Array.isArray(change.inserts)) {
// for (const insert of change.inserts) {
// const streamId = insert.id === '*' || !insert.id ? '*' : insert.id;
// await driver.query(dbhan, `XADD "${change.key}" ${streamId} value "${insert.value}"`);
// }
// }
// if (change.deletes && Array.isArray(change.deletes)) {
// for (const delId of change.deletes) {
// await driver.query(dbhan, `XDEL "${change.key}" "${delId}"`);
// }
// }
// }
// }
process.send({ msgtype: 'response', msgid });
} catch (err) {
process.send({
msgtype: 'response',
msgid,
errorMessage: extractErrorMessage(err, 'Error saving Redis data'),
});
}
}
async function handleSqlPreview({ msgid, objects, options }) {
await waitStructure();
const driver = requireEngineDriver(storedConnection);
@@ -602,7 +501,6 @@ const messageHandlers = {
schemaList: handleSchemaList,
executeSessionQuery: handleExecuteSessionQuery,
evalJsonScript: handleEvalJsonScript,
multiCallMethod: handleMultiCallMethod,
// runCommand: handleRunCommand,
};
+2 -2
View File
@@ -65,8 +65,6 @@ async function copyStream(input, output, options) {
});
}
} catch (err) {
logger.error(extractErrorLogData(err, { progressName }), 'DBGM-00157 Import/export job failed');
process.send({
msgtype: 'copyStreamError',
copyStreamError: {
@@ -84,6 +82,8 @@ async function copyStream(input, output, options) {
errorMessage: extractErrorMessage(err),
});
}
logger.error(extractErrorLogData(err, { progressName }), 'DBGM-00157 Import/export job failed');
// throw err;
}
}
-1
View File
@@ -64,7 +64,6 @@ async function dataReplicator({
createNew: compileOperationFunction(item.createNew, item.createCondition),
updateExisting: compileOperationFunction(item.updateExisting, item.updateCondition),
deleteMissing: !!item.deleteMissing,
skipUpdateColumns: item.skipUpdateColumns,
deleteRestrictionColumns: item.deleteRestrictionColumns ?? [],
openStream: item.openStream
? item.openStream
+3 -430
View File
@@ -360,12 +360,6 @@ module.exports = {
"columnName": "value",
"dataType": "varchar(1000)",
"notNull": false
},
{
"pureName": "config",
"columnName": "valueType",
"dataType": "varchar(50)",
"notNull": false
}
],
"foreignKeys": [],
@@ -686,34 +680,9 @@ module.exports = {
"columnName": "connectionDefinition",
"dataType": "text",
"notNull": false
},
{
"pureName": "connections",
"columnName": "import_source_id",
"dataType": "int",
"notNull": false
},
{
"pureName": "connections",
"columnName": "id_original",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [
{
"constraintType": "foreignKey",
"constraintName": "FK_connections_import_source_id",
"pureName": "connections",
"refTableName": "import_sources",
"columns": [
{
"columnName": "import_source_id",
"refColumnName": "id"
}
]
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "connections",
"constraintType": "primaryKey",
@@ -815,41 +784,6 @@ module.exports = {
}
]
},
{
"pureName": "import_sources",
"columns": [
{
"pureName": "import_sources",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "import_sources",
"columnName": "name",
"dataType": "varchar(250)",
"notNull": true
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "import_sources",
"constraintType": "primaryKey",
"constraintName": "PK_import_sources",
"columns": [
{
"columnName": "id"
}
]
},
"preloadedRows": [
{
"id": -1,
"name": "env"
}
]
},
{
"pureName": "roles",
"columns": [
@@ -865,34 +799,9 @@ module.exports = {
"columnName": "name",
"dataType": "varchar(250)",
"notNull": false
},
{
"pureName": "roles",
"columnName": "import_source_id",
"dataType": "int",
"notNull": false
},
{
"pureName": "roles",
"columnName": "id_original",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [
{
"constraintType": "foreignKey",
"constraintName": "FK_roles_import_source_id",
"pureName": "roles",
"refTableName": "import_sources",
"columns": [
{
"columnName": "import_source_id",
"refColumnName": "id"
}
]
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "roles",
"constraintType": "primaryKey",
@@ -939,12 +848,6 @@ module.exports = {
"columnName": "connection_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "role_connections",
"columnName": "import_source_id",
"dataType": "int",
"notNull": false
}
],
"foreignKeys": [
@@ -973,18 +876,6 @@ module.exports = {
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_role_connections_import_source_id",
"pureName": "role_connections",
"refTableName": "import_sources",
"columns": [
{
"columnName": "import_source_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
@@ -1037,18 +928,6 @@ module.exports = {
"columnName": "database_permission_role_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "role_databases",
"columnName": "import_source_id",
"dataType": "int",
"notNull": false
},
{
"pureName": "role_databases",
"columnName": "id_original",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [
@@ -1089,18 +968,6 @@ module.exports = {
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_role_databases_import_source_id",
"pureName": "role_databases",
"refTableName": "import_sources",
"columns": [
{
"columnName": "import_source_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
@@ -1214,12 +1081,6 @@ module.exports = {
"columnName": "permission",
"dataType": "varchar(250)",
"notNull": true
},
{
"pureName": "role_permissions",
"columnName": "import_source_id",
"dataType": "int",
"notNull": false
}
],
"foreignKeys": [
@@ -1235,18 +1096,6 @@ module.exports = {
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_role_permissions_import_source_id",
"pureName": "role_permissions",
"refTableName": "import_sources",
"columns": [
{
"columnName": "import_source_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
@@ -1329,18 +1178,6 @@ module.exports = {
"columnName": "table_permission_scope_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "role_tables",
"columnName": "import_source_id",
"dataType": "int",
"notNull": false
},
{
"pureName": "role_tables",
"columnName": "id_original",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [
@@ -1393,18 +1230,6 @@ module.exports = {
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_role_tables_import_source_id",
"pureName": "role_tables",
"refTableName": "import_sources",
"columns": [
{
"columnName": "import_source_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
@@ -1498,86 +1323,6 @@ module.exports = {
]
}
},
{
"pureName": "role_team_folders",
"columns": [
{
"pureName": "role_team_folders",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "role_team_folders",
"columnName": "role_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "role_team_folders",
"columnName": "team_folder_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "role_team_folders",
"columnName": "allow_read_files",
"dataType": "int",
"notNull": false
},
{
"pureName": "role_team_folders",
"columnName": "allow_write_files",
"dataType": "int",
"notNull": false
},
{
"pureName": "role_team_folders",
"columnName": "allow_use_files",
"dataType": "int",
"notNull": false
}
],
"foreignKeys": [
{
"constraintType": "foreignKey",
"constraintName": "FK_role_team_folders_role_id",
"pureName": "role_team_folders",
"refTableName": "roles",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "role_id",
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_role_team_folders_team_folder_id",
"pureName": "role_team_folders",
"refTableName": "team_folders",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "team_folder_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
"pureName": "role_team_folders",
"constraintType": "primaryKey",
"constraintName": "PK_role_team_folders",
"columns": [
{
"columnName": "id"
}
]
}
},
{
"pureName": "table_permission_roles",
"columns": [
@@ -1735,14 +1480,6 @@ module.exports = {
"columnName": "metadata",
"dataType": "varchar(1000)",
"notNull": false
},
{
"pureName": "team_files",
"columnName": "team_folder_id",
"dataType": "int",
"notNull": true,
"defaultValue": -1,
"defaultConstraint": "DF_team_files_team_folder_id"
}
],
"foreignKeys": [
@@ -1769,18 +1506,6 @@ module.exports = {
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_team_files_team_folder_id",
"pureName": "team_files",
"refTableName": "team_folders",
"columns": [
{
"columnName": "team_folder_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
@@ -1808,12 +1533,6 @@ module.exports = {
"columnName": "name",
"dataType": "varchar(250)",
"notNull": true
},
{
"pureName": "team_file_types",
"columnName": "format",
"dataType": "varchar(50)",
"notNull": false
}
],
"foreignKeys": [],
@@ -1830,73 +1549,7 @@ module.exports = {
"preloadedRows": [
{
"id": -1,
"name": "sql",
"format": "text"
},
{
"id": -2,
"name": "diagrams",
"format": "json"
},
{
"id": -3,
"name": "query",
"format": "json"
},
{
"id": -4,
"name": "perspectives",
"format": "json"
},
{
"id": -5,
"name": "impexp",
"format": "json"
},
{
"id": -6,
"name": "shell",
"format": "text"
},
{
"id": -7,
"name": "dbcompare",
"format": "json"
}
]
},
{
"pureName": "team_folders",
"columns": [
{
"pureName": "team_folders",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "team_folders",
"columnName": "folder_name",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "team_folders",
"constraintType": "primaryKey",
"constraintName": "PK_team_folders",
"columns": [
{
"columnName": "id"
}
]
},
"preloadedRows": [
{
"id": -1,
"folder_name": "default"
"name": "sql"
}
]
},
@@ -2498,86 +2151,6 @@ module.exports = {
}
]
}
},
{
"pureName": "user_team_folders",
"columns": [
{
"pureName": "user_team_folders",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "user_team_folders",
"columnName": "user_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "user_team_folders",
"columnName": "team_folder_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "user_team_folders",
"columnName": "allow_read_files",
"dataType": "int",
"notNull": false
},
{
"pureName": "user_team_folders",
"columnName": "allow_write_files",
"dataType": "int",
"notNull": false
},
{
"pureName": "user_team_folders",
"columnName": "allow_use_files",
"dataType": "int",
"notNull": false
}
],
"foreignKeys": [
{
"constraintType": "foreignKey",
"constraintName": "FK_user_team_folders_user_id",
"pureName": "user_team_folders",
"refTableName": "users",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "user_id",
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_user_team_folders_team_folder_id",
"pureName": "user_team_folders",
"refTableName": "team_folders",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "team_folder_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
"pureName": "user_team_folders",
"constraintType": "primaryKey",
"constraintName": "PK_user_team_folders",
"columns": [
{
"columnName": "id"
}
]
}
}
],
"collections": [],
+6 -13
View File
@@ -193,7 +193,7 @@ async function getCloudSigninHeaders(holder = null) {
return null;
}
async function updateCloudFiles(isRefresh, language) {
async function updateCloudFiles(isRefresh) {
let lastCloudFilesTags;
try {
lastCloudFilesTags = await fs.readFile(path.join(datadir(), 'cloud-files-tags.txt'), 'utf-8');
@@ -218,7 +218,6 @@ async function updateCloudFiles(isRefresh, language) {
...getLicenseHttpHeaders(),
...(await getCloudInstanceHeaders()),
'x-app-version': currentVersion.version,
'x-app-language': language || 'en',
},
}
);
@@ -275,7 +274,7 @@ async function ensurePromoWidgetDataLoaded() {
promoWidgetDataLoaded = true;
}
async function updatePremiumPromoWidget(language) {
async function updatePremiumPromoWidget() {
await ensurePromoWidgetDataLoaded();
const tags = (await collectCloudFilesSearchTags()).join(',');
@@ -284,10 +283,8 @@ async function updatePremiumPromoWidget(language) {
`${DBGATE_CLOUD_URL}/premium-promo-widget?identifier=${promoWidgetData?.identifier ?? 'empty'}&tags=${tags}`,
{
headers: {
...getLicenseHttpHeaders(),
...(await getCloudInstanceHeaders()),
'x-app-version': currentVersion.version,
'x-app-language': language || 'en',
},
}
);
@@ -302,21 +299,17 @@ async function updatePremiumPromoWidget(language) {
socket.emitChanged(`promo-widget-changed`);
}
async function refreshPublicFiles(isRefresh, uiLanguage) {
const language = platformInfo.isElectron
? (await config.getCachedSettings())?.['localization.language'] || 'en'
: uiLanguage;
async function refreshPublicFiles(isRefresh) {
if (!cloudFiles) {
await loadCloudFiles();
}
try {
await updateCloudFiles(isRefresh, language);
await updateCloudFiles(isRefresh);
} catch (err) {
logger.error(extractErrorLogData(err), 'DBGM-00166 Error updating cloud files');
}
const configSettings = await config.get();
if (!isProApp() || configSettings?.trialDaysLeft != null) {
await updatePremiumPromoWidget(language);
if (!isProApp()) {
await updatePremiumPromoWidget();
}
}
-454
View File
@@ -1,454 +0,0 @@
const path = require('path');
const _ = require('lodash');
const { safeJsonParse, getDatabaseFileLabel } = require('dbgate-tools');
const crypto = require('crypto');
function extractConnectionsFromEnv(env) {
if (!env?.CONNECTIONS) {
return null;
}
const connections = _.compact(env.CONNECTIONS.split(',')).map(id => ({
_id: id,
engine: env[`ENGINE_${id}`],
server: env[`SERVER_${id}`],
user: env[`USER_${id}`],
password: env[`PASSWORD_${id}`],
passwordMode: env[`PASSWORD_MODE_${id}`],
port: env[`PORT_${id}`],
databaseUrl: env[`URL_${id}`],
useDatabaseUrl: !!env[`URL_${id}`],
databaseFile: env[`FILE_${id}`]?.replace(
'%%E2E_TEST_DATA_DIRECTORY%%',
path.join(path.dirname(path.dirname(__dirname)), 'e2e-tests', 'tmpdata')
),
socketPath: env[`SOCKET_PATH_${id}`],
serviceName: env[`SERVICE_NAME_${id}`],
authType: env[`AUTH_TYPE_${id}`] || (env[`SOCKET_PATH_${id}`] ? 'socket' : undefined),
defaultDatabase: env[`DATABASE_${id}`] || (env[`FILE_${id}`] ? getDatabaseFileLabel(env[`FILE_${id}`]) : null),
singleDatabase: !!env[`DATABASE_${id}`] || !!env[`FILE_${id}`],
displayName: env[`LABEL_${id}`],
isReadOnly: env[`READONLY_${id}`],
databases: env[`DBCONFIG_${id}`] ? safeJsonParse(env[`DBCONFIG_${id}`]) : null,
allowedDatabases: env[`ALLOWED_DATABASES_${id}`]?.replace(/\|/g, '\n'),
allowedDatabasesRegex: env[`ALLOWED_DATABASES_REGEX_${id}`],
parent: env[`PARENT_${id}`] || undefined,
useSeparateSchemas: !!env[`USE_SEPARATE_SCHEMAS_${id}`],
localDataCenter: env[`LOCAL_DATA_CENTER_${id}`],
// SSH tunnel
useSshTunnel: env[`USE_SSH_${id}`],
sshHost: env[`SSH_HOST_${id}`],
sshPort: env[`SSH_PORT_${id}`],
sshMode: env[`SSH_MODE_${id}`],
sshLogin: env[`SSH_LOGIN_${id}`],
sshPassword: env[`SSH_PASSWORD_${id}`],
sshKeyfile: env[`SSH_KEY_FILE_${id}`],
sshKeyfilePassword: env[`SSH_KEY_FILE_PASSWORD_${id}`],
// SSL
useSsl: env[`USE_SSL_${id}`],
sslCaFile: env[`SSL_CA_FILE_${id}`],
sslCertFile: env[`SSL_CERT_FILE_${id}`],
sslCertFilePassword: env[`SSL_CERT_FILE_PASSWORD_${id}`],
sslKeyFile: env[`SSL_KEY_FILE_${id}`],
sslRejectUnauthorized: env[`SSL_REJECT_UNAUTHORIZED_${id}`],
trustServerCertificate: env[`SSL_TRUST_CERTIFICATE_${id}`],
}));
return connections;
}
function extractImportEntitiesFromEnv(env) {
const portalConnections = extractConnectionsFromEnv(env) || [];
const connections = portalConnections.map((conn, index) => ({
...conn,
id_original: conn._id,
import_source_id: -1,
conid: crypto.randomUUID(),
_id: undefined,
id: index + 1, // autoincrement id
useDatabaseUrl: conn.useDatabaseUrl ? 1 : 0,
isReadOnly: conn.isReadOnly ? 1 : 0,
useSeparateSchemas: conn.useSeparateSchemas ? 1 : 0,
trustServerCertificate: conn.trustServerCertificate ? 1 : 0,
singleDatabase: conn.singleDatabase ? 1 : 0,
useSshTunnel: conn.useSshTunnel ? 1 : 0,
useSsl: conn.useSsl ? 1 : 0,
sslRejectUnauthorized: conn.sslRejectUnauthorized ? 1 : 0,
}));
const connectionEnvIdToDbId = {};
for (const conn of connections) {
connectionEnvIdToDbId[conn.id_original] = conn.id;
}
const connectionsRegex = /^ROLE_(.+)_CONNECTIONS$/;
const permissionsRegex = /^ROLE_(.+)_PERMISSIONS$/;
const dbConnectionRegex = /^ROLE_(.+)_DATABASES_(.+)_CONNECTION$/;
const dbDatabasesRegex = /^ROLE_(.+)_DATABASES_(.+)_DATABASES$/;
const dbDatabasesRegexRegex = /^ROLE_(.+)_DATABASES_(.+)_DATABASES_REGEX$/;
const dbPermissionRegex = /^ROLE_(.+)_DATABASES_(.+)_PERMISSION$/;
const tableConnectionRegex = /^ROLE_(.+)_TABLES_(.+)_CONNECTION$/;
const tableDatabasesRegex = /^ROLE_(.+)_TABLES_(.+)_DATABASES$/;
const tableDatabasesRegexRegex = /^ROLE_(.+)_TABLES_(.+)_DATABASES_REGEX$/;
const tableSchemasRegex = /^ROLE_(.+)_TABLES_(.+)_SCHEMAS$/;
const tableSchemasRegexRegex = /^ROLE_(.+)_TABLES_(.+)_SCHEMAS_REGEX$/;
const tableTablesRegex = /^ROLE_(.+)_TABLES_(.+)_TABLES$/;
const tableTablesRegexRegex = /^ROLE_(.+)_TABLES_(.+)_TABLES_REGEX$/;
const tablePermissionRegex = /^ROLE_(.+)_TABLES_(.+)_PERMISSION$/;
const tableScopeRegex = /^ROLE_(.+)_TABLES_(.+)_SCOPE$/;
const roles = [];
const role_connections = [];
const role_permissions = [];
const role_databases = [];
const role_tables = [];
// Permission name to ID mappings
const databasePermissionMap = {
view: -1,
read_content: -2,
write_data: -3,
run_script: -4,
deny: -5,
};
const tablePermissionMap = {
read: -1,
update_only: -2,
create_update_delete: -3,
run_script: -4,
deny: -5,
};
const tableScopeMap = {
all_objects: -1,
tables: -2,
views: -3,
tables_views_collections: -4,
procedures: -5,
functions: -6,
triggers: -7,
sql_objects: -8,
collections: -9,
};
// Collect database and table permissions data
const databasePermissions = {};
const tablePermissions = {};
// First pass: collect all database and table permission data
for (const key in env) {
const dbConnMatch = key.match(dbConnectionRegex);
const dbDatabasesMatch = key.match(dbDatabasesRegex);
const dbDatabasesRegexMatch = key.match(dbDatabasesRegexRegex);
const dbPermMatch = key.match(dbPermissionRegex);
const tableConnMatch = key.match(tableConnectionRegex);
const tableDatabasesMatch = key.match(tableDatabasesRegex);
const tableDatabasesRegexMatch = key.match(tableDatabasesRegexRegex);
const tableSchemasMatch = key.match(tableSchemasRegex);
const tableSchemasRegexMatch = key.match(tableSchemasRegexRegex);
const tableTablesMatch = key.match(tableTablesRegex);
const tableTablesRegexMatch = key.match(tableTablesRegexRegex);
const tablePermMatch = key.match(tablePermissionRegex);
const tableScopeMatch = key.match(tableScopeRegex);
// Database permissions
if (dbConnMatch) {
const [, roleName, permId] = dbConnMatch;
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
databasePermissions[roleName][permId].connection = env[key];
}
if (dbDatabasesMatch) {
const [, roleName, permId] = dbDatabasesMatch;
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
databasePermissions[roleName][permId].databases = env[key]?.replace(/\|/g, '\n');
}
if (dbDatabasesRegexMatch) {
const [, roleName, permId] = dbDatabasesRegexMatch;
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
databasePermissions[roleName][permId].databasesRegex = env[key];
}
if (dbPermMatch) {
const [, roleName, permId] = dbPermMatch;
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
databasePermissions[roleName][permId].permission = env[key];
}
// Table permissions
if (tableConnMatch) {
const [, roleName, permId] = tableConnMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].connection = env[key];
}
if (tableDatabasesMatch) {
const [, roleName, permId] = tableDatabasesMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].databases = env[key]?.replace(/\|/g, '\n');
}
if (tableDatabasesRegexMatch) {
const [, roleName, permId] = tableDatabasesRegexMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].databasesRegex = env[key];
}
if (tableSchemasMatch) {
const [, roleName, permId] = tableSchemasMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].schemas = env[key];
}
if (tableSchemasRegexMatch) {
const [, roleName, permId] = tableSchemasRegexMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].schemasRegex = env[key];
}
if (tableTablesMatch) {
const [, roleName, permId] = tableTablesMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].tables = env[key]?.replace(/\|/g, '\n');
}
if (tableTablesRegexMatch) {
const [, roleName, permId] = tableTablesRegexMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].tablesRegex = env[key];
}
if (tablePermMatch) {
const [, roleName, permId] = tablePermMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].permission = env[key];
}
if (tableScopeMatch) {
const [, roleName, permId] = tableScopeMatch;
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
tablePermissions[roleName][permId].scope = env[key];
}
}
// Second pass: process roles, connections, and permissions
for (const key in env) {
const connMatch = key.match(connectionsRegex);
const permMatch = key.match(permissionsRegex);
if (connMatch) {
const roleName = connMatch[1];
let role = roles.find(r => r.name === roleName);
if (!role) {
role = {
id: roles.length + 1,
name: roleName,
import_source_id: -1,
};
roles.push(role);
}
const connIds = env[key]
.split(',')
.map(id => id.trim())
.filter(id => id.length > 0);
for (const connId of connIds) {
const dbId = connectionEnvIdToDbId[connId];
if (dbId) {
role_connections.push({
role_id: role.id,
connection_id: dbId,
import_source_id: -1,
});
}
}
}
if (permMatch) {
const roleName = permMatch[1];
let role = roles.find(r => r.name === roleName);
if (!role) {
role = {
id: roles.length + 1,
name: roleName,
import_source_id: -1,
};
roles.push(role);
}
const permissions = env[key]
.split(',')
.map(p => p.trim())
.filter(p => p.length > 0);
for (const permission of permissions) {
role_permissions.push({
role_id: role.id,
permission,
import_source_id: -1,
});
}
}
}
// Process database permissions
for (const roleName in databasePermissions) {
let role = roles.find(r => r.name === roleName);
if (!role) {
role = {
id: roles.length + 1,
name: roleName,
import_source_id: -1,
};
roles.push(role);
}
for (const permId in databasePermissions[roleName]) {
const perm = databasePermissions[roleName][permId];
if (perm.connection && perm.permission) {
const dbId = connectionEnvIdToDbId[perm.connection];
const permissionId = databasePermissionMap[perm.permission];
if (dbId && permissionId) {
role_databases.push({
role_id: role.id,
connection_id: dbId,
database_names_list: perm.databases || null,
database_names_regex: perm.databasesRegex || null,
database_permission_role_id: permissionId,
id_original: permId,
import_source_id: -1,
});
}
}
}
}
// Process table permissions
for (const roleName in tablePermissions) {
let role = roles.find(r => r.name === roleName);
if (!role) {
role = {
id: roles.length + 1,
name: roleName,
import_source_id: -1,
};
roles.push(role);
}
for (const permId in tablePermissions[roleName]) {
const perm = tablePermissions[roleName][permId];
if (perm.connection && perm.permission) {
const dbId = connectionEnvIdToDbId[perm.connection];
const permissionId = tablePermissionMap[perm.permission];
const scopeId = tableScopeMap[perm.scope || 'all_objects'];
if (dbId && permissionId && scopeId) {
role_tables.push({
role_id: role.id,
connection_id: dbId,
database_names_list: perm.databases || null,
database_names_regex: perm.databasesRegex || null,
schema_names_list: perm.schemas || null,
schema_names_regex: perm.schemasRegex || null,
table_names_list: perm.tables || null,
table_names_regex: perm.tablesRegex || null,
table_permission_role_id: permissionId,
table_permission_scope_id: scopeId,
id_original: permId,
import_source_id: -1,
});
}
}
}
}
if (connections.length == 0 && roles.length == 0) {
return null;
}
return {
connections,
roles,
role_connections,
role_permissions,
role_databases,
role_tables,
};
}
function createStorageFromEnvReplicatorItems(importEntities) {
return [
{
name: 'connections',
findExisting: true,
createNew: true,
updateExisting: true,
matchColumns: ['id_original', 'import_source_id'],
deleteMissing: true,
deleteRestrictionColumns: ['import_source_id'],
skipUpdateColumns: ['conid'],
jsonArray: importEntities.connections,
},
{
name: 'roles',
findExisting: true,
createNew: true,
updateExisting: true,
matchColumns: ['name', 'import_source_id'],
deleteMissing: true,
deleteRestrictionColumns: ['import_source_id'],
jsonArray: importEntities.roles,
},
{
name: 'role_connections',
findExisting: true,
createNew: true,
updateExisting: false,
deleteMissing: true,
matchColumns: ['role_id', 'connection_id', 'import_source_id'],
jsonArray: importEntities.role_connections,
deleteRestrictionColumns: ['import_source_id'],
},
{
name: 'role_permissions',
findExisting: true,
createNew: true,
updateExisting: false,
deleteMissing: true,
matchColumns: ['role_id', 'permission', 'import_source_id'],
jsonArray: importEntities.role_permissions,
deleteRestrictionColumns: ['import_source_id'],
},
{
name: 'role_databases',
findExisting: true,
createNew: true,
updateExisting: true,
deleteMissing: true,
matchColumns: ['role_id', 'id_original', 'import_source_id'],
jsonArray: importEntities.role_databases,
deleteRestrictionColumns: ['import_source_id'],
},
{
name: 'role_tables',
findExisting: true,
createNew: true,
updateExisting: true,
deleteMissing: true,
matchColumns: ['role_id', 'id_original', 'import_source_id'],
jsonArray: importEntities.role_tables,
deleteRestrictionColumns: ['import_source_id'],
},
];
}
module.exports = {
extractConnectionsFromEnv,
extractImportEntitiesFromEnv,
createStorageFromEnvReplicatorItems,
};
+2 -10
View File
@@ -1,4 +1,4 @@
const getDiagramExport = (html, css, themeType, themeVariables, watermark) => {
const getDiagramExport = (html, css, themeType, themeClassName, watermark) => {
const watermarkHtml = watermark
? `
<div style="position: fixed; bottom: 0; right: 0; padding: 5px; font-size: 12px; color: var(--theme-font-2); background-color: var(--theme-bg-2); border-top-left-radius: 5px; border: 1px solid var(--theme-border);">
@@ -6,19 +6,11 @@ const getDiagramExport = (html, css, themeType, themeVariables, watermark) => {
</div>
`
: '';
// Convert theme variables object to CSS custom properties
const themeVariablesCSS = themeVariables
? `:root {\n${Object.entries(themeVariables).map(([key, value]) => ` ${key}: ${value};`).join('\n')}\n}`
: '';
return `<html>
<meta charset='utf-8'>
<head>
<style>
${themeVariablesCSS}
${css}
body {
@@ -63,7 +55,7 @@ const getDiagramExport = (html, css, themeType, themeVariables, watermark) => {
</script>
</head>
<body class='${themeType == 'dark' ? 'theme-type-dark' : 'theme-type-light'}' style='user-select:none; cursor:pointer'>
<body class='${themeType == 'dark' ? 'theme-type-dark' : 'theme-type-light'} ${themeClassName}' style='user-select:none; cursor:pointer'>
${html}
${watermarkHtml}
</body>
+3 -13
View File
@@ -14,10 +14,9 @@ class QueryStreamTableWriter {
this.currentChangeIndex = 1;
this.initializedFile = false;
this.sesid = sesid;
this.started = new Date().getTime();
}
initializeFromQuery(structure, resultIndex, chartDefinition, autoDetectCharts = false, options = {}) {
initializeFromQuery(structure, resultIndex, chartDefinition, autoDetectCharts = false) {
this.jslid = crypto.randomUUID();
this.currentFile = path.join(jsldir(), `${this.jslid}.jsonl`);
fs.writeFileSync(
@@ -25,7 +24,6 @@ class QueryStreamTableWriter {
JSON.stringify({
...structure,
__isStreamHeader: true,
...options
}) + '\n'
);
this.currentStream = fs.createWriteStream(this.currentFile, { flags: 'a' });
@@ -120,13 +118,6 @@ class QueryStreamTableWriter {
this.chartProcessor = null;
}
}
process.send({
msgtype: 'endrecordset',
jslid: this.jslid,
rowCount: this.currentRowCount,
sesid: this.sesid,
durationMs: new Date().getTime() - this.started,
});
resolve();
});
} else {
@@ -180,7 +171,7 @@ class StreamHandler {
process.send({ msgtype: 'changedCurrentDatabase', database, sesid: this.sesid });
}
recordset(columns, options) {
recordset(columns) {
if (this.rowsLimitOverflow) {
return;
}
@@ -190,8 +181,7 @@ class StreamHandler {
Array.isArray(columns) ? { columns } : columns,
this.queryStreamInfoHolder.resultIndex,
this.frontMatter?.[`chart-${this.queryStreamInfoHolder.resultIndex + 1}`],
this.autoDetectCharts,
options
this.autoDetectCharts
);
this.queryStreamInfoHolder.resultIndex += 1;
this.rowCounter = 0;
-1
View File
@@ -2,5 +2,4 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['js'],
reporters: ['default', 'github-actions'],
};
-188
View File
@@ -1,188 +0,0 @@
import { DatabaseMethodCallItem, DatabaseMethodCallList } from 'dbgate-types';
export interface ChangeSetRedis_String {
key: string;
type: 'string';
value: string;
}
export interface ChangeSetRedis_JSON {
key: string;
type: 'json';
value: string;
}
export interface ChangeSetRedis_Hash {
key: string;
type: 'hash';
inserts: { key: string; value: string; ttl: number }[];
updates: { key: string; value: string; ttl: number }[];
deletes: string[];
}
export interface ChangeSetRedis_List {
key: string;
type: 'list';
inserts: { index: number; value: string }[];
updates: { index: number; value: string }[];
deletes: number[];
}
export interface ChangeSetRedis_Set {
key: string;
type: 'set';
inserts: string[];
deletes: string[];
}
export interface ChangeSetRedis_ZSet {
key: string;
type: 'zset';
inserts: { member: string; score: number }[];
updates: { member: string; score: number }[];
deletes: string[];
}
export type ChangeSetRedisType =
| ChangeSetRedis_String
| ChangeSetRedis_JSON
| ChangeSetRedis_Hash
| ChangeSetRedis_List
| ChangeSetRedis_Set
| ChangeSetRedis_ZSet;
export interface ChangeSetRedis {
changes: ChangeSetRedisType[];
}
export function redisChangeSetToRedisCommands(changeSet: ChangeSetRedis): DatabaseMethodCallList {
const calls: DatabaseMethodCallItem[] = [];
for (const change of changeSet.changes) {
if (change.type === 'string') {
calls.push({
method: 'SET',
args: [change.key, change.value],
});
} else if (change.type === 'json') {
calls.push({
method: 'JSON.SET',
args: [change.key, '$', change.value],
});
} else if (change.type === 'hash') {
if (change.updates && Array.isArray(change.updates)) {
for (const update of change.updates) {
calls.push({
method: 'HSET',
args: [change.key, update.key, update.value],
});
if (update.ttl !== undefined && update.ttl !== null && update.ttl !== -1) {
calls.push({
method: 'HEXPIRE',
args: [change.key, update.ttl, 'FIELDS', 1, update.key],
});
}
}
}
if (change.inserts && Array.isArray(change.inserts)) {
for (const insert of change.inserts) {
calls.push({
method: 'HSET',
args: [change.key, insert.key, insert.value],
});
if (insert.ttl !== undefined && insert.ttl !== null && insert.ttl !== -1) {
calls.push({
method: 'HEXPIRE',
args: [change.key, insert.ttl, 'FIELDS', 1, insert.key],
});
}
}
}
if (change.deletes && Array.isArray(change.deletes)) {
for (const delKey of change.deletes) {
calls.push({
method: 'HDEL',
args: [change.key, delKey],
});
}
}
} else if (change.type === 'zset') {
if (change.updates && Array.isArray(change.updates)) {
for (const update of change.updates) {
calls.push({
method: 'ZADD',
args: [change.key, update.score, update.member],
});
}
}
if (change.inserts && Array.isArray(change.inserts)) {
for (const insert of change.inserts) {
calls.push({
method: 'ZADD',
args: [change.key, insert.score, insert.member],
});
}
}
if (change.deletes && Array.isArray(change.deletes)) {
for (const delMember of change.deletes) {
calls.push({
method: 'ZREM',
args: [change.key, delMember],
});
}
}
} else if (change.type === 'list') {
if (change.updates && Array.isArray(change.updates)) {
for (const update of change.updates) {
calls.push({
method: 'LSET',
args: [change.key, update.index, update.value],
});
}
}
if (change.inserts && Array.isArray(change.inserts)) {
for (const insert of change.inserts) {
calls.push({
method: 'RPUSH',
args: [change.key, insert.value],
});
}
}
} else if (change.type === 'set') {
if (change.inserts && Array.isArray(change.inserts)) {
for (const insert of change.inserts) {
calls.push({
method: 'SADD',
args: [change.key, insert],
});
}
}
if (change.deletes && Array.isArray(change.deletes)) {
for (const delValue of change.deletes) {
calls.push({
method: 'SREM',
args: [change.key, delValue],
});
}
}
}
}
return { calls };
}
export function convertRedisCallListToScript(callList: DatabaseMethodCallList): string {
let script = '';
for (const call of callList.calls) {
script += `${call.method} ${call.args.map((arg) => (typeof arg === 'string' ? `"${arg}"` : arg)).join(' ')}\n`;
}
return script;
}
+1 -7
View File
@@ -23,7 +23,6 @@ export interface DataReplicatorItem {
deleteMissing: boolean;
deleteRestrictionColumns: string[];
matchColumns: string[];
skipUpdateColumns?: string[];
}
export interface DataReplicatorOptions {
@@ -152,12 +151,7 @@ class ReplicatorItemHolder {
chunk,
this.table.columns.map(x => x.columnName)
),
[
this.autoColumn,
...this.backReferences.map(x => x.columnName),
...this.references.map(x => x.columnName),
...(this.item.skipUpdateColumns || []),
]
[this.autoColumn, ...this.backReferences.map(x => x.columnName), ...this.references.map(x => x.columnName)]
);
return res;
-1
View File
@@ -25,4 +25,3 @@ export * from './CustomGridDisplay';
export * from './ScriptDrivedDeployer';
export * from './chartDefinitions';
export * from './chartProcessor';
export * from './ChangeSetRedis';
+1 -14
View File
@@ -35,12 +35,6 @@ program
.option('-u, --user <user>', 'user name')
.option('-p, --password <password>', 'password')
.option('-d, --database <database>', 'database name')
.option('--url <url>', 'database url')
.option('--file <file>', 'database file')
.option('--socket-path <socketPath>', 'socket path')
.option('--service-name <serviceName>', 'service name (for Oracle)')
.option('--auth-type <authType>', 'authentication type')
.option('--use-ssl', 'use SSL connection')
.option('--auto-index-foreign-keys', 'automatically adds indexes to all foreign keys')
.option(
'--load-data-condition <condition>',
@@ -54,7 +48,7 @@ program
.command('deploy <modelFolder>')
.description('Deploys model to database')
.action(modelFolder => {
const { engine, server, user, password, database, url, file, transaction } = program.opts();
const { engine, server, user, password, database, transaction } = program.opts();
// const hooks = [];
// if (program.autoIndexForeignKeys) hooks.push(dbmodel.hooks.autoIndexForeignKeys);
@@ -66,13 +60,6 @@ program
user,
password,
database,
databaseUrl: url,
useDatabaseUrl: !!url,
databaseFile: file,
socketPath: program.socketPath,
serviceName: program.serviceName,
authType: program.authType,
useSsl: program.useSsl,
},
modelFolder,
useTransaction: transaction,
-1
View File
@@ -2,5 +2,4 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['js'],
reporters: ['default', 'github-actions'],
};
+2 -5
View File
@@ -1,4 +1,4 @@
import { arrayToHexString, base64ToHex, evalFilterBehaviour, isTypeDateTime } from 'dbgate-tools';
import { arrayToHexString, evalFilterBehaviour, isTypeDateTime } from 'dbgate-tools';
import { format, toDate } from 'date-fns';
import _isString from 'lodash/isString';
import _cloneDeepWith from 'lodash/cloneDeepWith';
@@ -21,13 +21,10 @@ export function getFilterValueExpression(value, dataType?) {
if (value === false) return 'FALSE';
if (value.$oid) return `ObjectId("${value.$oid}")`;
if (value.$bigint) return value.$bigint;
if (value.$decimal) return value.$decimal;
if (value.type == 'Buffer' && Array.isArray(value.data)) {
return '0x' + arrayToHexString(value.data);
}
if (value?.$binary?.base64) {
return base64ToHex(value.$binary.base64);
}
return `="${value}"`;
}
+5 -2
View File
@@ -2,7 +2,7 @@ import P from 'parsimmon';
import moment from 'moment';
import { Condition } from 'dbgate-sqltree';
import { interpretEscapes, token, word, whitespace } from './common';
import { hexToBase64, parseNumberSafe } from 'dbgate-tools';
import { hexStringToArray, parseNumberSafe } from 'dbgate-tools';
import { FilterBehaviour, TransformType } from 'dbgate-types';
const binaryCondition =
@@ -385,7 +385,10 @@ const createParser = (filterBehaviour: FilterBehaviour) => {
hexstring: () =>
token(P.regexp(/0x(([0-9a-fA-F][0-9a-fA-F])+)/, 1))
.map(x => ({ $binary: { base64: hexToBase64(x) } }))
.map(x => ({
type: 'Buffer',
data: hexStringToArray(x),
}))
.desc('hex string'),
noQuotedString: () => P.regexp(/[^\s^,^'^"]+/).desc('string unquoted'),
+2 -5
View File
@@ -1,7 +1,7 @@
import type { SqlDumper } from 'dbgate-types';
import { Command, Select, Update, Delete, Insert } from './types';
import { dumpSqlExpression } from './dumpSqlExpression';
import { dumpSqlFromDefinition, dumpSqlSourceDef, dumpSqlSourceRef } from './dumpSqlSource';
import { dumpSqlFromDefinition, dumpSqlSourceRef } from './dumpSqlSource';
import { dumpSqlCondition } from './dumpSqlCondition';
export function dumpSqlSelect(dmp: SqlDumper, cmd: Select) {
@@ -115,10 +115,7 @@ export function dumpSqlInsert(dmp: SqlDumper, cmd: Insert) {
cmd.fields.map(x => x.targetColumn)
);
dmp.putCollection(',', cmd.fields, x => dumpSqlExpression(dmp, x));
if (cmd.whereNotExistsSource) {
dmp.put(' ^from ');
dumpSqlSourceDef(dmp, cmd.whereNotExistsSource);
} else if (dmp.dialect.requireFromDual) {
if (dmp.dialect.requireFromDual) {
dmp.put(' ^from ^dual ');
}
dmp.put(' ^where ^not ^exists (^select * ^from %f ^where ', cmd.targetTable);
@@ -2,7 +2,6 @@ import _ from 'lodash';
import type { SqlDumper } from 'dbgate-types';
import { Expression, ColumnRefExpression } from './types';
import { dumpSqlSourceRef } from './dumpSqlSource';
import { dumpSqlSelect } from './dumpSqlCommand';
export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) {
switch (expr.exprType) {
@@ -68,11 +67,5 @@ export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) {
});
dmp.put(')');
break;
case 'select':
dmp.put('(');
dumpSqlSelect(dmp, expr.select);
dmp.put(')');
break;
}
}
@@ -19,7 +19,6 @@ function isLike(value, test) {
function extractRawValue(value) {
if (value?.$bigint) return value.$bigint;
if (value?.$oid) return value.$oid;
if (value?.$decimal) return value.$decimal;
return value;
}
+1 -8
View File
@@ -44,7 +44,6 @@ export interface Insert {
fields: UpdateField[];
targetTable: NamedObjectInfo;
insertWhereNotExistsCondition?: Condition;
whereNotExistsSource?: Source;
}
export interface AllowIdentityInsert {
@@ -227,11 +226,6 @@ export interface RowNumberExpression {
orderBy: OrderByExpression[];
}
export interface SelectExpression {
exprType: 'select';
select: Select;
}
export type Expression =
| ColumnRefExpression
| ValueExpression
@@ -241,8 +235,7 @@ export type Expression =
| CallExpression
| MethodCallExpression
| TranformExpression
| RowNumberExpression
| SelectExpression;
| RowNumberExpression;
export type OrderByExpression = Expression & { direction: 'ASC' | 'DESC' };
export type ResultField = Expression & { alias?: string };
-1
View File
@@ -2,5 +2,4 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['js'],
reporters: ['default', 'github-actions'],
};
+1 -1
View File
@@ -33,7 +33,7 @@
},
"dependencies": {
"blueimp-md5": "^2.19.0",
"dbgate-query-splitter": "^4.11.9",
"dbgate-query-splitter": "^4.11.7",
"dbgate-sqltree": "^6.0.0-alpha.1",
"debug": "^4.3.4",
"json-stable-stringify": "^1.0.1",
-5
View File
@@ -164,11 +164,6 @@ export class DatabaseAnalyser<TClient = any> {
const res = {};
for (const field of STRUCTURE_FIELDS) {
const isAll = this.modifications.some(x => x.action == 'all' && x.objectTypeField == field);
if (isAll) {
res[field] = newlyAnalysed[field] || [];
continue;
}
const removedIds = this.modifications
.filter(x => x.action == 'remove' && x.objectTypeField == field)
.map(x => x.objectId);
+9 -84
View File
@@ -26,7 +26,6 @@ import _isDate from 'lodash/isDate';
import _isArray from 'lodash/isArray';
import _isPlainObject from 'lodash/isPlainObject';
import _keys from 'lodash/keys';
import _cloneDeep from 'lodash/cloneDeep';
import uuidv1 from 'uuid/v1';
export class SqlDumper implements AlterProcessor {
@@ -79,16 +78,7 @@ export class SqlDumper implements AlterProcessor {
else if (_isNumber(value)) this.putRaw(value.toString());
else if (_isDate(value)) this.putStringValue(new Date(value).toISOString());
else if (value?.type == 'Buffer' && _isArray(value?.data)) this.putByteArrayValue(value?.data);
else if (value?.$binary?.base64) {
const binary = atob(value.$binary.base64);
const bytes = new Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
this.putByteArrayValue(bytes);
}
else if (value?.$bigint) this.putRaw(value?.$bigint);
else if (value?.$decimal) this.putRaw(value?.$decimal);
else if (_isPlainObject(value) || _isArray(value)) this.putStringValue(JSON.stringify(value));
else this.put('^null');
}
@@ -668,68 +658,6 @@ export class SqlDumper implements AlterProcessor {
}
}
sanitizeTableConstraints(table: TableInfo): TableInfo {
// Create a deep copy of the table
const sanitized = _cloneDeep(table);
// Get the set of existing column names
const existingColumns = new Set(sanitized.columns.map(col => col.columnName));
// Filter primary key columns to only include existing columns
if (sanitized.primaryKey) {
const validPkColumns = sanitized.primaryKey.columns.filter(col => existingColumns.has(col.columnName));
if (validPkColumns.length === 0) {
// If no valid columns remain, remove the primary key entirely
sanitized.primaryKey = null;
} else if (validPkColumns.length < sanitized.primaryKey.columns.length) {
// Update primary key with only valid columns
sanitized.primaryKey = {
...sanitized.primaryKey,
columns: validPkColumns
};
}
}
// Filter sorting key columns to only include existing columns
if (sanitized.sortingKey) {
const validSkColumns = sanitized.sortingKey.columns.filter(col => existingColumns.has(col.columnName));
if (validSkColumns.length === 0) {
sanitized.sortingKey = null;
} else if (validSkColumns.length < sanitized.sortingKey.columns.length) {
sanitized.sortingKey = {
...sanitized.sortingKey,
columns: validSkColumns
};
}
}
// Filter foreign keys to only include those with all columns present
if (sanitized.foreignKeys) {
sanitized.foreignKeys = sanitized.foreignKeys.filter(fk =>
fk.columns.every(col => existingColumns.has(col.columnName))
);
}
// Filter indexes to only include those with all columns present
if (sanitized.indexes) {
sanitized.indexes = sanitized.indexes.filter(idx =>
idx.columns.every(col => existingColumns.has(col.columnName))
);
}
// Filter unique constraints to only include those with all columns present
if (sanitized.uniques) {
sanitized.uniques = sanitized.uniques.filter(uq =>
uq.columns.every(col => existingColumns.has(col.columnName))
);
}
// Filter dependencies (references from other tables) - these should remain as-is
// since they don't affect the CREATE TABLE statement for this table
return sanitized;
}
recreateTable(oldTable: TableInfo, newTable: TableInfo) {
if (!oldTable.pairingId || !newTable.pairingId || oldTable.pairingId != newTable.pairingId) {
throw new Error('Recreate is not possible: oldTable.paringId != newTable.paringId');
@@ -744,51 +672,48 @@ export class SqlDumper implements AlterProcessor {
}))
.filter(x => x.newcol);
// Create a sanitized version of newTable with constraints that only reference existing columns
const sanitizedNewTable = this.sanitizeTableConstraints(newTable);
if (this.driver.supportsTransactions) {
this.dropConstraints(oldTable, true);
this.renameTable(oldTable, tmpTable);
this.createTable(sanitizedNewTable);
this.createTable(newTable);
const autoinc = sanitizedNewTable.columns.find(x => x.autoIncrement);
const autoinc = newTable.columns.find(x => x.autoIncrement);
if (autoinc) {
this.allowIdentityInsert(sanitizedNewTable, true);
this.allowIdentityInsert(newTable, true);
}
this.putCmd(
'^insert ^into %f (%,i) select %,i ^from %f',
sanitizedNewTable,
newTable,
columnPairs.map(x => x.newcol.columnName),
columnPairs.map(x => x.oldcol.columnName),
{ ...oldTable, pureName: tmpTable }
);
if (autoinc) {
this.allowIdentityInsert(sanitizedNewTable, false);
this.allowIdentityInsert(newTable, false);
}
if (this.dialect.dropForeignKey) {
sanitizedNewTable.dependencies.forEach(cnt => this.createConstraint(cnt));
newTable.dependencies.forEach(cnt => this.createConstraint(cnt));
}
this.dropTable({ ...oldTable, pureName: tmpTable });
} else {
// we have to preserve old table as long as possible
this.createTable({ ...sanitizedNewTable, pureName: tmpTable });
this.createTable({ ...newTable, pureName: tmpTable });
this.putCmd(
'^insert ^into %f (%,i) select %,s ^from %f',
{ ...sanitizedNewTable, pureName: tmpTable },
{ ...newTable, pureName: tmpTable },
columnPairs.map(x => x.newcol.columnName),
columnPairs.map(x => x.oldcol.columnName),
oldTable
);
this.dropTable(oldTable);
this.renameTable({ ...sanitizedNewTable, pureName: tmpTable }, newTable.pureName);
this.renameTable({ ...newTable, pureName: tmpTable }, newTable.pureName);
}
}
+42 -118
View File
@@ -91,8 +91,8 @@ interface AlterOperation_RenameConstraint {
}
interface AlterOperation_RecreateTable {
operationType: 'recreateTable';
oldTable: TableInfo;
newTable: TableInfo;
table: TableInfo;
operations: AlterOperation[];
}
interface AlterOperation_FillPreloadedRows {
operationType: 'fillPreloadedRows';
@@ -249,11 +249,11 @@ export class AlterPlan {
});
}
recreateTable(oldTable: TableInfo, newTable: TableInfo) {
recreateTable(table: TableInfo, operations: AlterOperation[]) {
this.operations.push({
operationType: 'recreateTable',
oldTable,
newTable,
table,
operations,
});
this.recreates.tables += 1;
}
@@ -337,13 +337,7 @@ export class AlterPlan {
return opRes;
}),
op,
].filter(op => {
// filter duplicated drops
const existingDrop = this.operations.find(
o => o.operationType == 'dropConstraint' && o.oldObject === op['oldObject']
);
return existingDrop == null;
});
];
return res;
}
@@ -504,119 +498,51 @@ export class AlterPlan {
return [];
}
const oldTable = this.wholeOldDb.tables.find(
x => x.pureName == op[objectField].pureName && x.schemaName == op[objectField].schemaName
);
const newTable = this.wholeNewDb.tables.find(
const table = this.wholeNewDb.tables.find(
x => x.pureName == op[objectField].pureName && x.schemaName == op[objectField].schemaName
);
this.recreates.tables += 1;
return [
{
operationType: 'recreateTable',
oldTable,
newTable,
// operations: [op],
table,
operations: [op],
},
];
}
return null;
}
_removeRecreatedTableAlters(): AlterOperation[] {
const res: AlterOperation[] = [];
const recreates = new Set<string>();
for (const op of this.operations) {
if (op.operationType == 'recreateTable' && op.oldTable && op.newTable) {
const key = `${op.oldTable.schemaName}||${op.oldTable.pureName}`;
recreates.add(key);
}
}
for (const op of this.operations) {
switch (op.operationType) {
case 'createColumn':
case 'createConstraint':
{
const key = `${op.newObject.schemaName}||${op.newObject.pureName}`;
if (recreates.has(key)) {
// skip create inside recreated table
continue;
}
}
break;
case 'dropColumn':
case 'dropConstraint':
case 'changeColumn':
{
const key = `${op.oldObject.schemaName}||${op.oldObject.pureName}`;
if (recreates.has(key)) {
// skip drop/change inside recreated table
continue;
}
}
break;
case 'renameColumn':
{
const key = `${op.object.schemaName}||${op.object.pureName}`;
if (recreates.has(key)) {
// skip rename inside recreated table
continue;
}
}
break;
}
res.push(op);
}
return res;
}
_groupTableRecreations(): AlterOperation[] {
const res = [];
const recreates = new Set<string>();
const recreates = {};
for (const op of this.operations) {
if (op.operationType == 'recreateTable' && op.oldTable && op.newTable) {
const key = `${op.oldTable.schemaName}||${op.oldTable.pureName}`;
if (recreates.has(key)) {
// prevent duplicate recreates
continue;
if (op.operationType == 'recreateTable' && op.table) {
const existingRecreate = recreates[`${op.table.schemaName}||${op.table.pureName}`];
if (existingRecreate) {
existingRecreate.operations.push(...op.operations);
} else {
const recreate = {
...op,
operations: [...op.operations],
};
res.push(recreate);
recreates[`${op.table.schemaName}||${op.table.pureName}`] = recreate;
}
recreates.add(key);
} else {
// @ts-ignore
const oldObject: TableInfo = op.oldObject || op.object;
if (oldObject) {
const recreated = recreates[`${oldObject.schemaName}||${oldObject.pureName}`];
if (recreated) {
recreated.operations.push(op);
continue;
}
}
res.push(op);
}
res.push(op);
}
return res;
// const res = [];
// const recreates = {};
// for (const op of this.operations) {
// if (op.operationType == 'recreateTable' && op.table) {
// const existingRecreate = recreates[`${op.table.schemaName}||${op.table.pureName}`];
// if (existingRecreate) {
// existingRecreate.operations.push(...op.operations);
// } else {
// const recreate = {
// ...op,
// operations: [...op.operations],
// };
// res.push(recreate);
// recreates[`${op.table.schemaName}||${op.table.pureName}`] = recreate;
// }
// } else {
// // @ts-ignore
// const oldObject: TableInfo = op.oldObject || op.object;
// if (oldObject) {
// const recreated = recreates[`${oldObject.schemaName}||${oldObject.pureName}`];
// if (recreated) {
// recreated.operations.push(op);
// continue;
// }
// }
// res.push(op);
// }
// }
// return res;
}
_moveForeignKeysToLast(): AlterOperation[] {
@@ -685,8 +611,6 @@ export class AlterPlan {
// console.log('*****************OPERATIONS3', this.operations);
this.operations = this._removeRecreatedTableAlters();
this.operations = this._moveForeignKeysToLast();
// console.log('*****************OPERATIONS4', this.operations);
@@ -749,16 +673,16 @@ export function runAlterOperation(op: AlterOperation, processor: AlterProcessor)
break;
case 'recreateTable':
{
// const oldTable = generateTablePairingId(op.table);
// const newTable = _.cloneDeep(oldTable);
// const newDb = DatabaseAnalyser.createEmptyStructure();
// newDb.tables.push(newTable);
// // console.log('////////////////////////////newTable1', newTable);
// op.operations.forEach(child => runAlterOperation(child, new DatabaseInfoAlterProcessor(newDb)));
// // console.log('////////////////////////////op.operations', op.operations);
// // console.log('////////////////////////////op.table', op.table);
// // console.log('////////////////////////////newTable2', newTable);
processor.recreateTable(op.oldTable, op.newTable);
const oldTable = generateTablePairingId(op.table);
const newTable = _.cloneDeep(oldTable);
const newDb = DatabaseAnalyser.createEmptyStructure();
newDb.tables.push(newTable);
// console.log('////////////////////////////newTable1', newTable);
op.operations.forEach(child => runAlterOperation(child, new DatabaseInfoAlterProcessor(newDb)));
// console.log('////////////////////////////op.operations', op.operations);
// console.log('////////////////////////////op.table', op.table);
// console.log('////////////////////////////newTable2', newTable);
processor.recreateTable(oldTable, newTable);
}
break;
}
-1
View File
@@ -47,7 +47,6 @@ export const mongoFilterBehaviour: FilterBehaviour = {
allowStringToken: true,
allowNumberDualTesting: true,
allowObjectIdTesting: true,
allowHexString: true,
};
export const evalFilterBehaviour: FilterBehaviour = {
-1
View File
@@ -146,5 +146,4 @@ export const DATA_FOLDER_NAMES = [
{ name: 'datadeploy', label: 'Data deploy jobs' },
{ name: 'dbcompare', label: 'Database compare jobs' },
{ name: 'apps', label: 'Applications' },
{ name: 'themes', label: 'Themes' },
];
+15 -73
View File
@@ -43,20 +43,6 @@ export function hexStringToArray(inputString) {
return res;
}
export function base64ToHex(base64String) {
const binaryString = atob(base64String);
const hexString = Array.from(binaryString, c => c.charCodeAt(0).toString(16).padStart(2, '0')).join('');
return '0x' + hexString.toUpperCase();
}
export function hexToBase64(hexString) {
const binaryString = hexString
.match(/.{1,2}/g)
.map(byte => String.fromCharCode(parseInt(byte, 16)))
.join('');
return btoa(binaryString);
}
export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
if (!_isString(value)) return value;
@@ -68,9 +54,8 @@ export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
const mHex = value.match(/^0x([0-9a-fA-F][0-9a-fA-F])+$/);
if (mHex) {
return {
$binary: {
base64: hexToBase64(value.substring(2)),
},
type: 'Buffer',
data: hexStringToArray(value.substring(2)),
};
}
}
@@ -201,26 +186,6 @@ function stringifyJsonToGrid(value): ReturnType<typeof stringifyCellValue> {
return { value: '(JSON)', gridStyle: 'nullCellStyle' };
}
function formatNumberCustomSeparator(value, thousandsSeparator) {
const [intPart, decPart] = value.split('.');
const intPartWithSeparator = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
return decPart ? `${intPartWithSeparator}.${decPart}` : intPartWithSeparator;
}
function formatCellNumber(value, gridFormattingOptions?: { thousandsSeparator?: string }) {
const separator = gridFormattingOptions?.thousandsSeparator;
if (_isNumber(value)) {
if (separator === 'none' || (value < 1000 && value > -1000)) return value.toString();
if (separator === 'system') return value.toLocaleString();
}
// fallback for system locale
if (separator === 'space' || separator === 'system') return formatNumberCustomSeparator(value.toString(), ' ');
if (separator === 'narrowspace') return formatNumberCustomSeparator(value.toString(), '\u202F');
if (separator === 'comma') return formatNumberCustomSeparator(value.toString(), ',');
if (separator === 'dot') return formatNumberCustomSeparator(value.toString(), '.');
return value.toString();
}
export function stringifyCellValue(
value,
intent:
@@ -231,7 +196,7 @@ export function stringifyCellValue(
| 'exportIntent'
| 'clipboardIntent',
editorTypes?: DataEditorTypesBehaviour,
gridFormattingOptions?: { thousandsSeparator?: string },
gridFormattingOptions?: { useThousandsSeparator?: boolean },
jsonParsedValue?: any
): {
value: string;
@@ -265,26 +230,11 @@ export function stringifyCellValue(
if (value === true) return { value: 'true', gridStyle: 'valueCellStyle' };
if (value === false) return { value: 'false', gridStyle: 'valueCellStyle' };
if (value?.$binary?.base64) {
return {
value: base64ToHex(value.$binary.base64),
gridStyle: 'valueCellStyle',
};
}
if (value?.$decimal) {
return {
value: formatCellNumber(value.$decimal, gridFormattingOptions),
gridStyle: 'valueCellStyle',
};
}
if (editorTypes?.parseHexAsBuffer) {
// if (value?.type == 'Buffer' && _isArray(value.data)) {
// return { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' };
// }
if (value?.type == 'Buffer' && _isArray(value.data)) {
return { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' };
}
}
if (editorTypes?.parseObjectIdAsDollar) {
if (value?.$oid) {
switch (intent) {
@@ -298,13 +248,13 @@ export function stringifyCellValue(
}
if (value?.$bigint) {
return {
value: formatCellNumber(value.$bigint, gridFormattingOptions),
value: value.$bigint,
gridStyle: 'valueCellStyle',
};
}
if (typeof value === 'bigint') {
return {
value: formatCellNumber(value.toString(), gridFormattingOptions),
value: value.toString(),
gridStyle: 'valueCellStyle',
};
}
@@ -379,8 +329,13 @@ export function stringifyCellValue(
if (_isNumber(value)) {
switch (intent) {
case 'gridCellIntent':
const separator = gridFormattingOptions?.thousandsSeparator;
return { value: formatCellNumber(value, gridFormattingOptions), gridStyle: 'valueCellStyle' };
return {
value:
gridFormattingOptions?.useThousandsSeparator && (value >= 10000 || value <= -10000)
? value.toLocaleString()
: value.toString(),
gridStyle: 'valueCellStyle',
};
default:
return { value: value.toString() };
}
@@ -472,9 +427,6 @@ export function shouldOpenMultilineDialog(value) {
if (value?.$bigint) {
return false;
}
if (value?.$decimal) {
return false;
}
if (_isPlainObject(value) || _isArray(value)) {
return true;
}
@@ -504,7 +456,6 @@ export function getIconForRedisType(type) {
case 'binary':
return 'img type-binary';
case 'ReJSON-RL':
case 'JSON':
return 'img type-rejson';
default:
return null;
@@ -531,9 +482,6 @@ export function getAsImageSrc(obj) {
if (obj?.type == 'Buffer' && _isArray(obj?.data)) {
return `data:image/png;base64, ${arrayBufferToBase64(obj?.data)}`;
}
if (obj?.$binary?.base64) {
return `data:image/png;base64, ${obj.$binary.base64}`;
}
if (_isString(obj) && (obj.startsWith('http://') || obj.startsWith('https://'))) {
return obj;
@@ -726,9 +674,6 @@ export function deserializeJsTypesFromJsonParse(obj) {
if (value?.$bigint) {
return BigInt(value.$bigint);
}
if (value?.$decimal) {
return value.$decimal;
}
});
}
@@ -743,9 +688,6 @@ export function deserializeJsTypesReviver(key, value) {
if (value?.$bigint) {
return BigInt(value.$bigint);
}
if (value?.$decimal) {
return value.$decimal;
}
return value;
}
-1
View File
@@ -16,7 +16,6 @@ export interface SqlDumper extends AlterProcessor {
transform(type: TransformType, dumpExpr: () => void);
createDatabase(name: string);
dropDatabase(name: string);
comment(value: string);
callableTemplate(func: CallableObjectInfo);
-13
View File
@@ -224,15 +224,6 @@ export interface RestoreDatabaseSettings extends BackupRestoreSettingsBase {
inputFile: string;
}
export interface DatabaseMethodCallItem {
method: string;
args: any[];
}
export interface DatabaseMethodCallList {
calls: DatabaseMethodCallItem[];
}
export interface EngineDriver<TClient = any, TDataBase = any> extends FilterBehaviourProvider {
engine: string;
title: string;
@@ -247,7 +238,6 @@ export interface EngineDriver<TClient = any, TDataBase = any> extends FilterBeha
supportsDatabaseRestore?: boolean;
supportsServerSummary?: boolean;
supportsDatabaseProfiler?: boolean;
supportsIncrementalAnalysis?: boolean;
requiresDefaultSortCriteria?: boolean;
profilerFormatterFunction?: string;
profilerTimestampFunction?: string;
@@ -262,7 +252,6 @@ export interface EngineDriver<TClient = any, TDataBase = any> extends FilterBeha
collectionPluralLabel?: string;
collectionNameLabel?: string;
newCollectionFormParams?: any[];
icon?: any;
supportedCreateDatabase?: boolean;
showConnectionField?: (
@@ -347,8 +336,6 @@ export interface EngineDriver<TClient = any, TDataBase = any> extends FilterBeha
readCollection(dbhan: DatabaseHandle<TClient, TDataBase>, options: ReadCollectionOptions): Promise<any>;
updateCollection(dbhan: DatabaseHandle<TClient, TDataBase>, changeSet: any): Promise<any>;
getCollectionUpdateScript(changeSet: any, collectionInfo: CollectionInfo): string;
getKeyValueMethodCallList(changeSet: any): DatabaseMethodCallList;
invokeMethodCallList(dbhan: DatabaseHandle<TClient, TDataBase>, callList: DatabaseMethodCallList): Promise<void>;
createDatabase(dbhan: DatabaseHandle<TClient, TDataBase>, name: string): Promise;
dropDatabase(dbhan: DatabaseHandle<TClient, TDataBase>, name: string): Promise;
getQuerySplitterOptions(usage: 'stream' | 'script' | 'editor' | 'import'): any;
+3 -3
View File
@@ -23,11 +23,10 @@ export interface FileFormatDefinition {
}
export interface ThemeDefinition {
themeClassName: string;
themeName: string;
themeType: 'light' | 'dark';
isBuiltInTheme?: boolean;
themeVariables?: { [key: string]: string };
themePublicCloudPath?: string;
themeCss?: string;
}
export interface PluginDefinition {
@@ -48,4 +47,5 @@ export interface ExtensionsDirectory {
fileFormats: FileFormatDefinition[];
quickExports: QuickExportDefinition[];
drivers: EngineDriver[];
themes: ThemeDefinition[];
}
-2
View File
@@ -96,6 +96,4 @@ export type TestEngineInfo = {
}>;
objects?: Array<TestObjectInfo>;
binaryDataType?: string;
};
+2 -14
View File
@@ -20,30 +20,18 @@
<link rel="stylesheet" href="dimensions.css" />
<link rel="stylesheet" href="bulma.css" />
<link rel="stylesheet" href="icon-colors.css" />
<link rel="stylesheet" href="build/tailwind.css" />
<link rel="stylesheet" href="build/bundle.css" />
<link rel="stylesheet" href="build/fonts/materialdesignicons.css" />
<link rel="stylesheet" href="build/diff2html.min.css" />
<script lang="javascript">
window.dbgate_page = '{{page}}';
if (localStorage.getItem('currentThemeType') == 'dark') {
document.documentElement.style.setProperty('--theme-background', '#111');
document.documentElement.style.setProperty('--theme-foreground', '#e3e3e3');
} else {
document.documentElement.style.setProperty('--theme-background', '#fff');
document.documentElement.style.setProperty('--theme-foreground', '#262626');
}
</script>
<script defer src="build/bundle.js"></script>
<style>
body {
background-color: var(--theme-background);
}
.lds-ellipsis {
display: inline-block;
position: relative;
@@ -56,7 +44,7 @@
width: 13px;
height: 13px;
border-radius: 50%;
background: var(--theme-foreground);
background: #000;
animation-timing-function: cubic-bezier(0, 1, 1, 0);
}
.lds-ellipsis div:nth-child(1) {
+4 -9
View File
@@ -25,16 +25,14 @@
"@rollup/plugin-node-resolve": "^13.0.5",
"@rollup/plugin-replace": "^3.0.0",
"@rollup/plugin-typescript": "^8.2.5",
"@tailwindcss/postcss": "^4.1.18",
"@tsconfig/svelte": "^1.0.0",
"ace-builds": "^1.36.5",
"autoprefixer": "^10.4.23",
"chart.js": "^4.4.2",
"chartjs-adapter-moment": "^1.0.0",
"chartjs-plugin-datalabels": "^2.2.0",
"cross-env": "^7.0.3",
"dbgate-datalib": "^6.0.0-alpha.1",
"dbgate-query-splitter": "^4.11.9",
"dbgate-query-splitter": "^4.11.7",
"dbgate-sqltree": "^6.0.0-alpha.1",
"dbgate-tools": "^6.0.0-alpha.1",
"dbgate-types": "^6.0.0-alpha.1",
@@ -46,24 +44,21 @@
"json-stable-stringify": "^1.0.1",
"localforage": "^1.9.0",
"lodash": "^4.17.21",
"postcss": "^8.5.6",
"randomcolor": "^0.6.2",
"resize-observer-polyfill": "^1.5.1",
"rollup": "^2.57.0",
"rollup-plugin-copy": "^3.3.0",
"rollup-plugin-css-only": "^3.1.0",
"rollup-plugin-livereload": "^2.0.0",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-svelte": "^7.2.2",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
"sirv-cli": "^1.0.0",
"sql-formatter": "^3.1.0",
"svelte": "^4.2.20",
"svelte": "^3.46.4",
"svelte-check": "^1.0.0",
"svelte-markdown": "^0.1.4",
"svelte-preprocess": "^4.9.5",
"svelte-select": "^4.4.7",
"tailwindcss": "^4.1.18",
"tslib": "^2.3.1",
"typescript": "^4.4.3",
"uuid": "^3.4.0"
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
plugins: {
'@tailwindcss/postcss': {},
autoprefixer: {},
},
};
+2 -9
View File
@@ -2,21 +2,14 @@
--dim-widget-icon-size: 50px;
--dim-statusbar-height: 22px;
--dim-left-panel-width: 300px;
--dim-right-panel-width: 300px;
--dim-tabs-height: 33px;
--dim-tabs-panel-height: calc( var(--dim-visible-tabs-databases) * 20px + var(--dim-tabs-height) );
--dim-splitter-thickness: 4px;
--dim-splitter-thickness: 3px;
--dim-visible-left-panel: 1; /* set from JS */
--dim-content-left: calc(
var(--dim-widget-icon-size) + var(--dim-visible-left-panel) *
(var(--dim-left-panel-width))
);
--dim-visible-right-panel: 0; /* set from JS */
--dim-content-right: calc(
var(--dim-visible-right-panel) *
(var(--dim-right-panel-width))
(var(--dim-left-panel-width) + var(--dim-splitter-thickness))
);
--dim-visible-toolbar: 0; /* set from JS */
+33 -163
View File
@@ -12,47 +12,21 @@ body {
}
.horizontal-split-handle {
width: 0px;
position: relative;
cursor: col-resize;
}
.horizontal-split-handle::before {
content: '';
position: absolute;
cursor: col-resize;
left: -1px;
right: -1px;
top: 0;
bottom: 0;
background-color: var(--theme-border);
width: var(--dim-splitter-thickness);
background-color: transparent;
transition: background-color 0.2s ease;
z-index: 200;
cursor: col-resize;
}
.horizontal-split-handle:hover::before {
background-color: var(--theme-splitter-active);
.horizontal-split-handle:hover {
background-color: var(--theme-bg-2);
}
.vertical-split-handle {
height: 0px;
position: relative;
cursor: row-resize;
}
.vertical-split-handle::before {
content: '';
position: absolute;
cursor: row-resize;
top: -1px;
bottom: -1px;
left: 0;
right: 0;
background-color: var(--theme-border);
height: var(--dim-splitter-thickness);
background-color: transparent;
transition: background-color 0.2s ease;
z-index: 200;
cursor: row-resize;
}
.vertical-split-handle:hover::before {
background-color: var(--theme-splitter-active);
.vertical-split-handle:hover {
background-color: var(--theme-bg-2);
}
.icon-invisible {
@@ -143,32 +117,21 @@ body {
max-width: 16.6666%;
}
.largeFormMarker input[type='text'],
.largeFormMarker input[type='number'],
.largeFormMarker input[type='password'],
.largeFormMarker textarea {
.largeFormMarker input[type='text'], .largeFormMarker input[type='number'], .largeFormMarker input[type='password'], .largeFormMarker textarea {
width: 100%;
padding: 10px 10px;
font-size: 14px;
box-sizing: border-box;
border-radius: 4px;
border: var(--theme-input-border);
background: var(--theme-input-background);
border: 1px solid var(--theme-border);
}
.input1 {
padding: 5px 2px;
padding: 5px 5px;
font-size: 14px;
box-sizing: border-box;
border-radius: 4px;
border: var(--theme-input-border);
background: var(--theme-input-background);
}
.input1:focus {
outline: none;
border: var(--theme-input-border-focus);
box-shadow: var(--theme-input-focus-ring);
border: 1px solid var(--theme-border);
}
.largeFormMarker select {
@@ -185,88 +148,54 @@ body *::-webkit-scrollbar {
}
body *::-webkit-scrollbar-track {
border-radius: 1px;
background: var(--theme-scrollbar-background);
background-color: var(--theme-bg-1);
}
body *::-webkit-scrollbar-corner {
border-radius: 1px;
background: var(--theme-scrollbar-corner-background);
background-color: var(--theme-bg-2);
}
body *::-webkit-scrollbar-thumb {
border-radius: 1px;
background: var(--theme-scrollbar-thumb-background);
background-color: var(--theme-bg-3);
}
body *::-webkit-scrollbar-thumb:hover {
background: var(--theme-scrollbar-thumb-background-hover);
background-color: var(--theme-bg-4);
}
input {
background: var(--theme-input-background);
color: var(--theme-generic-font);
border: var(--theme-input-border);
background-color: var(--theme-bg-0);
color: var(--theme-font-1);
border: 1px solid var(--theme-border);
}
input[disabled] {
background: var(--theme-input-background-disabled);
color: var(--theme-input-foreground-disabled);
}
.largeFormMarker input[disabled] {
background: var(--theme-input-background-disabled);
color: var(--theme-input-foreground-disabled);
background-color: var(--theme-bg-1);
}
select {
padding: 10px 12px;
border: var(--theme-input-border);
border-radius: 4px;
background-color: var(--theme-input-background);
color: var(--theme-input-foreground);
font-size: 13px;
transition: all 0.15s ease;
font-family: inherit;
}
select:hover {
border: var(--theme-input-border-hover);
}
select:focus {
outline: none;
border: var(--theme-input-border-focus);
box-shadow: var(--theme-input-focus-ring);
background-color: var(--theme-bg-0);
color: var(--theme-font-1);
border: 1px solid var(--theme-border);
}
select[disabled] {
background-color: var(--theme-input-background-disabled);
color: var(--theme-input-foreground-disabled);
cursor: not-allowed;
border: var(--theme-input-border-disabled);
}
.largeFormMarker select[disabled] {
background: var(--theme-input-background-disabled);
color: var(--theme-input-foreground-disabled);
background-color: var(--theme-bg-1);
}
.classicform select {
padding: 5px 5px 4px;
}
.selectContainer.focused {
box-shadow: var(--theme-input-focus-ring);
}
textarea {
background: var(--theme-input-background);
color: var(--theme-generic-font);
border: var(--theme-input-border);
background-color: var(--theme-bg-0);
color: var(--theme-font-1);
border: 1px solid var(--theme-border);
}
textarea[disabled] {
background: var(--theme-input-background-disabled);
color: var(--theme-input-foreground-disabled);
background-color: var(--theme-bg-1);
}
.ace_gutter-cell.ace-gutter-sql-run {
@@ -290,70 +219,11 @@ textarea[disabled] {
}
.ace_gutter-cell.ace-gutter-sql-run:hover {
background-color: var(--theme-bg-2);
background-color: var(--theme-bg-2);
}
.ace_gutter-cell.ace-gutter-current-part {
/* background-color: var(--theme-bg-2); */
font-weight: bold;
color: var(--theme-font-hover);
}
input[type='checkbox'] {
appearance: none;
width: 16px;
height: 16px;
border-radius: 4px;
border: var(--theme-checkbox-border);
background-color: var(--theme-input-background);
display: inline-grid;
place-content: center;
cursor: pointer;
}
input[type='checkbox']:hover:not(:disabled) {
border: 1px solid var(--theme-checkbox-hover-not-disabled);
}
input[type='checkbox']:checked:hover {
border: 1px solid var(--theme-checkbox-background);
}
input[type='checkbox']:checked {
background-color: var(--theme-checkbox-background);
border: var(--theme-checkbox-border);
}
input[type='checkbox']::before {
content: '';
width: 10px;
height: 10px;
transform: scale(0);
transition: transform 120ms ease;
background-color: var(--theme-checkbox-mark);
clip-path: polygon(
14% 44%,
0 65%,
50% 100%,
100% 16%,
80% 0,
43% 62%
);
}
input[type='checkbox']:checked::before {
transform: scale(1);
}
input[type='checkbox']:disabled {
cursor: not-allowed;
background-color: var(--theme-checkbox-background-disabled);
border: var(--theme-checkbox-border);
}
input[type='checkbox']:disabled::before {
background-color: var(--theme-checkbox-background-disabled-before);
}
/* background-color: var(--theme-bg-2); */
font-weight: bold;
color: var(--theme-font-hover);
}
+4 -4
View File
@@ -23,12 +23,12 @@
}
.color-icon-statusbar-red {
color: var(--theme-statusbar-icon-error);
.color-icon-inv-green {
color: var(--theme-icon-inv-green);
}
.color-icon-statusbar-green {
color: var(--theme-statusbar-icon-ok);
.color-icon-inv-red {
color: var(--theme-icon-inv-red);
}
.premium-background-gradient {
-288
View File
@@ -1,288 +0,0 @@
/* Force all Tailwind color variables to be included in build */
body {
/* Slate */
--tw-copy-slate-50: var(--tw-color-slate-50);
--tw-copy-slate-100: var(--tw-color-slate-100);
--tw-copy-slate-200: var(--tw-color-slate-200);
--tw-copy-slate-300: var(--tw-color-slate-300);
--tw-copy-slate-400: var(--tw-color-slate-400);
--tw-copy-slate-500: var(--tw-color-slate-500);
--tw-copy-slate-600: var(--tw-color-slate-600);
--tw-copy-slate-700: var(--tw-color-slate-700);
--tw-copy-slate-800: var(--tw-color-slate-800);
--tw-copy-slate-900: var(--tw-color-slate-900);
--tw-copy-slate-950: var(--tw-color-slate-950);
/* Gray */
--tw-copy-gray-50: var(--tw-color-gray-50);
--tw-copy-gray-100: var(--tw-color-gray-100);
--tw-copy-gray-200: var(--tw-color-gray-200);
--tw-copy-gray-300: var(--tw-color-gray-300);
--tw-copy-gray-400: var(--tw-color-gray-400);
--tw-copy-gray-500: var(--tw-color-gray-500);
--tw-copy-gray-600: var(--tw-color-gray-600);
--tw-copy-gray-700: var(--tw-color-gray-700);
--tw-copy-gray-800: var(--tw-color-gray-800);
--tw-copy-gray-900: var(--tw-color-gray-900);
--tw-copy-gray-950: var(--tw-color-gray-950);
/* Zinc */
--tw-copy-zinc-50: var(--tw-color-zinc-50);
--tw-copy-zinc-100: var(--tw-color-zinc-100);
--tw-copy-zinc-200: var(--tw-color-zinc-200);
--tw-copy-zinc-300: var(--tw-color-zinc-300);
--tw-copy-zinc-400: var(--tw-color-zinc-400);
--tw-copy-zinc-500: var(--tw-color-zinc-500);
--tw-copy-zinc-600: var(--tw-color-zinc-600);
--tw-copy-zinc-700: var(--tw-color-zinc-700);
--tw-copy-zinc-800: var(--tw-color-zinc-800);
--tw-copy-zinc-900: var(--tw-color-zinc-900);
--tw-copy-zinc-950: var(--tw-color-zinc-950);
/* Neutral */
--tw-copy-neutral-50: var(--tw-color-neutral-50);
--tw-copy-neutral-100: var(--tw-color-neutral-100);
--tw-copy-neutral-200: var(--tw-color-neutral-200);
--tw-copy-neutral-300: var(--tw-color-neutral-300);
--tw-copy-neutral-400: var(--tw-color-neutral-400);
--tw-copy-neutral-500: var(--tw-color-neutral-500);
--tw-copy-neutral-600: var(--tw-color-neutral-600);
--tw-copy-neutral-700: var(--tw-color-neutral-700);
--tw-copy-neutral-800: var(--tw-color-neutral-800);
--tw-copy-neutral-900: var(--tw-color-neutral-900);
--tw-copy-neutral-950: var(--tw-color-neutral-950);
/* Stone */
--tw-copy-stone-50: var(--tw-color-stone-50);
--tw-copy-stone-100: var(--tw-color-stone-100);
--tw-copy-stone-200: var(--tw-color-stone-200);
--tw-copy-stone-300: var(--tw-color-stone-300);
--tw-copy-stone-400: var(--tw-color-stone-400);
--tw-copy-stone-500: var(--tw-color-stone-500);
--tw-copy-stone-600: var(--tw-color-stone-600);
--tw-copy-stone-700: var(--tw-color-stone-700);
--tw-copy-stone-800: var(--tw-color-stone-800);
--tw-copy-stone-900: var(--tw-color-stone-900);
--tw-copy-stone-950: var(--tw-color-stone-950);
/* Red */
--tw-copy-red-50: var(--tw-color-red-50);
--tw-copy-red-100: var(--tw-color-red-100);
--tw-copy-red-200: var(--tw-color-red-200);
--tw-copy-red-300: var(--tw-color-red-300);
--tw-copy-red-400: var(--tw-color-red-400);
--tw-copy-red-500: var(--tw-color-red-500);
--tw-copy-red-600: var(--tw-color-red-600);
--tw-copy-red-700: var(--tw-color-red-700);
--tw-copy-red-800: var(--tw-color-red-800);
--tw-copy-red-900: var(--tw-color-red-900);
--tw-copy-red-950: var(--tw-color-red-950);
/* Orange */
--tw-copy-orange-50: var(--tw-color-orange-50);
--tw-copy-orange-100: var(--tw-color-orange-100);
--tw-copy-orange-200: var(--tw-color-orange-200);
--tw-copy-orange-300: var(--tw-color-orange-300);
--tw-copy-orange-400: var(--tw-color-orange-400);
--tw-copy-orange-500: var(--tw-color-orange-500);
--tw-copy-orange-600: var(--tw-color-orange-600);
--tw-copy-orange-700: var(--tw-color-orange-700);
--tw-copy-orange-800: var(--tw-color-orange-800);
--tw-copy-orange-900: var(--tw-color-orange-900);
--tw-copy-orange-950: var(--tw-color-orange-950);
/* Amber */
--tw-copy-amber-50: var(--tw-color-amber-50);
--tw-copy-amber-100: var(--tw-color-amber-100);
--tw-copy-amber-200: var(--tw-color-amber-200);
--tw-copy-amber-300: var(--tw-color-amber-300);
--tw-copy-amber-400: var(--tw-color-amber-400);
--tw-copy-amber-500: var(--tw-color-amber-500);
--tw-copy-amber-600: var(--tw-color-amber-600);
--tw-copy-amber-700: var(--tw-color-amber-700);
--tw-copy-amber-800: var(--tw-color-amber-800);
--tw-copy-amber-900: var(--tw-color-amber-900);
--tw-copy-amber-950: var(--tw-color-amber-950);
/* Yellow */
--tw-copy-yellow-50: var(--tw-color-yellow-50);
--tw-copy-yellow-100: var(--tw-color-yellow-100);
--tw-copy-yellow-200: var(--tw-color-yellow-200);
--tw-copy-yellow-300: var(--tw-color-yellow-300);
--tw-copy-yellow-400: var(--tw-color-yellow-400);
--tw-copy-yellow-500: var(--tw-color-yellow-500);
--tw-copy-yellow-600: var(--tw-color-yellow-600);
--tw-copy-yellow-700: var(--tw-color-yellow-700);
--tw-copy-yellow-800: var(--tw-color-yellow-800);
--tw-copy-yellow-900: var(--tw-color-yellow-900);
--tw-copy-yellow-950: var(--tw-color-yellow-950);
/* Lime */
--tw-copy-lime-50: var(--tw-color-lime-50);
--tw-copy-lime-100: var(--tw-color-lime-100);
--tw-copy-lime-200: var(--tw-color-lime-200);
--tw-copy-lime-300: var(--tw-color-lime-300);
--tw-copy-lime-400: var(--tw-color-lime-400);
--tw-copy-lime-500: var(--tw-color-lime-500);
--tw-copy-lime-600: var(--tw-color-lime-600);
--tw-copy-lime-700: var(--tw-color-lime-700);
--tw-copy-lime-800: var(--tw-color-lime-800);
--tw-copy-lime-900: var(--tw-color-lime-900);
--tw-copy-lime-950: var(--tw-color-lime-950);
/* Green */
--tw-copy-green-50: var(--tw-color-green-50);
--tw-copy-green-100: var(--tw-color-green-100);
--tw-copy-green-200: var(--tw-color-green-200);
--tw-copy-green-300: var(--tw-color-green-300);
--tw-copy-green-400: var(--tw-color-green-400);
--tw-copy-green-500: var(--tw-color-green-500);
--tw-copy-green-600: var(--tw-color-green-600);
--tw-copy-green-700: var(--tw-color-green-700);
--tw-copy-green-800: var(--tw-color-green-800);
--tw-copy-green-900: var(--tw-color-green-900);
--tw-copy-green-950: var(--tw-color-green-950);
/* Emerald */
--tw-copy-emerald-50: var(--tw-color-emerald-50);
--tw-copy-emerald-100: var(--tw-color-emerald-100);
--tw-copy-emerald-200: var(--tw-color-emerald-200);
--tw-copy-emerald-300: var(--tw-color-emerald-300);
--tw-copy-emerald-400: var(--tw-color-emerald-400);
--tw-copy-emerald-500: var(--tw-color-emerald-500);
--tw-copy-emerald-600: var(--tw-color-emerald-600);
--tw-copy-emerald-700: var(--tw-color-emerald-700);
--tw-copy-emerald-800: var(--tw-color-emerald-800);
--tw-copy-emerald-900: var(--tw-color-emerald-900);
--tw-copy-emerald-950: var(--tw-color-emerald-950);
/* Teal */
--tw-copy-teal-50: var(--tw-color-teal-50);
--tw-copy-teal-100: var(--tw-color-teal-100);
--tw-copy-teal-200: var(--tw-color-teal-200);
--tw-copy-teal-300: var(--tw-color-teal-300);
--tw-copy-teal-400: var(--tw-color-teal-400);
--tw-copy-teal-500: var(--tw-color-teal-500);
--tw-copy-teal-600: var(--tw-color-teal-600);
--tw-copy-teal-700: var(--tw-color-teal-700);
--tw-copy-teal-800: var(--tw-color-teal-800);
--tw-copy-teal-900: var(--tw-color-teal-900);
--tw-copy-teal-950: var(--tw-color-teal-950);
/* Cyan */
--tw-copy-cyan-50: var(--tw-color-cyan-50);
--tw-copy-cyan-100: var(--tw-color-cyan-100);
--tw-copy-cyan-200: var(--tw-color-cyan-200);
--tw-copy-cyan-300: var(--tw-color-cyan-300);
--tw-copy-cyan-400: var(--tw-color-cyan-400);
--tw-copy-cyan-500: var(--tw-color-cyan-500);
--tw-copy-cyan-600: var(--tw-color-cyan-600);
--tw-copy-cyan-700: var(--tw-color-cyan-700);
--tw-copy-cyan-800: var(--tw-color-cyan-800);
--tw-copy-cyan-900: var(--tw-color-cyan-900);
--tw-copy-cyan-950: var(--tw-color-cyan-950);
/* Sky */
--tw-copy-sky-50: var(--tw-color-sky-50);
--tw-copy-sky-100: var(--tw-color-sky-100);
--tw-copy-sky-200: var(--tw-color-sky-200);
--tw-copy-sky-300: var(--tw-color-sky-300);
--tw-copy-sky-400: var(--tw-color-sky-400);
--tw-copy-sky-500: var(--tw-color-sky-500);
--tw-copy-sky-600: var(--tw-color-sky-600);
--tw-copy-sky-700: var(--tw-color-sky-700);
--tw-copy-sky-800: var(--tw-color-sky-800);
--tw-copy-sky-900: var(--tw-color-sky-900);
--tw-copy-sky-950: var(--tw-color-sky-950);
/* Blue */
--tw-copy-blue-50: var(--tw-color-blue-50);
--tw-copy-blue-100: var(--tw-color-blue-100);
--tw-copy-blue-200: var(--tw-color-blue-200);
--tw-copy-blue-300: var(--tw-color-blue-300);
--tw-copy-blue-400: var(--tw-color-blue-400);
--tw-copy-blue-500: var(--tw-color-blue-500);
--tw-copy-blue-600: var(--tw-color-blue-600);
--tw-copy-blue-700: var(--tw-color-blue-700);
--tw-copy-blue-800: var(--tw-color-blue-800);
--tw-copy-blue-900: var(--tw-color-blue-900);
--tw-copy-blue-950: var(--tw-color-blue-950);
/* Indigo */
--tw-copy-indigo-50: var(--tw-color-indigo-50);
--tw-copy-indigo-100: var(--tw-color-indigo-100);
--tw-copy-indigo-200: var(--tw-color-indigo-200);
--tw-copy-indigo-300: var(--tw-color-indigo-300);
--tw-copy-indigo-400: var(--tw-color-indigo-400);
--tw-copy-indigo-500: var(--tw-color-indigo-500);
--tw-copy-indigo-600: var(--tw-color-indigo-600);
--tw-copy-indigo-700: var(--tw-color-indigo-700);
--tw-copy-indigo-800: var(--tw-color-indigo-800);
--tw-copy-indigo-900: var(--tw-color-indigo-900);
--tw-copy-indigo-950: var(--tw-color-indigo-950);
/* Violet */
--tw-copy-violet-50: var(--tw-color-violet-50);
--tw-copy-violet-100: var(--tw-color-violet-100);
--tw-copy-violet-200: var(--tw-color-violet-200);
--tw-copy-violet-300: var(--tw-color-violet-300);
--tw-copy-violet-400: var(--tw-color-violet-400);
--tw-copy-violet-500: var(--tw-color-violet-500);
--tw-copy-violet-600: var(--tw-color-violet-600);
--tw-copy-violet-700: var(--tw-color-violet-700);
--tw-copy-violet-800: var(--tw-color-violet-800);
--tw-copy-violet-900: var(--tw-color-violet-900);
--tw-copy-violet-950: var(--tw-color-violet-950);
/* Purple */
--tw-copy-purple-50: var(--tw-color-purple-50);
--tw-copy-purple-100: var(--tw-color-purple-100);
--tw-copy-purple-200: var(--tw-color-purple-200);
--tw-copy-purple-300: var(--tw-color-purple-300);
--tw-copy-purple-400: var(--tw-color-purple-400);
--tw-copy-purple-500: var(--tw-color-purple-500);
--tw-copy-purple-600: var(--tw-color-purple-600);
--tw-copy-purple-700: var(--tw-color-purple-700);
--tw-copy-purple-800: var(--tw-color-purple-800);
--tw-copy-purple-900: var(--tw-color-purple-900);
--tw-copy-purple-950: var(--tw-color-purple-950);
/* Fuchsia */
--tw-copy-fuchsia-50: var(--tw-color-fuchsia-50);
--tw-copy-fuchsia-100: var(--tw-color-fuchsia-100);
--tw-copy-fuchsia-200: var(--tw-color-fuchsia-200);
--tw-copy-fuchsia-300: var(--tw-color-fuchsia-300);
--tw-copy-fuchsia-400: var(--tw-color-fuchsia-400);
--tw-copy-fuchsia-500: var(--tw-color-fuchsia-500);
--tw-copy-fuchsia-600: var(--tw-color-fuchsia-600);
--tw-copy-fuchsia-700: var(--tw-color-fuchsia-700);
--tw-copy-fuchsia-800: var(--tw-color-fuchsia-800);
--tw-copy-fuchsia-900: var(--tw-color-fuchsia-900);
--tw-copy-fuchsia-950: var(--tw-color-fuchsia-950);
/* Pink */
--tw-copy-pink-50: var(--tw-color-pink-50);
--tw-copy-pink-100: var(--tw-color-pink-100);
--tw-copy-pink-200: var(--tw-color-pink-200);
--tw-copy-pink-300: var(--tw-color-pink-300);
--tw-copy-pink-400: var(--tw-color-pink-400);
--tw-copy-pink-500: var(--tw-color-pink-500);
--tw-copy-pink-600: var(--tw-color-pink-600);
--tw-copy-pink-700: var(--tw-color-pink-700);
--tw-copy-pink-800: var(--tw-color-pink-800);
--tw-copy-pink-900: var(--tw-color-pink-900);
--tw-copy-pink-950: var(--tw-color-pink-950);
/* Rose */
--tw-copy-rose-50: var(--tw-color-rose-50);
--tw-copy-rose-100: var(--tw-color-rose-100);
--tw-copy-rose-200: var(--tw-color-rose-200);
--tw-copy-rose-300: var(--tw-color-rose-300);
--tw-copy-rose-400: var(--tw-color-rose-400);
--tw-copy-rose-500: var(--tw-color-rose-500);
--tw-copy-rose-600: var(--tw-color-rose-600);
--tw-copy-rose-700: var(--tw-color-rose-700);
--tw-copy-rose-800: var(--tw-color-rose-800);
--tw-copy-rose-900: var(--tw-color-rose-900);
--tw-copy-rose-950: var(--tw-color-rose-950);
}
-16
View File
@@ -9,7 +9,6 @@ import typescript from '@rollup/plugin-typescript';
import replace from '@rollup/plugin-replace';
import css from 'rollup-plugin-css-only';
import json from '@rollup/plugin-json';
import postcss from 'rollup-plugin-postcss';
const production = !process.env.ROLLUP_WATCH;
@@ -35,21 +34,6 @@ function serve() {
}
export default [
// Separate entry for Tailwind CSS processing
{
input: 'src/tailwind.css',
output: {
file: 'public/build/tailwind.css',
},
plugins: [
postcss({
extract: true,
minimize: production,
sourceMap: !production,
}),
],
},
{
input: 'src/query/QueryParserWorker.js',
output: {
+2 -8
View File
@@ -27,7 +27,7 @@
import SettingsListener from './utility/SettingsListener.svelte';
import { handleAuthOnStartup } from './clientAuth';
import { initializeAppUpdates } from './utility/appUpdate';
import { _t, getCurrentTranslations, saveSelectedLanguageToCache } from './translations';
import { _t, saveSelectedLanguageToCache } from './translations';
import { installCloudListeners } from './utility/cloudListeners';
export let isAdminPage = false;
@@ -61,13 +61,7 @@
initializeAppUpdates();
installCloudListeners();
refreshPublicCloudFiles();
saveSelectedLanguageToCache(config.preferrendLanguage);
const electron = getElectron();
if (electron) {
electron.send('translation-data', JSON.stringify(getCurrentTranslations()));
global.TRANSLATION_DATA = getCurrentTranslations();
}
saveSelectedLanguageToCache();
}
loadedApi = loadedApiValue;
+73 -117
View File
@@ -14,7 +14,6 @@
import ErrorInfo from './elements/ErrorInfo.svelte';
import { isOneOfPage } from './utility/pageDefs';
import { openWebLink } from './utility/simpleTools';
import FontIcon from './icons/FontIcon.svelte';
const config = useConfig();
const values = writable({ amoid: null, databaseServer: null });
@@ -23,15 +22,17 @@
$: trialDaysLeft = $config?.trialDaysLeft;
let errorMessage = '';
let expiredMessageSet = false;
let isInsertingLicense = false;
$: trialButtonAvailable = !isExpired && trialDaysLeft == null;
$: if (isExpired && !expiredMessageSet) {
errorMessage = 'Your license is expired';
expiredMessageSet = true;
}
// $: console.log('CONFIG', $config);
$: {
if ($config?.isLicenseValid && trialDaysLeft == null) {
if ($config?.isLicenseValid) {
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
}
}
@@ -40,124 +41,83 @@
<FormProviderCore {values}>
<SpecialPageLayout>
{#if getElectron() || ($config?.storageDatabase && hasPermission('admin/license'))}
<div class="heading">Thank you for using DbGate!</div>
<div class="heading">License</div>
<FormTextAreaField label="Enter your license key" name="licenseKey" rows={5} />
{#if isExpired}
<div class="infotext"><FontIcon icon="img warn" /> Your license has expired. Please insert new license.</div>
{:else if trialDaysLeft > 0}
<div class="infotext">
<FontIcon icon="img warn" /> Your trial period will expire in {trialDaysLeft} day{trialDaysLeft != 1
? 's'
: ''}.
</div>
{:else}
<div class="infotext">
<FontIcon icon="img info" /> Proceed by selecting a licensing option or providing your license key.
</div>
{/if}
<div class="submit">
<FormSubmit
value="Save license"
on:click={async e => {
sessionStorage.setItem('continueTrialConfirmed', '1');
const { licenseKey } = e.detail;
const resp = await apiCall('config/save-license-key', { licenseKey, tryToRenew: true });
if (resp?.status == 'ok') {
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
} else {
errorMessage = resp?.errorMessage || 'Error saving license key';
}
}}
/>
</div>
{#if isInsertingLicense}
<FormTextAreaField label="Enter your license key" name="licenseKey" rows={5} />
<div class="submit">
<div class="flex flex1">
<div class="col-6 flex">
<FormSubmit
value="Save license"
on:click={async e => {
sessionStorage.setItem('continueTrialConfirmed', '1');
const { licenseKey } = e.detail;
const resp = await apiCall('config/save-license-key', { licenseKey, tryToRenew: true });
if (resp?.status == 'ok') {
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
} else {
errorMessage = resp?.errorMessage || 'Error saving license key';
}
}}
/>
</div>
<div class="col-6 flex">
<FormStyledButton
value="Cancel"
on:click={() => {
isInsertingLicense = false;
errorMessage = '';
}}
/>
</div>
</div>
</div>
{/if}
{#if !isInsertingLicense}
{#if !isExpired && trialDaysLeft == null}
<div class="submit">
<FormStyledButton
value="Insert license key"
on:click={() => {
isInsertingLicense = true;
}}
/>
</div>
{#if trialButtonAvailable}
<div class="submit">
<FormStyledButton
value="Start 30-day trial"
on:click={async e => {
errorMessage = '';
const license = await apiCall('config/start-trial');
if (license?.status == 'ok') {
sessionStorage.setItem('continueTrialConfirmed', '1');
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
} else {
errorMessage = license?.errorMessage || 'Error starting trial';
}
}}
/>
</div>
{/if}
{#if trialDaysLeft > 0}
<div class="submit">
<FormStyledButton
value={`Continue trial (${trialDaysLeft} days left)`}
on:click={async e => {
value="Start 30-day trial"
on:click={async e => {
errorMessage = '';
const license = await apiCall('config/start-trial');
if (license?.status == 'ok') {
sessionStorage.setItem('continueTrialConfirmed', '1');
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
}}
/>
</div>
{/if}
<div class="submit">
<FormStyledButton
value="Purchase DbGate Premium"
on:click={async e => {
// openWebLink(
// `https://auth.dbgate.eu/create-checkout-session-simple?source=trial-${isExpired ? 'expired' : (trialDaysLeft ?? 'no')}`
// );
// openWebLink(
// `https://auth-proxy.dbgate.udolni.net/redirect-to-purchase?product=${getElectron() ? 'premium' : 'teram-premium'}&source=trial-${isExpired ? 'expired' : (trialDaysLeft ?? 'no')}`
// );
openWebLink(
`https://auth.dbgate.eu/redirect-to-purchase?product=${getElectron() ? 'premium' : 'team-premium'}&source=trial-${isExpired ? 'expired' : (trialDaysLeft ?? 'no')}`
);
} else {
errorMessage = license?.errorMessage || 'Error starting trial';
}
}}
/>
</div>
{/if}
{#if getElectron()}
<div class="submit">
<FormStyledButton
value="Exit"
on:click={e => {
getElectron().send('quit-app');
}}
/>
</div>
{/if}
{#if trialDaysLeft > 0}
<div class="submit">
<FormStyledButton
value={`Continue trial (${trialDaysLeft} days left)`}
on:click={async e => {
sessionStorage.setItem('continueTrialConfirmed', '1');
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
}}
/>
</div>
{/if}
<div class="submit">
<FormStyledButton
value="Purchase DbGate Premium"
on:click={async e => {
// openWebLink(
// `https://auth.dbgate.eu/create-checkout-session-simple?source=trial-${isExpired ? 'expired' : (trialDaysLeft ?? 'no')}`
// );
// openWebLink(
// `https://auth-proxy.dbgate.udolni.net/redirect-to-purchase?product=${getElectron() ? 'premium' : 'teram-premium'}&source=trial-${isExpired ? 'expired' : (trialDaysLeft ?? 'no')}`
// );
openWebLink(
`https://auth.dbgate.eu/redirect-to-purchase?product=${getElectron() ? 'premium' : 'team-premium'}&source=trial-${isExpired ? 'expired' : (trialDaysLeft ?? 'no')}`
);
}}
/>
</div>
{#if getElectron()}
<div class="submit">
<FormStyledButton
value="Exit"
on:click={e => {
getElectron().send('quit-app');
}}
/>
</div>
{/if}
{#if errorMessage}
@@ -181,10 +141,6 @@
font-size: xx-large;
}
.infotext {
margin: 1em;
}
.submit {
margin: var(--dim-large-form-margin);
display: flex;
+1 -1
View File
@@ -16,7 +16,7 @@
<div class="heading">Configuration error</div>
{#if $config?.checkedLicense?.status == 'error'}
<ErrorInfo
message={`Invalid license. Please contact sales@dbgate.io for more details. ${$config?.checkedLicense?.error || ''}`}
message={`Invalid license. Please contact sales@dbgate.io for more details. ${$config?.checkedLicense?.error}`}
/>
{:else if $config?.configurationError}
<ErrorInfo message={$config?.configurationError} />
+4 -4
View File
@@ -335,13 +335,13 @@
border-radius: 5px;
cursor: pointer;
border: var(--theme-formbutton-border);
background: var(--theme-formbutton-background);
color: var(--theme-formbutton-foreground);
border: 1px solid var(--theme-bg-button-inv-3);
background-color: var(--theme-bg-button-inv-2);
color: var(--theme-font-inv-1);
}
.loginButton:hover {
background: var(--theme-formbutton-background-hover);
background-color: var(--theme-bg-button-inv-3);
}
.login-link {
+31 -47
View File
@@ -2,6 +2,8 @@
import WidgetContainer from './widgets/WidgetContainer.svelte';
import WidgetIconPanel from './widgets/WidgetIconPanel.svelte';
import {
currentTheme,
currentThemeDefinition,
isFileDragActive,
leftPanelWidth,
openedSnackbars,
@@ -9,10 +11,13 @@
visibleWidgetSideBar,
visibleCommandPalette,
visibleTitleBar,
rightPanelWidget,
rightPanelWidth,
visibleToolbar,
systemThemeStore,
} from './stores';
import TabsPanel from './tabpanel/TabsPanel.svelte';
import TabRegister from './tabpanel/TabRegister.svelte';
import CommandPalette from './commands/CommandPalette.svelte';
import Toolbar from './widgets/Toolbar.svelte';
import splitterDrag from './utility/splitterDrag';
import CurrentDropDownMenu from './modals/CurrentDropDownMenu.svelte';
import StatusBar from './widgets/StatusBar.svelte';
@@ -23,15 +28,22 @@
import TitleBar from './widgets/TitleBar.svelte';
import FontIcon from './icons/FontIcon.svelte';
import getElectron from './utility/getElectron';
import TabsContainer from './tabpanel/TabsContainer.svelte';
import MultiTabsContainer from './tabpanel/MultiTabsContainer.svelte';
import { currentThemeType } from './plugins/themes';
import RightWidgetContainer from './widgets/RightWidgetContainer.svelte';
$: currentThemeTypeClass = $currentThemeType == 'dark' ? 'theme-type-dark' : 'theme-type-light';
$: currentThemeType = $currentThemeDefinition?.themeType == 'dark' ? 'theme-type-dark' : 'theme-type-light';
$: themeStyle = `<st` + `yle id="themePlugin">${$currentThemeDefinition?.themeCss}</st` + `yle>`;
const isElectron = !!getElectron();
</script>
<svelte:head>
{#if $currentThemeDefinition?.themeCss}
{@html themeStyle}
{/if}
</svelte:head>
<div class="not-supported" class:isElectron>
<div class="m-5 big-icon"><FontIcon icon="img warn" /></div>
<div class="m-3">Sorry, DbGate is not supported on mobile devices.</div>
@@ -39,7 +51,7 @@
</div>
<div
class={`${currentThemeTypeClass} root dbgate-screen`}
class={`${$currentTheme ?? $systemThemeStore} ${currentThemeType} root dbgate-screen`}
class:isElectron
use:dragDropFileTarget
on:contextmenu={e => e.preventDefault()}
@@ -65,28 +77,21 @@
</div>
{#if $selectedWidget && $visibleWidgetSideBar}
<div
class="horizontal-split-handle left-splitter"
class="horizontal-split-handle splitter"
use:splitterDrag={'clientX'}
on:resizeSplitter={e => leftPanelWidth.update(x => x + e.detail)}
/>
{/if}
{#if $rightPanelWidget}
<div
class="horizontal-split-handle right-splitter"
use:splitterDrag={'clientX'}
on:resizeSplitter={e => rightPanelWidth.update(x => x - e.detail)}
/>
{/if}
{#if $rightPanelWidget}
<div class="rightpanel">
<RightWidgetContainer />
</div>
{/if}
{#if $visibleCommandPalette}
<div class="commads">
<CommandPalette />
</div>
{/if}
{#if $visibleToolbar}
<div class="toolbar">
<Toolbar />
</div>
{/if}
<CurrentDropDownMenu />
<ModalLayer />
{#if $isFileDragActive}
@@ -101,7 +106,7 @@
<style>
.root {
color: var(--theme-generic-font);
color: var(--theme-font-1);
}
.iconbar {
position: fixed;
@@ -110,11 +115,11 @@
top: var(--dim-header-top);
bottom: var(--dim-statusbar-height);
width: var(--dim-widget-icon-size);
background: var(--theme-widget-panel-background);
background: var(--theme-bg-inv-1);
}
.statusbar {
position: fixed;
background: var(--theme-statusbar-background);
background: var(--theme-bg-statusbar-inv);
height: var(--dim-statusbar-height);
left: 0;
right: 0;
@@ -127,22 +132,8 @@
left: var(--dim-widget-icon-size);
bottom: var(--dim-statusbar-height);
width: var(--dim-left-panel-width);
background-color: var(--theme-sidebar-background);
color: var(--theme-sidebar-foreground);
background-color: var(--theme-bg-1);
display: flex;
border-right: var(--theme-sidebar-border);
}
.rightpanel {
position: fixed;
top: var(--dim-header-top);
right: 0;
bottom: var(--dim-statusbar-height);
width: var(--dim-right-panel-width);
background-color: var(--theme-altsidebar-background);
color: var(--theme-altsidebar-foreground);
display: flex;
border-left: var(--theme-altsidebar-border);
}
.commads {
position: fixed;
@@ -158,20 +149,13 @@
background: var(--theme-bg-1);
}
.left-splitter {
.splitter {
position: absolute;
top: var(--dim-header-top);
bottom: var(--dim-statusbar-height);
left: calc(var(--dim-widget-icon-size) + var(--dim-left-panel-width));
}
.right-splitter {
position: absolute;
top: var(--dim-header-top);
bottom: var(--dim-statusbar-height);
right: var(--dim-content-right);
}
.snackbar-container {
z-index: 1000;
position: fixed;
@@ -213,7 +197,7 @@
top: var(--dim-header-top);
left: var(--dim-content-left);
bottom: var(--dim-statusbar-height);
right: var(--dim-content-right);
background-color: var(--theme-content-background);
right: 0;
background-color: var(--theme-bg-1);
}
</style>
@@ -7,7 +7,6 @@
export let onSetPermission;
export let label;
export let folder;
export let disabled = false;
</script>
<PermissionCheckBox
@@ -16,7 +15,6 @@
permissions={$values.permissions}
basePermissions={$values.basePermissions}
{onSetPermission}
{disabled}
/>
<div class="ml-4">
@@ -26,7 +24,6 @@
permissions={$values.permissions}
basePermissions={$values.basePermissions}
{onSetPermission}
{disabled}
/>
<PermissionCheckBox
label="Write"
@@ -34,6 +31,5 @@
permissions={$values.permissions}
basePermissions={$values.basePermissions}
{onSetPermission}
{disabled}
/>
</div>
@@ -1 +0,0 @@
This component is only for Premium edition
@@ -53,15 +53,14 @@
import InputTextModal from '../modals/InputTextModal.svelte';
import ConfirmModal from '../modals/ConfirmModal.svelte';
import { apiCall } from '../utility/api';
import { _t } from '../translations';
export let data;
const handleRename = () => {
showModal(InputTextModal, {
value: data.fileName,
label: _t('appFile.newFileName', { defaultMessage: 'New file name' }),
header: _t('appFile.renameFile', { defaultMessage: 'Rename file' }),
label: 'New file name',
header: 'Rename file',
onConfirm: newFile => {
apiCall('apps/rename-file', {
file: data.fileName,
@@ -75,7 +74,7 @@
const handleDelete = () => {
showModal(ConfirmModal, {
message: _t('appFile.deleteFileConfirm', { defaultMessage: 'Really delete file {fileName}?', values: { fileName: data.fileName } }),
message: `Really delete file ${data.fileName}?`,
onConfirm: () => {
apiCall('apps/delete-file', {
file: data.fileName,
@@ -102,10 +101,10 @@
function createMenu() {
return [
{ text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
{ text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
data.fileType.endsWith('.sql') && { text: _t('common.openSql', { defaultMessage: 'Open SQL' }), onClick: handleOpenSqlFile },
data.fileType.endsWith('.json') && { text: _t('common.openJson', { defaultMessage: 'Open JSON' }), onClick: handleOpenJsonFile },
{ text: 'Delete', onClick: handleDelete },
{ text: 'Rename', onClick: handleRename },
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile },
data.fileType.endsWith('.json') && { text: 'Open JSON', onClick: handleOpenJsonFile },
// data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile },
];
@@ -15,7 +15,6 @@
import InputTextModal from '../modals/InputTextModal.svelte';
import { apiCall } from '../utility/api';
import { useConnectionList } from '../utility/metadataLoaders';
import { _t } from '../translations';
export let data;
@@ -35,8 +34,8 @@
showModal(InputTextModal, {
value: name,
label: _t('appFolder.newApplicationName', { defaultMessage: 'New application name' }),
header: _t('appFolder.renameApplication', { defaultMessage: 'Rename application' }),
label: 'New application name',
header: 'Rename application',
onConfirm: async newFolder => {
await apiCall('apps/rename-folder', {
folder: data.name,
@@ -61,16 +60,16 @@
function createMenu() {
return [
{ text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
{ text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
{ text: 'Delete', onClick: handleDelete },
{ text: 'Rename', onClick: handleRename },
$currentDatabase && [
!isOnCurrentDb($currentDatabase, $connections) && {
text: _t('appFolder.enableOnCurrentDatabase', { defaultMessage: 'Enable on current database' }),
text: 'Enable on current database',
onClick: () => setOnCurrentDb(true),
},
isOnCurrentDb($currentDatabase, $connections) && {
text: _t('appFolder.disableOnCurrentDatabase', { defaultMessage: 'Disable on current database' }),
text: 'Disable on current database',
onClick: () => setOnCurrentDb(false),
},
],
@@ -91,7 +90,7 @@
title={data.name}
icon={'img app'}
statusIcon={isOnCurrentDb($currentDatabase, $connections) ? 'icon check' : null}
statusTitle={_t('appFolder.applicationUsedForDatabase', { defaultMessage: 'Application {application} is used for database {database}', values: { application: data.name, database: $currentDatabase?.name } })}
statusTitle={`Application ${data.name} is used for database ${$currentDatabase?.name}`}
isBold={data.name == $currentApplication}
on:click={() => ($currentApplication = data.name)}
menu={createMenu}
+11 -12
View File
@@ -213,20 +213,20 @@
position: relative;
}
.main:hover:not(.disableHover) {
background-color: var(--theme-sidebar-background-hover);
background-color: var(--theme-bg-hover);
}
.isBold {
font-weight: bold;
}
.isGrayed {
color: var(--theme-generic-font-grayed);
color: var(--theme-font-3);
}
.isChoosed {
background-color: var(--theme-sidebar-background-active);
background-color: var(--theme-bg-3);
}
:global(.app-object-list-focused) .isChoosed {
background-color: var(--theme-sidebar-background-focused);
background-color: var(--theme-bg-selected);
}
.status {
margin-left: 5px;
@@ -234,24 +234,23 @@
.ext-info {
font-weight: normal;
margin-left: 5px;
color: var(--theme-sidebar-foreground-grayed);
color: var(--theme-font-3);
}
.expand-icon {
margin-right: 3px;
}
.pin,
.pin-active,
.unpin {
.pin-active {
z-index: 150;
position: absolute;
right: 0;
}
.pin {
color: var(--theme-sidebar-foreground-button);
color: var(--theme-font-2);
}
.pin:hover {
color: var(--theme-sidebar-foreground-hover);
color: var(--theme-font-hover);
}
.main .pin {
visibility: hidden;
@@ -261,13 +260,13 @@
}
.unpin {
color: var(--theme-sidebar-foreground-button);
color: var(--theme-font-2);
}
.unpin:hover {
color: var(--theme-sidebar-foreground-hover);
color: var(--theme-font-hover);
}
.pin-active {
color: var(--theme-sidebar-foreground-button);
color: var(--theme-font-2);
}
</style>

Some files were not shown because too many files have changed in this diff Show More