Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ff830f5b0 | |||
| 7214516950 | |||
| c6cbd77b88 | |||
| 5535bf91a1 |
@@ -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: |
|
||||
|
||||
@@ -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: |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 =
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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');
|
||||
})();
|
||||
@@ -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',
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,4 +1,3 @@
|
||||
module.exports = {
|
||||
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
@@ -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,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');
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Vendored
-54
@@ -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
|
||||
@@ -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",
|
||||
|
||||
@@ -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',
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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": [],
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2,5 +2,4 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleFileExtensions: ['js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -25,4 +25,3 @@ export * from './CustomGridDisplay';
|
||||
export * from './ScriptDrivedDeployer';
|
||||
export * from './chartDefinitions';
|
||||
export * from './chartProcessor';
|
||||
export * from './ChangeSetRedis';
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,5 +2,4 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleFileExtensions: ['js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
@@ -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}"`;
|
||||
}
|
||||
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -2,5 +2,4 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleFileExtensions: ['js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ export const mongoFilterBehaviour: FilterBehaviour = {
|
||||
allowStringToken: true,
|
||||
allowNumberDualTesting: true,
|
||||
allowObjectIdTesting: true,
|
||||
allowHexString: true,
|
||||
};
|
||||
|
||||
export const evalFilterBehaviour: FilterBehaviour = {
|
||||
|
||||
@@ -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' },
|
||||
];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Vendored
-1
@@ -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);
|
||||
|
||||
|
||||
Vendored
-13
@@ -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;
|
||||
|
||||
Vendored
+3
-3
@@ -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[];
|
||||
}
|
||||
|
||||
Vendored
-2
@@ -96,6 +96,4 @@ export type TestEngineInfo = {
|
||||
}>;
|
||||
|
||||
objects?: Array<TestObjectInfo>;
|
||||
|
||||
binaryDataType?: string;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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} />
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user