Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a3d9fe76d6 | |||
| 0f4f154637 | |||
| 7d112a208f | |||
| c867d39d8d | |||
| 83b6c939f7 | |||
| e1e4eb5d6f | |||
| a14c08f122 | |||
| 5fd50dcf45 | |||
| b2ac4ee245 | |||
| 0ad7c0546b | |||
| 748381fef3 | |||
| 7eb9e42210 | |||
| 36a4b67ef4 | |||
| 94b35e3d5f | |||
| c5aa82b76a | |||
| c2920e195f | |||
| 92a78a419e | |||
| 4f27c2b852 | |||
| ece5779b41 | |||
| 167aaa8491 | |||
| de622b055b | |||
| 7e88b930ec | |||
| c9adc2b852 | |||
| 91d3aba611 | |||
| 48bc11dcb5 | |||
| 9ee0b32cac | |||
| 4b6b74604b | |||
| 7ad3fc4751 | |||
| e604450cfb | |||
| 9cfbc83896 | |||
| 98b2f4ec35 | |||
| 47e30f2daf | |||
| 6c21da6959 | |||
| c5fe71d390 | |||
| d14ffcb736 | |||
| e694aca70b | |||
| 3c58cb1b9c | |||
| dc452cdadf | |||
| e855365cbb | |||
| cffa288227 | |||
| 89ddced342 | |||
| 7457328b59 | |||
| 44ff413810 | |||
| d174c2c2d8 | |||
| 480f4c9a8c | |||
| 7474cc5d8a | |||
| bda5c4f5dd | |||
| 4f5034c167 | |||
| 9470db1f4d | |||
| dfeb910ac9 | |||
| a5745795be | |||
| 98f2b5dd08 | |||
| f642c7570e | |||
| dca9ea24d7 | |||
| 43fd7b6000 | |||
| 1553ec3bd4 | |||
| 37d54811e0 | |||
| 0f2af6eb37 | |||
| 91546228fa | |||
| 5488ff06e0 | |||
| ef7f050bc5 | |||
| e5c94d9698 | |||
| d6ae3d4f16 | |||
| 9c1819467a | |||
| 417334d140 | |||
| aa7fb74312 |
@@ -43,7 +43,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- 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: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- 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: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 6195e103e1d45e4f59bade60df5dd1784f4e6c77
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -8,6 +8,19 @@ Builds:
|
||||
- linux - application for linux
|
||||
- win - application for Windows
|
||||
|
||||
## 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
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@
|
||||
"devDependencies": {
|
||||
"copyfiles": "^2.2.0",
|
||||
"cross-env": "^6.0.3",
|
||||
"electron": "30.0.2",
|
||||
"electron": "38.6.0",
|
||||
"electron-builder": "25.1.8"
|
||||
}
|
||||
}
|
||||
|
||||
+11
-8
@@ -85,7 +85,7 @@ function formatKeyText(keyText) {
|
||||
return keyText.replace('CtrlOrCommand+', 'Ctrl+');
|
||||
}
|
||||
|
||||
function commandItem(item) {
|
||||
function commandItem(item, disableAll = false) {
|
||||
const id = item.command;
|
||||
const command = commands[id];
|
||||
if (item.skipInApp) {
|
||||
@@ -95,7 +95,7 @@ function commandItem(item) {
|
||||
id,
|
||||
label: command ? command.menuName || command.toolbarName || command.name : id,
|
||||
accelerator: formatKeyText(command ? command.keyText : undefined),
|
||||
enabled: command ? command.enabled : false,
|
||||
enabled: command ? command.enabled && !disableAll : false,
|
||||
click() {
|
||||
if (mainWindow) {
|
||||
mainWindow.webContents.send('run-command', id);
|
||||
@@ -107,14 +107,14 @@ function commandItem(item) {
|
||||
};
|
||||
}
|
||||
|
||||
function buildMenu() {
|
||||
function buildMenu(disableAll = false) {
|
||||
let template = _cloneDeepWith(mainMenuDefinition({ editMenu: true, isMac: isMac() }), item => {
|
||||
if (item.divider) {
|
||||
return { type: 'separator' };
|
||||
}
|
||||
|
||||
if (item.command) {
|
||||
return commandItem(item);
|
||||
return commandItem(item, disableAll);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -129,7 +129,7 @@ function buildMenu() {
|
||||
{
|
||||
label: 'DbGate',
|
||||
submenu: [
|
||||
commandItem({ command: 'about.show' }),
|
||||
commandItem({ command: 'about.show' }, disableAll),
|
||||
{ role: 'services' },
|
||||
{ role: 'hide' },
|
||||
{ role: 'hideOthers' },
|
||||
@@ -145,7 +145,10 @@ function buildMenu() {
|
||||
}
|
||||
|
||||
ipcMain.on('update-commands', async (event, arg) => {
|
||||
commands = JSON.parse(arg);
|
||||
const parsed = JSON.parse(arg);
|
||||
commands = parsed.commands;
|
||||
const isModalOpened = parsed.isModalOpened;
|
||||
const dbgatePage = parsed.dbgatePage;
|
||||
for (const key of Object.keys(commands)) {
|
||||
const menu = mainMenu.getMenuItemById(key);
|
||||
if (!menu) continue;
|
||||
@@ -153,14 +156,14 @@ ipcMain.on('update-commands', async (event, arg) => {
|
||||
|
||||
// rebuild menu
|
||||
if (menu.label != command.text || menu.accelerator != command.keyText) {
|
||||
mainMenu = buildMenu();
|
||||
mainMenu = buildMenu(isModalOpened || !!dbgatePage);
|
||||
|
||||
Menu.setApplicationMenu(mainMenu);
|
||||
// mainWindow.setMenu(mainMenu);
|
||||
return;
|
||||
}
|
||||
|
||||
menu.enabled = command.enabled;
|
||||
menu.enabled = command.enabled && !isModalOpened && !dbgatePage;
|
||||
}
|
||||
});
|
||||
ipcMain.on('quit-app', async (event, arg) => {
|
||||
|
||||
+279
-224
@@ -16,9 +16,9 @@
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
"@electron/asar@^3.2.7":
|
||||
version "3.2.17"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.17.tgz#91d28087aad80d1a1c8cc4e667c6476edf50f949"
|
||||
integrity sha512-OcWImUI686w8LkghQj9R2ynZ2ME693Ek6L1SiaAgqGKzBaTIZw3fHDqN82Rcl+EU1Gm9EgkJ5KLIY/q5DCRbbA==
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.4.1.tgz#4e9196a4b54fba18c56cd8d5cac67c5bdc588065"
|
||||
integrity sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==
|
||||
dependencies:
|
||||
commander "^5.0.0"
|
||||
glob "^7.1.6"
|
||||
@@ -98,6 +98,18 @@
|
||||
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"
|
||||
@@ -202,16 +214,23 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/ms@*":
|
||||
version "0.7.34"
|
||||
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
|
||||
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78"
|
||||
integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==
|
||||
|
||||
"@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==
|
||||
"@types/node@*":
|
||||
version "24.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.0.tgz#6b79086b0dfc54e775a34ba8114dcc4e0221f31f"
|
||||
integrity sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
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"
|
||||
|
||||
"@types/plist@^3.0.1":
|
||||
version "3.0.5"
|
||||
@@ -229,9 +248,9 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/verror@^1.10.3":
|
||||
version "1.10.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.10.tgz#d5a4b56abac169bfbc8b23d291363a682e6fa087"
|
||||
integrity sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==
|
||||
version "1.10.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.11.tgz#d3d6b418978c8aa202d41e5bb3483227b6ecc1bb"
|
||||
integrity sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==
|
||||
|
||||
"@types/yauzl@^2.9.1":
|
||||
version "2.10.3"
|
||||
@@ -241,9 +260,9 @@
|
||||
"@types/node" "*"
|
||||
|
||||
"@xmldom/xmldom@^0.8.8":
|
||||
version "0.8.10"
|
||||
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99"
|
||||
integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==
|
||||
version "0.8.11"
|
||||
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608"
|
||||
integrity sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==
|
||||
|
||||
"@yarnpkg/lockfile@^1.1.0":
|
||||
version "1.1.0"
|
||||
@@ -263,14 +282,14 @@ agent-base@6, agent-base@^6.0.2:
|
||||
debug "4"
|
||||
|
||||
agent-base@^7.1.0, agent-base@^7.1.2:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1"
|
||||
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8"
|
||||
integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==
|
||||
|
||||
agentkeepalive@^4.2.1:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
|
||||
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a"
|
||||
integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==
|
||||
dependencies:
|
||||
humanize-ms "^1.2.1"
|
||||
|
||||
@@ -303,9 +322,9 @@ ansi-regex@^5.0.1:
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-regex@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654"
|
||||
integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==
|
||||
version "6.2.2"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1"
|
||||
integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==
|
||||
|
||||
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
@@ -315,9 +334,9 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
ansi-styles@^6.1.0:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
|
||||
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
|
||||
version "6.2.3"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041"
|
||||
integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==
|
||||
|
||||
app-builder-bin@5.0.0-alpha.10:
|
||||
version "5.0.0-alpha.10"
|
||||
@@ -363,9 +382,9 @@ app-builder-lib@25.1.8:
|
||||
temp-file "^3.4.0"
|
||||
|
||||
"aproba@^1.0.3 || ^2.0.0":
|
||||
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==
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.1.0.tgz#75500a190313d95c64e871e7e4284c6ac219f0b1"
|
||||
integrity sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==
|
||||
|
||||
are-we-there-yet@^3.0.0:
|
||||
version "3.0.1"
|
||||
@@ -395,10 +414,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.3:
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66"
|
||||
integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==
|
||||
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==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
@@ -447,33 +466,33 @@ boolean@^3.0.1:
|
||||
integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
version "1.1.12"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843"
|
||||
integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7"
|
||||
integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
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==
|
||||
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==
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
fill-range "^7.1.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==
|
||||
@@ -499,10 +518,10 @@ builder-util-runtime@9.2.10:
|
||||
debug "^4.3.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
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==
|
||||
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==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
sax "^1.2.4"
|
||||
@@ -571,7 +590,15 @@ cacheable-request@^7.0.2:
|
||||
normalize-url "^6.0.1"
|
||||
responselike "^2.0.0"
|
||||
|
||||
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
|
||||
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:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
@@ -744,9 +771,9 @@ cross-env@^6.0.3:
|
||||
cross-spawn "^7.0.0"
|
||||
|
||||
cross-spawn@^6.0.5:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
version "6.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57"
|
||||
integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
@@ -754,26 +781,19 @@ 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:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
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==
|
||||
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.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==
|
||||
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==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
@@ -825,9 +845,9 @@ delegates@^1.0.0:
|
||||
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
||||
|
||||
detect-libc@^2.0.1:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
|
||||
integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"
|
||||
integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
|
||||
|
||||
detect-node@^2.0.4:
|
||||
version "2.1.0"
|
||||
@@ -878,9 +898,18 @@ dotenv-expand@^11.0.6:
|
||||
dotenv "^16.4.5"
|
||||
|
||||
dotenv@^16.4.5:
|
||||
version "16.4.7"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26"
|
||||
integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==
|
||||
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"
|
||||
|
||||
eastasianwidth@^0.2.0:
|
||||
version "0.2.0"
|
||||
@@ -936,11 +965,11 @@ electron-publish@25.1.7:
|
||||
mime "^2.5.2"
|
||||
|
||||
electron-updater@^6.3.4:
|
||||
version "6.3.4"
|
||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.3.4.tgz#3934bc89875bb524c2cbbd11041114e97c0c2496"
|
||||
integrity sha512-uZUo7p1Y53G4tl6Cgw07X1yF8Jlz6zhaL7CQJDZ1fVVkOaBfE2cWtx80avwDVi8jHp+I/FWawrMgTAeCCNIfAg==
|
||||
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==
|
||||
dependencies:
|
||||
builder-util-runtime "9.2.5"
|
||||
builder-util-runtime "9.3.1"
|
||||
fs-extra "^10.1.0"
|
||||
js-yaml "^4.1.0"
|
||||
lazy-val "^1.0.5"
|
||||
@@ -949,13 +978,13 @@ electron-updater@^6.3.4:
|
||||
semver "^7.6.3"
|
||||
tiny-typed-emitter "^2.1.0"
|
||||
|
||||
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==
|
||||
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==
|
||||
dependencies:
|
||||
"@electron/get" "^2.0.0"
|
||||
"@types/node" "^20.9.0"
|
||||
"@types/node" "^22.7.7"
|
||||
extract-zip "^2.0.1"
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
@@ -976,9 +1005,9 @@ encoding@^0.1.13:
|
||||
iconv-lite "^0.6.2"
|
||||
|
||||
end-of-stream@^1.1.0:
|
||||
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==
|
||||
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==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
@@ -992,27 +1021,42 @@ 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:
|
||||
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-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-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.1.2"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
|
||||
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
|
||||
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
@@ -1020,9 +1064,9 @@ escape-string-regexp@^4.0.0:
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
exponential-backoff@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6"
|
||||
integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==
|
||||
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==
|
||||
|
||||
extract-zip@^2.0.1:
|
||||
version "2.0.1"
|
||||
@@ -1064,10 +1108,10 @@ filelist@^1.0.4:
|
||||
dependencies:
|
||||
minimatch "^5.0.1"
|
||||
|
||||
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==
|
||||
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==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
@@ -1079,20 +1123,22 @@ find-yarn-workspace-root@^2.0.0:
|
||||
micromatch "^4.0.2"
|
||||
|
||||
foreground-child@^3.1.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77"
|
||||
integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f"
|
||||
integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.0"
|
||||
cross-spawn "^7.0.6"
|
||||
signal-exit "^4.0.1"
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
|
||||
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
|
||||
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:
|
||||
@@ -1105,9 +1151,9 @@ fs-extra@^10.0.0, fs-extra@^10.1.0:
|
||||
universalify "^2.0.0"
|
||||
|
||||
fs-extra@^11.1.1:
|
||||
version "11.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b"
|
||||
integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==
|
||||
version "11.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4"
|
||||
integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^6.0.1"
|
||||
@@ -1168,16 +1214,29 @@ 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.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==
|
||||
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==
|
||||
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"
|
||||
has-proto "^1.0.1"
|
||||
has-symbols "^1.0.3"
|
||||
hasown "^2.0.0"
|
||||
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"
|
||||
|
||||
get-stream@^5.1.0:
|
||||
version "5.2.0"
|
||||
@@ -1241,12 +1300,10 @@ globalthis@^1.0.1:
|
||||
define-properties "^1.2.1"
|
||||
gopd "^1.0.1"
|
||||
|
||||
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"
|
||||
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==
|
||||
|
||||
got@^11.7.0, got@^11.8.5:
|
||||
version "11.8.6"
|
||||
@@ -1282,22 +1339,24 @@ has-property-descriptors@^1.0.0:
|
||||
dependencies:
|
||||
es-define-property "^1.0.0"
|
||||
|
||||
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-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-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-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-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.0:
|
||||
hasown@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
|
||||
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
|
||||
@@ -1312,9 +1371,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.1.1"
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
|
||||
integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5"
|
||||
integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==
|
||||
|
||||
http-proxy-agent@^5.0.0:
|
||||
version "5.0.0"
|
||||
@@ -1412,13 +1471,10 @@ 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@^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"
|
||||
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==
|
||||
|
||||
is-ci@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -1487,9 +1543,9 @@ isbinaryfile@^4.0.8:
|
||||
integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==
|
||||
|
||||
isbinaryfile@^5.0.0:
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.4.tgz#2a2edefa76cafa66613fe4c1ea52f7f031017bdf"
|
||||
integrity sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==
|
||||
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==
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -1506,14 +1562,13 @@ jackspeak@^3.1.2:
|
||||
"@pkgjs/parseargs" "^0.11.0"
|
||||
|
||||
jake@^10.8.5:
|
||||
version "10.9.1"
|
||||
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.1.tgz#8dc96b7fcc41cb19aa502af506da4e1d56f5e62b"
|
||||
integrity sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==
|
||||
version "10.9.4"
|
||||
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.4.tgz#d626da108c63d5cfb00ab5c25fadc7e0084af8e6"
|
||||
integrity sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==
|
||||
dependencies:
|
||||
async "^3.2.3"
|
||||
chalk "^4.0.2"
|
||||
async "^3.2.6"
|
||||
filelist "^1.0.4"
|
||||
minimatch "^3.1.2"
|
||||
picocolors "^1.1.1"
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
@@ -1522,11 +1577,6 @@ 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"
|
||||
@@ -1555,9 +1605,9 @@ jsonfile@^4.0.0:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62"
|
||||
integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==
|
||||
dependencies:
|
||||
universalify "^2.0.0"
|
||||
optionalDependencies:
|
||||
@@ -1580,11 +1630,11 @@ jsonwebtoken@^9.0.2:
|
||||
semver "^7.5.4"
|
||||
|
||||
jwa@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
|
||||
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.2.tgz#16011ac6db48de7b102777e57897901520eec7b9"
|
||||
integrity sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==
|
||||
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"
|
||||
|
||||
@@ -1729,12 +1779,17 @@ 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.5"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
|
||||
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
|
||||
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
|
||||
dependencies:
|
||||
braces "^3.0.2"
|
||||
braces "^3.0.3"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
mime-db@1.52.0:
|
||||
@@ -1770,13 +1825,13 @@ mimic-response@^3.1.0:
|
||||
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
|
||||
|
||||
minimatch@^10.0.0:
|
||||
version "10.0.1"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b"
|
||||
integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==
|
||||
version "10.1.1"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.1.1.tgz#e6e61b9b0c1dcab116b5a7d1458e8b6ae9e73a55"
|
||||
integrity sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
"@isaacs/brace-expansion" "^5.0.0"
|
||||
|
||||
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
|
||||
minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
@@ -1871,11 +1926,6 @@ 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"
|
||||
@@ -1892,9 +1942,9 @@ nice-try@^1.0.4:
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-abi@^3.45.0:
|
||||
version "3.71.0"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.71.0.tgz#52d84bbcd8575efb71468fbaa1f9a49b2c242038"
|
||||
integrity sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==
|
||||
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==
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
@@ -1904,9 +1954,9 @@ node-addon-api@^1.6.3:
|
||||
integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==
|
||||
|
||||
node-api-version@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.0.tgz#5177441da2b1046a4d4547ab9e0972eed7b1ac1d"
|
||||
integrity sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==
|
||||
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==
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
@@ -2081,6 +2131,11 @@ 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"
|
||||
@@ -2119,9 +2174,9 @@ promise-retry@^2.0.1:
|
||||
retry "^0.12.0"
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d"
|
||||
integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==
|
||||
dependencies:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
@@ -2261,9 +2316,9 @@ sanitize-filename@^1.6.3:
|
||||
truncate-utf8-bytes "^1.0.0"
|
||||
|
||||
sax@^1.2.4:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
|
||||
integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.3.tgz#fcebae3b756cdc8428321805f4b70f16ec0ab5db"
|
||||
integrity sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==
|
||||
|
||||
semver-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -2280,15 +2335,10 @@ 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:
|
||||
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==
|
||||
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==
|
||||
|
||||
serialize-error@^7.0.1:
|
||||
version "7.0.1"
|
||||
@@ -2372,11 +2422,11 @@ socks-proxy-agent@^7.0.0:
|
||||
socks "^2.6.2"
|
||||
|
||||
socks@^2.6.2:
|
||||
version "2.8.3"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5"
|
||||
integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==
|
||||
version "2.8.7"
|
||||
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea"
|
||||
integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==
|
||||
dependencies:
|
||||
ip-address "^9.0.5"
|
||||
ip-address "^10.0.1"
|
||||
smart-buffer "^4.2.0"
|
||||
|
||||
source-map-support@^0.5.19:
|
||||
@@ -2392,7 +2442,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.3:
|
||||
sprintf-js@^1.1.2:
|
||||
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==
|
||||
@@ -2454,9 +2504,9 @@ string_decoder@~1.1.1:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^7.0.1:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
|
||||
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
|
||||
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==
|
||||
dependencies:
|
||||
ansi-regex "^6.0.1"
|
||||
|
||||
@@ -2522,9 +2572,9 @@ tmp@^0.0.33:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
tmp@^0.2.0:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae"
|
||||
integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8"
|
||||
integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
@@ -2546,14 +2596,19 @@ type-fest@^0.13.1:
|
||||
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
|
||||
|
||||
typescript@^5.4.3:
|
||||
version "5.7.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6"
|
||||
integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==
|
||||
version "5.9.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
|
||||
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
|
||||
|
||||
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==
|
||||
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==
|
||||
|
||||
unique-filename@^2.0.0:
|
||||
version "2.0.1"
|
||||
@@ -2592,9 +2647,9 @@ uri-js@^4.2.2:
|
||||
punycode "^2.1.0"
|
||||
|
||||
utf8-byte-length@^1.0.1:
|
||||
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==
|
||||
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==
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
|
||||
@@ -49,6 +49,32 @@ 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);
|
||||
@@ -223,4 +249,51 @@ 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);
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -44,6 +44,7 @@ const mysqlEngine = {
|
||||
supportRenameSqlObject: false,
|
||||
dbSnapshotBySeconds: true,
|
||||
dumpFile: 'data/chinook-mysql.sql',
|
||||
binaryDataType: 'blob',
|
||||
dumpChecks: [
|
||||
{
|
||||
sql: 'select count(*) as res from genre',
|
||||
@@ -216,6 +217,7 @@ const postgreSqlEngine = {
|
||||
supportSchemas: true,
|
||||
supportRenameSqlObject: true,
|
||||
defaultSchemaName: 'public',
|
||||
binaryDataType: 'bytea',
|
||||
dumpFile: 'data/chinook-postgre.sql',
|
||||
dumpChecks: [
|
||||
{
|
||||
@@ -446,6 +448,7 @@ const sqlServerEngine = {
|
||||
supportTableComments: true,
|
||||
supportColumnComments: true,
|
||||
// skipSeparateSchemas: true,
|
||||
binaryDataType: 'varbinary(100)',
|
||||
triggers: [
|
||||
{
|
||||
testName: 'triggers before each row',
|
||||
@@ -506,6 +509,7 @@ const sqliteEngine = {
|
||||
},
|
||||
},
|
||||
],
|
||||
binaryDataType: 'blob',
|
||||
};
|
||||
|
||||
const libsqlFileEngine = {
|
||||
@@ -619,6 +623,7 @@ const oracleEngine = {
|
||||
},
|
||||
},
|
||||
],
|
||||
binaryDataType: 'blob',
|
||||
};
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo} */
|
||||
@@ -752,18 +757,18 @@ const enginesOnCi = [
|
||||
const enginesOnLocal = [
|
||||
// all engines, which would be run on local test
|
||||
// cassandraEngine,
|
||||
// mysqlEngine,
|
||||
//mysqlEngine,
|
||||
// mariaDbEngine,
|
||||
// postgreSqlEngine,
|
||||
// sqlServerEngine,
|
||||
// sqliteEngine,
|
||||
//postgreSqlEngine,
|
||||
//sqlServerEngine,
|
||||
sqliteEngine,
|
||||
// cockroachDbEngine,
|
||||
// clickhouseEngine,
|
||||
// libsqlFileEngine,
|
||||
// libsqlWsEngine,
|
||||
// oracleEngine,
|
||||
//oracleEngine,
|
||||
// duckdbEngine,
|
||||
firebirdEngine,
|
||||
//firebirdEngine,
|
||||
];
|
||||
|
||||
/** @type {import('dbgate-types').TestEngineInfo[] & Record<string, import('dbgate-types').TestEngineInfo>} */
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "6.6.9",
|
||||
"version": "6.6.12-premium-beta.5",
|
||||
"name": "dbgate-all",
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
|
||||
+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
|
||||
|
||||
@@ -29,7 +29,17 @@ const generateDeploySql = require('../shell/generateDeploySql');
|
||||
const { createTwoFilesPatch } = require('diff');
|
||||
const diff2htmlPage = require('../utility/diff2htmlPage');
|
||||
const processArgs = require('../utility/processArgs');
|
||||
const { testConnectionPermission, hasPermission, loadPermissionsFromRequest, loadTablePermissionsFromRequest, getTablePermissionRole, loadDatabasePermissionsFromRequest, getDatabasePermissionRole, getTablePermissionRoleLevelIndex, testDatabaseRolePermission } = require('../utility/hasPermission');
|
||||
const {
|
||||
testConnectionPermission,
|
||||
hasPermission,
|
||||
loadPermissionsFromRequest,
|
||||
loadTablePermissionsFromRequest,
|
||||
getTablePermissionRole,
|
||||
loadDatabasePermissionsFromRequest,
|
||||
getDatabasePermissionRole,
|
||||
getTablePermissionRoleLevelIndex,
|
||||
testDatabaseRolePermission,
|
||||
} = require('../utility/hasPermission');
|
||||
const { MissingCredentialsError } = require('../utility/exceptions');
|
||||
const pipeForkLogs = require('../utility/pipeForkLogs');
|
||||
const crypto = require('crypto');
|
||||
@@ -100,7 +110,7 @@ module.exports = {
|
||||
socket.emitChanged(`database-status-changed`, { conid, database });
|
||||
},
|
||||
|
||||
handle_ping() { },
|
||||
handle_ping() {},
|
||||
|
||||
// session event handlers
|
||||
|
||||
@@ -256,23 +266,24 @@ module.exports = {
|
||||
auditLogger:
|
||||
auditLogSessionGroup && select?.from?.name?.pureName
|
||||
? response => {
|
||||
sendToAuditLog(req, {
|
||||
category: 'dbop',
|
||||
component: 'DatabaseConnectionsController',
|
||||
event: 'sql.select',
|
||||
action: 'select',
|
||||
severity: 'info',
|
||||
conid,
|
||||
database,
|
||||
schemaName: select?.from?.name?.schemaName,
|
||||
pureName: select?.from?.name?.pureName,
|
||||
sumint1: response?.rows?.length,
|
||||
sessionParam: `${conid}::${database}::${select?.from?.name?.schemaName || '0'}::${select?.from?.name?.pureName
|
||||
sendToAuditLog(req, {
|
||||
category: 'dbop',
|
||||
component: 'DatabaseConnectionsController',
|
||||
event: 'sql.select',
|
||||
action: 'select',
|
||||
severity: 'info',
|
||||
conid,
|
||||
database,
|
||||
schemaName: select?.from?.name?.schemaName,
|
||||
pureName: select?.from?.name?.pureName,
|
||||
sumint1: response?.rows?.length,
|
||||
sessionParam: `${conid}::${database}::${select?.from?.name?.schemaName || '0'}::${
|
||||
select?.from?.name?.pureName
|
||||
}`,
|
||||
sessionGroup: auditLogSessionGroup,
|
||||
message: `Loaded table data from ${select?.from?.name?.pureName}`,
|
||||
});
|
||||
}
|
||||
sessionGroup: auditLogSessionGroup,
|
||||
message: `Loaded table data from ${select?.from?.name?.pureName}`,
|
||||
});
|
||||
}
|
||||
: null,
|
||||
}
|
||||
);
|
||||
@@ -335,21 +346,21 @@ module.exports = {
|
||||
auditLogger:
|
||||
auditLogSessionGroup && options?.pureName
|
||||
? response => {
|
||||
sendToAuditLog(req, {
|
||||
category: 'dbop',
|
||||
component: 'DatabaseConnectionsController',
|
||||
event: 'nosql.collectionData',
|
||||
action: 'select',
|
||||
severity: 'info',
|
||||
conid,
|
||||
database,
|
||||
pureName: options?.pureName,
|
||||
sumint1: response?.result?.rows?.length,
|
||||
sessionParam: `${conid}::${database}::${options?.pureName}`,
|
||||
sessionGroup: auditLogSessionGroup,
|
||||
message: `Loaded collection data ${options?.pureName}`,
|
||||
});
|
||||
}
|
||||
sendToAuditLog(req, {
|
||||
category: 'dbop',
|
||||
component: 'DatabaseConnectionsController',
|
||||
event: 'nosql.collectionData',
|
||||
action: 'select',
|
||||
severity: 'info',
|
||||
conid,
|
||||
database,
|
||||
pureName: options?.pureName,
|
||||
sumint1: response?.result?.rows?.length,
|
||||
sessionParam: `${conid}::${database}::${options?.pureName}`,
|
||||
sessionGroup: auditLogSessionGroup,
|
||||
message: `Loaded collection data ${options?.pureName}`,
|
||||
});
|
||||
}
|
||||
: null,
|
||||
}
|
||||
);
|
||||
@@ -455,10 +466,18 @@ module.exports = {
|
||||
[changeSet.inserts, 'create_update_delete'],
|
||||
[changeSet.deletes, 'create_update_delete'],
|
||||
[changeSet.updates, 'update_only'],
|
||||
]
|
||||
];
|
||||
for (const [operations, requiredRole] of fieldsAndRoles) {
|
||||
for (const operation of operations) {
|
||||
const role = getTablePermissionRole(conid, database, 'tables', operation.schemaName, operation.pureName, tablePermissions, databasePermissions);
|
||||
const role = getTablePermissionRole(
|
||||
conid,
|
||||
database,
|
||||
'tables',
|
||||
operation.schemaName,
|
||||
operation.pureName,
|
||||
tablePermissions,
|
||||
databasePermissions
|
||||
);
|
||||
if (getTablePermissionRoleLevelIndex(role) < getTablePermissionRoleLevelIndex(requiredRole)) {
|
||||
throw new Error('DBGM-00262 Permission not granted');
|
||||
}
|
||||
@@ -628,7 +647,15 @@ module.exports = {
|
||||
function applyTablePermissionRole(list, objectTypeField) {
|
||||
const res = [];
|
||||
for (const item of list ?? []) {
|
||||
const tablePermissionRole = getTablePermissionRole(conid, database, objectTypeField, item.schemaName, item.pureName, tablePermissions, databasePermissionRole);
|
||||
const tablePermissionRole = getTablePermissionRole(
|
||||
conid,
|
||||
database,
|
||||
objectTypeField,
|
||||
item.schemaName,
|
||||
item.pureName,
|
||||
tablePermissions,
|
||||
databasePermissionRole
|
||||
);
|
||||
if (tablePermissionRole != 'deny') {
|
||||
res.push({
|
||||
...item,
|
||||
@@ -647,7 +674,7 @@ module.exports = {
|
||||
functions: applyTablePermissionRole(opened.structure.functions, 'functions'),
|
||||
triggers: applyTablePermissionRole(opened.structure.triggers, 'triggers'),
|
||||
collections: applyTablePermissionRole(opened.structure.collections, 'collections'),
|
||||
}
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -881,17 +908,17 @@ module.exports = {
|
||||
return {
|
||||
...(command == 'backup'
|
||||
? driver.backupDatabaseCommand(
|
||||
connection,
|
||||
{ outputFile, database, options, selectedTables, skippedTables, argsFormat },
|
||||
// @ts-ignore
|
||||
externalTools
|
||||
)
|
||||
connection,
|
||||
{ outputFile, database, options, selectedTables, skippedTables, argsFormat },
|
||||
// @ts-ignore
|
||||
externalTools
|
||||
)
|
||||
: driver.restoreDatabaseCommand(
|
||||
connection,
|
||||
{ inputFile, database, options, argsFormat },
|
||||
// @ts-ignore
|
||||
externalTools
|
||||
)),
|
||||
connection,
|
||||
{ inputFile, database, options, argsFormat },
|
||||
// @ts-ignore
|
||||
externalTools
|
||||
)),
|
||||
transformMessage: driver.transformNativeCommandMessage
|
||||
? message => driver.transformNativeCommandMessage(message, command)
|
||||
: null,
|
||||
@@ -990,7 +1017,10 @@ module.exports = {
|
||||
async executeSessionQuery({ sesid, conid, database, sql }, req) {
|
||||
await testConnectionPermission(conid, req);
|
||||
logger.info({ sesid, sql }, 'DBGM-00010 Processing query');
|
||||
sessions.dispatchMessage(sesid, 'Query execution started');
|
||||
sessions.dispatchMessage(sesid, {
|
||||
message: 'Query execution started',
|
||||
sql,
|
||||
});
|
||||
|
||||
const opened = await this.ensureOpened(conid, database);
|
||||
opened.subprocess.send({ msgtype: 'executeSessionQuery', sql, sesid });
|
||||
|
||||
@@ -83,6 +83,16 @@ 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);
|
||||
},
|
||||
@@ -188,7 +198,10 @@ module.exports = {
|
||||
});
|
||||
|
||||
logger.info({ sesid, sql }, 'DBGM-00019 Processing query');
|
||||
this.dispatchMessage(sesid, 'Query execution started');
|
||||
this.dispatchMessage(sesid, {
|
||||
message: 'Query execution started',
|
||||
sql,
|
||||
});
|
||||
session.subprocess.send({
|
||||
msgtype: 'executeQuery',
|
||||
sql,
|
||||
|
||||
@@ -283,6 +283,7 @@ async function updatePremiumPromoWidget() {
|
||||
`${DBGATE_CLOUD_URL}/premium-promo-widget?identifier=${promoWidgetData?.identifier ?? 'empty'}&tags=${tags}`,
|
||||
{
|
||||
headers: {
|
||||
...getLicenseHttpHeaders(),
|
||||
...(await getCloudInstanceHeaders()),
|
||||
'x-app-version': currentVersion.version,
|
||||
},
|
||||
@@ -308,7 +309,8 @@ async function refreshPublicFiles(isRefresh) {
|
||||
} catch (err) {
|
||||
logger.error(extractErrorLogData(err), 'DBGM-00166 Error updating cloud files');
|
||||
}
|
||||
if (!isProApp()) {
|
||||
const configSettings = await config.get();
|
||||
if (!isProApp() || configSettings?.trialDaysLeft != null) {
|
||||
await updatePremiumPromoWidget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ class QueryStreamTableWriter {
|
||||
this.currentChangeIndex = 1;
|
||||
this.initializedFile = false;
|
||||
this.sesid = sesid;
|
||||
this.started = new Date().getTime();
|
||||
}
|
||||
|
||||
initializeFromQuery(structure, resultIndex, chartDefinition, autoDetectCharts = false) {
|
||||
initializeFromQuery(structure, resultIndex, chartDefinition, autoDetectCharts = false, options = {}) {
|
||||
this.jslid = crypto.randomUUID();
|
||||
this.currentFile = path.join(jsldir(), `${this.jslid}.jsonl`);
|
||||
fs.writeFileSync(
|
||||
@@ -24,6 +25,7 @@ class QueryStreamTableWriter {
|
||||
JSON.stringify({
|
||||
...structure,
|
||||
__isStreamHeader: true,
|
||||
...options
|
||||
}) + '\n'
|
||||
);
|
||||
this.currentStream = fs.createWriteStream(this.currentFile, { flags: 'a' });
|
||||
@@ -118,6 +120,13 @@ 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 {
|
||||
@@ -171,7 +180,7 @@ class StreamHandler {
|
||||
process.send({ msgtype: 'changedCurrentDatabase', database, sesid: this.sesid });
|
||||
}
|
||||
|
||||
recordset(columns) {
|
||||
recordset(columns, options) {
|
||||
if (this.rowsLimitOverflow) {
|
||||
return;
|
||||
}
|
||||
@@ -181,7 +190,8 @@ class StreamHandler {
|
||||
Array.isArray(columns) ? { columns } : columns,
|
||||
this.queryStreamInfoHolder.resultIndex,
|
||||
this.frontMatter?.[`chart-${this.queryStreamInfoHolder.resultIndex + 1}`],
|
||||
this.autoDetectCharts
|
||||
this.autoDetectCharts,
|
||||
options
|
||||
);
|
||||
this.queryStreamInfoHolder.resultIndex += 1;
|
||||
this.rowCounter = 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { arrayToHexString, evalFilterBehaviour, isTypeDateTime } from 'dbgate-tools';
|
||||
import { arrayToHexString, base64ToHex, evalFilterBehaviour, isTypeDateTime } from 'dbgate-tools';
|
||||
import { format, toDate } from 'date-fns';
|
||||
import _isString from 'lodash/isString';
|
||||
import _cloneDeepWith from 'lodash/cloneDeepWith';
|
||||
@@ -24,7 +24,9 @@ export function getFilterValueExpression(value, dataType?) {
|
||||
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 { hexStringToArray, parseNumberSafe } from 'dbgate-tools';
|
||||
import { hexToBase64, parseNumberSafe } from 'dbgate-tools';
|
||||
import { FilterBehaviour, TransformType } from 'dbgate-types';
|
||||
|
||||
const binaryCondition =
|
||||
@@ -385,10 +385,7 @@ const createParser = (filterBehaviour: FilterBehaviour) => {
|
||||
|
||||
hexstring: () =>
|
||||
token(P.regexp(/0x(([0-9a-fA-F][0-9a-fA-F])+)/, 1))
|
||||
.map(x => ({
|
||||
type: 'Buffer',
|
||||
data: hexStringToArray(x),
|
||||
}))
|
||||
.map(x => ({ $binary: { base64: hexToBase64(x) } }))
|
||||
.desc('hex string'),
|
||||
|
||||
noQuotedString: () => P.regexp(/[^\s^,^'^"]+/).desc('string unquoted'),
|
||||
|
||||
@@ -78,6 +78,14 @@ 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 (_isPlainObject(value) || _isArray(value)) this.putStringValue(JSON.stringify(value));
|
||||
else this.put('^null');
|
||||
|
||||
@@ -47,6 +47,7 @@ export const mongoFilterBehaviour: FilterBehaviour = {
|
||||
allowStringToken: true,
|
||||
allowNumberDualTesting: true,
|
||||
allowObjectIdTesting: true,
|
||||
allowHexString: true,
|
||||
};
|
||||
|
||||
export const evalFilterBehaviour: FilterBehaviour = {
|
||||
|
||||
@@ -43,6 +43,19 @@ 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;
|
||||
|
||||
@@ -54,9 +67,10 @@ export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
|
||||
const mHex = value.match(/^0x([0-9a-fA-F][0-9a-fA-F])+$/);
|
||||
if (mHex) {
|
||||
return {
|
||||
type: 'Buffer',
|
||||
data: hexStringToArray(value.substring(2)),
|
||||
};
|
||||
$binary: {
|
||||
base64: hexToBase64(value.substring(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,11 +244,19 @@ export function stringifyCellValue(
|
||||
if (value === true) return { value: 'true', gridStyle: 'valueCellStyle' };
|
||||
if (value === false) return { value: 'false', gridStyle: 'valueCellStyle' };
|
||||
|
||||
if (editorTypes?.parseHexAsBuffer) {
|
||||
if (value?.type == 'Buffer' && _isArray(value.data)) {
|
||||
return { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' };
|
||||
}
|
||||
if (value?.$binary?.base64) {
|
||||
return {
|
||||
value: base64ToHex(value.$binary.base64),
|
||||
gridStyle: 'valueCellStyle',
|
||||
};
|
||||
}
|
||||
|
||||
if (editorTypes?.parseHexAsBuffer) {
|
||||
// if (value?.type == 'Buffer' && _isArray(value.data)) {
|
||||
// return { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' };
|
||||
// }
|
||||
}
|
||||
|
||||
if (editorTypes?.parseObjectIdAsDollar) {
|
||||
if (value?.$oid) {
|
||||
switch (intent) {
|
||||
@@ -482,6 +504,9 @@ 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;
|
||||
|
||||
Vendored
+2
@@ -96,4 +96,6 @@ export type TestEngineInfo = {
|
||||
}>;
|
||||
|
||||
objects?: Array<TestObjectInfo>;
|
||||
|
||||
binaryDataType?: string;
|
||||
};
|
||||
|
||||
@@ -26,12 +26,23 @@
|
||||
|
||||
<script lang="javascript">
|
||||
window.dbgate_page = '{{page}}';
|
||||
</script>
|
||||
|
||||
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;
|
||||
@@ -44,7 +55,7 @@
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 50%;
|
||||
background: #000;
|
||||
background: var(--theme-foreground);
|
||||
animation-timing-function: cubic-bezier(0, 1, 1, 0);
|
||||
}
|
||||
.lds-ellipsis div:nth-child(1) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
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 });
|
||||
@@ -22,17 +23,15 @@
|
||||
$: trialDaysLeft = $config?.trialDaysLeft;
|
||||
|
||||
let errorMessage = '';
|
||||
let expiredMessageSet = false;
|
||||
|
||||
$: if (isExpired && !expiredMessageSet) {
|
||||
errorMessage = 'Your license is expired';
|
||||
expiredMessageSet = true;
|
||||
}
|
||||
let isInsertingLicense = false;
|
||||
|
||||
$: trialButtonAvailable = !isExpired && trialDaysLeft == null;
|
||||
|
||||
// $: console.log('CONFIG', $config);
|
||||
|
||||
$: {
|
||||
if ($config?.isLicenseValid) {
|
||||
if ($config?.isLicenseValid && trialDaysLeft == null) {
|
||||
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
|
||||
}
|
||||
}
|
||||
@@ -41,83 +40,124 @@
|
||||
<FormProviderCore {values}>
|
||||
<SpecialPageLayout>
|
||||
{#if getElectron() || ($config?.storageDatabase && hasPermission('admin/license'))}
|
||||
<div class="heading">License</div>
|
||||
<FormTextAreaField label="Enter your license key" name="licenseKey" rows={5} />
|
||||
<div class="heading">Thank you for using DbGate!</div>
|
||||
|
||||
<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 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}
|
||||
|
||||
{#if !isExpired && trialDaysLeft == null}
|
||||
{#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}
|
||||
<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') {
|
||||
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 => {
|
||||
sessionStorage.setItem('continueTrialConfirmed', '1');
|
||||
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
|
||||
} else {
|
||||
errorMessage = license?.errorMessage || 'Error starting trial';
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if trialDaysLeft > 0}
|
||||
<div class="submit">
|
||||
<FormStyledButton
|
||||
value={`Continue trial (${trialDaysLeft} days left)`}
|
||||
value="Purchase DbGate Premium"
|
||||
on:click={async e => {
|
||||
sessionStorage.setItem('continueTrialConfirmed', '1');
|
||||
internalRedirectTo(isOneOfPage('admin-license') ? '/admin.html' : '/index.html');
|
||||
// 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}
|
||||
|
||||
<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 getElectron()}
|
||||
<div class="submit">
|
||||
<FormStyledButton
|
||||
value="Exit"
|
||||
on:click={e => {
|
||||
getElectron().send('quit-app');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if errorMessage}
|
||||
@@ -141,6 +181,10 @@
|
||||
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} />
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import Link from '../elements/Link.svelte';
|
||||
import { focusedConnectionOrDatabase } from '../stores';
|
||||
import { tick } from 'svelte';
|
||||
import { _val } from '../translations';
|
||||
|
||||
export let list;
|
||||
export let module;
|
||||
@@ -38,19 +39,20 @@
|
||||
|
||||
$: matcher = module.createMatcher && module.createMatcher(filter, passProps?.searchSettings);
|
||||
|
||||
$: dataLabeled = _.compact(
|
||||
(list || []).map(data => {
|
||||
const dataCopy = {...data,
|
||||
group: (data?.group && _.isFunction(data.group)) ? data.group() : data.group,
|
||||
title: (data?.title && _.isFunction(data.title)) ? data.title() : data.title,
|
||||
description: (data?.description && _.isFunction(data.description)) ? data.description() : data.description,
|
||||
args: (data?.args || []).map(x => ({
|
||||
...x,
|
||||
label: (x?.label && _.isFunction(x.label)) ? x.label() : x.label,
|
||||
}))
|
||||
};
|
||||
$: listTranslated = (list || []).map(data => ({
|
||||
...data,
|
||||
group: data?.group && _val(data.group),
|
||||
title: data?.title && _val(data.title),
|
||||
description: data?.description && _val(data.description),
|
||||
args: (data?.args || []).map(x => ({
|
||||
...x,
|
||||
label: x?.label && _val(x.label),
|
||||
})),
|
||||
}));
|
||||
|
||||
const matchResult = matcher ? matcher(dataCopy) : true;
|
||||
$: dataLabeled = _.compact(
|
||||
(listTranslated || []).map(data => {
|
||||
const matchResult = matcher ? matcher(data) : true;
|
||||
|
||||
let isMatched = true;
|
||||
let isMainMatched = true;
|
||||
@@ -72,8 +74,8 @@
|
||||
isChildMatched = !module.disableShowChildrenWithParentMatch;
|
||||
}
|
||||
|
||||
const group = groupFunc ? groupFunc(dataCopy) : undefined;
|
||||
return { group, data: dataCopy, isMatched, isChildMatched, isMainMatched };
|
||||
const group = groupFunc ? groupFunc(data) : undefined;
|
||||
return { group, data, isMatched, isChildMatched, isMainMatched };
|
||||
})
|
||||
);
|
||||
|
||||
@@ -112,7 +114,8 @@
|
||||
|
||||
$: groups = groupFunc ? extendGroups(_.groupBy(dataLabeled, 'group'), emptyGroupNames) : null;
|
||||
|
||||
$: listLimited = isExpandedBySearch && !expandLimited ? filtered.slice(0, filter.trim().length < 3 ? 1 : 3) : list;
|
||||
$: listLimited =
|
||||
isExpandedBySearch && !expandLimited ? filtered.slice(0, filter.trim().length < 3 ? 1 : 3) : listTranslated;
|
||||
$: isListLimited = isExpandedBySearch && listLimited.length < filtered.length;
|
||||
$: listMissingItems = isListLimited ? filtered.slice(listLimited.length) : [];
|
||||
|
||||
|
||||
@@ -446,8 +446,7 @@ await dbgateApi.executeQuery(${JSON.stringify(
|
||||
driver?.databaseEngineTypes?.includes('document') && {
|
||||
onClick: handleNewCollection,
|
||||
text: _t('database.newCollection', {
|
||||
defaultMessage: 'New {collectionLabel}',
|
||||
values: { collectionLabel: driver?.collectionSingularLabel ?? 'collection/container' },
|
||||
defaultMessage: 'New collection/container'
|
||||
}),
|
||||
},
|
||||
hasPermission(`dbops/query`) &&
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts" context="module">
|
||||
import { copyTextToClipboard } from '../utility/clipboard';
|
||||
import { _t, _val } from '../translations';
|
||||
|
||||
export const extractKey = ({ schemaName, pureName }) => (schemaName ? `${schemaName}.${pureName}` : pureName);
|
||||
export const createMatcher =
|
||||
@@ -69,13 +70,13 @@
|
||||
|
||||
function createScriptTemplatesSubmenu(objectTypeField) {
|
||||
return {
|
||||
label: 'SQL template',
|
||||
label: _t('dbObject.sqlTemplate', { defaultMessage: 'SQL template' }),
|
||||
submenu: getSupportedScriptTemplates(objectTypeField),
|
||||
};
|
||||
}
|
||||
|
||||
interface DbObjMenuItem {
|
||||
label?: string;
|
||||
label?: string | (() => string);
|
||||
tab?: string;
|
||||
forceNewTab?: boolean;
|
||||
initialData?: any;
|
||||
@@ -113,19 +114,19 @@
|
||||
divider: true,
|
||||
},
|
||||
isProApp() && {
|
||||
label: 'Design query',
|
||||
label: _t('dbObject.designQuery', { defaultMessage: 'Design query' }),
|
||||
isQueryDesigner: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
isProApp() && {
|
||||
label: 'Design perspective query',
|
||||
label: _t('dbObject.designPerspectiveQuery', { defaultMessage: 'Design perspective query' }),
|
||||
tab: 'PerspectiveTab',
|
||||
forceNewTab: true,
|
||||
icon: 'img perspective',
|
||||
},
|
||||
createScriptTemplatesSubmenu('tables'),
|
||||
{
|
||||
label: 'SQL generator',
|
||||
label: _t('dbObject.sqlGenerator', { defaultMessage: 'SQL generator' }),
|
||||
submenu: [
|
||||
{
|
||||
label: 'CREATE TABLE',
|
||||
@@ -154,33 +155,33 @@
|
||||
divider: true,
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Drop table',
|
||||
label: _t('dbObject.dropTable', { defaultMessage: 'Drop table' }),
|
||||
isDrop: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/table/rename') &&
|
||||
!driver?.dialect.disableRenameTable && {
|
||||
label: 'Rename table',
|
||||
label: _t('dbObject.renameTable', { defaultMessage: 'Rename table' }),
|
||||
isRename: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/table/truncate') && {
|
||||
label: 'Truncate table',
|
||||
label: _t('dbObject.truncateTable', { defaultMessage: 'Truncate table' }),
|
||||
isTruncate: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
{
|
||||
label: 'Copy table name',
|
||||
label: _t('dbObject.copyTableName', { defaultMessage: 'Copy table name' }),
|
||||
isCopyTableName: true,
|
||||
requiresWriteAccess: false,
|
||||
},
|
||||
hasPermission('dbops/table/backup') && {
|
||||
label: 'Create table backup',
|
||||
label: _t('dbObject.createTableBackup', { defaultMessage: 'Create table backup' }),
|
||||
isDuplicateTable: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/model/view') && {
|
||||
label: 'Show diagram',
|
||||
label: _t('dbObject.showDiagram', { defaultMessage: 'Show diagram' }),
|
||||
isDiagram: true,
|
||||
},
|
||||
{
|
||||
@@ -204,18 +205,18 @@
|
||||
divider: true,
|
||||
},
|
||||
isProApp() && {
|
||||
label: 'Design query',
|
||||
label: _t('dbObject.designQuery', { defaultMessage: 'Design query' }),
|
||||
isQueryDesigner: true,
|
||||
},
|
||||
isProApp() && {
|
||||
label: 'Design perspective query',
|
||||
label: _t('dbObject.designPerspectiveQuery', { defaultMessage: 'Design perspective query' }),
|
||||
tab: 'PerspectiveTab',
|
||||
forceNewTab: true,
|
||||
icon: 'img perspective',
|
||||
},
|
||||
createScriptTemplatesSubmenu('views'),
|
||||
{
|
||||
label: 'SQL generator',
|
||||
label: _t('dbObject.sqlGenerator', { defaultMessage: 'SQL generator' }),
|
||||
submenu: [
|
||||
{
|
||||
label: 'CREATE VIEW',
|
||||
@@ -235,12 +236,12 @@
|
||||
divider: true,
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Drop view',
|
||||
label: _t('dbObject.dropView', { defaultMessage: 'Drop view' }),
|
||||
isDrop: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Rename view',
|
||||
label: _t('dbObject.renameView', { defaultMessage: 'Rename view' }),
|
||||
isRename: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
@@ -260,12 +261,12 @@
|
||||
divider: true,
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Drop view',
|
||||
label: _t('dbObject.dropView', { defaultMessage: 'Drop view' }),
|
||||
isDrop: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Rename view',
|
||||
label: _t('dbObject.renameView', { defaultMessage: 'Rename view' }),
|
||||
isRename: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
@@ -273,12 +274,12 @@
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
label: 'Query designer',
|
||||
label: _t('dbObject.queryDesigner', { defaultMessage: 'Query designer' }),
|
||||
isQueryDesigner: true,
|
||||
},
|
||||
createScriptTemplatesSubmenu('matviews'),
|
||||
{
|
||||
label: 'SQL generator',
|
||||
label: _t('dbObject.sqlGenerator', { defaultMessage: 'SQL generator' }),
|
||||
submenu: [
|
||||
{
|
||||
label: 'CREATE MATERIALIZED VIEW',
|
||||
@@ -306,7 +307,7 @@
|
||||
case 'queries':
|
||||
return [
|
||||
{
|
||||
label: 'Open data',
|
||||
label: _t('dbObject.openData', { defaultMessage: 'Open data' }),
|
||||
tab: 'QueryDataTab',
|
||||
forceNewTab: true,
|
||||
},
|
||||
@@ -318,18 +319,18 @@
|
||||
divider: true,
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Drop procedure',
|
||||
label: _t('dbObject.dropProcedure', { defaultMessage: 'Drop procedure' }),
|
||||
isDrop: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Rename procedure',
|
||||
label: _t('dbObject.renameProcedure', { defaultMessage: 'Rename procedure' }),
|
||||
isRename: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
createScriptTemplatesSubmenu('procedures'),
|
||||
{
|
||||
label: 'SQL generator',
|
||||
label: _t('dbObject.sqlGenerator', { defaultMessage: 'SQL generator' }),
|
||||
submenu: [
|
||||
{
|
||||
label: 'CREATE PROCEDURE',
|
||||
@@ -352,7 +353,7 @@
|
||||
return [
|
||||
...defaultDatabaseObjectAppObjectActions['triggers'],
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Drop trigger',
|
||||
label: _t('dbObject.dropTrigger', { defaultMessage: 'Drop trigger' }),
|
||||
isDrop: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
@@ -360,7 +361,7 @@
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
label: 'SQL generator',
|
||||
label: _t('dbObject.sqlGenerator', { defaultMessage: 'SQL generator' }),
|
||||
submenu: [
|
||||
{
|
||||
label: 'CREATE TRIGGER',
|
||||
@@ -384,7 +385,7 @@
|
||||
divider: true,
|
||||
},
|
||||
isProApp() && {
|
||||
label: 'Design perspective query',
|
||||
label: _t('dbObject.designPerspectiveQuery', { defaultMessage: 'Design perspective query' }),
|
||||
tab: 'PerspectiveTab',
|
||||
forceNewTab: true,
|
||||
icon: 'img perspective',
|
||||
@@ -395,17 +396,17 @@
|
||||
functionName: 'tableReader',
|
||||
},
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: `Drop ${driver?.collectionSingularLabel ?? 'collection/container'}`,
|
||||
label: _t('dbObject.dropCollection', { defaultMessage: 'Drop collection/container'}),
|
||||
isDropCollection: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/table/rename') && {
|
||||
label: `Rename ${driver?.collectionSingularLabel ?? 'collection/container'}`,
|
||||
label: _t('dbObject.renameCollection', { defaultMessage: 'Rename collection/container'}),
|
||||
isRenameCollection: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/table/backup') && {
|
||||
label: `Create ${driver?.collectionSingularLabel ?? 'collection/container'} backup`,
|
||||
label: _t('dbObject.createCollectionBackup', { defaultMessage: 'Create collection/container backup'}),
|
||||
isDuplicateCollection: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
@@ -418,7 +419,7 @@
|
||||
const menu: DbObjMenuItem[] = [
|
||||
...defaultDatabaseObjectAppObjectActions['schedulerEvents'],
|
||||
hasPermission('dbops/model/edit') && {
|
||||
label: 'Drop event',
|
||||
label: _t('dbObject.dropEvent', { defaultMessage: 'Drop event' }),
|
||||
isDrop: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
@@ -426,12 +427,12 @@
|
||||
|
||||
if (data?.status === 'ENABLED') {
|
||||
menu.push({
|
||||
label: 'Disable',
|
||||
label: _t('dbObject.disable', { defaultMessage: 'Disable' }),
|
||||
isDisableEvent: true,
|
||||
});
|
||||
} else {
|
||||
menu.push({
|
||||
label: 'Enable',
|
||||
label: _t('dbObject.enable', { defaultMessage: 'Enable' }),
|
||||
isEnableEvent: true,
|
||||
});
|
||||
}
|
||||
@@ -441,7 +442,7 @@
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
label: 'SQL generator',
|
||||
label: _t('dbObject.sqlGenerator', { defaultMessage: 'SQL generator' }),
|
||||
submenu: [
|
||||
{
|
||||
label: 'CREATE SCHEDULER EVENT',
|
||||
@@ -474,7 +475,7 @@
|
||||
if (menu.isQueryDesigner) {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Query #',
|
||||
title: _t('dbObject.query', { defaultMessage: 'Query #' }),
|
||||
icon: 'img query-design',
|
||||
tabComponent: 'QueryDesignTab',
|
||||
focused: true,
|
||||
@@ -499,7 +500,7 @@
|
||||
} else if (menu.isDiagram) {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Diagram #',
|
||||
title: _t('dbObject.diagram', { defaultMessage: 'Diagram #' }),
|
||||
icon: 'img diagram',
|
||||
tabComponent: 'DiagramTab',
|
||||
props: {
|
||||
@@ -589,7 +590,7 @@
|
||||
});
|
||||
} else if (menu.isDropCollection) {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really drop collection ${data.pureName}?`,
|
||||
message: _t('dbObject.confirmDropCollection', { defaultMessage: 'Really drop collection {name}?', values: { name: data.pureName } }),
|
||||
onConfirm: async () => {
|
||||
const dbid = _.pick(data, ['conid', 'database']);
|
||||
runOperationOnDatabase(dbid, {
|
||||
@@ -603,8 +604,8 @@
|
||||
} else if (menu.isRenameCollection) {
|
||||
const driver = await getDriver();
|
||||
showModal(InputTextModal, {
|
||||
label: `New ${driver?.collectionSingularLabel ?? 'collection/container'} name`,
|
||||
header: `Rename ${driver?.collectionSingularLabel ?? 'collection/container'}`,
|
||||
label: _t('dbObject.newCollectionName', { defaultMessage: 'New collection/container name' }),
|
||||
header: _t('dbObject.renameCollection', { defaultMessage: 'Rename collection/container' }),
|
||||
value: data.pureName,
|
||||
onConfirm: async newName => {
|
||||
const dbid = _.pick(data, ['conid', 'database']);
|
||||
@@ -620,7 +621,7 @@
|
||||
const driver = await getDriver();
|
||||
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really create ${driver?.collectionSingularLabel ?? 'collection/container'} copy named ${newName}?`,
|
||||
message: _t('dbObject.confirmCloneCollection', { defaultMessage: 'Really create collection/container copy named {name}?', values: { name: newName } }),
|
||||
onConfirm: async () => {
|
||||
const dbid = _.pick(data, ['conid', 'database']);
|
||||
runOperationOnDatabase(dbid, {
|
||||
@@ -718,7 +719,7 @@
|
||||
|
||||
const filteredSumenus = coreMenus.map(item => {
|
||||
if (!item.submenu) {
|
||||
return item;
|
||||
return { ...item , label: _val(item.label)};
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
@@ -768,7 +769,7 @@
|
||||
openNewTab(
|
||||
{
|
||||
// title: getObjectTitle(connection, schemaName, pureName),
|
||||
title: tabComponent ? getObjectTitle(connection, schemaName, pureName) : 'Query #',
|
||||
title: tabComponent ? getObjectTitle(connection, schemaName, pureName) : _t('dbObject.query', { defaultMessage: 'Query #' }),
|
||||
focused: tabComponent == null,
|
||||
tooltip,
|
||||
icon:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { __t } from '../translations';
|
||||
export function matchDatabaseObjectAppObject(obj1, obj2) {
|
||||
return (
|
||||
obj1?.objectTypeField == obj2?.objectTypeField &&
|
||||
@@ -11,12 +12,12 @@ export function matchDatabaseObjectAppObject(obj1, obj2) {
|
||||
function getTableLikeActions(dataTab) {
|
||||
return [
|
||||
{
|
||||
label: 'Open data',
|
||||
label: __t('dbObject.openData', { defaultMessage: 'Open data' }),
|
||||
tab: dataTab,
|
||||
defaultActionId: 'openTable',
|
||||
},
|
||||
{
|
||||
label: 'Open raw data',
|
||||
label: __t('dbObject.openRawData', { defaultMessage: 'Open raw data' }),
|
||||
tab: dataTab,
|
||||
defaultActionId: 'openRawTable',
|
||||
isRawMode: true,
|
||||
@@ -33,13 +34,13 @@ function getTableLikeActions(dataTab) {
|
||||
// defaultActionId: 'openForm',
|
||||
// },
|
||||
{
|
||||
label: 'Open structure',
|
||||
label: __t('dbObject.openStructure', { defaultMessage: 'Open structure' }),
|
||||
tab: 'TableStructureTab',
|
||||
icon: 'img table-structure',
|
||||
defaultActionId: 'openStructure',
|
||||
},
|
||||
{
|
||||
label: 'Show SQL',
|
||||
label: __t('dbObject.showSql', { defaultMessage: 'Show SQL' }),
|
||||
tab: 'SqlObjectTab',
|
||||
defaultActionId: 'showSql',
|
||||
icon: 'img sql-file',
|
||||
@@ -53,7 +54,7 @@ export const defaultDatabaseObjectAppObjectActions = {
|
||||
matviews: getTableLikeActions('ViewDataTab'),
|
||||
procedures: [
|
||||
{
|
||||
label: 'Show SQL',
|
||||
label: __t('dbObject.showSql', { defaultMessage: 'Show SQL' }),
|
||||
tab: 'SqlObjectTab',
|
||||
defaultActionId: 'showSql',
|
||||
icon: 'img sql-file',
|
||||
@@ -61,7 +62,7 @@ export const defaultDatabaseObjectAppObjectActions = {
|
||||
],
|
||||
functions: [
|
||||
{
|
||||
label: 'Show SQL',
|
||||
label: __t('dbObject.showSql', { defaultMessage: 'Show SQL' }),
|
||||
tab: 'SqlObjectTab',
|
||||
defaultActionId: 'showSql',
|
||||
icon: 'img sql-file',
|
||||
@@ -69,7 +70,7 @@ export const defaultDatabaseObjectAppObjectActions = {
|
||||
],
|
||||
triggers: [
|
||||
{
|
||||
label: 'Show SQL',
|
||||
label: __t('dbObject.showSql', { defaultMessage: 'Show SQL' }),
|
||||
tab: 'SqlObjectTab',
|
||||
defaultActionId: 'showSql',
|
||||
icon: 'img sql-file',
|
||||
@@ -77,12 +78,12 @@ export const defaultDatabaseObjectAppObjectActions = {
|
||||
],
|
||||
collections: [
|
||||
{
|
||||
label: 'Open data',
|
||||
label: __t('dbObject.openData', { defaultMessage: 'Open data' }),
|
||||
tab: 'CollectionDataTab',
|
||||
defaultActionId: 'openTable',
|
||||
},
|
||||
{
|
||||
label: 'Open JSON',
|
||||
label: __t('dbObject.openJson', { defaultMessage: 'Open JSON' }),
|
||||
tab: 'CollectionDataTab',
|
||||
defaultActionId: 'openJson',
|
||||
initialData: {
|
||||
@@ -94,7 +95,7 @@ export const defaultDatabaseObjectAppObjectActions = {
|
||||
],
|
||||
schedulerEvents: [
|
||||
{
|
||||
label: 'Show SQL',
|
||||
label: __t('dbObject.showSql', { defaultMessage: 'Show SQL' }),
|
||||
tab: 'SqlObjectTab',
|
||||
defaultActionId: 'showSql',
|
||||
icon: 'img sql-file',
|
||||
@@ -102,7 +103,7 @@ export const defaultDatabaseObjectAppObjectActions = {
|
||||
],
|
||||
queries: [
|
||||
{
|
||||
label: 'Show query',
|
||||
label: __t('dbObject.showQuery', { defaultMessage: 'Show query' }),
|
||||
tab: 'QueryDataTab',
|
||||
defaultActionId: 'showAppQuery',
|
||||
icon: 'img app-query',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script context="module">
|
||||
function getCommandTitle(command) {
|
||||
let res = _.isFunction(command.text) ? command.text() : command.text;
|
||||
let res = _val(command.text);
|
||||
if (command.keyText || command.keyTextFromGroup) {
|
||||
res += ` (${formatKeyText(command.keyText || command.keyTextFromGroup)})`;
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
import { formatKeyText } from '../utility/common';
|
||||
import ToolStripButton from './ToolStripButton.svelte';
|
||||
import _ from 'lodash';
|
||||
import { _val } from '../translations';
|
||||
|
||||
export let command;
|
||||
export let component = ToolStripButton;
|
||||
@@ -33,6 +34,6 @@
|
||||
{iconAfter}
|
||||
{...$$restProps}
|
||||
>
|
||||
{(_.isFunction(buttonLabel) ? buttonLabel() : buttonLabel) || (_.isFunction(cmd?.toolbarName) ? cmd.toolbarName() : cmd.toolbarName) || (_.isFunction(cmd?.name) ? cmd.name() : cmd.name)}
|
||||
{(_val(buttonLabel) || _val(cmd?.toolbarName) || _val(cmd?.name))}
|
||||
</svelte:component>
|
||||
{/if}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
import ToolStripCommandButton from './ToolStripCommandButton.svelte';
|
||||
import ToolStripDropDownButton from './ToolStripDropDownButton.svelte';
|
||||
import _ from 'lodash';
|
||||
import { _val } from '../translations';
|
||||
export let quickExportHandlerRef = null;
|
||||
export let command = 'sqlDataGrid.export';
|
||||
export let label = 'Export';
|
||||
@@ -39,7 +40,7 @@
|
||||
|
||||
{#if hasPermission('dbops/export')}
|
||||
{#if quickExportHandlerRef}
|
||||
<ToolStripDropDownButton menu={getExportMenu} label={_.isFunction(label) ? label() : label} icon="icon export" />
|
||||
<ToolStripDropDownButton menu={getExportMenu} label={_val(label)} icon="icon export" />
|
||||
{:else}
|
||||
<ToolStripCommandButton {command} />
|
||||
{/if}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
if (value?.type == 'Buffer' && _.isArray(value?.data)) {
|
||||
return 'data:image/png;base64, ' + btoa(String.fromCharCode.apply(null, value?.data));
|
||||
}
|
||||
if (value?.$binary?.base64) {
|
||||
return 'data:image/png;base64, ' + value.$binary.base64;
|
||||
}
|
||||
return null;
|
||||
} catch (err) {
|
||||
console.log('Error showing picture', err);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script context="module">
|
||||
registerCommand({
|
||||
id: 'commandPalette.show',
|
||||
category: 'Command palette',
|
||||
name: 'Show',
|
||||
toolbarName: 'Command palette',
|
||||
category: __t('command.commandPalette', { defaultMessage: 'Command palette' }),
|
||||
name: __t('command.commandPalette.show', { defaultMessage: 'Show' }),
|
||||
toolbarName: __t('command.commandPalette', { defaultMessage: 'Command palette' }),
|
||||
toolbarOrder: 0,
|
||||
keyText: 'F1',
|
||||
toolbar: true,
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'database.search',
|
||||
category: 'Database',
|
||||
toolbarName: 'Database search',
|
||||
name: 'Search',
|
||||
category: __t('command.database', { defaultMessage: 'Database' }),
|
||||
toolbarName: __t('command.database.databaseSearch', { defaultMessage: 'Database search' }),
|
||||
name: __t('command.database.search', { defaultMessage: 'Search' }),
|
||||
keyText: isElectronAvailable() ? 'CtrlOrCommand+P' : 'F3',
|
||||
onClick: () => visibleCommandPalette.set('database'),
|
||||
testEnabled: () => getVisibleCommandPalette() != 'database',
|
||||
@@ -81,6 +81,7 @@
|
||||
import { getLocalStorage } from '../utility/storageCache';
|
||||
import registerCommand from './registerCommand';
|
||||
import { formatKeyText, switchCurrentDatabase } from '../utility/common';
|
||||
import { _val, __t } from '../translations';
|
||||
|
||||
let domInput;
|
||||
let filter = '';
|
||||
@@ -117,7 +118,7 @@
|
||||
: sortedComands
|
||||
).filter(x => !x.isGroupCommand),
|
||||
{
|
||||
extract: x => x.text,
|
||||
extract: x => _val(x.text),
|
||||
pre: '<b>',
|
||||
post: '</b>',
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import getElectron from '../utility/getElectron';
|
||||
import registerCommand from './registerCommand';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { switchCurrentDatabase } from '../utility/common';
|
||||
import { __t } from '../translations';
|
||||
|
||||
registerCommand({
|
||||
id: 'database.changeState',
|
||||
category: 'Database',
|
||||
name: 'Change status',
|
||||
category: __t('command.database', { defaultMessage: 'Database' }),
|
||||
name: __t('command.database.changeStatus', { defaultMessage: 'Change status' }),
|
||||
getSubCommands: () => {
|
||||
const current = getCurrentDatabase();
|
||||
if (!current) return [];
|
||||
|
||||
@@ -3,6 +3,7 @@ import { recentDatabases, currentDatabase, getRecentDatabases } from '../stores'
|
||||
import registerCommand from './registerCommand';
|
||||
import { getConnectionLabel } from 'dbgate-tools';
|
||||
import { switchCurrentDatabase } from '../utility/common';
|
||||
import { __t } from '../translations';
|
||||
|
||||
currentDatabase.subscribe(value => {
|
||||
if (!value) return;
|
||||
@@ -24,8 +25,8 @@ function switchDatabaseCommand(db) {
|
||||
|
||||
registerCommand({
|
||||
id: 'database.switch',
|
||||
category: 'Database',
|
||||
name: 'Change to recent',
|
||||
category: __t('command.database', { defaultMessage: 'Database' }),
|
||||
name: __t('command.database.changeRecent', { defaultMessage: 'Change to recent' }),
|
||||
menuName: 'Switch recent database',
|
||||
keyText: 'CtrlOrCommand+D',
|
||||
getSubCommands: () => getRecentDatabases().map(switchDatabaseCommand),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { commands } from '../stores';
|
||||
import { invalidateCommandDefinitions } from './invalidateCommands';
|
||||
import _ from 'lodash';
|
||||
import { _val } from '../translations';
|
||||
|
||||
export interface SubCommand {
|
||||
text: string;
|
||||
@@ -44,10 +45,7 @@ export default function registerCommand(command: GlobalCommand) {
|
||||
[command.id]: {
|
||||
text:
|
||||
_.isFunction(command.category) || _.isFunction(command.name)
|
||||
? () =>
|
||||
`${_.isFunction(command.category) ? command.category() : command.category}: ${
|
||||
_.isFunction(command.name) ? command.name() : command.name
|
||||
}`
|
||||
? () => `${_val(command.category)}: ${_val(command.name)}`
|
||||
: `${command.category}: ${command.name}`,
|
||||
...command,
|
||||
enabled: !testEnabled,
|
||||
|
||||
@@ -52,6 +52,7 @@ import { openWebLink } from '../utility/simpleTools';
|
||||
import { _t } from '../translations';
|
||||
import ExportImportConnectionsModal from '../modals/ExportImportConnectionsModal.svelte';
|
||||
import { getBoolSettingsValue } from '../settings/settingsTools';
|
||||
import { __t } from '../translations';
|
||||
|
||||
// function themeCommand(theme: ThemeDefinition) {
|
||||
// return {
|
||||
@@ -69,42 +70,42 @@ import { getBoolSettingsValue } from '../settings/settingsTools';
|
||||
|
||||
registerCommand({
|
||||
id: 'theme.changeTheme',
|
||||
category: 'Theme',
|
||||
name: 'Change',
|
||||
toolbarName: 'Change theme',
|
||||
category: __t('command.theme', { defaultMessage: 'Theme' }),
|
||||
name: __t('command.theme.change', { defaultMessage: 'Change' }),
|
||||
toolbarName: __t('command.theme.changeToolbar', { defaultMessage: 'Change theme' }),
|
||||
onClick: () => showModal(SettingsModal, { selectedTab: 'theme' }),
|
||||
// getSubCommands: () => get(extensions).themes.map(themeCommand),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'toolbar.show',
|
||||
category: 'Toolbar',
|
||||
name: 'Show',
|
||||
category: __t('command.toolbar', { defaultMessage: 'Toolbar' }),
|
||||
name: __t('command.toolbar.show', { defaultMessage: 'Show' }),
|
||||
onClick: () => visibleToolbar.set(true),
|
||||
testEnabled: () => !getVisibleToolbar(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'toolbar.hide',
|
||||
category: 'Toolbar',
|
||||
name: 'Hide',
|
||||
category: __t('command.toolbar', { defaultMessage: 'Toolbar' }),
|
||||
name: __t('command.toolbar.hide', { defaultMessage: 'Hide' }),
|
||||
onClick: () => visibleToolbar.set(false),
|
||||
testEnabled: () => getVisibleToolbar(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'about.show',
|
||||
category: 'About',
|
||||
name: 'Show',
|
||||
toolbarName: 'About',
|
||||
category: __t('command.about', { defaultMessage: 'About' }),
|
||||
name: __t('command.about.show', { defaultMessage: 'Show' }),
|
||||
toolbarName: __t('command.about.toolbar', { defaultMessage: 'About' }),
|
||||
onClick: () => showModal(AboutModal),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'toggle.sidebar',
|
||||
category: 'Sidebar',
|
||||
name: 'Show',
|
||||
toolbarName: 'Toggle sidebar',
|
||||
category: __t('command.sidebar', { defaultMessage: 'Sidebar' }),
|
||||
name: __t('command.sidebar.show', { defaultMessage: 'Show' }),
|
||||
toolbarName: __t('command.sidebar.toggleToolbar', { defaultMessage: 'Toggle sidebar' }),
|
||||
keyText: 'CtrlOrCommand+B',
|
||||
onClick: () => visibleWidgetSideBar.update(x => !x),
|
||||
});
|
||||
@@ -113,10 +114,10 @@ registerCommand({
|
||||
id: 'new.connection',
|
||||
toolbar: true,
|
||||
icon: 'icon new-connection',
|
||||
toolbarName: 'Add connection',
|
||||
category: 'New',
|
||||
toolbarName: __t('command.new.connection', { defaultMessage: 'Add connection' }),
|
||||
category: __t('command.new', { defaultMessage: 'New'}),
|
||||
toolbarOrder: 1,
|
||||
name: 'Connection',
|
||||
name: __t('command.new.connection', { defaultMessage: 'Connection' }),
|
||||
testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase,
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
@@ -131,10 +132,10 @@ registerCommand({
|
||||
id: 'new.connectionOnCloud',
|
||||
toolbar: true,
|
||||
icon: 'img cloud-connection',
|
||||
toolbarName: 'Add connection',
|
||||
category: 'New',
|
||||
toolbarName: __t('command.new.connection', { defaultMessage: 'Add connection' }),
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
toolbarOrder: 1,
|
||||
name: 'Connection on Cloud',
|
||||
name: __t('command.new.connectionCloud', { defaultMessage: 'Connection on Cloud' }),
|
||||
testEnabled: () =>
|
||||
!getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase && !!getCloudSigninTokenHolder(),
|
||||
onClick: () => {
|
||||
@@ -153,10 +154,10 @@ registerCommand({
|
||||
id: 'new.connection.folder',
|
||||
toolbar: true,
|
||||
icon: 'icon add-folder',
|
||||
toolbarName: 'Add connection folder',
|
||||
category: 'New',
|
||||
toolbarName: __t('command.new.connectionFolderToolbar', { defaultMessage: 'Add connection folder' }),
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
toolbarOrder: 1,
|
||||
name: 'Connection folder',
|
||||
name: __t('command.new.connectionFolder', { defaultMessage: 'Connection folder' }),
|
||||
testEnabled: () => !getCurrentConfig()?.runAsPortal,
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
@@ -176,21 +177,21 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'new.query',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'icon file',
|
||||
toolbar: true,
|
||||
toolbarOrder: 2,
|
||||
name: 'Query',
|
||||
toolbarName: 'New query',
|
||||
name: __t('command.new.query', { defaultMessage: 'Query' }),
|
||||
toolbarName: __t('command.new.queryToolbar', { defaultMessage: 'New query' }),
|
||||
keyText: 'CtrlOrCommand+T',
|
||||
onClick: () => newQuery(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'new.shell',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img shell',
|
||||
name: 'JavaScript Shell',
|
||||
name: __t('command.new.shell', { defaultMessage: 'JavaScript Shell' }),
|
||||
menuName: 'New JavaScript shell',
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
@@ -204,9 +205,9 @@ registerCommand({
|
||||
if (isProApp()) {
|
||||
registerCommand({
|
||||
id: 'new.queryDesign',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img query-design',
|
||||
name: 'Query design',
|
||||
name: __t('command.new.queryDesign', { defaultMessage: 'Query design' }),
|
||||
menuName: 'New query design',
|
||||
onClick: () => newQueryDesign(),
|
||||
testEnabled: () =>
|
||||
@@ -218,9 +219,9 @@ if (isProApp()) {
|
||||
if (isProApp()) {
|
||||
registerCommand({
|
||||
id: 'new.modelTransform',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img transform',
|
||||
name: 'Model transform',
|
||||
name: __t('command.new.modelTransform', { defaultMessage: 'Model transform' }),
|
||||
menuName: 'New model transform',
|
||||
onClick: () => {
|
||||
openNewTab(
|
||||
@@ -262,9 +263,9 @@ if (isProApp()) {
|
||||
if (isProApp()) {
|
||||
registerCommand({
|
||||
id: 'new.perspective',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img perspective',
|
||||
name: 'Perspective',
|
||||
name: __t('command.new.perspective', { defaultMessage: 'Perspective' }),
|
||||
menuName: 'New perspective',
|
||||
onClick: () => newPerspective(),
|
||||
});
|
||||
@@ -273,9 +274,9 @@ if (isProApp()) {
|
||||
if (isProApp()) {
|
||||
registerCommand({
|
||||
id: 'new.application',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img app',
|
||||
name: 'Application',
|
||||
name: __t('command.new.application', { defaultMessage: 'Application' }),
|
||||
menuName: 'New application',
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
@@ -289,9 +290,9 @@ if (isProApp()) {
|
||||
|
||||
registerCommand({
|
||||
id: 'new.diagram',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img diagram',
|
||||
name: 'ER Diagram',
|
||||
name: __t('command.new.diagram', { defaultMessage: 'ER Diagram' }),
|
||||
menuName: 'New ER diagram',
|
||||
testEnabled: () =>
|
||||
getCurrentDatabase() &&
|
||||
@@ -301,9 +302,9 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'new.archiveFolder',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img archive',
|
||||
name: 'Archive folder',
|
||||
name: __t('command.new.archiveFolder', { defaultMessage: 'Archive folder' }),
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
value: '',
|
||||
@@ -335,11 +336,11 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'new.table',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'icon table',
|
||||
name: 'Table',
|
||||
name: __t('command.new.table', { defaultMessage: 'Table' }),
|
||||
toolbar: true,
|
||||
toolbarName: 'New table',
|
||||
toolbarName: __t('command.new.tableToolbar', { defaultMessage: 'New table' }),
|
||||
testEnabled: () => {
|
||||
if (!hasPermission('dbops/model/edit')) return false;
|
||||
const driver = findEngineDriver(get(currentDatabase)?.connection, getExtensions());
|
||||
@@ -355,11 +356,11 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'new.collection',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'icon table',
|
||||
name: 'Collection',
|
||||
name: __t('command.new.collection', { defaultMessage: 'Collection' }),
|
||||
toolbar: true,
|
||||
toolbarName: 'New collection/container',
|
||||
toolbarName: __t('command.new.collectionToolbar', { defaultMessage: 'New collection/container' }),
|
||||
testEnabled: () => {
|
||||
const driver = findEngineDriver(get(currentDatabase)?.connection, getExtensions());
|
||||
return !!get(currentDatabase) && driver?.databaseEngineTypes?.includes('document');
|
||||
@@ -381,9 +382,9 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'new.markdown',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img markdown',
|
||||
name: 'Markdown page',
|
||||
name: __t('command.new.markdown', { defaultMessage: 'Markdown page' }),
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'Page #',
|
||||
@@ -396,9 +397,9 @@ registerCommand({
|
||||
if (isProApp()) {
|
||||
registerCommand({
|
||||
id: 'new.modelCompare',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'icon compare',
|
||||
name: 'Compare DB',
|
||||
name: __t('command.new.modelCompare', { defaultMessage: 'Compare DB' }),
|
||||
toolbar: true,
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
@@ -412,9 +413,9 @@ if (isProApp()) {
|
||||
|
||||
registerCommand({
|
||||
id: 'new.jsonl',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img archive',
|
||||
name: 'JSON Lines',
|
||||
name: __t('command.new.jsonl', { defaultMessage: 'JSON Lines' }),
|
||||
menuName: 'New JSON lines file',
|
||||
onClick: () => {
|
||||
openNewTab(
|
||||
@@ -432,9 +433,9 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'new.sqliteDatabase',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img sqlite-database',
|
||||
name: 'SQLite database',
|
||||
name: __t('command.new.sqliteDatabase', { defaultMessage: 'SQLite database' }),
|
||||
menuName: _t('command.new.sqliteDatabase', { defaultMessage: 'New SQLite database' }),
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
@@ -452,9 +453,9 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'new.duckdbDatabase',
|
||||
category: 'New',
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
icon: 'img sqlite-database',
|
||||
name: 'DuckDB database',
|
||||
name: __t('command.new.duckdbDatabase', { defaultMessage: 'DuckDB database' }),
|
||||
menuName: _t('command.new.duckdbDatabase', { defaultMessage: 'New DuckDB database' }),
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
@@ -472,8 +473,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.changelog',
|
||||
category: 'Tabs',
|
||||
name: 'Changelog',
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.changelog', { defaultMessage: 'Changelog' }),
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'ChangeLog',
|
||||
@@ -488,7 +489,7 @@ registerCommand({
|
||||
id: 'group.save',
|
||||
category: null,
|
||||
isGroupCommand: true,
|
||||
name: 'Save',
|
||||
name: __t('command.save', { defaultMessage: 'Save' }),
|
||||
keyText: 'CtrlOrCommand+S',
|
||||
group: 'save',
|
||||
});
|
||||
@@ -497,7 +498,7 @@ registerCommand({
|
||||
id: 'group.saveAs',
|
||||
category: null,
|
||||
isGroupCommand: true,
|
||||
name: 'Save As',
|
||||
name: __t('command.saveAs', { defaultMessage: 'Save As' }),
|
||||
keyText: 'CtrlOrCommand+Shift+S',
|
||||
group: 'saveAs',
|
||||
});
|
||||
@@ -506,7 +507,7 @@ registerCommand({
|
||||
id: 'group.undo',
|
||||
category: null,
|
||||
isGroupCommand: true,
|
||||
name: 'Undo',
|
||||
name: __t('command.undo', { defaultMessage: 'Undo' }),
|
||||
keyText: 'CtrlOrCommand+Z',
|
||||
group: 'undo',
|
||||
});
|
||||
@@ -515,15 +516,15 @@ registerCommand({
|
||||
id: 'group.redo',
|
||||
category: null,
|
||||
isGroupCommand: true,
|
||||
name: 'Redo',
|
||||
name: __t('command.redo', { defaultMessage: 'Redo' }),
|
||||
keyText: 'CtrlOrCommand+Y',
|
||||
group: 'redo',
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'file.open',
|
||||
category: 'File',
|
||||
name: 'Open',
|
||||
category: __t('command.file', { defaultMessage: 'File' }),
|
||||
name: __t('command.file.open', { defaultMessage: 'Open' }),
|
||||
keyText: 'CtrlOrCommand+O',
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: openElectronFile,
|
||||
@@ -531,36 +532,36 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'file.openArchive',
|
||||
category: 'File',
|
||||
name: 'Open DB Model/Archive',
|
||||
category: __t('command.file', { defaultMessage: 'File' }),
|
||||
name: __t('command.file.openArchive', { defaultMessage: 'Open DB Model/Archive' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: openArchiveFolder,
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'folder.showLogs',
|
||||
category: 'Folder',
|
||||
name: 'Open logs',
|
||||
category: __t('command.folder', { defaultMessage: 'Folder' }),
|
||||
name: __t('command.folder.openLogs', { defaultMessage: 'Open logs' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => electron.showItemInFolder(getCurrentConfig().logsFilePath),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'folder.showData',
|
||||
category: 'Folder',
|
||||
name: 'Open data folder',
|
||||
category: __t('command.folder', { defaultMessage: 'Folder' }),
|
||||
name: __t('command.folder.openData', { defaultMessage: 'Open data folder' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => electron.showItemInFolder(getCurrentConfig().connectionsFilePath),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.resetSettings',
|
||||
category: 'File',
|
||||
name: 'Reset layout data & settings',
|
||||
category: __t('command.file', { defaultMessage: 'File' }),
|
||||
name: __t('command.file.resetLayout', { defaultMessage: 'Reset layout data & settings' }),
|
||||
testEnabled: () => true,
|
||||
onClick: () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really reset layout data? All opened tabs, settings and layout data will be lost. Connections and saved files will be preserved. After this, restart DbGate for applying changes.`,
|
||||
message: _t('command.file.resetLayoutConfirm', { defaultMessage: 'Really reset layout data? All opened tabs, settings and layout data will be lost. Connections and saved files will be preserved. After this, restart DbGate for applying changes.' }),
|
||||
onConfirm: async () => {
|
||||
await apiCall('config/delete-settings');
|
||||
localStorage.clear();
|
||||
@@ -577,8 +578,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.exportConnections',
|
||||
category: 'Settings',
|
||||
name: 'Export connections',
|
||||
category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
name: __t('command.settings.exportConnections', { defaultMessage: 'Export connections' }),
|
||||
testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase,
|
||||
onClick: () => {
|
||||
showModal(ExportImportConnectionsModal, {
|
||||
@@ -589,8 +590,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.importConnections',
|
||||
category: 'Settings',
|
||||
name: 'Import connections',
|
||||
category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
name: __t('command.settings.importConnections', { defaultMessage: 'Import connections' }),
|
||||
testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase,
|
||||
onClick: async () => {
|
||||
const files = await electron.showOpenDialog({
|
||||
@@ -615,8 +616,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'file.import',
|
||||
category: 'File',
|
||||
name: 'Import data',
|
||||
category: __t('command.file', { defaultMessage: 'File' }),
|
||||
name: __t('command.file.import', { defaultMessage: 'Import data' }),
|
||||
toolbar: true,
|
||||
icon: 'icon import',
|
||||
onClick: () =>
|
||||
@@ -636,8 +637,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'view.reset',
|
||||
category: 'View',
|
||||
name: 'Reset view',
|
||||
category: __t('command.view', { defaultMessage: 'View' }),
|
||||
name: __t('command.view.reset', { defaultMessage: 'Reset view' }),
|
||||
onClick: () => {
|
||||
const keys = [
|
||||
'leftPanelWidth',
|
||||
@@ -664,14 +665,14 @@ registerCommand({
|
||||
'currentArchive',
|
||||
];
|
||||
for (const key of keys) removeLocalStorage(key);
|
||||
showSnackbarSuccess('Restart DbGate (or reload on web) for applying changes');
|
||||
showSnackbarSuccess(_t('command.view.restart', { defaultMessage: 'Restart DbGate (or reload on web) for applying changes' }));
|
||||
},
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'sql.generator',
|
||||
category: 'SQL',
|
||||
name: 'SQL Generator',
|
||||
category: __t('command.sql', { defaultMessage: 'SQL' }),
|
||||
name: __t('command.sql.generator', { defaultMessage: 'SQL Generator' }),
|
||||
toolbar: true,
|
||||
icon: 'icon sql-generator',
|
||||
testEnabled: () =>
|
||||
@@ -687,8 +688,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'database.export',
|
||||
category: 'Database',
|
||||
name: 'Export database',
|
||||
category: __t('command.database', { defaultMessage: 'Database' }),
|
||||
name: __t('command.database.export', { defaultMessage: 'Export database' }),
|
||||
toolbar: true,
|
||||
icon: 'icon export',
|
||||
testEnabled: () => getCurrentDatabase() != null && hasPermission(`dbops/export`) && isProApp(),
|
||||
@@ -705,8 +706,8 @@ registerCommand({
|
||||
if (isProApp()) {
|
||||
registerCommand({
|
||||
id: 'database.compare',
|
||||
category: 'Database',
|
||||
name: 'Compare databases',
|
||||
category: __t('command.database', { defaultMessage: 'Database' }),
|
||||
name: __t('command.database.compare', { defaultMessage: 'Compare databases' }),
|
||||
toolbar: true,
|
||||
icon: 'icon compare',
|
||||
testEnabled: () =>
|
||||
@@ -738,8 +739,8 @@ if (isProApp()) {
|
||||
|
||||
registerCommand({
|
||||
id: 'database.chat',
|
||||
category: 'Database',
|
||||
name: 'Database chat',
|
||||
category: __t('command.database', { defaultMessage: 'Database' }),
|
||||
name: __t('command.database.chat', { defaultMessage: 'Database chat' }),
|
||||
toolbar: true,
|
||||
icon: 'icon ai',
|
||||
testEnabled: () =>
|
||||
@@ -763,11 +764,11 @@ if (isProApp()) {
|
||||
if (hasPermission('settings/change')) {
|
||||
registerCommand({
|
||||
id: 'settings.commands',
|
||||
category: 'Settings',
|
||||
name: 'Keyboard shortcuts',
|
||||
category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
name: __t('command.settings.shortcuts', { defaultMessage: 'Keyboard shortcuts' }),
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'Keyboard Shortcuts',
|
||||
title: _t('command.settings.shortcuts', { defaultMessage: 'Keyboard shortcuts' }),
|
||||
icon: 'icon keyboard',
|
||||
tabComponent: 'CommandListTab',
|
||||
props: {},
|
||||
@@ -778,9 +779,9 @@ if (hasPermission('settings/change')) {
|
||||
|
||||
registerCommand({
|
||||
id: 'settings.show',
|
||||
category: 'Settings',
|
||||
name: 'Change',
|
||||
toolbarName: 'Settings',
|
||||
category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
name: __t('command.settings.change', { defaultMessage: 'Change' }),
|
||||
toolbarName: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
onClick: () => showModal(SettingsModal),
|
||||
testEnabled: () => hasPermission('settings/change'),
|
||||
});
|
||||
@@ -788,8 +789,8 @@ if (hasPermission('settings/change')) {
|
||||
|
||||
registerCommand({
|
||||
id: 'cloud.logout',
|
||||
category: 'Cloud',
|
||||
name: 'Logout',
|
||||
category: __t('command.cloud', { defaultMessage: 'Cloud' }),
|
||||
name: __t('command.cloud.logout', { defaultMessage: 'Logout' }),
|
||||
onClick: () => {
|
||||
cloudSigninTokenHolder.set(null);
|
||||
},
|
||||
@@ -797,8 +798,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'file.exit',
|
||||
category: 'File',
|
||||
name: isMac() ? 'Quit' : 'Exit',
|
||||
category: __t('command.file', { defaultMessage: 'File' }),
|
||||
name: isMac() ? __t('command.file.quit', { defaultMessage: 'Quit' }) : __t('command.file.exit', { defaultMessage: 'Exit' }),
|
||||
// keyText: isMac() ? 'Command+Q' : null,
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('quit-app'),
|
||||
@@ -806,16 +807,16 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.logout',
|
||||
category: 'App',
|
||||
name: 'Logout',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.app.logout', { defaultMessage: 'Logout' }),
|
||||
testEnabled: () => getCurrentConfig()?.isUserLoggedIn,
|
||||
onClick: doLogout,
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.loggedUserCommands',
|
||||
category: 'App',
|
||||
name: 'Logged user',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.app.loggedUser', { defaultMessage: 'Logged user' }),
|
||||
getSubCommands: () => {
|
||||
const config = getCurrentConfig();
|
||||
if (!config) return [];
|
||||
@@ -832,16 +833,16 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.disconnect',
|
||||
category: 'App',
|
||||
name: 'Disconnect',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.app.disconnect', { defaultMessage: 'Disconnect' }),
|
||||
testEnabled: () => getCurrentConfig()?.singleConnection != null && !getCurrentConfig()?.isUserLoggedIn,
|
||||
onClick: () => disconnectServerConnection(getCurrentConfig()?.singleConnection?._id),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'file.checkForUpdates',
|
||||
category: 'App',
|
||||
name: 'Check for updates',
|
||||
id: 'app.checkForUpdates',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.app.checkForUpdates', { defaultMessage: 'Check for updates' }),
|
||||
// testEnabled: () => true,
|
||||
testEnabled: () => getAppUpdaterActive(),
|
||||
onClick: () => getElectron().send('check-for-updates'),
|
||||
@@ -867,7 +868,7 @@ export function registerFileCommands({
|
||||
id: idPrefix + '.save',
|
||||
group: 'save',
|
||||
category,
|
||||
name: 'Save',
|
||||
name: __t('command.save', { defaultMessage: 'Save' }),
|
||||
// keyText: 'CtrlOrCommand+S',
|
||||
icon: 'icon save',
|
||||
toolbar: true,
|
||||
@@ -879,14 +880,14 @@ export function registerFileCommands({
|
||||
id: idPrefix + '.saveAs',
|
||||
group: 'saveAs',
|
||||
category,
|
||||
name: 'Save As',
|
||||
name: __t('command.saveAs', { defaultMessage: 'Save As' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save-as', folder, format, fileExtension),
|
||||
});
|
||||
registerCommand({
|
||||
id: idPrefix + '.saveToDisk',
|
||||
category,
|
||||
name: 'Save to disk',
|
||||
name: __t('command.saveToDisk', { defaultMessage: 'Save to disk' }),
|
||||
testEnabled: () => getCurrentEditor() != null && getElectron() != null,
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save-to-disk', folder, format, fileExtension),
|
||||
});
|
||||
@@ -896,7 +897,7 @@ export function registerFileCommands({
|
||||
registerCommand({
|
||||
id: idPrefix + '.execute',
|
||||
category,
|
||||
name: 'Execute',
|
||||
name: __t('command.execute', { defaultMessage: 'Execute' }),
|
||||
icon: 'icon run',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -910,7 +911,7 @@ export function registerFileCommands({
|
||||
registerCommand({
|
||||
id: idPrefix + '.kill',
|
||||
category,
|
||||
name: 'Kill',
|
||||
name: __t('command.kill', { defaultMessage: 'Kill' }),
|
||||
icon: 'icon close',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -923,7 +924,7 @@ export function registerFileCommands({
|
||||
registerCommand({
|
||||
id: idPrefix + '.toggleComment',
|
||||
category,
|
||||
name: 'Toggle comment',
|
||||
name: __t('command.toggleComment', { defaultMessage: 'Toggle comment' }),
|
||||
keyText: 'CtrlOrCommand+/',
|
||||
disableHandleKeyText: 'CtrlOrCommand+/',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
@@ -935,7 +936,7 @@ export function registerFileCommands({
|
||||
registerCommand({
|
||||
id: idPrefix + '.copy',
|
||||
category,
|
||||
name: 'Copy',
|
||||
name: __t('command.copy', { defaultMessage: 'Copy' }),
|
||||
disableHandleKeyText: 'CtrlOrCommand+C',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().copy(),
|
||||
@@ -943,7 +944,7 @@ export function registerFileCommands({
|
||||
registerCommand({
|
||||
id: idPrefix + '.paste',
|
||||
category,
|
||||
name: 'Paste',
|
||||
name: __t('command.paste', { defaultMessage: 'Paste' }),
|
||||
disableHandleKeyText: 'CtrlOrCommand+V',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().paste(),
|
||||
@@ -954,7 +955,7 @@ export function registerFileCommands({
|
||||
registerCommand({
|
||||
id: idPrefix + '.find',
|
||||
category,
|
||||
name: 'Find',
|
||||
name: __t('command.find', { defaultMessage: 'Find' }),
|
||||
keyText: 'CtrlOrCommand+F',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().find(),
|
||||
@@ -963,7 +964,7 @@ export function registerFileCommands({
|
||||
id: idPrefix + '.replace',
|
||||
category,
|
||||
keyText: isMac() ? 'Alt+Command+F' : 'CtrlOrCommand+H',
|
||||
name: 'Replace',
|
||||
name: __t('command.replace', { defaultMessage: 'Replace' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().replace(),
|
||||
});
|
||||
@@ -972,7 +973,7 @@ export function registerFileCommands({
|
||||
registerCommand({
|
||||
id: idPrefix + '.undo',
|
||||
category,
|
||||
name: 'Undo',
|
||||
name: __t('command.undo', { defaultMessage: 'Undo' }),
|
||||
group: 'undo',
|
||||
icon: 'icon undo',
|
||||
testEnabled: () => getCurrentEditor()?.canUndo(),
|
||||
@@ -982,7 +983,7 @@ export function registerFileCommands({
|
||||
id: idPrefix + '.redo',
|
||||
category,
|
||||
group: 'redo',
|
||||
name: 'Redo',
|
||||
name: __t('command.redo', { defaultMessage: 'Redo' }),
|
||||
icon: 'icon redo',
|
||||
testEnabled: () => getCurrentEditor()?.canRedo(),
|
||||
onClick: () => getCurrentEditor().redo(),
|
||||
@@ -992,24 +993,24 @@ export function registerFileCommands({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.minimize',
|
||||
category: 'Application',
|
||||
name: 'Minimize',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.minimize', { defaultMessage: 'Minimize' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'minimize'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.maximize',
|
||||
category: 'Application',
|
||||
name: 'Maximize',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.maximize', { defaultMessage: 'Maximize' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'maximize'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.toggleFullScreen',
|
||||
category: 'Application',
|
||||
name: 'Toggle full screen',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.toggleFullScreen', { defaultMessage: 'Toggle full screen' }),
|
||||
keyText: 'F11',
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: async () => {
|
||||
@@ -1023,45 +1024,45 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.toggleDevTools',
|
||||
category: 'Application',
|
||||
name: 'Toggle Dev Tools',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.toggleDevTools', { defaultMessage: 'Toggle Dev Tools' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'devtools'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.reload',
|
||||
category: 'Application',
|
||||
name: 'Reload',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.reload', { defaultMessage: 'Reload' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'reload'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.openDocs',
|
||||
category: 'Application',
|
||||
name: 'Documentation',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.documentation', { defaultMessage: 'Documentation' }),
|
||||
onClick: () => openWebLink('https://docs.dbgate.io/'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.openWeb',
|
||||
category: 'Application',
|
||||
name: 'DbGate web',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.web', { defaultMessage: 'DbGate web' }),
|
||||
onClick: () => openWebLink('https://www.dbgate.io/'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.openIssue',
|
||||
category: 'Application',
|
||||
name: 'Report problem or feature request',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.openIssue', { defaultMessage: 'Report problem or feature request' }),
|
||||
onClick: () => openWebLink('https://github.com/dbgate/dbgate/issues/new'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'app.openSponsoring',
|
||||
category: 'Application',
|
||||
name: 'Become sponsor',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.becomeSponsor', { defaultMessage: 'Become sponsor' }),
|
||||
testEnabled: () => !isProApp(),
|
||||
onClick: () => openWebLink('https://opencollective.com/dbgate'),
|
||||
});
|
||||
@@ -1075,8 +1076,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.zoomIn',
|
||||
category: 'Application',
|
||||
name: 'Zoom in',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.zoomIn', { defaultMessage: 'Zoom in' }),
|
||||
keyText: 'CtrlOrCommand+=',
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'zoomin'),
|
||||
@@ -1084,8 +1085,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.zoomOut',
|
||||
category: 'Application',
|
||||
name: 'Zoom out',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.zoomOut', { defaultMessage: 'Zoom out' }),
|
||||
keyText: 'CtrlOrCommand+-',
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'zoomout'),
|
||||
@@ -1093,16 +1094,16 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.zoomReset',
|
||||
category: 'Application',
|
||||
name: 'Reset zoom',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.zoomReset', { defaultMessage: 'Reset zoom' }),
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'zoomreset'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'edit.undo',
|
||||
category: 'Edit',
|
||||
name: 'Undo',
|
||||
category: __t('command.edit', { defaultMessage: 'Edit' }),
|
||||
name: __t('command.edit.undo', { defaultMessage: 'Undo' }),
|
||||
keyText: 'CtrlOrCommand+Z',
|
||||
systemCommand: true,
|
||||
testEnabled: () => getElectron() != null,
|
||||
@@ -1111,8 +1112,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'edit.redo',
|
||||
category: 'Edit',
|
||||
name: 'Redo',
|
||||
category: __t('command.edit', { defaultMessage: 'Edit' }),
|
||||
name: __t('command.edit.redo', { defaultMessage: 'Redo' }),
|
||||
systemCommand: true,
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('window-action', 'redo'),
|
||||
@@ -1120,8 +1121,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'edit.cut',
|
||||
category: 'Edit',
|
||||
name: 'Cut',
|
||||
category: __t('command.edit', { defaultMessage: 'Edit' }),
|
||||
name: __t('command.edit.cut', { defaultMessage: 'Cut' }),
|
||||
keyText: 'CtrlOrCommand+X',
|
||||
systemCommand: true,
|
||||
testEnabled: () => getElectron() != null,
|
||||
@@ -1130,8 +1131,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'edit.copy',
|
||||
category: 'Edit',
|
||||
name: 'Copy',
|
||||
category: __t('command.edit', { defaultMessage: 'Edit' }),
|
||||
name: __t('command.edit.copy', { defaultMessage: 'Copy' }),
|
||||
keyText: 'CtrlOrCommand+C',
|
||||
systemCommand: true,
|
||||
testEnabled: () => getElectron() != null,
|
||||
@@ -1140,8 +1141,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'edit.paste',
|
||||
category: 'Edit',
|
||||
name: 'Paste',
|
||||
category: __t('command.edit', { defaultMessage: 'Edit' }),
|
||||
name: __t('command.edit.paste', { defaultMessage: 'Paste' }),
|
||||
keyText: 'CtrlOrCommand+V',
|
||||
systemCommand: true,
|
||||
testEnabled: () => getElectron() != null,
|
||||
@@ -1150,8 +1151,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'edit.selectAll',
|
||||
category: 'Edit',
|
||||
name: 'Select All',
|
||||
category: __t('command.edit', { defaultMessage: 'Edit' }),
|
||||
name: __t('command.edit.selectAll', { defaultMessage: 'Select All' }),
|
||||
keyText: 'CtrlOrCommand+A',
|
||||
systemCommand: true,
|
||||
testEnabled: () => getElectron() != null,
|
||||
@@ -1160,8 +1161,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'app.unsetCurrentDatabase',
|
||||
category: 'Application',
|
||||
name: 'Unset current database',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.unsetCurrentDatabase', { defaultMessage: 'Unset current database' }),
|
||||
testEnabled: () => getCurrentDatabase() != null,
|
||||
onClick: () => currentDatabase.set(null),
|
||||
});
|
||||
@@ -1170,8 +1171,8 @@ let loadedCampaignList = [];
|
||||
|
||||
registerCommand({
|
||||
id: 'internal.loadCampaigns',
|
||||
category: 'Internal',
|
||||
name: 'Load campaign list',
|
||||
category: __t('command.internal', { defaultMessage: 'Internal' }),
|
||||
name: __t('command.internal.loadCampaigns', { defaultMessage: 'Load campaign list' }),
|
||||
testEnabled: () => getBoolSettingsValue('internal.showCampaigns', false),
|
||||
onClick: async () => {
|
||||
const resp = await apiCall('cloud/promo-widget-list', {});
|
||||
@@ -1181,8 +1182,8 @@ registerCommand({
|
||||
|
||||
registerCommand({
|
||||
id: 'internal.showCampaigns',
|
||||
category: 'Internal',
|
||||
name: 'Show campaigns',
|
||||
category: __t('command.internal', { defaultMessage: 'Internal' }),
|
||||
name: __t('command.internal.showCampaigns', { defaultMessage: 'Show campaigns' }),
|
||||
testEnabled: () => getBoolSettingsValue('internal.showCampaigns', false) && loadedCampaignList?.length > 0,
|
||||
getSubCommands: () => {
|
||||
return loadedCampaignList.map(campaign => ({
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'collectionDataGrid.openQuery',
|
||||
category: 'Data grid',
|
||||
name: 'Open query',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.openQuery', { defaultMessage: 'Open query' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().openQuery(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'collectionDataGrid.export',
|
||||
category: 'Data grid',
|
||||
name: 'Export',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.export', { defaultMessage: 'Export' }),
|
||||
keyText: 'CtrlOrCommand+E',
|
||||
icon: 'icon export',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
@@ -140,6 +140,7 @@
|
||||
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
|
||||
import { mongoFilterBehaviour, standardFilterBehaviours } from 'dbgate-tools';
|
||||
import { openImportExportTab } from '../utility/importExportTools';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let display;
|
||||
|
||||
@@ -361,6 +361,7 @@
|
||||
detectSqlFilterBehaviour,
|
||||
stringifyCellValue,
|
||||
shouldOpenMultilineDialog,
|
||||
base64ToHex,
|
||||
} from 'dbgate-tools';
|
||||
import { getContext, onDestroy } from 'svelte';
|
||||
import _, { map } from 'lodash';
|
||||
@@ -421,7 +422,7 @@
|
||||
import { openJsonLinesData } from '../utility/openJsonLinesData';
|
||||
import contextMenuActivator from '../utility/contextMenuActivator';
|
||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||
import { __t, _t } from '../translations';
|
||||
import { __t, _t, _val } from '../translations';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import SaveArchiveModal from '../modals/SaveArchiveModal.svelte';
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
@@ -758,7 +759,7 @@
|
||||
|
||||
export function saveCellToFileEnabled() {
|
||||
const value = getSelectedExportableCell();
|
||||
return _.isString(value) || (value?.type == 'Buffer' && _.isArray(value?.data));
|
||||
return _.isString(value) || (value?.type == 'Buffer' && _.isArray(value?.data)) || (value?.$binary?.base64);
|
||||
}
|
||||
|
||||
export async function saveCellToFile() {
|
||||
@@ -771,6 +772,8 @@
|
||||
fs.promises.writeFile(file, value);
|
||||
} else if (value?.type == 'Buffer' && _.isArray(value?.data)) {
|
||||
fs.promises.writeFile(file, window['Buffer'].from(value.data));
|
||||
} else if (value?.$binary?.base64) {
|
||||
fs.promises.writeFile(file, window['Buffer'].from(value.$binary.base64, 'base64'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -796,8 +799,9 @@
|
||||
isText
|
||||
? data
|
||||
: {
|
||||
type: 'Buffer',
|
||||
data: [...data],
|
||||
$binary: {
|
||||
base64: data.toString('base64'),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1795,12 +1799,12 @@
|
||||
text: _t('datagrid.copyAdvanced', { defaultMessage: 'Copy advanced'}),
|
||||
submenu: [
|
||||
_.keys(copyRowsFormatDefs).map(format => ({
|
||||
text: _.isFunction(copyRowsFormatDefs[format].label) ? copyRowsFormatDefs[format].label() : copyRowsFormatDefs[format].label,
|
||||
text: _val(copyRowsFormatDefs[format].label),
|
||||
onClick: () => copyToClipboardCore(format),
|
||||
})),
|
||||
{ divider: true },
|
||||
_.keys(copyRowsFormatDefs).map(format => ({
|
||||
text: _t('datagrid.setFormat', { defaultMessage: 'Set format: ' }) + (_.isFunction(copyRowsFormatDefs[format].name) ? copyRowsFormatDefs[format].name() : copyRowsFormatDefs[format].name),
|
||||
text: _t('datagrid.setFormat', { defaultMessage: 'Set format: ' }) + (_val(copyRowsFormatDefs[format].name)),
|
||||
onClick: () => ($copyRowsFormat = format),
|
||||
})),
|
||||
|
||||
@@ -1870,7 +1874,7 @@
|
||||
return [
|
||||
menu,
|
||||
{
|
||||
text: _.isFunction(copyRowsFormatDefs[$copyRowsFormat].label) ? copyRowsFormatDefs[$copyRowsFormat].label() : copyRowsFormatDefs[$copyRowsFormat].label,
|
||||
text: _val(copyRowsFormatDefs[$copyRowsFormat].label),
|
||||
onClick: () => copyToClipboardCore($copyRowsFormat),
|
||||
keyText: 'CtrlOrCommand+C',
|
||||
tag: 'copy',
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'jslTableGrid.export',
|
||||
category: 'Data grid',
|
||||
name: 'Export',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.export', { defaultMessage: 'Export' }),
|
||||
icon: 'icon export',
|
||||
keyText: 'CtrlOrCommand+E',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
|
||||
import { openImportExportTab } from '../utility/importExportTools';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let jslid;
|
||||
export let display;
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
{/if}
|
||||
|
||||
{#if dependencies.length > 0}
|
||||
<div class="bold nowrap ml-1">Dependent tables ({dependencies.length})</div>
|
||||
<div class="bold nowrap ml-1">{_t('dataGrid.dependentTables', { defaultMessage: 'Dependent tables' })} ({dependencies.length})</div>
|
||||
{#each dependencies.filter(fk => filterName(filter, fk.pureName)) as fk}
|
||||
<div
|
||||
class="link"
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'designer.arrange',
|
||||
category: 'Designer',
|
||||
category: __t('command.designer', { defaultMessage: 'Designer' }),
|
||||
icon: 'icon arrange',
|
||||
name: 'Arrange',
|
||||
name: __t('command.designer.arrange', { defaultMessage: 'Arrange' }),
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
testEnabled: () => getCurrentEditor()?.canArrange(),
|
||||
@@ -15,9 +15,9 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'diagram.export',
|
||||
category: 'Designer',
|
||||
toolbarName: 'Export diagram',
|
||||
name: 'Export diagram',
|
||||
category: __t('command.designer', { defaultMessage: 'Designer' }),
|
||||
toolbarName: __t('command.designer.exportDiagram', { defaultMessage: 'Export diagram' }),
|
||||
name: __t('command.designer.exportDiagram', { defaultMessage: 'Export diagram' }),
|
||||
icon: 'icon report',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'diagram.deleteSelectedTables',
|
||||
category: 'Designer',
|
||||
toolbarName: 'Remove',
|
||||
name: 'Remove selected tables',
|
||||
category: __t('command.designer', { defaultMessage: 'Designer' }),
|
||||
toolbarName: __t('command.designer.remove', { defaultMessage: 'Remove' }),
|
||||
name: __t('command.designer.removeSelectedTables', { defaultMessage: 'Remove selected tables' }),
|
||||
icon: 'icon delete',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -67,6 +67,7 @@
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import dragScroll from '../utility/dragScroll';
|
||||
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let value;
|
||||
export let onChange;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
import { onMount, afterUpdate } from 'svelte';
|
||||
|
||||
export let code = '';
|
||||
export let inline = false;
|
||||
export let onClick = null;
|
||||
|
||||
let domCode;
|
||||
|
||||
@@ -29,7 +31,11 @@
|
||||
The `sql` class hints the language; highlight.js will
|
||||
read it even though we register the grammar explicitly.
|
||||
-->
|
||||
<pre bind:this={domCode} class="sql">{code}</pre>
|
||||
{#if inline}
|
||||
<span bind:this={domCode} class="sql" class:clickable={!!onClick} on:click={onClick}>{code}</span>
|
||||
{:else}
|
||||
<pre bind:this={domCode} class="sql" class:clickable={!!onClick} on:click={onClick}>{code}</pre>
|
||||
{/if}
|
||||
{/key}
|
||||
|
||||
<style>
|
||||
@@ -38,4 +44,8 @@
|
||||
padding: 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
import { evaluateCondition } from 'dbgate-sqltree';
|
||||
import { compileCompoudEvalCondition } from 'dbgate-filterparser';
|
||||
import { chevronExpandIcon } from '../icons/expandIcons';
|
||||
import { _val } from '../translations';
|
||||
|
||||
export let columns: (TableControlColumn | false)[];
|
||||
export let rows = null;
|
||||
@@ -368,7 +369,7 @@
|
||||
{/if}
|
||||
{/key}
|
||||
{:else}
|
||||
{ _.isFunction(row[col.fieldName]) ? row[col.fieldName]() : row[col.fieldName] || ''}
|
||||
{ _val(row[col.fieldName]) || '' }
|
||||
{/if}
|
||||
</td>
|
||||
{/each}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import { getFormContext } from './FormProviderCore.svelte';
|
||||
import TextField from './TextField.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let name;
|
||||
export let disabled = false;
|
||||
@@ -29,7 +30,7 @@
|
||||
setFieldValue(name, e.target['value']);
|
||||
}
|
||||
}}
|
||||
placeholder={isCrypted ? '(Password is encrypted)' : undefined}
|
||||
placeholder={isCrypted ? _t('common.passwordEncrypted', { defaultMessage: 'Password is encrypted' }) : undefined}
|
||||
type={isCrypted || showPassword ? 'text' : 'password'}
|
||||
/>
|
||||
{#if !isCrypted}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getFormContext } from './FormProviderCore.svelte';
|
||||
import TextField from './TextField.svelte';
|
||||
import { _val } from '../translations';
|
||||
|
||||
export let name;
|
||||
export let defaultValue;
|
||||
@@ -11,7 +12,7 @@
|
||||
|
||||
<TextField
|
||||
{...$$restProps}
|
||||
value={$values?.[name] ?? defaultValue}
|
||||
value={$values?.[name] ? _val($values[name]) : defaultValue}
|
||||
on:input={e => setFieldValue(name, e.target['value'])}
|
||||
on:input={e => {
|
||||
if (saveOnInput) {
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'collectionJsonView.expandAll',
|
||||
category: 'Collection data',
|
||||
name: 'Expand all',
|
||||
category: __t('command.collectionData', { defaultMessage: 'Collection data' }),
|
||||
name: __t('command.collectionData.expandAll', { defaultMessage: 'Expand all' }),
|
||||
isRelatedToTab: true,
|
||||
icon: 'icon expand-all',
|
||||
onClick: () => getCurrentEditor().handleExpandAll(),
|
||||
@@ -12,8 +12,8 @@
|
||||
});
|
||||
registerCommand({
|
||||
id: 'collectionJsonView.collapseAll',
|
||||
category: 'Collection data',
|
||||
name: 'Collapse all',
|
||||
category: __t('command.collectionData', { defaultMessage: 'Collection data' }),
|
||||
name: __t('command.collectionData.collapseAll', { defaultMessage: 'Collapse all' }),
|
||||
isRelatedToTab: true,
|
||||
icon: 'icon collapse-all',
|
||||
onClick: () => getCurrentEditor().handleCollapseAll(),
|
||||
@@ -37,6 +37,7 @@
|
||||
import CollectionJsonRow from './CollectionJsonRow.svelte';
|
||||
import { getIntSettingsValue } from '../settings/settingsTools';
|
||||
import invalidateCommands from '../commands/invalidateCommands';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.refresh',
|
||||
category: 'Data form',
|
||||
name: _t('common.refresh', { defaultMessage: 'Refresh' }),
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('common.refresh', { defaultMessage: 'Refresh' }),
|
||||
keyText: 'F5 | CtrlOrCommand+R',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.copyToClipboard',
|
||||
category: 'Data form',
|
||||
name: 'Copy to clipboard',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.copyToClipboard', { defaultMessage: 'Copy to clipboard' }),
|
||||
keyText: 'CtrlOrCommand+C',
|
||||
disableHandleKeyText: 'CtrlOrCommand+C',
|
||||
testEnabled: () => getCurrentDataForm() != null,
|
||||
@@ -36,8 +36,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.revertRowChanges',
|
||||
category: 'Data form',
|
||||
name: 'Revert row changes',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.revertRowChanges', { defaultMessage: 'Revert row changes' }),
|
||||
keyText: 'CtrlOrCommand+U',
|
||||
testEnabled: () => getCurrentDataForm()?.getGrider()?.containsChanges,
|
||||
onClick: () => getCurrentDataForm().getGrider().revertRowChanges(0),
|
||||
@@ -45,8 +45,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.setNull',
|
||||
category: 'Data form',
|
||||
name: 'Set NULL',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.setNull', { defaultMessage: 'Set NULL' }),
|
||||
keyText: 'CtrlOrCommand+0',
|
||||
testEnabled: () => getCurrentDataForm() != null && !getCurrentDataForm()?.getEditorTypes()?.supportFieldRemoval,
|
||||
onClick: () => getCurrentDataForm().setFixedValue(null),
|
||||
@@ -54,8 +54,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.removeField',
|
||||
category: 'Data form',
|
||||
name: 'Remove field',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.removeField', { defaultMessage: 'Remove field' }),
|
||||
keyText: 'CtrlOrCommand+0',
|
||||
testEnabled: () => getCurrentDataForm() != null && getCurrentDataForm()?.getEditorTypes()?.supportFieldRemoval,
|
||||
onClick: () => getCurrentDataForm().setFixedValue(undefined),
|
||||
@@ -63,8 +63,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.undo',
|
||||
category: 'Data form',
|
||||
name: 'Undo',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.undo', { defaultMessage: 'Undo' }),
|
||||
group: 'undo',
|
||||
icon: 'icon undo',
|
||||
toolbar: true,
|
||||
@@ -75,8 +75,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.redo',
|
||||
category: 'Data form',
|
||||
name: 'Redo',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.redo', { defaultMessage: 'Redo' }),
|
||||
group: 'redo',
|
||||
icon: 'icon redo',
|
||||
toolbar: true,
|
||||
@@ -87,16 +87,16 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.reconnect',
|
||||
category: 'Data grid',
|
||||
name: 'Reconnect',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.reconnect', { defaultMessage: 'Reconnect' }),
|
||||
testEnabled: () => getCurrentDataForm() != null,
|
||||
onClick: () => getCurrentDataForm().reconnect(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.filterSelected',
|
||||
category: 'Data form',
|
||||
name: 'Filter this value',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.filterSelected', { defaultMessage: 'Filter this value' }),
|
||||
keyText: 'CtrlOrCommand+Shift+F',
|
||||
testEnabled: () => getCurrentDataForm() != null,
|
||||
onClick: () => getCurrentDataForm().filterSelectedValue(),
|
||||
@@ -104,16 +104,16 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.addToFilter',
|
||||
category: 'Data form',
|
||||
name: 'Add to filter',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.addToFilter', { defaultMessage: 'Add to filter' }),
|
||||
testEnabled: () => getCurrentDataForm() != null,
|
||||
onClick: () => getCurrentDataForm().addToFilter(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.goToFirst',
|
||||
category: 'Data form',
|
||||
name: 'First',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.goToFirst', { defaultMessage: 'First' }),
|
||||
keyText: 'CtrlOrCommand+Home',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -124,8 +124,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.goToPrevious',
|
||||
category: 'Data form',
|
||||
name: 'Previous',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.goToPrevious', { defaultMessage: 'Previous' }),
|
||||
keyText: 'CtrlOrCommand+ArrowUp',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -136,8 +136,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.goToNext',
|
||||
category: 'Data form',
|
||||
name: 'Next',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.goToNext', { defaultMessage: 'Next' }),
|
||||
keyText: 'CtrlOrCommand+ArrowDown',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -148,8 +148,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'dataForm.goToLast',
|
||||
category: 'Data form',
|
||||
name: 'Last',
|
||||
category: __t('command.dataForm', { defaultMessage: 'Data form' }),
|
||||
name: __t('command.dataForm.goToLast', { defaultMessage: 'Last' }),
|
||||
keyText: 'CtrlOrCommand+End',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -197,7 +197,7 @@
|
||||
import resizeObserver from '../utility/resizeObserver';
|
||||
import openReferenceForm from './openReferenceForm';
|
||||
import { useSettings } from '../utility/metadataLoaders';
|
||||
import { _t } from '../translations';
|
||||
import { _t, __t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
@@ -243,20 +243,16 @@
|
||||
|
||||
function getRowCountInfo(allRowCount) {
|
||||
if (rowCountNotAvailable) {
|
||||
return `Row: ${((display.config.formViewRecordNumber || 0) + 1).toLocaleString()} / ???`;
|
||||
return _t('dataForm.rowCount', { defaultMessage: 'Row: {rowCount} / ???', values: { rowCount: ((display.config.formViewRecordNumber || 0) + 1).toLocaleString() } });
|
||||
}
|
||||
if (rowData == null) {
|
||||
if (allRowCount != null) {
|
||||
return `Out of bounds: ${(
|
||||
(display.config.formViewRecordNumber || 0) + 1
|
||||
).toLocaleString()} / ${allRowCount.toLocaleString()}`;
|
||||
return _t('dataForm.outOfBounds', { defaultMessage: 'Out of bounds: {current} / {total}', values: { current: ((display.config.formViewRecordNumber || 0) + 1).toLocaleString(), total: allRowCount.toLocaleString() } });
|
||||
}
|
||||
return 'No data';
|
||||
return _t('dataForm.noData', { defaultMessage: 'No data' });
|
||||
}
|
||||
if (allRowCount == null || display == null) return 'Loading row count...';
|
||||
return `Row: ${(
|
||||
(display.config.formViewRecordNumber || 0) + 1
|
||||
).toLocaleString()} / ${allRowCount.toLocaleString()}`;
|
||||
if (allRowCount == null || display == null) return _t('dataForm.loadingRowCount', { defaultMessage: 'Loading row count...' });
|
||||
return _t('dataForm.rowCount', { defaultMessage: 'Row: {current} / {total}', values: { current: ((display.config.formViewRecordNumber || 0) + 1).toLocaleString(), total: allRowCount.toLocaleString() } });
|
||||
}
|
||||
|
||||
export function getGrider() {
|
||||
@@ -720,7 +716,7 @@
|
||||
</div>
|
||||
|
||||
{#if isLoading}
|
||||
<LoadingInfo wrapper message="Loading data" />
|
||||
<LoadingInfo wrapper message={_t('common.loadingData', { defaultMessage: 'Loading data' })} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
import KeyboardModal from './KeyboardModal.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal, showModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let command;
|
||||
|
||||
@@ -23,16 +24,16 @@
|
||||
|
||||
<FormProviderCore {values}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Configure commmand</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('commandModal.configure', { defaultMessage: 'Configure command' })}</svelte:fragment>
|
||||
|
||||
<FormTextField label="Category" name="category" disabled />
|
||||
<FormTextField label="Name" name="name" disabled />
|
||||
<FormTextField label={_t('commandModal.category', { defaultMessage: 'Category' })} name="category" disabled />
|
||||
<FormTextField label={_t('commandModal.name', { defaultMessage: 'Name' })} name="name" disabled />
|
||||
|
||||
<div class="row">
|
||||
<FormTextField label="Keyboard shortcut" name="keyText" templateProps={{ noMargin: true }} focused />
|
||||
<FormTextField label={_t('commandModal.keyboardShortcut', { defaultMessage: 'Keyboard shortcut' })} name="keyText" templateProps={{ noMargin: true }} focused />
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Keyboard"
|
||||
value={_t('commandModal.keyboard', { defaultMessage: 'Keyboard' })}
|
||||
on:click={handleKeyboard}
|
||||
data-testid="CommandModal_keyboardButton"
|
||||
/>
|
||||
@@ -56,7 +57,7 @@
|
||||
/>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Reset"
|
||||
value={_t('common.reset', { defaultMessage: 'Reset' })}
|
||||
on:click={() => {
|
||||
closeCurrentModal();
|
||||
apiCall('config/update-settings', {
|
||||
@@ -64,7 +65,7 @@
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProviderCore>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import { parseCellValue, safeJsonParse, stringifyCellValue } from 'dbgate-tools';
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
import ErrorMessageModal from './ErrorMessageModal.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let onSave;
|
||||
export let value;
|
||||
@@ -49,14 +50,14 @@
|
||||
if (parsed) {
|
||||
textValue = JSON.stringify(parsed, null, 2);
|
||||
} else {
|
||||
showModal(ErrorMessageModal, { message: 'Not valid JSON' });
|
||||
showModal(ErrorMessageModal, { message: _t('dataGrid.formatJson.invalid', { defaultMessage: 'Not valid JSON' }) });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">Edit cell value</div>
|
||||
<div slot="header">{_t('dataGrid.editCellValue', { defaultMessage: 'Edit cell value' })}</div>
|
||||
|
||||
<div class="editor">
|
||||
<AceEditor bind:value={textValue} bind:this={editor} onKeyDown={handleKeyDown} mode={syntaxMode} />
|
||||
@@ -72,21 +73,21 @@
|
||||
closeCurrentModal();
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormStyledButton type="button" value="Format JSON" on:click={handleFormatJson} />
|
||||
<FormStyledButton type="button" skipWidth={true} value={_t('dataGrid.formatJson', { defaultMessage: 'Format JSON' })} on:click={handleFormatJson} />
|
||||
|
||||
Code highlighting:
|
||||
{_t('dataGrid.codeHighlighting', { defaultMessage: 'Code highlighting:' })}
|
||||
<SelectField
|
||||
isNative
|
||||
value={syntaxMode}
|
||||
on:change={e => (syntaxMode = e.detail)}
|
||||
options={[
|
||||
{ value: 'text', label: 'None (raw text)' },
|
||||
{ value: 'text', label: _t('dataGrid.codeHighlighting.none', { defaultMessage: 'None (raw text)' }) },
|
||||
{ value: 'json', label: 'JSON' },
|
||||
{ value: 'html', label: 'HTML' },
|
||||
{ value: 'html', label: 'HTML'},
|
||||
{ value: 'xml', label: 'XML' },
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let title = 'Error';
|
||||
export let title = _t('common.error', { defaultMessage: 'Error' });
|
||||
export let message;
|
||||
export let showAsCode = false;
|
||||
</script>
|
||||
@@ -30,7 +31,7 @@
|
||||
{/if}
|
||||
|
||||
<div slot="footer">
|
||||
<FormSubmit value="Close" on:click={closeCurrentModal} data-testid="ErrorMessageModal_closeButton" />
|
||||
<FormSubmit value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} data-testid="ErrorMessageModal_closeButton" />
|
||||
</div>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import keycodes from '../utility/keycodes';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let onChange;
|
||||
let value;
|
||||
@@ -38,7 +39,7 @@
|
||||
</script>
|
||||
|
||||
<ModalBase {...$$restProps} simple>
|
||||
<div class="mb-2">Show desired key combination and press ENTER</div>
|
||||
<div class="mb-2">_{_t('commandModal.showKeyCombination', { defaultMessage: 'Show desired key combination and press ENTER' })}</div>
|
||||
<div class="largeFormMarker">
|
||||
<TextField on:keydown={handleKeyDown} bind:value focused />
|
||||
</div>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import ErrorMessageModal from './ErrorMessageModal.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal, showModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let driver;
|
||||
export let dbid;
|
||||
@@ -44,14 +45,14 @@
|
||||
<FormProvider initialValues={{ name: '' }}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">
|
||||
Create {driver?.collectionSingularLabel ?? 'collection/container'}
|
||||
{_t('dbObject.createCollection', { defaultMessage: 'Create collection/container'})}
|
||||
</svelte:fragment>
|
||||
|
||||
<FormArgumentList args={driver?.newCollectionFormParams} />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit value="OK" on:click={e => handleSubmit(e.detail)} disabled={isSaving} />
|
||||
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<script lang='ts'>
|
||||
import _ from 'lodash';
|
||||
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||
import newQuery from '../query/newQuery';
|
||||
import SqlEditor from '../query/SqlEditor.svelte';
|
||||
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let sql;
|
||||
export let onConfirm;
|
||||
export let engine = null;
|
||||
</script>
|
||||
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">SQL Script</div>
|
||||
|
||||
<div class="editor">
|
||||
<SqlEditor {engine} value={sql} readOnly />
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value={_t('common.close', { defaultMessage: 'Close' })}
|
||||
on:click={closeCurrentModal}
|
||||
data-testid="ShowSqlModal_closeButton"
|
||||
/>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Open script"
|
||||
on:click={() => {
|
||||
newQuery({
|
||||
initialData: sql,
|
||||
});
|
||||
|
||||
closeCurrentModal();
|
||||
}}
|
||||
data-testid="ShowSqlModal_openScriptButton"
|
||||
/>
|
||||
</div>
|
||||
</ModalBase>
|
||||
|
||||
<style>
|
||||
.editor {
|
||||
position: relative;
|
||||
height: 30vh;
|
||||
width: 40vw;
|
||||
}
|
||||
|
||||
.form-margin {
|
||||
margin: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
@@ -15,6 +15,8 @@
|
||||
import _ from 'lodash';
|
||||
import { apiCall } from '../utility/api';
|
||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||
import { base64ToHex } from 'dbgate-tools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let onConfirm;
|
||||
export let conid;
|
||||
@@ -73,15 +75,15 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Choose value from {field}</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('dataGrid.chooseValue', { defaultMessage: 'Choose value from {field}', values: { field } })}</svelte:fragment>
|
||||
|
||||
<!-- <FormTextField name="search" label='Search' placeholder="Search" bind:value={search} /> -->
|
||||
<div class="largeFormMarker">
|
||||
<SearchInput placeholder="Search" bind:value={search} isDebounced />
|
||||
<SearchInput placeholder={_t('common.search', { defaultMessage: 'Search' })} bind:value={search} isDebounced />
|
||||
</div>
|
||||
|
||||
{#if isLoading}
|
||||
<LoadingInfo message="Loading data" />
|
||||
<LoadingInfo message={_t('common.loadingData', { defaultMessage: 'Loading data' })} />
|
||||
{/if}
|
||||
|
||||
{#if !isLoading && rows}
|
||||
@@ -111,8 +113,8 @@
|
||||
},
|
||||
{
|
||||
fieldName: 'value',
|
||||
header: 'Value',
|
||||
formatter: row => (row.value == null ? '(NULL)' : row.value),
|
||||
header: _t('dataGrid.value', { defaultMessage: 'Value' }),
|
||||
formatter: row => (row.value == null ? '(NULL)' : row.value?.$binary?.base64 ? base64ToHex(row.value.$binary.base64) : row.value),
|
||||
},
|
||||
]}
|
||||
>
|
||||
@@ -146,7 +148,7 @@
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
if (force && value?.type == 'Buffer' && _.isArray(value.data)) {
|
||||
return String.fromCharCode.apply(String, value.data);
|
||||
}
|
||||
else if (force && value?.$binary?.base64) {
|
||||
return atob(value.$binary.base64);
|
||||
}
|
||||
return stringifyCellValue(value, 'gridCellIntent').value;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
--token-base: #303030;
|
||||
--token-text: #ddd;
|
||||
--token-keyword: white;
|
||||
--token-keyword: #096dd9;
|
||||
--token-selector-tag: white;
|
||||
--token-literal: white;
|
||||
--token-section: white;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
import RowsFilterSwitcher from '../forms/RowsFilterSwitcher.svelte';
|
||||
import SearchInput from '../elements/SearchInput.svelte';
|
||||
import { filterName } from 'dbgate-tools';
|
||||
import InlineButton from '../buttons/InlineButton.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
|
||||
export let items: any[];
|
||||
export let showProcedure = false;
|
||||
@@ -12,8 +14,10 @@
|
||||
export let startLine = 0;
|
||||
export let onMessageClick = null;
|
||||
export let onExplainError = null;
|
||||
export let engine = null;
|
||||
|
||||
export let filter = '';
|
||||
export let onClear = null;
|
||||
|
||||
$: time0 = items[0] && new Date(items[0].time).getTime();
|
||||
|
||||
@@ -37,6 +41,17 @@
|
||||
|
||||
<div class="main">
|
||||
<div class="topbar">
|
||||
{#if onClear}
|
||||
<InlineButton
|
||||
icon="img clear"
|
||||
on:click={() => {
|
||||
onClear();
|
||||
}}
|
||||
>
|
||||
<FontIcon icon="icon delete" padRight />
|
||||
Clear
|
||||
</InlineButton>
|
||||
{/if}
|
||||
<RowsFilterSwitcher
|
||||
icon="img debug"
|
||||
label="Debug"
|
||||
@@ -92,6 +107,7 @@
|
||||
previousRow={index > 0 ? items[index - 1] : null}
|
||||
{onMessageClick}
|
||||
{onExplainError}
|
||||
{engine}
|
||||
/>
|
||||
{/each}
|
||||
</table>
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { plusExpandIcon } from '../icons/expandIcons';
|
||||
import InlineButton from '../buttons/InlineButton.svelte';
|
||||
import SqlHighlighter from '../elements/SqlHighlighter.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import ShowSqlModal from '../modals/ShowSqlModal.svelte';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
|
||||
export let row;
|
||||
export let index;
|
||||
@@ -29,6 +33,7 @@
|
||||
export let previousRow = null;
|
||||
export let onMessageClick = null;
|
||||
export let onExplainError = null;
|
||||
export let engine = null;
|
||||
|
||||
let isExpanded = false;
|
||||
</script>
|
||||
@@ -55,10 +60,39 @@
|
||||
}}><FontIcon icon="img ai" /> Explain</InlineButton
|
||||
>
|
||||
{/if}
|
||||
{#if row.jslid}
|
||||
<InlineButton
|
||||
title="Show data"
|
||||
inlineBlock
|
||||
data-testid={`MessageViewRow-showDataButton-${index}`}
|
||||
on:click={e => {
|
||||
openNewTab({
|
||||
title: 'Query data #',
|
||||
icon: 'img query-data',
|
||||
tabComponent: 'ArchiveFileTab',
|
||||
props: {
|
||||
jslid: row.jslid,
|
||||
},
|
||||
});
|
||||
}}><FontIcon icon="img query-data" /> Show Data</InlineButton
|
||||
>
|
||||
{/if}
|
||||
{#if row.sql}
|
||||
<SqlHighlighter
|
||||
code={row.sql.substring(0, 100) + (row.sql.length > 100 ? '...' : '')}
|
||||
inline
|
||||
onClick={() => {
|
||||
showModal(ShowSqlModal, {
|
||||
sql: row.sql,
|
||||
engine,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
</td>
|
||||
<td>{moment(row.time).format('HH:mm:ss')}</td>
|
||||
<td>{formatDuration(new Date(row.time).getTime() - time0)}</td>
|
||||
<td> {previousRow ? formatDuration(new Date(row.time).getTime() - new Date(previousRow.time).getTime()) : 'n/a'}</td>
|
||||
<td>{previousRow ? formatDuration(new Date(row.time).getTime() - new Date(previousRow.time).getTime()) : 'n/a'}</td>
|
||||
{#if showProcedure}
|
||||
<td>{row.procedure || ''}</td>
|
||||
{/if}
|
||||
|
||||
@@ -12,12 +12,13 @@
|
||||
export let showLine = false;
|
||||
export let showCaller = false;
|
||||
export let eventName;
|
||||
export let executeNumber;
|
||||
export let executeNumber = null;
|
||||
export let showNoMessagesAlert = false;
|
||||
export let startLine = 0;
|
||||
export let onChangeErrors = null;
|
||||
export let onMessageClick = null;
|
||||
export let onExplainError = null;
|
||||
export let engine = null;
|
||||
|
||||
const cachedMessagesRef = createRef([]);
|
||||
const lastErrorMessageCountRef = createRef(0);
|
||||
@@ -43,6 +44,11 @@
|
||||
return () => {};
|
||||
});
|
||||
|
||||
function handleClearMessages() {
|
||||
cachedMessagesRef.set([]);
|
||||
displayedMessages = [];
|
||||
}
|
||||
|
||||
$: {
|
||||
if (executeNumber >= 0) {
|
||||
displayedMessages = [];
|
||||
@@ -79,5 +85,7 @@
|
||||
{showCaller}
|
||||
{startLine}
|
||||
{onExplainError}
|
||||
{engine}
|
||||
onClear={executeNumber == null ? handleClearMessages : null}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
@@ -143,19 +143,20 @@ ORDER BY
|
||||
label={_t('settings.tabGroup.showServerName', { defaultMessage: 'Show server name alongside database name in title of the tab group' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
<!-- <div class="heading">{_t('settings.localization', { defaultMessage: 'Localization' })}</div>
|
||||
<div class="heading">{_t('settings.localization', { defaultMessage: 'Localization' })}</div>
|
||||
<FormSelectField
|
||||
label="Language"
|
||||
label={_t('settings.localization.language', { defaultMessage: 'Language' })}
|
||||
name="localization.language"
|
||||
defaultValue={getSelectedLanguage()}
|
||||
isNative
|
||||
options={[
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'cs', label: 'Czech' },
|
||||
{ value: 'cs', label: 'Čeština' },
|
||||
{ value: 'sk', label: 'Slovenčina' },
|
||||
]}
|
||||
on:change={() => {
|
||||
showModal(ConfirmModal, {
|
||||
message: 'Application will be reloaded to apply new language settings',
|
||||
message: _t('settings.localization.reloadWarning', { defaultMessage: 'Application will be reloaded to apply new language settings' }),
|
||||
onConfirm: () => {
|
||||
setTimeout(() => {
|
||||
internalRedirectTo('/');
|
||||
@@ -163,7 +164,7 @@ ORDER BY
|
||||
},
|
||||
});
|
||||
}}
|
||||
/> -->
|
||||
/>
|
||||
|
||||
<div class="heading">{_t('settings.dataGrid.title', { defaultMessage: 'Data grid' })}</div>
|
||||
<FormTextField
|
||||
|
||||
+37
-18
@@ -9,6 +9,7 @@ import { safeJsonParse } from 'dbgate-tools';
|
||||
import { apiCall } from './utility/api';
|
||||
import { getOpenedTabsStorageName, isAdminPage } from './utility/pageDefs';
|
||||
import { switchCurrentDatabase } from './utility/common';
|
||||
import { tick } from 'svelte';
|
||||
|
||||
export interface TabDefinition {
|
||||
title: string;
|
||||
@@ -189,7 +190,6 @@ export const cloudConnectionsStore = writable({});
|
||||
|
||||
export const promoWidgetPreview = writable(null);
|
||||
|
||||
|
||||
export const DEFAULT_OBJECT_SEARCH_SETTINGS = {
|
||||
pureName: true,
|
||||
schemaName: false,
|
||||
@@ -228,6 +228,12 @@ currentTheme.subscribe(value => {
|
||||
});
|
||||
export const getCurrentTheme = () => currentThemeValue;
|
||||
|
||||
let extensionsValue: ExtensionsDirectory = null;
|
||||
extensions.subscribe(value => {
|
||||
extensionsValue = value;
|
||||
});
|
||||
export const getExtensions = () => extensionsValue;
|
||||
|
||||
export const currentThemeDefinition = derived(
|
||||
[currentTheme, extensions, systemThemeStore],
|
||||
([$currentTheme, $extensions, $systemTheme]) => {
|
||||
@@ -239,7 +245,9 @@ currentThemeDefinition.subscribe(value => {
|
||||
if (value?.themeType && getCurrentTheme()) {
|
||||
localStorage.setItem('currentThemeType', value?.themeType);
|
||||
} else {
|
||||
localStorage.removeItem('currentThemeType');
|
||||
if (extensionsValue?.themes?.length > 0) {
|
||||
localStorage.removeItem('currentThemeType');
|
||||
}
|
||||
}
|
||||
});
|
||||
export const openedConnectionsWithTemporary = derived(
|
||||
@@ -310,17 +318,40 @@ openedTabs.subscribe(value => {
|
||||
});
|
||||
export const getOpenedTabs = () => openedTabsValue;
|
||||
|
||||
let openedModalsValue = [];
|
||||
openedModals.subscribe(value => {
|
||||
openedModalsValue = value;
|
||||
|
||||
tick().then(() => {
|
||||
dispatchUpdateCommands();
|
||||
});
|
||||
});
|
||||
export const getOpenedModals = () => openedModalsValue;
|
||||
|
||||
let commandsValue = null;
|
||||
commands.subscribe(value => {
|
||||
commandsValue = value;
|
||||
|
||||
const electron = getElectron();
|
||||
if (electron) {
|
||||
electron.send('update-commands', JSON.stringify(value));
|
||||
}
|
||||
tick().then(() => {
|
||||
dispatchUpdateCommands();
|
||||
});
|
||||
});
|
||||
export const getCommands = () => commandsValue;
|
||||
|
||||
function dispatchUpdateCommands() {
|
||||
const electron = getElectron();
|
||||
if (electron) {
|
||||
electron.send(
|
||||
'update-commands',
|
||||
JSON.stringify({
|
||||
isModalOpened: openedModalsValue?.length > 0,
|
||||
commands: commandsValue,
|
||||
dbgatePage: window['dbgate_page'],
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let activeTabValue = null;
|
||||
activeTab.subscribe(value => {
|
||||
activeTabValue = value;
|
||||
@@ -366,12 +397,6 @@ export const getCurrentDatabase = () => currentDatabaseValue;
|
||||
let currentSettingsValue = null;
|
||||
export const getCurrentSettings = () => currentSettingsValue || {};
|
||||
|
||||
let extensionsValue: ExtensionsDirectory = null;
|
||||
extensions.subscribe(value => {
|
||||
extensionsValue = value;
|
||||
});
|
||||
export const getExtensions = () => extensionsValue;
|
||||
|
||||
let openedConnectionsValue = null;
|
||||
openedConnections.subscribe(value => {
|
||||
openedConnectionsValue = value;
|
||||
@@ -418,12 +443,6 @@ selectedDatabaseObjectAppObject.subscribe(value => {
|
||||
});
|
||||
export const getSelectedDatabaseObjectAppObject = () => selectedDatabaseObjectAppObjectValue;
|
||||
|
||||
let openedModalsValue = [];
|
||||
openedModals.subscribe(value => {
|
||||
openedModalsValue = value;
|
||||
});
|
||||
export const getOpenedModals = () => openedModalsValue;
|
||||
|
||||
let focusedConnectionOrDatabaseValue = null;
|
||||
focusedConnectionOrDatabase.subscribe(value => {
|
||||
focusedConnectionOrDatabaseValue = value;
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header"
|
||||
>{constraintInfo ? _t('tableEdit.editConstraintLabel', { defaultMessage: 'Edit {constraintLabel}', values: { constraintLabel: _.isFunction(constraintLabel) ? constraintLabel() : constraintLabel } }) : _t('tableEdit.addConstraintLabel', { defaultMessage: 'Add {constraintLabel}', values: { constraintLabel: _.isFunction(constraintLabel) ? constraintLabel() : constraintLabel } })}</svelte:fragment
|
||||
>{constraintInfo ? _t('tableEdit.editConstraintLabel', { defaultMessage: 'Edit {constraintLabel}', values: { constraintLabel } }) : _t('tableEdit.addConstraintLabel', { defaultMessage: 'Add {constraintLabel}', values: { constraintLabel } })}</svelte:fragment
|
||||
>
|
||||
|
||||
<div class="largeFormMarker">
|
||||
|
||||
@@ -239,8 +239,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.nextTab',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.nextTab', { defaultMessage: 'Next tab' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.nextTab', { defaultMessage: 'Next tab' }),
|
||||
keyText: 'Ctrl+Tab',
|
||||
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 2,
|
||||
onClick: () => switchTabByOrder(false),
|
||||
@@ -248,8 +248,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.previousTab',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.previousTab', { defaultMessage: 'Previous tab' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.previousTab', { defaultMessage: 'Previous tab' }),
|
||||
keyText: 'Ctrl+Shift+Tab',
|
||||
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 2,
|
||||
onClick: () => switchTabByOrder(true),
|
||||
@@ -257,16 +257,16 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.closeAll',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.closeAll', { defaultMessage: 'Close all tabs' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.closeAll', { defaultMessage: 'Close all tabs' }),
|
||||
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 1,
|
||||
onClick: closeAll,
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.closeTab',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.closeTab', { defaultMessage: 'Close tab' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.closeTab', { defaultMessage: 'Close tab' }),
|
||||
keyText: isElectronAvailable() ? 'CtrlOrCommand+W' : 'Alt+W',
|
||||
testEnabled: () => {
|
||||
const hasAnyOtherTab = getOpenedTabs().filter(x => !x.closedTime).length >= 1;
|
||||
@@ -279,24 +279,24 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.closeTabsWithCurrentDb',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.closeTabsWithCurrentDb', { defaultMessage: 'Close tabs with current DB' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.closeTabsWithCurrentDb', { defaultMessage: 'Close tabs with current DB' }),
|
||||
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 1 && !!getCurrentDatabase(),
|
||||
onClick: closeTabsWithCurrentDb,
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.closeTabsButCurrentDb',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.closeTabsButCurrentDb', { defaultMessage: 'Close tabs but current DB' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.closeTabsButCurrentDb', { defaultMessage: 'Close tabs but current DB' }),
|
||||
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 1 && !!getCurrentDatabase(),
|
||||
onClick: closeTabsButCurrentDb,
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.reopenClosedTab',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.reopenClosedTab', { defaultMessage: 'Reopen closed tab' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.reopenClosedTab', { defaultMessage: 'Reopen closed tab' }),
|
||||
keyText: 'CtrlOrCommand+Shift+T',
|
||||
testEnabled: () => getOpenedTabs().filter(x => x.closedTime).length >= 1,
|
||||
onClick: reopenClosedTab,
|
||||
@@ -304,8 +304,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tabs.addToFavorites',
|
||||
category: 'Tabs',
|
||||
name: _t('command.tabs.addToFavorites', { defaultMessage: 'Add current tab to favorites' }),
|
||||
category: __t('command.tabs', { defaultMessage: 'Tabs' }),
|
||||
name: __t('command.tabs.addToFavorites', { defaultMessage: 'Add current tab to favorites' }),
|
||||
// icon: 'icon favorite',
|
||||
// toolbar: true,
|
||||
testEnabled: () =>
|
||||
@@ -360,6 +360,7 @@
|
||||
import NewObjectModal from '../modals/NewObjectModal.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { openWebLink } from '../utility/simpleTools';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let multiTabIndex;
|
||||
export let shownTab;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
registerCommand({
|
||||
id: 'archiveFile.save',
|
||||
group: 'save',
|
||||
category: 'Archive file',
|
||||
name: 'Save',
|
||||
category: __t('command.archiveFile', { defaultMessage: 'Archive file' }),
|
||||
name: __t('command.archiveFile.save', { defaultMessage: 'Save' }),
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
icon: 'icon save',
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'archiveFile.saveAs',
|
||||
category: 'Archive file',
|
||||
name: 'Save as',
|
||||
category: __t('command.archiveFile', { defaultMessage: 'Archive file' }),
|
||||
name: __t('command.archiveFile.saveAs', { defaultMessage: 'Save as' }),
|
||||
icon: 'icon save',
|
||||
isRelatedToTab: true,
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
@@ -49,6 +49,7 @@
|
||||
import { changeTab, markTabSaved, markTabUnsaved, sleep } from '../utility/common';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
import createUndoReducer from '../utility/createUndoReducer';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export const activator = createActivator('ArchiveFileTab', true);
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
registerCommand({
|
||||
id: 'collectionTable.save',
|
||||
group: 'save',
|
||||
category: 'Collection data',
|
||||
name: 'Save',
|
||||
category: __t('command.collectionData', { defaultMessage: 'Collection data' }),
|
||||
name: __t('command.collectionData.save', { defaultMessage: 'Save' }),
|
||||
// keyText: 'CtrlOrCommand+S',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -56,6 +56,7 @@
|
||||
import useEditorData from '../query/useEditorData';
|
||||
import { markTabSaved, markTabUnsaved } from '../utility/common';
|
||||
import { getNumberIcon } from '../icons/FontIcon.svelte';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
registerFileCommands({
|
||||
idPrefix: 'diagram',
|
||||
category: 'Diagram',
|
||||
category: __t('command.diagram', { defaultMessage: 'Diagram' }),
|
||||
getCurrentEditor,
|
||||
folder: 'diagrams',
|
||||
format: 'json',
|
||||
@@ -32,6 +32,7 @@
|
||||
import DiagramSettings from '../designer/DiagramSettings.svelte';
|
||||
import { derived } from 'svelte/store';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
registerFileCommands({
|
||||
idPrefix: 'favoriteJsonEditor',
|
||||
category: 'Favorite JSON editor',
|
||||
category: __t('command.favoriteJsonEditor', { defaultMessage: 'Favorite JSON editor' }),
|
||||
getCurrentEditor,
|
||||
folder: null,
|
||||
format: null,
|
||||
@@ -15,15 +15,15 @@
|
||||
registerCommand({
|
||||
id: 'favoriteJsonEditor.save',
|
||||
group: 'save',
|
||||
name: 'Save',
|
||||
category: 'Favorite JSON editor',
|
||||
name: __t('command.favoriteJsonEditor.save', { defaultMessage: 'Save' }),
|
||||
category: __t('command.favoriteJsonEditor', { defaultMessage: 'Favorite JSON editor' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().save(),
|
||||
});
|
||||
registerCommand({
|
||||
id: 'favoriteJsonEditor.preview',
|
||||
name: 'Preview',
|
||||
category: 'Favorite JSON editor',
|
||||
name: __t('command.favoriteJsonEditor.preview', { defaultMessage: 'Preview' }),
|
||||
category: __t('command.favoriteJsonEditor', { defaultMessage: 'Favorite JSON editor' }),
|
||||
keyText: 'F5 | CtrlOrCommand+Enter',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().preview(),
|
||||
@@ -43,6 +43,7 @@
|
||||
import { openFavorite } from '../appobj/FavoriteFileAppObject.svelte';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let tabid;
|
||||
export let savedFile;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
id: 'jsonl.save',
|
||||
group: 'save',
|
||||
category: 'JSON Lines editor',
|
||||
name: 'Save',
|
||||
name: __t('command.jsonl.save', { defaultMessage: 'Save' }),
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
icon: 'icon save',
|
||||
@@ -28,7 +28,7 @@
|
||||
registerCommand({
|
||||
id: 'jsonl.preview',
|
||||
category: 'JSON Lines editor',
|
||||
name: 'Preview',
|
||||
name: __t('command.jsonl.preview', { defaultMessage: 'Preview' }),
|
||||
icon: 'icon preview',
|
||||
keyText: 'F5',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
@@ -38,7 +38,7 @@
|
||||
registerCommand({
|
||||
id: 'jsonl.previewNewTab',
|
||||
category: 'JSON Lines editor',
|
||||
name: 'Preview in new tab',
|
||||
name: __t('command.jsonl.previewNewTab', { defaultMessage: 'Preview in new tab' }),
|
||||
icon: 'icon preview',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().previewMewTab(),
|
||||
@@ -47,7 +47,7 @@
|
||||
registerCommand({
|
||||
id: 'jsonl.closePreview',
|
||||
category: 'JSON Lines editor',
|
||||
name: 'Close preview',
|
||||
name: __t('command.jsonl.closePreview', { defaultMessage: 'Close preview' }),
|
||||
icon: 'icon close',
|
||||
testEnabled: () => getCurrentEditor()?.isPreview(),
|
||||
onClick: () => getCurrentEditor().closePreview(),
|
||||
@@ -74,6 +74,7 @@
|
||||
import VerticalSplitter from '../elements/VerticalSplitter.svelte';
|
||||
import JslDataGrid from '../datagrid/JslDataGrid.svelte';
|
||||
import ToolStripCommandSplitButton from '../buttons/ToolStripCommandSplitButton.svelte';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let tabid;
|
||||
export let archiveFolder;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
registerCommand({
|
||||
id: 'markdown.preview',
|
||||
category: 'Markdown',
|
||||
name: 'Preview',
|
||||
name: __t('command.markdown.preview', { defaultMessage: 'Preview' }),
|
||||
icon: 'icon run',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -38,6 +38,7 @@
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import { setSelectedTab } from '../utility/common';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let tabid;
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'queryData.stopLoading',
|
||||
category: 'Query data',
|
||||
name: 'Stop loading',
|
||||
category: __t('command.queryData', { defaultMessage: 'Query data' }),
|
||||
name: __t('command.queryData.stopLoading', { defaultMessage: 'Stop loading' }),
|
||||
icon: 'icon stop',
|
||||
testEnabled: () => getCurrentEditor()?.isLoading(),
|
||||
onClick: () => getCurrentEditor().stopLoading(),
|
||||
@@ -32,6 +32,7 @@
|
||||
import yaml from 'js-yaml';
|
||||
import JslChart from '../charts/JslChart.svelte';
|
||||
import ToolStripButton from '../buttons/ToolStripButton.svelte';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export const activator = createActivator('QueryDataTab', true);
|
||||
|
||||
|
||||
@@ -771,12 +771,12 @@
|
||||
<SocketMessageView
|
||||
eventName={sessionId ? `session-info-${sessionId}` : null}
|
||||
onMessageClick={handleMesageClick}
|
||||
{executeNumber}
|
||||
startLine={executeStartLine}
|
||||
showProcedure
|
||||
showLine
|
||||
onChangeErrors={handleChangeErrors}
|
||||
onExplainError={isProApp() ? handleExplainError : null}
|
||||
engine={$connection && $connection.engine}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</ResultTabs>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'serverSummary.refresh',
|
||||
category: 'Server sumnmary',
|
||||
name: _t('common.refresh', { defaultMessage: 'Refresh' }),
|
||||
category: __t('command.serverSummary', { defaultMessage: 'Server summary' }),
|
||||
name: __t('common.refresh', { defaultMessage: 'Refresh' }),
|
||||
keyText: 'F5 | CtrlOrCommand+R',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -21,7 +21,7 @@
|
||||
import LoadingInfo from '../elements/LoadingInfo.svelte';
|
||||
import TabControl from '../elements/TabControl.svelte';
|
||||
|
||||
import { _t } from '../translations';
|
||||
import { _t, __t } from '../translations';
|
||||
import { apiCall } from '../utility/api';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
registerCommand({
|
||||
id: 'shell.copyNodeScript',
|
||||
category: 'Shell',
|
||||
name: 'Copy nodejs script',
|
||||
name: __t('command.shell.copyNodeScript', { defaultMessage: 'Copy nodejs script' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().copyNodeScript(),
|
||||
});
|
||||
@@ -49,6 +49,7 @@
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
import useEffect from '../utility/useEffect';
|
||||
import useTimerLabel from '../utility/useTimerLabel';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let tabid;
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'sqlObject.find',
|
||||
category: 'SQL Object',
|
||||
name: 'Find',
|
||||
category: __t('command.sqlObject', { defaultMessage: 'SQL Object' }),
|
||||
name: __t('command.sqlObject.find', { defaultMessage: 'Find' }),
|
||||
keyText: 'CtrlOrCommand+F',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().find(),
|
||||
@@ -31,6 +31,7 @@
|
||||
import ToolStripButton from '../buttons/ToolStripButton.svelte';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import { getBoolSettingsValue } from '../settings/settingsTools';
|
||||
import { __t } from '../translations';
|
||||
|
||||
export let tabid;
|
||||
export let appObjectData;
|
||||
|
||||
@@ -81,3 +81,7 @@ export function _t(key: string, options: TranslateOptions): string {
|
||||
export function __t(key: string, options: TranslateOptions): () => string {
|
||||
return () => _t(key, options);
|
||||
}
|
||||
|
||||
export function _val<T>(x: T | (() => T)): T {
|
||||
return typeof x === 'function' ? (x as () => T)() : x;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { currentDatabase, getExtensions, getOpenedTabs, loadingSchemaLists, open
|
||||
import _ from 'lodash';
|
||||
import { getSchemaList } from './metadataLoaders';
|
||||
import { showSnackbarError } from './snackbar';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export class LoadingToken {
|
||||
isCanceled = false;
|
||||
@@ -57,8 +58,14 @@ export function setSelectedTab(tabid) {
|
||||
}
|
||||
|
||||
export function getObjectTypeFieldLabel(objectTypeField, driver?) {
|
||||
if (objectTypeField == 'matviews') return 'Materialized Views';
|
||||
if (objectTypeField == 'collections') return _.startCase(driver?.collectionPluralLabel) ?? 'Collections/Containers';
|
||||
if (objectTypeField == 'tables') return _t('dbObject.tables', { defaultMessage: 'Tables' });
|
||||
if (objectTypeField == 'views') return _t('dbObject.views', { defaultMessage: 'Views' });
|
||||
if (objectTypeField == 'procedures') return _t('dbObject.procedures', { defaultMessage: 'Procedures' });
|
||||
if (objectTypeField == 'functions') return _t('dbObject.functions', { defaultMessage: 'Functions' });
|
||||
if (objectTypeField == 'triggers') return _t('dbObject.triggers', { defaultMessage: 'Triggers' });
|
||||
if (objectTypeField == 'schedulerEvents') return _t('dbObject.schedulerEvents', { defaultMessage: 'Scheduler Events' });
|
||||
if (objectTypeField == 'matviews') return _t('dbObject.matviews', { defaultMessage: 'Materialized Views' });
|
||||
if (objectTypeField == 'collections') return _t('dbObject.collections', { defaultMessage: 'Collections/Containers' });
|
||||
return _.startCase(objectTypeField);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import invalidateCommands from '../commands/invalidateCommands';
|
||||
import { runGroupCommand } from '../commands/runCommand';
|
||||
import { currentDropDownMenu, visibleCommandPalette } from '../stores';
|
||||
import getAsArray from './getAsArray';
|
||||
import { _val } from '../translations';
|
||||
|
||||
let isContextMenuSupressed = false;
|
||||
|
||||
@@ -114,7 +115,7 @@ function mapItem(item, commands) {
|
||||
if (command) {
|
||||
const commandText = item.text || command.menuName || command.toolbarName || command.name;
|
||||
return {
|
||||
text: _.isFunction(commandText) ? commandText() : commandText,
|
||||
text: _val(commandText),
|
||||
keyText: command.keyText || command.keyTextFromGroup || command.disableHandleKeyText,
|
||||
onClick: () => {
|
||||
if (command.isGroupCommand) {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
<WidgetColumnBarItem
|
||||
title={driver?.databaseEngineTypes?.includes('document')
|
||||
? (driver?.collectionPluralLabel ?? 'Collections/containers')
|
||||
? _t('widget.collectionsContainers', { defaultMessage: 'Collections/containers' })
|
||||
: _t('widget.tablesViewsFunctions', { defaultMessage: 'Tables, views, functions' })}
|
||||
name="dbObjects"
|
||||
storageName="dbObjectsWidget"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import { getConfig } from '../utility/metadataLoaders';
|
||||
import { handleAuthOnStartup } from '../clientAuth';
|
||||
import { setConfigForPermissions } from '../utility/hasPermission';
|
||||
import { visibleTitleBar } from '../stores';
|
||||
import TitleBar from './TitleBar.svelte';
|
||||
|
||||
async function loadApi() {
|
||||
try {
|
||||
@@ -21,10 +23,22 @@
|
||||
|
||||
loadApi();
|
||||
});
|
||||
|
||||
const isDark =
|
||||
localStorage.getItem('currentThemeType') === 'dark' ||
|
||||
(!localStorage.getItem('currentThemeType') &&
|
||||
window.matchMedia &&
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
</script>
|
||||
|
||||
<div class="root theme-light theme-type-light">
|
||||
<div class="text">DbGate</div>
|
||||
<div class={`root ${isDark ? 'theme-dark theme-type-dark' : 'theme-light theme-type-light'}`}>
|
||||
{#if $visibleTitleBar}
|
||||
<div class="titlebar">
|
||||
<TitleBar />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="text" class:visibleTitleBar={!!$visibleTitleBar}>DbGate</div>
|
||||
<div class="wrap">
|
||||
<div class="logo">
|
||||
<img class="img" src="logo192.png" />
|
||||
@@ -59,6 +73,10 @@
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.text.visibleTitleBar {
|
||||
top: calc(var(--dim-titlebar-height) + 1rem);
|
||||
}
|
||||
|
||||
.root {
|
||||
color: var(--theme-font-1);
|
||||
display: flex;
|
||||
@@ -98,4 +116,12 @@
|
||||
flex-wrap: wrap;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.titlebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: var(--dim-titlebar-height);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
{#if driver?.databaseEngineTypes?.includes('document')}
|
||||
<div class="m-1" />
|
||||
<InlineButton on:click={() => runCommand('new.collection')}
|
||||
>New {driver?.collectionSingularLabel ?? 'collection/container'}</InlineButton
|
||||
>{_t('sqlObject.newCollection', { defaultMessage: 'New collection/container'})}</InlineButton
|
||||
>
|
||||
{/if}
|
||||
</WidgetsInnerContainer>
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
import { apiOn } from '../utility/api';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
|
||||
$: title = _.compact([$activeTab?.title, $currentDatabase?.name, isProApp() ? 'DbGate Premium' : 'DbGate']).join(
|
||||
' - '
|
||||
);
|
||||
$: appName = isProApp() ? 'DbGate Premium' : 'DbGate Community';
|
||||
$: title = _.compact([$activeTab?.title, $currentDatabase?.name, appName]).join(' - ');
|
||||
const electron = getElectron();
|
||||
|
||||
let isMaximized = false;
|
||||
@@ -27,11 +26,13 @@
|
||||
<div class="container" on:dblclick|stopPropagation|preventDefault={() => electron.send('window-action', 'maximize')}>
|
||||
{#if !isMac()}
|
||||
<div class="icon"><img src="logo192.png" width="20" height="20" /></div>
|
||||
<div class="menu">
|
||||
<HorizontalMenu items={mainMenuDefinition({ editMenu: !!electron })} />
|
||||
</div>
|
||||
{#if !window['dbgate_page']}
|
||||
<div class="menu">
|
||||
<HorizontalMenu items={mainMenuDefinition({ editMenu: !!electron })} />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
<div class="title">{title}</div>
|
||||
<div class="title">{window['dbgate_page'] ? appName : title}</div>
|
||||
|
||||
{#if !isMac()}
|
||||
<div class="actions">
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import NewObjectModal from '../modals/NewObjectModal.svelte';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import { usePromoWidget } from '../utility/metadataLoaders';
|
||||
import { useConfig, usePromoWidget } from '../utility/metadataLoaders';
|
||||
|
||||
let domSettings;
|
||||
let domCloudAccount;
|
||||
@@ -170,6 +170,7 @@
|
||||
}
|
||||
|
||||
$: promoWidgetData = $promoWidgetPreview || $promoWidget;
|
||||
$: config = useConfig();
|
||||
</script>
|
||||
|
||||
<div class="main">
|
||||
@@ -180,7 +181,7 @@
|
||||
{/if}
|
||||
{#each widgets
|
||||
.filter(x => x && hasPermission(`widgets/${x.name}`))
|
||||
.filter(x => !x.isPremiumPromo || (!isProApp() && promoWidgetData?.state == 'data'))
|
||||
.filter(x => !x.isPremiumPromo || (($config?.trialDaysLeft != null || !isProApp()) && promoWidgetData?.state == 'data'))
|
||||
// .filter(x => !x.isPremiumOnly || isProApp())
|
||||
.filter(x => x.name != 'cloud-private' || $cloudSigninTokenHolder) as item}
|
||||
<div
|
||||
|
||||
@@ -6,6 +6,54 @@ const { getLogger } = global.DBGATE_PACKAGES['dbgate-tools'];
|
||||
|
||||
const logger = getLogger('csvWriter');
|
||||
|
||||
class RecodeTransform extends stream.Transform {
|
||||
constructor(toEncoding = 'utf8') {
|
||||
super({ readableObjectMode: false, writableObjectMode: false });
|
||||
this.to = String(toEncoding).toLowerCase();
|
||||
this.decoder = new (global.TextDecoder || require('util').TextDecoder)('utf-8', { fatal: false });
|
||||
}
|
||||
|
||||
_encodeString(str) {
|
||||
if (this.to === 'utf8' || this.to === 'utf-8') {
|
||||
return Buffer.from(str, 'utf8');
|
||||
}
|
||||
if (this.to === 'utf16le' || this.to === 'ucs2' || this.to === 'utf-16le') {
|
||||
return Buffer.from(str, 'utf16le');
|
||||
}
|
||||
if (this.to === 'utf16be' || this.to === 'utf-16be') {
|
||||
const le = Buffer.from(str, 'utf16le');
|
||||
for (let i = 0; i + 1 < le.length; i += 2) {
|
||||
const a = le[i];
|
||||
le[i] = le[i + 1];
|
||||
le[i + 1] = a;
|
||||
}
|
||||
return le;
|
||||
}
|
||||
throw new Error(`Unsupported target encoding: ${this.to}`);
|
||||
}
|
||||
|
||||
_transform(chunk, enc, cb) {
|
||||
try {
|
||||
if (!Buffer.isBuffer(chunk)) chunk = Buffer.from(chunk, enc);
|
||||
const part = this.decoder.decode(chunk, { stream: true });
|
||||
if (part.length) this.push(this._encodeString(part));
|
||||
cb();
|
||||
} catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
}
|
||||
|
||||
_flush(cb) {
|
||||
try {
|
||||
const rest = this.decoder.decode();
|
||||
if (rest.length) this.push(this._encodeString(rest));
|
||||
cb();
|
||||
} catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CsvPrepareStream extends stream.Transform {
|
||||
constructor({ header }) {
|
||||
super({ objectMode: true });
|
||||
@@ -26,18 +74,59 @@ class CsvPrepareStream extends stream.Transform {
|
||||
}
|
||||
}
|
||||
|
||||
async function writer({ fileName, encoding = 'utf-8', header = true, delimiter, quoted }) {
|
||||
async function writer({
|
||||
fileName,
|
||||
encoding = 'utf-8',
|
||||
header = true,
|
||||
delimiter,
|
||||
quoted,
|
||||
writeBom,
|
||||
writeSepHeader,
|
||||
recordDelimiter,
|
||||
}) {
|
||||
logger.info(`DBGM-00133 Writing file ${fileName}`);
|
||||
const csvPrepare = new CsvPrepareStream({ header });
|
||||
const csvStream = csv.stringify({ delimiter, quoted });
|
||||
const csvStream = csv.stringify({ delimiter, quoted, record_delimiter: recordDelimiter || undefined });
|
||||
const fileStream = fs.createWriteStream(fileName, encoding);
|
||||
// csvPrepare.pipe(csvStream);
|
||||
// csvStream.pipe(fileStream);
|
||||
// csvPrepare['finisher'] = fileStream;
|
||||
if (writeBom) {
|
||||
switch (encoding.toLowerCase()) {
|
||||
case 'utf-8':
|
||||
case 'utf8':
|
||||
fileStream.write(Buffer.from([0xef, 0xbb, 0xbf]));
|
||||
break;
|
||||
case 'utf-16':
|
||||
case 'utf16':
|
||||
fileStream.write(Buffer.from([0xff, 0xfe]));
|
||||
break;
|
||||
case 'utf-16le':
|
||||
case 'utf16le':
|
||||
fileStream.write(Buffer.from([0xff, 0xfe]));
|
||||
break;
|
||||
case 'utf-16be':
|
||||
case 'utf16be':
|
||||
fileStream.write(Buffer.from([0xfe, 0xff]));
|
||||
break;
|
||||
case 'utf-32le':
|
||||
case 'utf32le':
|
||||
fileStream.write(Buffer.from([0xff, 0xfe, 0x00, 0x00]));
|
||||
break;
|
||||
case 'utf-32be':
|
||||
case 'utf32be':
|
||||
fileStream.write(Buffer.from([0x00, 0x00, 0xfe, 0xff]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (writeSepHeader) {
|
||||
fileStream.write(`sep=${delimiter}${recordDelimiter || '\n'}`);
|
||||
}
|
||||
|
||||
csvPrepare.requireFixedStructure = true;
|
||||
|
||||
return [csvPrepare, csvStream, fileStream];
|
||||
// return csvPrepare;
|
||||
return encoding.toLowerCase() === 'utf8' || encoding.toLowerCase() === 'utf-8'
|
||||
? [csvPrepare, csvStream, fileStream]
|
||||
: [csvPrepare, csvStream, new RecodeTransform(encoding), fileStream];
|
||||
}
|
||||
|
||||
module.exports = writer;
|
||||
|
||||
@@ -39,6 +39,24 @@ const fileFormat = {
|
||||
apiName: 'header',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'writeBom',
|
||||
label: 'Write BOM (Byte Order Mark)',
|
||||
apiName: 'writeBom',
|
||||
direction: 'target',
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
name: 'recordDelimiter',
|
||||
label: 'Record Delimiter',
|
||||
options: [
|
||||
{ name: 'CR', value: '\r' },
|
||||
{ name: 'CRLF', value: '\r\n' },
|
||||
],
|
||||
apiName: 'recordDelimiter',
|
||||
direction: 'target',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -68,5 +86,31 @@ export default {
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'CSV file for MS Excel',
|
||||
extension: 'csv',
|
||||
createWriter: (fileName) => ({
|
||||
functionName: 'writer@dbgate-plugin-csv',
|
||||
props: {
|
||||
fileName,
|
||||
delimiter: ';',
|
||||
recordDelimiter: '\r\n',
|
||||
encoding: 'utf16le',
|
||||
writeSepHeader: true,
|
||||
writeBom: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: 'TSV file (tab separated)',
|
||||
extension: 'tsv',
|
||||
createWriter: (fileName) => ({
|
||||
functionName: 'writer@dbgate-plugin-csv',
|
||||
props: {
|
||||
fileName,
|
||||
delimiter: '\t',
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -51,6 +51,10 @@ function findArrayResult(resValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function BinData(_subType, base64) {
|
||||
return Buffer.from(base64, 'base64');
|
||||
}
|
||||
|
||||
async function getScriptableDb(dbhan) {
|
||||
const db = dbhan.getDatabase();
|
||||
db.getCollection = (name) => db.collection(name);
|
||||
@@ -156,9 +160,9 @@ const driver = {
|
||||
// return printable;
|
||||
// }
|
||||
let func;
|
||||
func = eval(`(db,ObjectId) => ${sql}`);
|
||||
func = eval(`(db,ObjectId,BinData) => ${sql}`);
|
||||
const db = await getScriptableDb(dbhan);
|
||||
const res = func(db, ObjectId.createFromHexString);
|
||||
const res = func(db, ObjectId.createFromHexString, BinData);
|
||||
if (isPromise(res)) await res;
|
||||
},
|
||||
async operation(dbhan, operation, options) {
|
||||
@@ -285,7 +289,7 @@ const driver = {
|
||||
} else {
|
||||
let func;
|
||||
try {
|
||||
func = eval(`(db,ObjectId) => ${sql}`);
|
||||
func = eval(`(db,ObjectId,BinData) => ${sql}`);
|
||||
} catch (err) {
|
||||
options.info({
|
||||
message: 'Error compiling expression: ' + err.message,
|
||||
@@ -299,7 +303,7 @@ const driver = {
|
||||
|
||||
let exprValue;
|
||||
try {
|
||||
exprValue = func(db, ObjectId.createFromHexString);
|
||||
exprValue = func(db, ObjectId.createFromHexString, BinData);
|
||||
} catch (err) {
|
||||
options.info({
|
||||
message: 'Error evaluating expression: ' + err.message,
|
||||
@@ -411,9 +415,9 @@ const driver = {
|
||||
// highWaterMark: 100,
|
||||
// });
|
||||
|
||||
func = eval(`(db,ObjectId) => ${sql}`);
|
||||
func = eval(`(db,ObjectId,BinData) => ${sql}`);
|
||||
const db = await getScriptableDb(dbhan);
|
||||
exprValue = func(db, ObjectId.createFromHexString);
|
||||
exprValue = func(db, ObjectId.createFromHexString, BinData);
|
||||
|
||||
const pass = new stream.PassThrough({
|
||||
objectMode: true,
|
||||
|
||||
@@ -15,7 +15,10 @@ function mongoReplacer(key, value) {
|
||||
function jsonStringifyWithObjectId(obj) {
|
||||
return JSON.stringify(obj, mongoReplacer, 2)
|
||||
.replace(/\{\s*\"\$oid\"\s*\:\s*\"([0-9a-f]+)\"\s*\}/g, (m, id) => `ObjectId("${id}")`)
|
||||
.replace(/\{\s*\"\$bigint\"\s*\:\s*\"([0-9]+)\"\s*\}/g, (m, num) => `${num}n`);
|
||||
.replace(/\{\s*\"\$bigint\"\s*\:\s*\"([0-9]+)\"\s*\}/g, (m, num) => `${num}n`)
|
||||
.replace(/\{\s*"\$binary"\s*:\s*\{\s*"base64"\s*:\s*"([^"]+)"(?:\s*,\s*"subType"\s*:\s*"([0-9a-fA-F]{2})")?\s*\}\s*\}/g, (m, base64, subType) => {
|
||||
return `BinData(${parseInt(subType || "00", 16)}, "${base64}")`;
|
||||
});
|
||||
}
|
||||
|
||||
/** @type {import('dbgate-types').SqlDialect} */
|
||||
@@ -129,7 +132,7 @@ const driver = {
|
||||
|
||||
getCollectionExportQueryScript(collection, condition, sort) {
|
||||
return `db.getCollection('${collection}')
|
||||
.find(${JSON.stringify(convertToMongoCondition(condition) || {})})
|
||||
.find(${jsonStringifyWithObjectId(convertToMongoCondition(condition) || {})})
|
||||
.sort(${JSON.stringify(convertToMongoSort(sort) || {})})`;
|
||||
},
|
||||
getCollectionExportQueryJson(collection, condition, sort) {
|
||||
@@ -148,6 +151,7 @@ const driver = {
|
||||
parseJsonObject: true,
|
||||
parseObjectIdAsDollar: true,
|
||||
parseDateAsDollar: true,
|
||||
parseHexAsBuffer: true,
|
||||
|
||||
explicitDataType: true,
|
||||
supportNumberType: true,
|
||||
|
||||
@@ -24,6 +24,15 @@ function extractTediousColumns(columns, addDriverNativeColumn = false) {
|
||||
return res;
|
||||
}
|
||||
|
||||
function modifyRow(row, columns) {
|
||||
columns.forEach((col) => {
|
||||
if (Buffer.isBuffer(row[col.columnName])) {
|
||||
row[col.columnName] = { $binary: { base64: Buffer.from(row[col.columnName]).toString('base64') } };
|
||||
}
|
||||
});
|
||||
return row;
|
||||
}
|
||||
|
||||
async function getDefaultAzureSqlToken() {
|
||||
const credential = new ManagedIdentityCredential();
|
||||
const tokenResponse = await credential.getToken('https://database.windows.net/.default');
|
||||
@@ -69,7 +78,11 @@ async function tediousConnect(storedConnection) {
|
||||
const [host, instance] = (server || '').split('\\');
|
||||
const connectionOptions = {
|
||||
instanceName: instance,
|
||||
encrypt: !!ssl || authType == 'msentra' || authType == 'azureManagedIdentity',
|
||||
encrypt:
|
||||
!!ssl ||
|
||||
authType == 'msentra' ||
|
||||
authType == 'azureManagedIdentity' ||
|
||||
server?.endsWith('.database.windows.net'),
|
||||
cryptoCredentialsDetails: ssl ? _.pick(ssl, ['ca', 'cert', 'key']) : undefined,
|
||||
trustServerCertificate: ssl ? (!ssl.ca && !ssl.cert && !ssl.key ? true : ssl.rejectUnauthorized) : undefined,
|
||||
enableArithAbort: true,
|
||||
@@ -121,9 +134,12 @@ async function tediousQueryCore(dbhan, sql, options) {
|
||||
});
|
||||
request.on('row', function (columns) {
|
||||
result.rows.push(
|
||||
_.zipObject(
|
||||
result.columns.map(x => x.columnName),
|
||||
columns.map(x => x.value)
|
||||
modifyRow(
|
||||
_.zipObject(
|
||||
result.columns.map(x => x.columnName),
|
||||
columns.map(x => x.value)
|
||||
),
|
||||
result.columns
|
||||
)
|
||||
);
|
||||
});
|
||||
@@ -148,13 +164,17 @@ async function tediousReadQuery(dbhan, sql, structure) {
|
||||
currentColumns = extractTediousColumns(columns);
|
||||
pass.write({
|
||||
__isStreamHeader: true,
|
||||
engine: 'mssql@dbgate-plugin-mssql',
|
||||
...(structure || { columns: currentColumns }),
|
||||
});
|
||||
});
|
||||
request.on('row', function (columns) {
|
||||
const row = _.zipObject(
|
||||
currentColumns.map(x => x.columnName),
|
||||
columns.map(x => x.value)
|
||||
const row = modifyRow(
|
||||
_.zipObject(
|
||||
currentColumns.map(x => x.columnName),
|
||||
columns.map(x => x.value)
|
||||
),
|
||||
currentColumns
|
||||
);
|
||||
pass.write(row);
|
||||
});
|
||||
@@ -165,6 +185,7 @@ async function tediousReadQuery(dbhan, sql, structure) {
|
||||
|
||||
async function tediousStream(dbhan, sql, options) {
|
||||
let currentColumns = [];
|
||||
let skipAffectedMessage = false;
|
||||
|
||||
const handleInfo = info => {
|
||||
const { message, lineNumber, procName } = info;
|
||||
@@ -200,22 +221,29 @@ async function tediousStream(dbhan, sql, options) {
|
||||
dbhan.client.off('infoMessage', handleInfo);
|
||||
dbhan.client.off('errorMessage', handleError);
|
||||
|
||||
options.info({
|
||||
message: `${rowCount} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
});
|
||||
if (!skipAffectedMessage) {
|
||||
options.info({
|
||||
message: `${rowCount} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
rowsAffected: rowCount,
|
||||
});
|
||||
}
|
||||
});
|
||||
request.on('columnMetadata', function (columns) {
|
||||
currentColumns = extractTediousColumns(columns);
|
||||
options.recordset(currentColumns);
|
||||
options.recordset(currentColumns, { engine: 'mssql@dbgate-plugin-mssql' });
|
||||
});
|
||||
request.on('row', function (columns) {
|
||||
const row = _.zipObject(
|
||||
currentColumns.map(x => x.columnName),
|
||||
columns.map(x => x.value)
|
||||
const row = modifyRow(
|
||||
_.zipObject(
|
||||
currentColumns.map(x => x.columnName),
|
||||
columns.map(x => x.value)
|
||||
),
|
||||
currentColumns
|
||||
);
|
||||
options.row(row);
|
||||
skipAffectedMessage = true;
|
||||
});
|
||||
dbhan.client.execSqlBatch(request);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,15 @@ function extractColumns(fields) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function modifyRow(row, columns) {
|
||||
columns.forEach((col) => {
|
||||
if (Buffer.isBuffer(row[col.columnName])) {
|
||||
row[col.columnName] = { $binary: { base64: Buffer.from(row[col.columnName]).toString('base64') } };
|
||||
}
|
||||
});
|
||||
return row;
|
||||
}
|
||||
|
||||
function zipDataRow(rowArray, columns) {
|
||||
return _.zipObject(
|
||||
columns.map(x => x.columnName),
|
||||
@@ -99,8 +108,8 @@ const drivers = driverBases.map(driverBase => ({
|
||||
return new Promise((resolve, reject) => {
|
||||
dbhan.client.query(sql, function (error, results, fields) {
|
||||
if (error) reject(error);
|
||||
const columns = extractColumns(fields);
|
||||
resolve({ rows: results && columns && results.map && results.map(row => zipDataRow(row, columns)), columns });
|
||||
const columns = extractColumns(fields);
|
||||
resolve({ rows: results && columns && results.map && results.map(row => modifyRow(zipDataRow(row, columns), columns)), columns });
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -129,20 +138,21 @@ const drivers = driverBases.map(driverBase => ({
|
||||
message: `${row.affectedRows} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
rowsAffected: row.affectedRows,
|
||||
});
|
||||
if (row.stateChanges?.schema) {
|
||||
options.changedCurrentDatabase(row.stateChanges.schema);
|
||||
}
|
||||
} else {
|
||||
if (columns) {
|
||||
options.row(zipDataRow(row, columns));
|
||||
options.row(modifyRow(zipDataRow(row, columns), columns));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleFields = fields => {
|
||||
columns = extractColumns(fields);
|
||||
if (columns) options.recordset(columns);
|
||||
if (columns) options.recordset(columns, { engine: driverBase.engine });
|
||||
};
|
||||
|
||||
const handleError = error => {
|
||||
@@ -176,10 +186,11 @@ const drivers = driverBases.map(driverBase => ({
|
||||
columns = extractColumns(fields);
|
||||
pass.write({
|
||||
__isStreamHeader: true,
|
||||
engine: driverBase.engine,
|
||||
...(structure || { columns }),
|
||||
});
|
||||
})
|
||||
.on('result', row => pass.write(zipDataRow(row, columns)))
|
||||
.on('result', row => pass.write(modifyRow(zipDataRow(row, columns), columns)))
|
||||
.on('end', () => pass.end());
|
||||
|
||||
return pass;
|
||||
|
||||
@@ -37,6 +37,15 @@ function zipDataRow(rowArray, columns) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
function modifyRow(row, columns) {
|
||||
columns.forEach(col => {
|
||||
if (Buffer.isBuffer(row[col.columnName])) {
|
||||
row[col.columnName] = { $binary: { base64: row[col.columnName].toString('base64') } };
|
||||
}
|
||||
});
|
||||
return row;
|
||||
}
|
||||
|
||||
let oracleClientInitialized = false;
|
||||
|
||||
/** @type {import('dbgate-types').EngineDriver} */
|
||||
@@ -106,7 +115,7 @@ const driver = {
|
||||
const res = await dbhan.client.execute(sql);
|
||||
try {
|
||||
const columns = extractOracleColumns(res.metaData);
|
||||
return { rows: (res.rows || []).map(row => zipDataRow(row, columns)), columns };
|
||||
return { rows: (res.rows || []).map(row => modifyRow(zipDataRow(row, columns), columns)), columns };
|
||||
} catch (err) {
|
||||
return {
|
||||
rows: [],
|
||||
@@ -134,7 +143,7 @@ const driver = {
|
||||
if (!wasHeader) {
|
||||
columns = extractOracleColumns(row);
|
||||
if (columns && columns.length > 0) {
|
||||
options.recordset(columns);
|
||||
options.recordset(columns, { engine: driverBase.engine });
|
||||
}
|
||||
wasHeader = true;
|
||||
}
|
||||
@@ -147,11 +156,11 @@ const driver = {
|
||||
if (!wasHeader) {
|
||||
columns = extractOracleColumns(row);
|
||||
if (columns && columns.length > 0) {
|
||||
options.recordset(columns);
|
||||
options.recordset(columns, { engine: driverBase.engine });
|
||||
}
|
||||
wasHeader = true;
|
||||
}
|
||||
options.row(zipDataRow(row, columns));
|
||||
options.row(modifyRow(zipDataRow(row, columns), columns));
|
||||
});
|
||||
|
||||
query.on('end', () => {
|
||||
@@ -214,15 +223,16 @@ const driver = {
|
||||
|
||||
if (rows && metaData) {
|
||||
const columns = extractOracleColumns(metaData);
|
||||
options.recordset(columns);
|
||||
options.recordset(columns, { engine: driverBase.engine });
|
||||
for (const row of rows) {
|
||||
options.row(zipDataRow(row, columns));
|
||||
options.row(modifyRow(zipDataRow(row, columns), columns));
|
||||
}
|
||||
} else if (rowsAffected) {
|
||||
options.info({
|
||||
message: `${rowsAffected} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
rowsAffected,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -302,6 +312,7 @@ const driver = {
|
||||
if (columns && columns.length > 0) {
|
||||
pass.write({
|
||||
__isStreamHeader: true,
|
||||
engine: driverBase.engine,
|
||||
...(structure || { columns }),
|
||||
});
|
||||
}
|
||||
@@ -310,7 +321,7 @@ const driver = {
|
||||
});
|
||||
|
||||
query.on('data', row => {
|
||||
pass.write(zipDataRow(row, columns));
|
||||
pass.write(modifyRow(zipDataRow(row, columns), columns));
|
||||
});
|
||||
|
||||
query.on('end', () => {
|
||||
|
||||
@@ -136,9 +136,9 @@ class Dumper extends SqlDumper {
|
||||
// else super.putValue(value);
|
||||
// }
|
||||
|
||||
// putByteArrayValue(value) {
|
||||
// this.putRaw(`e'\\\\x${arrayToHexString(value)}'`);
|
||||
// }
|
||||
putByteArrayValue(value) {
|
||||
this.putRaw(`HEXTORAW('${arrayToHexString(value)}')`);
|
||||
}
|
||||
|
||||
putValue(value, dataType) {
|
||||
if (dataType?.toLowerCase() == 'timestamp') {
|
||||
|
||||
@@ -48,6 +48,9 @@ function transformRow(row, columnsToTransform) {
|
||||
if (dataTypeName == 'geography') {
|
||||
row[columnName] = extractGeographyDate(row[columnName]);
|
||||
}
|
||||
else if (dataTypeName == 'bytea' && row[columnName]) {
|
||||
row[columnName] = { $binary: { base64: Buffer.from(row[columnName]).toString('base64') } };
|
||||
}
|
||||
}
|
||||
|
||||
return row;
|
||||
@@ -159,7 +162,7 @@ const drivers = driverBases.map(driverBase => ({
|
||||
conid,
|
||||
};
|
||||
|
||||
const datatypes = await this.query(dbhan, `SELECT oid, typname FROM pg_type WHERE typname in ('geography')`);
|
||||
const datatypes = await this.query(dbhan, `SELECT oid, typname FROM pg_type WHERE typname in ('geography', 'bytea')`);
|
||||
const typeIdToName = _.fromPairs(datatypes.rows.map(cur => [cur.oid, cur.typname]));
|
||||
dbhan['typeIdToName'] = typeIdToName;
|
||||
|
||||
@@ -181,7 +184,14 @@ const drivers = driverBases.map(driverBase => ({
|
||||
}
|
||||
const res = await dbhan.client.query({ text: sql, rowMode: 'array' });
|
||||
const columns = extractPostgresColumns(res, dbhan);
|
||||
return { rows: (res.rows || []).map(row => zipDataRow(row, columns)), columns };
|
||||
|
||||
const transormableTypeNames = Object.values(dbhan.typeIdToName ?? {});
|
||||
const columnsToTransform = columns.filter(x => transormableTypeNames.includes(x.dataTypeName));
|
||||
|
||||
const zippedRows = (res.rows || []).map(row => zipDataRow(row, columns));
|
||||
const transformedRows = zippedRows.map(row => transformRow(row, columnsToTransform));
|
||||
|
||||
return { rows: transformedRows, columns };
|
||||
},
|
||||
stream(dbhan, sql, options) {
|
||||
const handleNotice = notice => {
|
||||
@@ -208,7 +218,7 @@ const drivers = driverBases.map(driverBase => ({
|
||||
if (!wasHeader) {
|
||||
columns = extractPostgresColumns(query._result, dbhan);
|
||||
if (columns && columns.length > 0) {
|
||||
options.recordset(columns);
|
||||
options.recordset(columns, { engine: driverBase.engine });
|
||||
}
|
||||
wasHeader = true;
|
||||
}
|
||||
@@ -232,6 +242,7 @@ const drivers = driverBases.map(driverBase => ({
|
||||
message: `${rowCount} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
rowsAffected: rowCount,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -327,6 +338,7 @@ const drivers = driverBases.map(driverBase => ({
|
||||
columns = extractPostgresColumns(query._result, dbhan);
|
||||
pass.write({
|
||||
__isStreamHeader: true,
|
||||
engine: driverBase.engine,
|
||||
...(structure || { columns }),
|
||||
});
|
||||
wasHeader = true;
|
||||
|
||||
@@ -4,7 +4,7 @@ const stream = require('stream');
|
||||
const driverBases = require('../frontend/drivers');
|
||||
const Analyser = require('./Analyser');
|
||||
const { splitQuery, sqliteSplitterOptions } = require('dbgate-query-splitter');
|
||||
const { runStreamItem, waitForDrain } = require('./helpers');
|
||||
const { runStreamItem, waitForDrain, modifyRow } = require('./helpers');
|
||||
const { getLogger, createBulkInsertStreamBase, extractErrorLogData } = global.DBGATE_PACKAGES['dbgate-tools'];
|
||||
|
||||
const logger = getLogger('sqliteDriver');
|
||||
@@ -51,7 +51,7 @@ const libsqlDriver = {
|
||||
const columns = stmtColumns.length > 0 ? stmtColumns : extractColumns(rows[0]);
|
||||
|
||||
return {
|
||||
rows,
|
||||
rows: rows.map((row) => modifyRow(row, columns)),
|
||||
columns: columns.map((col) => ({
|
||||
columnName: col.name,
|
||||
dataType: col.type,
|
||||
@@ -66,7 +66,7 @@ const libsqlDriver = {
|
||||
console.log('#stream', sql);
|
||||
const inTransaction = dbhan.client.transaction(() => {
|
||||
for (const sqlItem of sqlSplitted) {
|
||||
runStreamItem(dbhan, sqlItem, options, rowCounter);
|
||||
runStreamItem(dbhan, sqlItem, options, rowCounter, driverBases[1].engine);
|
||||
}
|
||||
|
||||
if (rowCounter.date) {
|
||||
@@ -74,6 +74,7 @@ const libsqlDriver = {
|
||||
message: `${rowCounter.count} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
rowsAffected: rowCounter.count,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -114,9 +115,10 @@ const libsqlDriver = {
|
||||
|
||||
async readQueryTask(stmt, pass) {
|
||||
// let sent = 0;
|
||||
const columns = stmt.columns();
|
||||
for (const row of stmt.iterate()) {
|
||||
// sent++;
|
||||
if (!pass.write(row)) {
|
||||
if (!pass.write(modifyRow(row, columns))) {
|
||||
// console.log('WAIT DRAIN', sent);
|
||||
await waitForDrain(pass);
|
||||
}
|
||||
@@ -134,6 +136,7 @@ const libsqlDriver = {
|
||||
|
||||
pass.write({
|
||||
__isStreamHeader: true,
|
||||
engine: driverBases[1].engine,
|
||||
...(structure || {
|
||||
columns: columns.map((col) => ({
|
||||
columnName: col.name,
|
||||
|
||||
@@ -5,7 +5,7 @@ const Analyser = require('./Analyser');
|
||||
const driverBases = require('../frontend/drivers');
|
||||
const { splitQuery, sqliteSplitterOptions } = require('dbgate-query-splitter');
|
||||
const { getLogger, createBulkInsertStreamBase, extractErrorLogData } = global.DBGATE_PACKAGES['dbgate-tools'];
|
||||
const { runStreamItem, waitForDrain } = require('./helpers');
|
||||
const { runStreamItem, waitForDrain, modifyRow } = require('./helpers');
|
||||
|
||||
const logger = getLogger('sqliteDriver');
|
||||
|
||||
@@ -40,7 +40,7 @@ const driver = {
|
||||
const columns = stmt.columns();
|
||||
const rows = stmt.all();
|
||||
return {
|
||||
rows,
|
||||
rows: rows.map((row) => modifyRow(row, columns)),
|
||||
columns: columns.map((col) => ({
|
||||
columnName: col.name,
|
||||
dataType: col.type,
|
||||
@@ -61,7 +61,7 @@ const driver = {
|
||||
|
||||
const inTransaction = dbhan.client.transaction(() => {
|
||||
for (const sqlItem of sqlSplitted) {
|
||||
runStreamItem(dbhan, sqlItem, options, rowCounter);
|
||||
runStreamItem(dbhan, sqlItem, options, rowCounter, driverBases[0].engine);
|
||||
}
|
||||
|
||||
if (rowCounter.date) {
|
||||
@@ -69,6 +69,7 @@ const driver = {
|
||||
message: `${rowCounter.count} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
rowsAffected: rowCounter.count,
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -102,9 +103,10 @@ const driver = {
|
||||
|
||||
async readQueryTask(stmt, pass) {
|
||||
// let sent = 0;
|
||||
const columns = stmt.columns();
|
||||
for (const row of stmt.iterate()) {
|
||||
// sent++;
|
||||
if (!pass.write(row)) {
|
||||
if (!pass.write(modifyRow(row, columns))) {
|
||||
// console.log('WAIT DRAIN', sent);
|
||||
await waitForDrain(pass);
|
||||
}
|
||||
@@ -122,6 +124,7 @@ const driver = {
|
||||
|
||||
pass.write({
|
||||
__isStreamHeader: true,
|
||||
engine: driverBases[0].engine,
|
||||
...(structure || {
|
||||
columns: columns.map((col) => ({
|
||||
columnName: col.name,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
|
||||
function runStreamItem(dbhan, sql, options, rowCounter) {
|
||||
function runStreamItem(dbhan, sql, options, rowCounter, engine) {
|
||||
const stmt = dbhan.client.prepare(sql);
|
||||
console.log(stmt);
|
||||
console.log(stmt.reader);
|
||||
@@ -12,11 +12,12 @@ function runStreamItem(dbhan, sql, options, rowCounter) {
|
||||
columns.map((col) => ({
|
||||
columnName: col.name,
|
||||
dataType: col.type,
|
||||
}))
|
||||
})),
|
||||
{ engine }
|
||||
);
|
||||
|
||||
for (const row of stmt.iterate()) {
|
||||
options.row(row);
|
||||
options.row(modifyRow(row, columns));
|
||||
}
|
||||
} else {
|
||||
const info = stmt.run();
|
||||
@@ -27,6 +28,7 @@ function runStreamItem(dbhan, sql, options, rowCounter) {
|
||||
message: `${rowCounter.count} rows affected`,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
rowsAffected: rowCounter.count,
|
||||
});
|
||||
rowCounter.count = 0;
|
||||
rowCounter.date = null;
|
||||
@@ -43,7 +45,17 @@ async function waitForDrain(stream) {
|
||||
});
|
||||
}
|
||||
|
||||
function modifyRow(row, columns) {
|
||||
columns.forEach((col) => {
|
||||
if (row[col.name] instanceof Uint8Array || row[col.name] instanceof ArrayBuffer) {
|
||||
row[col.name] = { $binary: { base64: Buffer.from(row[col.name]).toString('base64') } };
|
||||
}
|
||||
});
|
||||
return row;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
runStreamItem,
|
||||
waitForDrain,
|
||||
modifyRow,
|
||||
};
|
||||
|
||||
@@ -45,6 +45,10 @@ class StringifyStream extends stream.Transform {
|
||||
|
||||
elementValue(element, value) {
|
||||
this.startElement(element);
|
||||
if (value?.$binary?.base64) {
|
||||
const buffer = Buffer.from(value.$binary.base64, 'base64');
|
||||
value = '0x' +buffer.toString('hex').toUpperCase();
|
||||
}
|
||||
this.push(escapeXml(`${value}`));
|
||||
this.endElement(element);
|
||||
}
|
||||
|
||||
+220
-1
@@ -44,6 +44,64 @@
|
||||
"columnsConstraintEditor.addNewColumn": "Přidat nový sloupec",
|
||||
"columnsConstraintEditor.chooseColumn": "Vybrat sloupec",
|
||||
"columnsConstraintEditor.selectColumn": "Vybrat sloupec",
|
||||
"command.about": "O aplikaci",
|
||||
"command.about.show": "Zobrazit",
|
||||
"command.about.toolbar": "O aplikaci",
|
||||
"command.app.checkForUpdates": "Zkontrolovat dostupné aktualizace",
|
||||
"command.app.disconnect": "Odpojit",
|
||||
"command.app.loggedUser": "Přihlášený uživatel",
|
||||
"command.app.logout": "Odhlásit",
|
||||
"command.application": "Aplikace",
|
||||
"command.application.becomeSponsor": "Stát se sponzorem",
|
||||
"command.application.documentation": "Dokumentace",
|
||||
"command.application.maximize": "Maximalizovat",
|
||||
"command.application.minimize": "Minimalizovat",
|
||||
"command.application.openIssue": "Nahlásit problém nebo požadavek na funkci",
|
||||
"command.application.reload": "Obnovit",
|
||||
"command.application.toggleDevTools": "Přepnout vývojářské nástroje",
|
||||
"command.application.toggleFullScreen": "Přepnout celou obrazovku",
|
||||
"command.application.unsetCurrentDatabase": "Zrušit aktuální databázi",
|
||||
"command.application.web": "DbGate web",
|
||||
"command.application.zoomIn": "Přiblížit",
|
||||
"command.application.zoomOut": "Oddálit",
|
||||
"command.application.zoomReset": "Resetovat přiblížení",
|
||||
"command.archiveFile": "Archivní soubor",
|
||||
"command.archiveFile.save": "Uložit",
|
||||
"command.archiveFile.saveAs": "Uložit jako",
|
||||
"command.cloud": "Cloud",
|
||||
"command.cloud.logout": "Odhlásit",
|
||||
"command.collectionData": "Data kolekce",
|
||||
"command.collectionData.collapseAll": "Sbalit vše",
|
||||
"command.collectionData.expandAll": "Rozbalit vše",
|
||||
"command.collectionData.save": "Uložit",
|
||||
"command.commandPalette": "Paleta příkazů",
|
||||
"command.commandPalette.show": "Zobrazit",
|
||||
"command.copy": "Kopírovat",
|
||||
"command.dataForm": "Formulář dat",
|
||||
"command.dataForm.addToFilter": "Přidat do filtru",
|
||||
"command.dataForm.copyToClipboard": "Zkopírovat do schránky",
|
||||
"command.dataForm.filterSelected": "Filtrovat tuto hodnotu",
|
||||
"command.dataForm.goToFirst": "První",
|
||||
"command.dataForm.goToLast": "Poslední",
|
||||
"command.dataForm.goToNext": "Další",
|
||||
"command.dataForm.goToPrevious": "Předchozí",
|
||||
"command.dataForm.redo": "Znovu",
|
||||
"command.dataForm.removeField": "Odstranit pole",
|
||||
"command.dataForm.revertRowChanges": "Vrátit změny řádku",
|
||||
"command.dataForm.setNull": "Nastavit NULL",
|
||||
"command.dataForm.undo": "Vrátit",
|
||||
"command.dataGrid": "Datová mřížka",
|
||||
"command.dataGrid.export": "Export",
|
||||
"command.dataGrid.openQuery": "Otevřít dotaz",
|
||||
"command.dataGrid.reconnect": "Znovu připojit",
|
||||
"command.database": "Databáze",
|
||||
"command.database.changeRecent": "Změnit na nedávnou",
|
||||
"command.database.changeStatus": "Změnit stav",
|
||||
"command.database.chat": "Chat databáze",
|
||||
"command.database.compare": "Porovnat databáze",
|
||||
"command.database.databaseSearch": "Vyhledávání v databázi",
|
||||
"command.database.export": "Exportovat databázi",
|
||||
"command.database.search": "Vyhledat",
|
||||
"command.datagrid": "Datová mřížka",
|
||||
"command.datagrid.addJsonDocument": "Přidat JSON dokument",
|
||||
"command.datagrid.addNewColumn": "Přidat nový sloupec",
|
||||
@@ -91,9 +149,69 @@
|
||||
"command.datagrid.viewJsonValue": "Zobrazit buňku jako JSON dokument",
|
||||
"command.datagrid.witchToTable": "Přepnout na tabulku",
|
||||
"command.datgrid.hideColumn": "Skrýt sloupec",
|
||||
"command.designer": "Návrhář",
|
||||
"command.designer.arrange": "Uspořádat",
|
||||
"command.designer.exportDiagram": "Exportovat diagram",
|
||||
"command.designer.remove": "Odebrat",
|
||||
"command.designer.removeSelectedTables": "Odebrat vybrané tabulky",
|
||||
"command.diagram": "Diagram",
|
||||
"command.edit": "Upravit",
|
||||
"command.edit.copy": "Kopírovat",
|
||||
"command.edit.cut": "Vyjmout",
|
||||
"command.edit.paste": "Vložit",
|
||||
"command.edit.redo": "Znovu",
|
||||
"command.edit.selectAll": "Vybrat vše",
|
||||
"command.edit.undo": "Zpět",
|
||||
"command.execute": "Spustit",
|
||||
"command.favoriteJsonEditor": "Oblíbený JSON editor",
|
||||
"command.favoriteJsonEditor.preview": "Náhled",
|
||||
"command.favoriteJsonEditor.save": "Uložit",
|
||||
"command.file": "Soubor",
|
||||
"command.file.exit": "Ukončit",
|
||||
"command.file.import": "Importovat data",
|
||||
"command.file.open": "Otevřít",
|
||||
"command.file.openArchive": "Otevřít DB Model/Archiv",
|
||||
"command.file.quit": "Ukončit",
|
||||
"command.file.resetLayout": "Resetovat data rozložení a nastavení",
|
||||
"command.file.resetLayoutConfirm": "Opravdu resetovat data rozložení? Všechny otevřené karty, nastavení a data rozložení budou ztracena. Připojení a uložené soubory budou zachovány. Po tomto restartujte DbGate pro použití změn.",
|
||||
"command.find": "Najít",
|
||||
"command.folder": "Složka",
|
||||
"command.folder.openData": "Otevřít složku dat",
|
||||
"command.folder.openLogs": "Otevřít logy",
|
||||
"command.internal": "Interní",
|
||||
"command.internal.loadCampaigns": "Načíst seznam kampaní",
|
||||
"command.internal.showCampaigns": "Zobrazit kampaně",
|
||||
"command.jsonl.closePreview": "Zavřít náhled",
|
||||
"command.jsonl.preview": "Náhled",
|
||||
"command.jsonl.previewNewTab": "Náhled v nové kartě",
|
||||
"command.jsonl.save": "Uložit",
|
||||
"command.kill": "Ukončit",
|
||||
"command.markdown.preview": "Náhled",
|
||||
"command.new": "Nový",
|
||||
"command.new.application": "Aplikace",
|
||||
"command.new.archiveFolder": "Složka archivů",
|
||||
"command.new.collection": "Kolekce",
|
||||
"command.new.collectionToolbar": "Nová kolekce/kontejner",
|
||||
"command.new.connection": "Přidat připojení",
|
||||
"command.new.connectionCloud": "Připojení na Cloud",
|
||||
"command.new.connectionFolder": "Složka připojení",
|
||||
"command.new.connectionFolderToolbar": "Přidat složku připojení",
|
||||
"command.new.diagram": "ER Diagram",
|
||||
"command.new.duckdbDatabase": "Nová DuckDB databáze",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Markdown stránka",
|
||||
"command.new.modelCompare": "Porovnat DB",
|
||||
"command.new.modelTransform": "Transformace modelu",
|
||||
"command.new.perspective": "Perspektiva",
|
||||
"command.new.query": "Dotaz",
|
||||
"command.new.queryDesign": "Design dotazu",
|
||||
"command.new.queryToolbar": "Nový dotaz",
|
||||
"command.new.shell": "JavaScript Shell",
|
||||
"command.new.sqliteDatabase": "Nová SQLite databáze",
|
||||
"command.new.table": "Tabulka",
|
||||
"command.new.tableToolbar": "Nová tabulka",
|
||||
"command.openQuery": "Otevřít dotaz",
|
||||
"command.paste": "Vložit",
|
||||
"command.query": "Dotaz",
|
||||
"command.query.AiAssistant": "AI Asistent",
|
||||
"command.query.autocommitOffSwitch": "Automatické potvrzování: VYPNUTO",
|
||||
@@ -109,12 +227,35 @@
|
||||
"command.query.toggleAutoExecute": "Přepnout automatické spuštění",
|
||||
"command.query.toggleFixedConnection": "Přepnout pevné připojení",
|
||||
"command.query.toggleVisibleResultTabs": "Přepnout zobrazení záložek výsledků",
|
||||
"command.queryData": "Údaje z dotazu",
|
||||
"command.queryData.stopLoading": "Zastavit načítání",
|
||||
"command.redo": "Znovu",
|
||||
"command.replace": "Nahradit",
|
||||
"command.save": "Uložit",
|
||||
"command.saveAs": "Uložit jako",
|
||||
"command.saveToDisk": "Uložit na disk",
|
||||
"command.serverSummary": "Souhrn serveru",
|
||||
"command.settings": "Nastavení",
|
||||
"command.settings.change": "Změnit",
|
||||
"command.settings.exportConnections": "Exportovat připojení",
|
||||
"command.settings.importConnections": "Importovat připojení",
|
||||
"command.settings.shortcuts": "Klávesové zkratky",
|
||||
"command.shell.copyNodeScript": "Kopírovat nodejs script",
|
||||
"command.sidebar": "Postranní panel",
|
||||
"command.sidebar.show": "Zobrazit",
|
||||
"command.sidebar.toggleToolbar": "Přepnout postranní panel",
|
||||
"command.sql": "SQL",
|
||||
"command.sql.generator": "SQL Generátor",
|
||||
"command.sqlObject": "SQL Objekt",
|
||||
"command.sqlObject.find": "Najít",
|
||||
"command.tableData": "Data tabulky",
|
||||
"command.tableData.save": "Uložit",
|
||||
"command.tableEditor": "Editor tabulek",
|
||||
"command.tableEditor.reset": "Resetovat změny",
|
||||
"command.tableEditor.save": "Uložit",
|
||||
"command.tabs": "Karty",
|
||||
"command.tabs.addToFavorites": "Přidat aktuální kartu do oblíbených",
|
||||
"command.tabs.changelog": "Seznam změn",
|
||||
"command.tabs.closeAll": "Zavřít všechny karty",
|
||||
"command.tabs.closeTab": "Zavřít kartu",
|
||||
"command.tabs.closeTabsButCurrentDb": "Zavřít karty kromě aktuální DB",
|
||||
@@ -122,6 +263,23 @@
|
||||
"command.tabs.nextTab": "Další karta",
|
||||
"command.tabs.previousTab": "Předchozí karta",
|
||||
"command.tabs.reopenClosedTab": "Znovu otevřít zavřenou kartu",
|
||||
"command.theme": "Téma",
|
||||
"command.theme.change": "Změnit",
|
||||
"command.theme.changeToolbar": "Změnit téma",
|
||||
"command.toggleComment": "Přepnout komentář",
|
||||
"command.toolbar": "Panel nástrojů",
|
||||
"command.toolbar.hide": "Skrýt",
|
||||
"command.toolbar.show": "Zobrazit",
|
||||
"command.undo": "Zpět",
|
||||
"command.view": "Zobrazení",
|
||||
"command.view.reset": "Resetovat zobrazení",
|
||||
"command.view.restart": "Restartovat DbGate (nebo obnovit na webu) pro použití změn",
|
||||
"commandModal.category": "Kategorie",
|
||||
"commandModal.configure": "Konfigurovat příkaz",
|
||||
"commandModal.keyboard": "Klávesnice",
|
||||
"commandModal.keyboardShortcut": "Klávesová zkratka",
|
||||
"commandModal.name": "Název",
|
||||
"commandModal.showKeyCombination": "Zadejte požadovanou kombinaci kláves a stiskněte ENTER",
|
||||
"common.addNew": "Přidat nový",
|
||||
"common.advanced": "Pokročilé",
|
||||
"common.archive": "Archivovat (JSONL)",
|
||||
@@ -140,6 +298,7 @@
|
||||
"common.delete": "Smazat",
|
||||
"common.description": "Popis",
|
||||
"common.erDiagram": "ER Diagram",
|
||||
"common.error": "Chyba",
|
||||
"common.execute": "Spustit",
|
||||
"common.export": "Export",
|
||||
"common.exportDatabase": "Exportovat databázi",
|
||||
@@ -147,19 +306,23 @@
|
||||
"common.general": "Obecné",
|
||||
"common.import": "Import",
|
||||
"common.kill": "Ukončit",
|
||||
"common.loadingData": "Načítání dat",
|
||||
"common.name": "Název",
|
||||
"common.notSelectedOptional": "(nezvoleno - volitelné)",
|
||||
"common.parameters": "Parametry",
|
||||
"common.passwordEncrypted": "Heslo je zašifrované",
|
||||
"common.perspective": "Perspektiva",
|
||||
"common.query": "Dotaz",
|
||||
"common.queryDesigner": "Návrhář dotazů",
|
||||
"common.queryEditor": "Editor SQL dotazů",
|
||||
"common.refresh": "Obnovit",
|
||||
"common.remove": "Odstranit",
|
||||
"common.reset": "Resetovat",
|
||||
"common.save": "Uložit",
|
||||
"common.saveAndNext": "Uložit a další",
|
||||
"common.saveToArchive": "Uložit do archívu",
|
||||
"common.schema": "Schéma",
|
||||
"common.search": "Hledat",
|
||||
"common.searchBy": "Hledat podle:",
|
||||
"common.sqlGenerator": "SQL Generátor",
|
||||
"common.table": "Tabulka",
|
||||
@@ -240,13 +403,25 @@
|
||||
"connection.user": "Uživatel",
|
||||
"connection.viewDetails": "Zobrazit detaily",
|
||||
"connection.windowsDomain": "Doména (zadejte pro použití NTLM autentizace)",
|
||||
"dataForm.loadingRowCount": "Načítání počtu řádků...",
|
||||
"dataForm.noData": "Žádná data",
|
||||
"dataForm.outOfBounds": "Mimo rozsah: {current} / {total}",
|
||||
"dataForm.rowCount": "Řádek: {current} / {total}",
|
||||
"dataGrid.chooseValue": "Vybrat hodnotu z {field}",
|
||||
"dataGrid.codeHighlighting": "Zvýraznění kódu:",
|
||||
"dataGrid.codeHighlighting.none": "Žádné (neformátovaný text)",
|
||||
"dataGrid.columns": "Sloupce",
|
||||
"dataGrid.dependentTables": "Závislé tabulky",
|
||||
"dataGrid.editCellValue": "Upravit hodnotu buňky",
|
||||
"dataGrid.filters": "Filtry",
|
||||
"dataGrid.formatJson": "Formátovat JSON",
|
||||
"dataGrid.formatJson.invalid": "Neplatný JSON",
|
||||
"dataGrid.macros": "Makra",
|
||||
"dataGrid.multiColumnFilter": "Filtr více sloupců",
|
||||
"dataGrid.references": "Reference",
|
||||
"dataGrid.referencesTables": "Reference na tabulky",
|
||||
"dataGrid.searchReferences": "Hledat reference",
|
||||
"dataGrid.value": "Hodnota",
|
||||
"database.backup": "Záloha #",
|
||||
"database.chooseArchiveFolderForDataDeployer": "Vybrat archivní složku pro data deployer",
|
||||
"database.closeConfirm": "Uzavření připojení uzavře {count} otevřených karet, pokračovat?",
|
||||
@@ -270,7 +445,7 @@
|
||||
"database.exportDbModel": "Export DB model",
|
||||
"database.generateScript": "Vygenerovat skript",
|
||||
"database.import": "Import",
|
||||
"database.newCollection": "Nová {collectionLabel}",
|
||||
"database.newCollection": "Nová kolekce/kontejner",
|
||||
"database.newQuery": "Nový dotaz",
|
||||
"database.newTable": "Nová tabulka",
|
||||
"database.perspective": "Perspektiva #",
|
||||
@@ -349,6 +524,48 @@
|
||||
"datagrid.searchMacros": "Hledat makra",
|
||||
"datagrid.setFormat": "Nastavit formát: ",
|
||||
"datagrid.structure": "Struktura",
|
||||
"dbObject.collections": "Kolekce/Kontejnery",
|
||||
"dbObject.confirmCloneCollection": "Opravdu vytvořit kopii kolekce/kontejneru s názvem {name}?",
|
||||
"dbObject.confirmDropCollection": "Opravdu odstranit kolekci {name}?",
|
||||
"dbObject.copyTableName": "Kopírovat název tabulky",
|
||||
"dbObject.createCollection": "Vytvořit kolekci/kontejner",
|
||||
"dbObject.createCollectionBackup": "Vytvořit zálohu kolekce/kontejneru",
|
||||
"dbObject.createTableBackup": "Vytvořit zálohu tabulky",
|
||||
"dbObject.designPerspectiveQuery": "Návrh perspektivního dotazu",
|
||||
"dbObject.designQuery": "Návrh dotazu",
|
||||
"dbObject.diagram": "Diagram #",
|
||||
"dbObject.disable": "Zakázat",
|
||||
"dbObject.dropCollection": "Odstranit kolekci/kontejner",
|
||||
"dbObject.dropEvent": "Odstranit událost",
|
||||
"dbObject.dropProcedure": "Odstranit proceduru",
|
||||
"dbObject.dropTable": "Odstranit tabulku",
|
||||
"dbObject.dropTrigger": "Odstranit trigger",
|
||||
"dbObject.dropView": "Odstranit pohled",
|
||||
"dbObject.enable": "Povolit",
|
||||
"dbObject.functions": "Funkce",
|
||||
"dbObject.matviews": "Materializované pohledy",
|
||||
"dbObject.newCollectionName": "Nový název kolekce/kontejneru",
|
||||
"dbObject.openData": "Otevřít data",
|
||||
"dbObject.openJson": "Otevřít JSON",
|
||||
"dbObject.openRawData": "Otevřít surová data",
|
||||
"dbObject.openStructure": "Otevřít strukturu",
|
||||
"dbObject.procedures": "Procedury",
|
||||
"dbObject.query": "Dotaz #",
|
||||
"dbObject.queryDesigner": "Návrhář dotazů",
|
||||
"dbObject.renameCollection": "Přejmenovat kolekci/kontejner",
|
||||
"dbObject.renameProcedure": "Přejmenovat proceduru",
|
||||
"dbObject.renameTable": "Přejmenovat tabulku",
|
||||
"dbObject.renameView": "Přejmenovat pohled",
|
||||
"dbObject.schedulerEvents": "Události plánovače",
|
||||
"dbObject.showDiagram": "Zobrazit diagram",
|
||||
"dbObject.showQuery": "Zobrazit dotaz",
|
||||
"dbObject.showSql": "Zobrazit SQL",
|
||||
"dbObject.sqlGenerator": "SQL generátor",
|
||||
"dbObject.sqlTemplate": "SQL šablona",
|
||||
"dbObject.tables": "Tabulky",
|
||||
"dbObject.triggers": "Triggery",
|
||||
"dbObject.truncateTable": "Oříznout tabulku",
|
||||
"dbObject.views": "Pohledy",
|
||||
"error.driverNotFound": "Neplatné připojení k databázi, ovladač nebyl nalezen",
|
||||
"error.selectedCloudConnection": "Vybrané připojení je z DbGate cloudu",
|
||||
"error.selectedNotCloudConnection": "Vybrané připojení není z DbGate cloudu",
|
||||
@@ -587,6 +804,7 @@
|
||||
"sqlObject.columnName": "Název sloupce",
|
||||
"sqlObject.databaseEmpty": "Databáze {database} je prázdná nebo struktura není načtena, stiskněte tlačítko Obnovit pro znovunačtení struktury",
|
||||
"sqlObject.loadingStructure": "Načítání struktury databáze",
|
||||
"sqlObject.newCollection": "Nová kolekce/kontejner",
|
||||
"sqlObject.schemaName": "Schéma",
|
||||
"sqlObject.search.placeholder": "Hledat v tabulkách, pohledech, procedurách",
|
||||
"sqlObject.searchBy": "Hledat podle:",
|
||||
@@ -654,6 +872,7 @@
|
||||
"tableEditor.yes": "ANO",
|
||||
"tableStructure.alter": "Upravit tabulku",
|
||||
"tableStructure.create": "Vytvořit tabulku",
|
||||
"widget.collectionsContainers": "Kolekce/kontejnery",
|
||||
"widget.databaseContent": "Obsah databáze",
|
||||
"widget.databases": "Databáze",
|
||||
"widget.keys": "Klíče",
|
||||
|
||||
+220
-1
@@ -44,6 +44,64 @@
|
||||
"columnsConstraintEditor.addNewColumn": "Add new column",
|
||||
"columnsConstraintEditor.chooseColumn": "Choose column",
|
||||
"columnsConstraintEditor.selectColumn": "Select column",
|
||||
"command.about": "About",
|
||||
"command.about.show": "Show",
|
||||
"command.about.toolbar": "About",
|
||||
"command.app.checkForUpdates": "Check for updates",
|
||||
"command.app.disconnect": "Disconnect",
|
||||
"command.app.loggedUser": "Logged user",
|
||||
"command.app.logout": "Logout",
|
||||
"command.application": "Application",
|
||||
"command.application.becomeSponsor": "Become sponsor",
|
||||
"command.application.documentation": "Documentation",
|
||||
"command.application.maximize": "Maximize",
|
||||
"command.application.minimize": "Minimize",
|
||||
"command.application.openIssue": "Report problem or feature request",
|
||||
"command.application.reload": "Reload",
|
||||
"command.application.toggleDevTools": "Toggle Dev Tools",
|
||||
"command.application.toggleFullScreen": "Toggle full screen",
|
||||
"command.application.unsetCurrentDatabase": "Unset current database",
|
||||
"command.application.web": "DbGate web",
|
||||
"command.application.zoomIn": "Zoom in",
|
||||
"command.application.zoomOut": "Zoom out",
|
||||
"command.application.zoomReset": "Reset zoom",
|
||||
"command.archiveFile": "Archive file",
|
||||
"command.archiveFile.save": "Save",
|
||||
"command.archiveFile.saveAs": "Save as",
|
||||
"command.cloud": "Cloud",
|
||||
"command.cloud.logout": "Logout",
|
||||
"command.collectionData": "Collection data",
|
||||
"command.collectionData.collapseAll": "Collapse all",
|
||||
"command.collectionData.expandAll": "Expand all",
|
||||
"command.collectionData.save": "Save",
|
||||
"command.commandPalette": "Command palette",
|
||||
"command.commandPalette.show": "Show",
|
||||
"command.copy": "Copy",
|
||||
"command.dataForm": "Data form",
|
||||
"command.dataForm.addToFilter": "Add to filter",
|
||||
"command.dataForm.copyToClipboard": "Copy to clipboard",
|
||||
"command.dataForm.filterSelected": "Filter this value",
|
||||
"command.dataForm.goToFirst": "First",
|
||||
"command.dataForm.goToLast": "Last",
|
||||
"command.dataForm.goToNext": "Next",
|
||||
"command.dataForm.goToPrevious": "Previous",
|
||||
"command.dataForm.redo": "Redo",
|
||||
"command.dataForm.removeField": "Remove field",
|
||||
"command.dataForm.revertRowChanges": "Revert row changes",
|
||||
"command.dataForm.setNull": "Set NULL",
|
||||
"command.dataForm.undo": "Undo",
|
||||
"command.dataGrid": "Data grid",
|
||||
"command.dataGrid.export": "Export",
|
||||
"command.dataGrid.openQuery": "Open query",
|
||||
"command.dataGrid.reconnect": "Reconnect",
|
||||
"command.database": "Database",
|
||||
"command.database.changeRecent": "Change to recent",
|
||||
"command.database.changeStatus": "Change status",
|
||||
"command.database.chat": "Database chat",
|
||||
"command.database.compare": "Compare databases",
|
||||
"command.database.databaseSearch": "Database search",
|
||||
"command.database.export": "Export database",
|
||||
"command.database.search": "Search",
|
||||
"command.datagrid": "Data grid",
|
||||
"command.datagrid.addJsonDocument": "Add JSON document",
|
||||
"command.datagrid.addNewColumn": "Add new column",
|
||||
@@ -91,9 +149,69 @@
|
||||
"command.datagrid.viewJsonValue": "View cell as JSON document",
|
||||
"command.datagrid.witchToTable": "Switch to table",
|
||||
"command.datgrid.hideColumn": "Hide column",
|
||||
"command.designer": "Designer",
|
||||
"command.designer.arrange": "Arrange",
|
||||
"command.designer.exportDiagram": "Export diagram",
|
||||
"command.designer.remove": "Remove",
|
||||
"command.designer.removeSelectedTables": "Remove selected tables",
|
||||
"command.diagram": "Diagram",
|
||||
"command.edit": "Edit",
|
||||
"command.edit.copy": "Copy",
|
||||
"command.edit.cut": "Cut",
|
||||
"command.edit.paste": "Paste",
|
||||
"command.edit.redo": "Redo",
|
||||
"command.edit.selectAll": "Select All",
|
||||
"command.edit.undo": "Undo",
|
||||
"command.execute": "Execute",
|
||||
"command.favoriteJsonEditor": "Favorite JSON editor",
|
||||
"command.favoriteJsonEditor.preview": "Preview",
|
||||
"command.favoriteJsonEditor.save": "Save",
|
||||
"command.file": "File",
|
||||
"command.file.exit": "Exit",
|
||||
"command.file.import": "Import data",
|
||||
"command.file.open": "Open",
|
||||
"command.file.openArchive": "Open DB Model/Archive",
|
||||
"command.file.quit": "Quit",
|
||||
"command.file.resetLayout": "Reset layout data & settings",
|
||||
"command.file.resetLayoutConfirm": "Really reset layout data? All opened tabs, settings and layout data will be lost. Connections and saved files will be preserved. After this, restart DbGate for applying changes.",
|
||||
"command.find": "Find",
|
||||
"command.folder": "Folder",
|
||||
"command.folder.openData": "Open data folder",
|
||||
"command.folder.openLogs": "Open logs",
|
||||
"command.internal": "Internal",
|
||||
"command.internal.loadCampaigns": "Load campaign list",
|
||||
"command.internal.showCampaigns": "Show campaigns",
|
||||
"command.jsonl.closePreview": "Close preview",
|
||||
"command.jsonl.preview": "Preview",
|
||||
"command.jsonl.previewNewTab": "Preview in new tab",
|
||||
"command.jsonl.save": "Save",
|
||||
"command.kill": "Kill",
|
||||
"command.markdown.preview": "Preview",
|
||||
"command.new": "New",
|
||||
"command.new.application": "Application",
|
||||
"command.new.archiveFolder": "Archive folder",
|
||||
"command.new.collection": "Collection",
|
||||
"command.new.collectionToolbar": "New collection/container",
|
||||
"command.new.connection": "Add connection",
|
||||
"command.new.connectionCloud": "Connection on Cloud",
|
||||
"command.new.connectionFolder": "Connection folder",
|
||||
"command.new.connectionFolderToolbar": "Add connection folder",
|
||||
"command.new.diagram": "ER Diagram",
|
||||
"command.new.duckdbDatabase": "New DuckDB database",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Markdown page",
|
||||
"command.new.modelCompare": "Compare DB",
|
||||
"command.new.modelTransform": "Model transform",
|
||||
"command.new.perspective": "Perspective",
|
||||
"command.new.query": "Query",
|
||||
"command.new.queryDesign": "Query design",
|
||||
"command.new.queryToolbar": "New query",
|
||||
"command.new.shell": "JavaScript Shell",
|
||||
"command.new.sqliteDatabase": "New SQLite database",
|
||||
"command.new.table": "Table",
|
||||
"command.new.tableToolbar": "New table",
|
||||
"command.openQuery": "Open query",
|
||||
"command.paste": "Paste",
|
||||
"command.query": "Query",
|
||||
"command.query.AiAssistant": "AI Assistant",
|
||||
"command.query.autocommitOffSwitch": "Auto commit: OFF",
|
||||
@@ -109,12 +227,35 @@
|
||||
"command.query.toggleAutoExecute": "Toggle auto execute",
|
||||
"command.query.toggleFixedConnection": "Toggle fixed connection",
|
||||
"command.query.toggleVisibleResultTabs": "Toggle visible result tabs",
|
||||
"command.queryData": "Query data",
|
||||
"command.queryData.stopLoading": "Stop loading",
|
||||
"command.redo": "Redo",
|
||||
"command.replace": "Replace",
|
||||
"command.save": "Save",
|
||||
"command.saveAs": "Save As",
|
||||
"command.saveToDisk": "Save to disk",
|
||||
"command.serverSummary": "Server summary",
|
||||
"command.settings": "Settings",
|
||||
"command.settings.change": "Change",
|
||||
"command.settings.exportConnections": "Export connections",
|
||||
"command.settings.importConnections": "Import connections",
|
||||
"command.settings.shortcuts": "Keyboard shortcuts",
|
||||
"command.shell.copyNodeScript": "Copy nodejs script",
|
||||
"command.sidebar": "Sidebar",
|
||||
"command.sidebar.show": "Show",
|
||||
"command.sidebar.toggleToolbar": "Toggle sidebar",
|
||||
"command.sql": "SQL",
|
||||
"command.sql.generator": "SQL Generator",
|
||||
"command.sqlObject": "SQL Object",
|
||||
"command.sqlObject.find": "Find",
|
||||
"command.tableData": "Table data",
|
||||
"command.tableData.save": "Save",
|
||||
"command.tableEditor": "Table editor",
|
||||
"command.tableEditor.reset": "Reset changes",
|
||||
"command.tableEditor.save": "Save",
|
||||
"command.tabs": "Tabs",
|
||||
"command.tabs.addToFavorites": "Add current tab to favorites",
|
||||
"command.tabs.changelog": "Changelog",
|
||||
"command.tabs.closeAll": "Close all tabs",
|
||||
"command.tabs.closeTab": "Close tab",
|
||||
"command.tabs.closeTabsButCurrentDb": "Close tabs but current DB",
|
||||
@@ -122,6 +263,23 @@
|
||||
"command.tabs.nextTab": "Next tab",
|
||||
"command.tabs.previousTab": "Previous tab",
|
||||
"command.tabs.reopenClosedTab": "Reopen closed tab",
|
||||
"command.theme": "Theme",
|
||||
"command.theme.change": "Change",
|
||||
"command.theme.changeToolbar": "Change theme",
|
||||
"command.toggleComment": "Toggle comment",
|
||||
"command.toolbar": "Toolbar",
|
||||
"command.toolbar.hide": "Hide",
|
||||
"command.toolbar.show": "Show",
|
||||
"command.undo": "Undo",
|
||||
"command.view": "View",
|
||||
"command.view.reset": "Reset view",
|
||||
"command.view.restart": "Restart DbGate (or reload on web) for applying changes",
|
||||
"commandModal.category": "Category",
|
||||
"commandModal.configure": "Configure command",
|
||||
"commandModal.keyboard": "Keyboard",
|
||||
"commandModal.keyboardShortcut": "Keyboard shortcut",
|
||||
"commandModal.name": "Name",
|
||||
"commandModal.showKeyCombination": "Show desired key combination and press ENTER",
|
||||
"common.addNew": "Add new",
|
||||
"common.advanced": "Advanced",
|
||||
"common.archive": "Archive (JSONL)",
|
||||
@@ -140,6 +298,7 @@
|
||||
"common.delete": "Delete",
|
||||
"common.description": "Description",
|
||||
"common.erDiagram": "ER Diagram",
|
||||
"common.error": "Error",
|
||||
"common.execute": "Execute",
|
||||
"common.export": "Export",
|
||||
"common.exportDatabase": "Export database",
|
||||
@@ -147,19 +306,23 @@
|
||||
"common.general": "General",
|
||||
"common.import": "Import",
|
||||
"common.kill": "Kill",
|
||||
"common.loadingData": "Loading data",
|
||||
"common.name": "Name",
|
||||
"common.notSelectedOptional": "(not selected - optional)",
|
||||
"common.parameters": "Parameters",
|
||||
"common.passwordEncrypted": "Password is encrypted",
|
||||
"common.perspective": "Perspective",
|
||||
"common.query": "Query",
|
||||
"common.queryDesigner": "Query Designer",
|
||||
"common.queryEditor": "SQL query editor",
|
||||
"common.refresh": "Refresh",
|
||||
"common.remove": "Remove",
|
||||
"common.reset": "Reset",
|
||||
"common.save": "Save",
|
||||
"common.saveAndNext": "Save and next",
|
||||
"common.saveToArchive": "Save to archive",
|
||||
"common.schema": "Schema",
|
||||
"common.search": "Search",
|
||||
"common.searchBy": "Search by:",
|
||||
"common.sqlGenerator": "SQL Generator",
|
||||
"common.table": "Table",
|
||||
@@ -240,13 +403,25 @@
|
||||
"connection.user": "User",
|
||||
"connection.viewDetails": "View details",
|
||||
"connection.windowsDomain": "Domain (specify to use NTLM authentication)",
|
||||
"dataForm.loadingRowCount": "Loading row count...",
|
||||
"dataForm.noData": "No data",
|
||||
"dataForm.outOfBounds": "Out of bounds: {current} / {total}",
|
||||
"dataForm.rowCount": "Row: {current} / {total}",
|
||||
"dataGrid.chooseValue": "Choose value from {field}",
|
||||
"dataGrid.codeHighlighting": "Code highlighting:",
|
||||
"dataGrid.codeHighlighting.none": "None (raw text)",
|
||||
"dataGrid.columns": "Columns",
|
||||
"dataGrid.dependentTables": "Dependent tables",
|
||||
"dataGrid.editCellValue": "Edit cell value",
|
||||
"dataGrid.filters": "Filters",
|
||||
"dataGrid.formatJson": "Format JSON",
|
||||
"dataGrid.formatJson.invalid": "Not valid JSON",
|
||||
"dataGrid.macros": "Macros",
|
||||
"dataGrid.multiColumnFilter": "Multi column filter",
|
||||
"dataGrid.references": "References",
|
||||
"dataGrid.referencesTables": "References tables",
|
||||
"dataGrid.searchReferences": "Search references",
|
||||
"dataGrid.value": "Value",
|
||||
"database.backup": "Backup #",
|
||||
"database.chooseArchiveFolderForDataDeployer": "Choose archive folder for data deployer",
|
||||
"database.closeConfirm": "Closing connection will close {count} opened tabs, continue?",
|
||||
@@ -270,7 +445,7 @@
|
||||
"database.exportDbModel": "Export DB model",
|
||||
"database.generateScript": "Generate script",
|
||||
"database.import": "Import",
|
||||
"database.newCollection": "New {collectionLabel}",
|
||||
"database.newCollection": "New collection/container",
|
||||
"database.newQuery": "New query",
|
||||
"database.newTable": "New table",
|
||||
"database.perspective": "Perspective #",
|
||||
@@ -349,6 +524,48 @@
|
||||
"datagrid.searchMacros": "Search macros",
|
||||
"datagrid.setFormat": "Set format: ",
|
||||
"datagrid.structure": "Structure",
|
||||
"dbObject.collections": "Collections/Containers",
|
||||
"dbObject.confirmCloneCollection": "Really create collection/container copy named {name}?",
|
||||
"dbObject.confirmDropCollection": "Really drop collection {name}?",
|
||||
"dbObject.copyTableName": "Copy table name",
|
||||
"dbObject.createCollection": "Create collection/container",
|
||||
"dbObject.createCollectionBackup": "Create collection/container backup",
|
||||
"dbObject.createTableBackup": "Create table backup",
|
||||
"dbObject.designPerspectiveQuery": "Design perspective query",
|
||||
"dbObject.designQuery": "Design query",
|
||||
"dbObject.diagram": "Diagram #",
|
||||
"dbObject.disable": "Disable",
|
||||
"dbObject.dropCollection": "Drop collection/container",
|
||||
"dbObject.dropEvent": "Drop event",
|
||||
"dbObject.dropProcedure": "Drop procedure",
|
||||
"dbObject.dropTable": "Drop table",
|
||||
"dbObject.dropTrigger": "Drop trigger",
|
||||
"dbObject.dropView": "Drop view",
|
||||
"dbObject.enable": "Enable",
|
||||
"dbObject.functions": "Functions",
|
||||
"dbObject.matviews": "Materialized Views",
|
||||
"dbObject.newCollectionName": "New collection/container name",
|
||||
"dbObject.openData": "Open data",
|
||||
"dbObject.openJson": "Open JSON",
|
||||
"dbObject.openRawData": "Open raw data",
|
||||
"dbObject.openStructure": "Open structure",
|
||||
"dbObject.procedures": "Procedures",
|
||||
"dbObject.query": "Query #",
|
||||
"dbObject.queryDesigner": "Query designer",
|
||||
"dbObject.renameCollection": "Rename collection/container",
|
||||
"dbObject.renameProcedure": "Rename procedure",
|
||||
"dbObject.renameTable": "Rename table",
|
||||
"dbObject.renameView": "Rename view",
|
||||
"dbObject.schedulerEvents": "Scheduler Events",
|
||||
"dbObject.showDiagram": "Show diagram",
|
||||
"dbObject.showQuery": "Show query",
|
||||
"dbObject.showSql": "Show SQL",
|
||||
"dbObject.sqlGenerator": "SQL generator",
|
||||
"dbObject.sqlTemplate": "SQL template",
|
||||
"dbObject.tables": "Tables",
|
||||
"dbObject.triggers": "Triggers",
|
||||
"dbObject.truncateTable": "Truncate table",
|
||||
"dbObject.views": "Views",
|
||||
"error.driverNotFound": "Invalid database connection, driver not found",
|
||||
"error.selectedCloudConnection": "Selected connection is from DbGate cloud",
|
||||
"error.selectedNotCloudConnection": "Selected connection is not from DbGate cloud",
|
||||
@@ -587,6 +804,7 @@
|
||||
"sqlObject.columnName": "Column name",
|
||||
"sqlObject.databaseEmpty": "Database {database} is empty or structure is not loaded, press Refresh button to reload structure",
|
||||
"sqlObject.loadingStructure": "Loading database structure",
|
||||
"sqlObject.newCollection": "New collection/container",
|
||||
"sqlObject.schemaName": "Schema",
|
||||
"sqlObject.search.placeholder": "Search in tables, views, procedures",
|
||||
"sqlObject.searchBy": "Search by:",
|
||||
@@ -654,6 +872,7 @@
|
||||
"tableEditor.yes": "YES",
|
||||
"tableStructure.alter": "Alter table",
|
||||
"tableStructure.create": "Create table",
|
||||
"widget.collectionsContainers": "Collections/containers",
|
||||
"widget.databaseContent": "Database content",
|
||||
"widget.databases": "Databases",
|
||||
"widget.keys": "Keys",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user