1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-06-05 21:59:22 +02:00

Compare commits

..

20 Commits

Author SHA1 Message Date
3e739bcaa2 chore(release): 0.7.19-beta.2 2023-10-29 11:47:08 +01:00
debc1da289 fix: ssh tunnel keep-alive not working properly 2023-10-28 19:09:19 +02:00
3c2e2be40f chore: regenerate package-lock.json 2023-10-28 18:47:06 +02:00
581ec6a25d Merge branch 'develop' of https://github.com/antares-sql/antares into develop 2023-10-28 18:25:03 +02:00
d30a978cd6 refactor: replace ssh2-promise with @fabio286/ssh2-promise 2023-10-28 18:25:01 +02:00
0015f2e860 Merge branch 'master' of https://github.com/antares-sql/antares into develop 2023-10-28 11:58:06 +02:00
389e6624d8 chore: update stylelint dependencies 2023-10-28 11:55:18 +02:00
275344eb8b chore(release): 0.7.19-beta.1 2023-10-26 01:07:15 +02:00
cf24adf99e Merge branch 'develop' of https://github.com/antares-sql/antares into beta 2023-10-26 01:06:54 +02:00
2eae580e18 chore: update electron 2023-10-22 19:04:31 +02:00
e4eb27d503 feat(MySQL): RLIKE and NOT RLIKE regular expression filters, closes #688 2023-10-18 18:08:01 +02:00
580973fd04 chore(release): 0.7.19-beta.0 2023-10-14 15:04:00 +02:00
215ab783ab chore: email change 2023-10-14 15:03:09 +02:00
72148e991c Merge branch 'master' of https://github.com/antares-sql/antares into develop 2023-10-13 09:23:41 +02:00
6e4c16741a chore: Update CODE_OF_CONDUCT.md 2023-10-13 09:22:04 +02:00
9f9c63bfcc feat: "now" and "random" options added in datetime related data in insert rows tool, closes #402 2023-10-10 18:36:35 +02:00
c0dcf30e73 fix: IN and NOT IN filters not working properly, fixes #687 2023-10-09 18:13:30 +02:00
ddd290c903 fix: timeout issue on long time sql import 2023-10-03 18:19:16 +02:00
267c017921 chore(release): 0.7.18 2023-10-03 09:31:58 +02:00
b3b698b3a2 fix: hotfix for Microsoft Store unauthorized process 2023-10-03 09:31:26 +02:00
27 changed files with 14959 additions and 506 deletions

BIN
.nvmrc Normal file

Binary file not shown.

View File

@@ -2,6 +2,40 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.7.19-beta.2](https://github.com/antares-sql/antares/compare/v0.7.19-beta.1...v0.7.19-beta.2) (2023-10-29)
### Bug Fixes
* ssh tunnel keep-alive not working properly ([debc1da](https://github.com/antares-sql/antares/commit/debc1da289d5e35d59adf69d094b329cf93af536))
### [0.7.19-beta.1](https://github.com/antares-sql/antares/compare/v0.7.19-beta.0...v0.7.19-beta.1) (2023-10-25)
### Features
* **MySQL:** RLIKE and NOT RLIKE regular expression filters, closes [#688](https://github.com/antares-sql/antares/issues/688) ([e4eb27d](https://github.com/antares-sql/antares/commit/e4eb27d503e8f912178359c01c62a9b523d17848))
### [0.7.19-beta.0](https://github.com/antares-sql/antares/compare/v0.7.18...v0.7.19-beta.0) (2023-10-14)
### Features
* "now" and "random" options added in datetime related data in insert rows tool, closes [#402](https://github.com/antares-sql/antares/issues/402) ([9f9c63b](https://github.com/antares-sql/antares/commit/9f9c63bfcc3423bfeef143cd835f48c62900a799))
### Bug Fixes
* IN and NOT IN filters not working properly, fixes [#687](https://github.com/antares-sql/antares/issues/687) ([c0dcf30](https://github.com/antares-sql/antares/commit/c0dcf30e73a69b25b01ba31d21b27c1983ed2db6))
* timeout issue on long time sql import ([ddd290c](https://github.com/antares-sql/antares/commit/ddd290c90344241eaa70cb528552e942fd7edec0))
### [0.7.18](https://github.com/antares-sql/antares/compare/v0.7.17...v0.7.18) (2023-10-03)
### Bug Fixes
* hotfix for Microsoft Store unauthorized process ([b3b698b](https://github.com/antares-sql/antares/commit/b3b698b3a23a3c848921ab40fc0fec5d8178ef0e))
### [0.7.17](https://github.com/antares-sql/antares/compare/v0.7.17-beta.2...v0.7.17) (2023-09-30) ### [0.7.17](https://github.com/antares-sql/antares/compare/v0.7.17-beta.2...v0.7.17) (2023-09-30)
### [0.7.17-beta.2](https://github.com/antares-sql/antares/compare/v0.7.17-beta.1...v0.7.17-beta.2) (2023-09-28) ### [0.7.17-beta.2](https://github.com/antares-sql/antares/compare/v0.7.17-beta.1...v0.7.17-beta.2) (2023-09-28)

View File

@@ -61,7 +61,7 @@ representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at reported to the community leaders responsible for enforcement at
fabio286@gmail.com. info@fabiodistasio.it.
All complaints will be reviewed and investigated promptly and fairly. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the All community leaders are obligated to respect the privacy and security of the

14959
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{ {
"name": "antares", "name": "antares",
"productName": "Antares", "productName": "Antares",
"version": "0.7.17", "version": "0.7.19-beta.2",
"description": "A modern, fast and productivity driven SQL client with a focus in UX.", "description": "A modern, fast and productivity driven SQL client with a focus in UX.",
"license": "MIT", "license": "MIT",
"repository": "https://github.com/antares-sql/antares.git", "repository": "https://github.com/antares-sql/antares.git",
@@ -27,7 +27,7 @@
"contributors:add": "all-contributors add", "contributors:add": "all-contributors add",
"contributors:generate": "all-contributors generate" "contributors:generate": "all-contributors generate"
}, },
"author": "Fabio Di Stasio <fabio286@gmail.com>", "author": "Fabio Di Stasio <info@fabiodistasio.it>",
"main": "./dist/main.js", "main": "./dist/main.js",
"antares": { "antares": {
"devtoolsId": "nhdogjmejiglipccpnnnanhbledajbpd" "devtoolsId": "nhdogjmejiglipccpnnnanhbledajbpd"
@@ -146,7 +146,7 @@
"source-map-support": "~0.5.20", "source-map-support": "~0.5.20",
"spectre.css": "~0.5.9", "spectre.css": "~0.5.9",
"sql-formatter": "~13.0.0", "sql-formatter": "~13.0.0",
"ssh2-promise": "~1.0.2", "@fabio286/ssh2-promise": "~1.0.4-b",
"v-mask": "~2.3.0", "v-mask": "~2.3.0",
"vue": "~3.3.4", "vue": "~3.3.4",
"vue-i18n": "~9.2.2", "vue-i18n": "~9.2.2",
@@ -171,7 +171,7 @@
"chalk": "~4.1.2", "chalk": "~4.1.2",
"cross-env": "~7.0.2", "cross-env": "~7.0.2",
"css-loader": "~6.5.0", "css-loader": "~6.5.0",
"electron": "~22.3.23", "electron": "~22.3.27",
"electron-builder": "~22.10.3", "electron-builder": "~22.10.3",
"eslint": "~7.32.0", "eslint": "~7.32.0",
"eslint-config-standard": "~16.0.3", "eslint-config-standard": "~16.0.3",
@@ -193,10 +193,10 @@
"sass-loader": "~12.3.0", "sass-loader": "~12.3.0",
"standard-version": "~9.3.1", "standard-version": "~9.3.1",
"style-loader": "~3.3.1", "style-loader": "~3.3.1",
"stylelint": "~14.9.1", "stylelint": "^15.11.0",
"stylelint-config-recommended-vue": "~1.4.0", "stylelint-config-recommended-vue": "~1.5.0",
"stylelint-config-standard": "~26.0.0", "stylelint-config-standard": "~34.0.0",
"stylelint-scss": "~4.3.0", "stylelint-scss": "~5.3.0",
"tree-kill": "~1.2.2", "tree-kill": "~1.2.2",
"ts-loader": "~9.2.8", "ts-loader": "~9.2.8",
"ts-node": "~10.9.1", "ts-node": "~10.9.1",
@@ -208,10 +208,5 @@
"webpack-cli": "~4.9.1", "webpack-cli": "~4.9.1",
"webpack-dev-server": "~4.11.1", "webpack-dev-server": "~4.11.1",
"xvfb-maybe": "~0.2.1" "xvfb-maybe": "~0.2.1"
},
"overrides": {
"ssh2-promise": {
"ssh2": "github:Fabio286/ssh2"
}
} }
} }

View File

@@ -51,6 +51,7 @@ export default class {
{ name: 'collation', group: 'database', types: ['string'] }, { name: 'collation', group: 'database', types: ['string'] },
{ name: 'engine', group: 'database', types: ['string'] }, { name: 'engine', group: 'database', types: ['string'] },
{ name: 'now', group: 'date', types: ['string', 'datetime'] },
{ name: 'past', group: 'date', types: ['string', 'datetime'] }, { name: 'past', group: 'date', types: ['string', 'datetime'] },
{ name: 'future', group: 'date', types: ['string', 'datetime'] }, { name: 'future', group: 'date', types: ['string', 'datetime'] },
// { name: 'between', group: 'date', types: ['string'] }, // { name: 'between', group: 'date', types: ['string'] },
@@ -161,7 +162,9 @@ export default class {
{ name: 'filePath', group: 'system', types: ['string'] }, { name: 'filePath', group: 'system', types: ['string'] },
{ name: 'semver', group: 'system', types: ['string'] }, { name: 'semver', group: 'system', types: ['string'] },
{ name: 'now', group: 'time', types: ['string', 'time'] },
{ name: 'recent', group: 'time', types: ['string', 'time'] }, { name: 'recent', group: 'time', types: ['string', 'time'] },
{ name: 'random', group: 'time', types: ['string', 'time'] },
{ name: 'vehicle', group: 'vehicle', types: ['string'] }, { name: 'vehicle', group: 'vehicle', types: ['string'] },
{ name: 'manufacturer', group: 'vehicle', types: ['string'] }, { name: 'manufacturer', group: 'vehicle', types: ['string'] },

View File

@@ -9,6 +9,7 @@ export const defaults: Customizations = {
dataTypes: [], dataTypes: [],
indexTypes: [], indexTypes: [],
foreignActions: [], foreignActions: [],
operators: ['=', '!=', '>', '<', '>=', '<=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'BETWEEN', 'IS NULL', 'IS NOT NULL'],
// Core // Core
database: false, database: false,
collations: false, collations: false,

View File

@@ -9,6 +9,7 @@ export const customizations: Customizations = {
defaultUser: 'root', defaultUser: 'root',
defaultDatabase: null, defaultDatabase: null,
dataTypes: mysqlTypes, dataTypes: mysqlTypes,
operators: ['=', '!=', '>', '<', '>=', '<=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'RLIKE', 'NOT RLIKE', 'BETWEEN', 'IS NULL', 'IS NOT NULL'],
indexTypes: [ indexTypes: [
'PRIMARY', 'PRIMARY',
'INDEX', 'INDEX',

View File

@@ -1,3 +1,4 @@
import SSHConfig from '@fabio286/ssh2-promise/lib/sshConfig';
import * as mysql from 'mysql2/promise'; import * as mysql from 'mysql2/promise';
import * as pg from 'pg'; import * as pg from 'pg';
import { FirebirdSQLClient } from 'src/main/libs/clients/FirebirdSQLClient'; import { FirebirdSQLClient } from 'src/main/libs/clients/FirebirdSQLClient';
@@ -5,7 +6,6 @@ import MysqlExporter from 'src/main/libs/exporters/sql/MysqlExporter';
import PostgreSQLExporter from 'src/main/libs/exporters/sql/PostgreSQLExporter'; import PostgreSQLExporter from 'src/main/libs/exporters/sql/PostgreSQLExporter';
import MySQLImporter from 'src/main/libs/importers/sql/MySQLlImporter'; import MySQLImporter from 'src/main/libs/importers/sql/MySQLlImporter';
import PostgreSQLImporter from 'src/main/libs/importers/sql/PostgreSQLImporter'; import PostgreSQLImporter from 'src/main/libs/importers/sql/PostgreSQLImporter';
import SSHConfig from 'ssh2-promise/lib/sshConfig';
import { MySQLClient } from '../../main/libs/clients/MySQLClient'; import { MySQLClient } from '../../main/libs/clients/MySQLClient';
import { PostgreSQLClient } from '../../main/libs/clients/PostgreSQLClient'; import { PostgreSQLClient } from '../../main/libs/clients/PostgreSQLClient';
@@ -363,8 +363,7 @@ export interface QueryBuilderObject {
offset: number; offset: number;
join: string[]; join: string[];
update: string[]; update: string[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any insert: {[key: string]: string | boolean | number }[];
insert: {[key: string]: any}[];
delete: boolean; delete: boolean;
} }

View File

@@ -1,4 +1,5 @@
import { TypesGroup } from './antares'; import { TypesGroup } from './antares';
import { TableFilterOperator } from './tableApis';
export interface Customizations { export interface Customizations {
// Defaults // Defaults
@@ -8,6 +9,7 @@ export interface Customizations {
dataTypes?: TypesGroup[]; dataTypes?: TypesGroup[];
indexTypes?: string[]; indexTypes?: string[];
foreignActions?: string[]; foreignActions?: string[];
operators?: TableFilterOperator[];
// Core // Core
database?: boolean; database?: boolean;
collations?: boolean; collations?: boolean;

View File

@@ -21,7 +21,7 @@ export interface TableDeleteParams {
rows: {[key: string]: any}; rows: {[key: string]: any};
} }
export type TableFilterOperator = '=' | '!=' | '>' | '<' | '>=' | '<=' | 'IN' | 'NOT IN' | 'LIKE' | 'NOT LIKE' | 'BETWEEN' | 'IS NULL' | 'IS NOT NULL' export type TableFilterOperator = '=' | '!=' | '>' | '<' | '>=' | '<=' | 'IN' | 'NOT IN' | 'LIKE' | 'NOT LIKE' | 'RLIKE' | 'NOT RLIKE' | 'BETWEEN' | 'IS NULL' | 'IS NOT NULL'
export interface TableFilterClausole { export interface TableFilterClausole {
active: boolean; active: boolean;

View File

@@ -0,0 +1,17 @@
import { faker } from '@faker-js/faker';
import * as moment from 'moment';
export const fakerCustom = {
seed: faker.seed,
setLocale: faker.setLocale,
...faker,
date: {
now: () => moment().format('YYYY-MM-DD HH:mm:ss'),
...faker.date
},
time: {
now: () => moment().format('HH:mm:ss'),
random: () => moment(faker.date.recent()).format('HH:mm:ss'),
...faker.time
}
};

View File

@@ -55,7 +55,7 @@ export default (connections: {[key: string]: antares.Client}) => {
port: conn.sshPort ? conn.sshPort : 22, port: conn.sshPort ? conn.sshPort : 22,
privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : null, privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : null,
passphrase: conn.sshPassphrase, passphrase: conn.sshPassphrase,
keepaliveInterval: conn.sshKeepAliveInterval ?? conn.sshKeepAliveInterval*1000 keepaliveInterval: conn.sshKeepAliveInterval ? conn.sshKeepAliveInterval*1000 : null
}; };
} }
@@ -137,7 +137,7 @@ export default (connections: {[key: string]: antares.Client}) => {
port: conn.sshPort ? conn.sshPort : 22, port: conn.sshPort ? conn.sshPort : 22,
privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : null, privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : null,
passphrase: conn.sshPassphrase, passphrase: conn.sshPassphrase,
keepaliveInterval: conn.sshKeepAliveInterval ?? conn.sshKeepAliveInterval*1000 keepaliveInterval: conn.sshKeepAliveInterval ? conn.sshKeepAliveInterval*1000 : null
}; };
} }

View File

@@ -1,8 +1,8 @@
import { faker } from '@faker-js/faker';
import customizations from 'common/customizations'; import customizations from 'common/customizations';
import { ARRAY, BIT, BLOB, BOOLEAN, DATE, DATETIME, FLOAT, LONG_TEXT, NUMBER, TEXT, TEXT_SEARCH } from 'common/fieldTypes'; import { ARRAY, BIT, BLOB, BOOLEAN, DATE, DATETIME, FLOAT, LONG_TEXT, NUMBER, TEXT, TEXT_SEARCH } from 'common/fieldTypes';
import * as antares from 'common/interfaces/antares'; import * as antares from 'common/interfaces/antares';
import { InsertRowsParams } from 'common/interfaces/tableApis'; import { InsertRowsParams } from 'common/interfaces/tableApis';
import { fakerCustom } from 'common/libs/fakerCustom';
import { sqlEscaper } from 'common/libs/sqlUtils'; import { sqlEscaper } from 'common/libs/sqlUtils';
import { ipcMain } from 'electron'; import { ipcMain } from 'electron';
import * as fs from 'fs'; import * as fs from 'fs';
@@ -371,19 +371,19 @@ export default (connections: {[key: string]: antares.Client}) => {
let fakeValue; let fakeValue;
if (params.locale) if (params.locale)
faker.locale = params.locale; fakerCustom.locale = params.locale;
if (Object.keys(params.row[key].params).length) { if (Object.keys(params.row[key].params).length) {
Object.keys(params.row[key].params).forEach(param => { Object.keys(params.row[key].params).forEach(param => {
if (!isNaN(params.row[key].params[param])) if (!isNaN(params.row[key].params[param]))// Converts string numerics params to number
parsedParams[param] = +params.row[key].params[param]; parsedParams[param] = Number(params.row[key].params[param]);
}); });
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
fakeValue = (faker as any)[params.row[key].group][params.row[key].method](parsedParams); fakeValue = (fakerCustom as any)[params.row[key].group][params.row[key].method](parsedParams);
} }
else else
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
fakeValue = (faker as any)[params.row[key].group][params.row[key].method](); fakeValue = (fakerCustom as any)[params.row[key].group][params.row[key].method]();
if (typeof fakeValue === 'string') { if (typeof fakeValue === 'string') {
if (params.row[key].length) if (params.row[key].length)

View File

@@ -1,7 +1,7 @@
import * as antares from 'common/interfaces/antares'; import * as antares from 'common/interfaces/antares';
import mysql from 'mysql2/promise'; import mysql from 'mysql2/promise';
import * as pg from 'pg'; import * as pg from 'pg';
import SSH2Promise from 'ssh2-promise'; import SSH2Promise = require('@fabio286/ssh2-promise');
const queryLogger = ({ sql, cUid }: {sql: string; cUid: string}) => { const queryLogger = ({ sql, cUid }: {sql: string; cUid: string}) => {
// Remove comments, newlines and multiple spaces // Remove comments, newlines and multiple spaces
@@ -16,7 +16,7 @@ const queryLogger = ({ sql, cUid }: {sql: string; cUid: string}) => {
/** /**
* As Simple As Possible Query Builder Core * As Simple As Possible Query Builder Core
*/ */
export abstract class AntaresCore { export abstract class BaseClient {
_client: antares.ClientCode; _client: antares.ClientCode;
protected _cUid: string protected _cUid: string
protected _params: mysql.ConnectionOptions | pg.ClientConfig | { databasePath: string; readonly: boolean}; protected _params: mysql.ConnectionOptions | pg.ClientConfig | { databasePath: string; readonly: boolean};

View File

@@ -4,9 +4,9 @@ import * as antares from 'common/interfaces/antares';
import * as firebird from 'node-firebird'; import * as firebird from 'node-firebird';
import * as path from 'path'; import * as path from 'path';
import { AntaresCore } from '../AntaresCore'; import { BaseClient } from './BaseClient';
export class FirebirdSQLClient extends AntaresCore { export class FirebirdSQLClient extends BaseClient {
private _schema?: string; private _schema?: string;
private _runningConnections: Map<string, number>; private _runningConnections: Map<string, number>;
private _connectionsToCommit: Map<string, firebird.Transaction>; private _connectionsToCommit: Map<string, firebird.Transaction>;

View File

@@ -1,12 +1,12 @@
import SSH2Promise = require('@fabio286/ssh2-promise');
import SSHConfig from '@fabio286/ssh2-promise/lib/sshConfig';
import dataTypes from 'common/data-types/mysql'; import dataTypes from 'common/data-types/mysql';
import * as antares from 'common/interfaces/antares'; import * as antares from 'common/interfaces/antares';
import * as mysql from 'mysql2/promise'; import * as mysql from 'mysql2/promise';
import { AntaresCore } from '../AntaresCore'; import { BaseClient } from './BaseClient';
import SSH2Promise = require('ssh2-promise');
import SSHConfig from 'ssh2-promise/lib/sshConfig';
export class MySQLClient extends AntaresCore { export class MySQLClient extends BaseClient {
private _schema?: string; private _schema?: string;
private _runningConnections: Map<string, number>; private _runningConnections: Map<string, number>;
private _connectionsToCommit: Map<string, mysql.Connection | mysql.PoolConnection>; private _connectionsToCommit: Map<string, mysql.Connection | mysql.PoolConnection>;
@@ -168,7 +168,10 @@ export class MySQLClient extends AntaresCore {
dbConfig.port = tunnel.localPort; dbConfig.port = tunnel.localPort;
} }
catch (err) { catch (err) {
if (this._ssh) this._ssh.close(); if (this._ssh) {
this._ssh.close();
this._ssh.closeTunnel();
}
throw err; throw err;
} }
} }
@@ -187,7 +190,10 @@ export class MySQLClient extends AntaresCore {
this._connection.end(); this._connection.end();
clearInterval(this._keepaliveTimer); clearInterval(this._keepaliveTimer);
this._keepaliveTimer = undefined; this._keepaliveTimer = undefined;
if (this._ssh) this._ssh.close(); if (this._ssh) {
this._ssh.close();
this._ssh.closeTunnel();
}
} }
async getConnection () { async getConnection () {
@@ -256,9 +262,12 @@ export class MySQLClient extends AntaresCore {
} }
private async keepAlive () { private async keepAlive () {
const connection = await (this._connection as mysql.Pool).getConnection(); try {
await connection.ping(); const connection = await (this._connection as mysql.Pool).getConnection();
connection.release(); await connection.ping();
connection.release();
}
catch (_) {}
} }
use (schema: string) { use (schema: string) {

View File

@@ -1,13 +1,13 @@
import SSH2Promise = require('@fabio286/ssh2-promise');
import SSHConfig from '@fabio286/ssh2-promise/lib/sshConfig';
import dataTypes from 'common/data-types/postgresql'; import dataTypes from 'common/data-types/postgresql';
import * as antares from 'common/interfaces/antares'; import * as antares from 'common/interfaces/antares';
import * as pg from 'pg'; import * as pg from 'pg';
import * as pgAst from 'pgsql-ast-parser'; import * as pgAst from 'pgsql-ast-parser';
import { AntaresCore } from '../AntaresCore';
import SSH2Promise = require('ssh2-promise');
import SSHConfig from 'ssh2-promise/lib/sshConfig';
import { ConnectionOptions } from 'tls'; import { ConnectionOptions } from 'tls';
import { BaseClient } from './BaseClient';
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function pgToString (value: any) { function pgToString (value: any) {
return value.toString(); return value.toString();
@@ -81,7 +81,7 @@ type builtinsTypes =
'JSONB' | 'JSONB' |
'REGNAMESPACE' | 'REGNAMESPACE' |
'REGROLE'; 'REGROLE';
export class PostgreSQLClient extends AntaresCore { export class PostgreSQLClient extends BaseClient {
private _schema?: string; private _schema?: string;
private _runningConnections: Map<string, number>; private _runningConnections: Map<string, number>;
private _connectionsToCommit: Map<string, pg.Client | pg.PoolClient>; private _connectionsToCommit: Map<string, pg.Client | pg.PoolClient>;
@@ -180,7 +180,10 @@ export class PostgreSQLClient extends AntaresCore {
dbConfig.port = tunnel.localPort; dbConfig.port = tunnel.localPort;
} }
catch (err) { catch (err) {
if (this._ssh) this._ssh.close(); if (this._ssh) {
this._ssh.close();
this._ssh.closeTunnel();
}
throw err; throw err;
} }
} }
@@ -236,13 +239,19 @@ export class PostgreSQLClient extends AntaresCore {
this._connection.end(); this._connection.end();
clearInterval(this._keepaliveTimer); clearInterval(this._keepaliveTimer);
this._keepaliveTimer = undefined; this._keepaliveTimer = undefined;
if (this._ssh) this._ssh.close(); if (this._ssh) {
this._ssh.close();
this._ssh.closeTunnel();
}
} }
private async keepAlive () { private async keepAlive () {
const connection = await this._connection.connect() as pg.PoolClient; try {
await connection.query('SELECT 1+1'); const connection = await this._connection.connect() as pg.PoolClient;
connection.release(); await connection.query('SELECT 1+1');
connection.release();
}
catch (_) {}
} }
use (schema: string, connection?: pg.Client | pg.PoolClient) { use (schema: string, connection?: pg.Client | pg.PoolClient) {

View File

@@ -3,9 +3,9 @@ import dataTypes from 'common/data-types/sqlite';
import { DATETIME, FLOAT, NUMBER, TIME } from 'common/fieldTypes'; import { DATETIME, FLOAT, NUMBER, TIME } from 'common/fieldTypes';
import * as antares from 'common/interfaces/antares'; import * as antares from 'common/interfaces/antares';
import { AntaresCore } from '../AntaresCore'; import { BaseClient } from './BaseClient';
export class SQLiteClient extends AntaresCore { export class SQLiteClient extends BaseClient {
private _schema?: string; private _schema?: string;
private _connectionsToCommit: Map<string, sqlite.Database>; private _connectionsToCommit: Map<string, sqlite.Database>;
protected _connection?: sqlite.Database; protected _connection?: sqlite.Database;

View File

@@ -6,6 +6,7 @@ const isWindows = process.platform === 'win32';
const indexPath = path.resolve(__dirname, 'index.html').split(path.sep).join('/'); const indexPath = path.resolve(__dirname, 'index.html').split(path.sep).join('/');
export function validateSender (frame: WebFrameMain) { export function validateSender (frame: WebFrameMain) {
if (process.windowsStore) return true; // TEMP HOTFIX
const frameUrl = new URL(frame.url); const frameUrl = new URL(frame.url);
const prefix = isWindows ? 'file:///' : 'file://'; const prefix = isWindows ? 'file:///' : 'file://';
const framePath = frameUrl.href.replace(prefix, ''); const framePath = frameUrl.href.replace(prefix, '');

View File

@@ -1,8 +1,8 @@
import SSHConfig from '@fabio286/ssh2-promise/lib/sshConfig';
import * as antares from 'common/interfaces/antares'; import * as antares from 'common/interfaces/antares';
import { ImportOptions } from 'common/interfaces/importer'; import { ImportOptions } from 'common/interfaces/importer';
import * as mysql from 'mysql2'; import * as mysql from 'mysql2';
import * as pg from 'pg'; import * as pg from 'pg';
import SSHConfig from 'ssh2-promise/lib/sshConfig';
import { MySQLClient } from '../libs/clients/MySQLClient'; import { MySQLClient } from '../libs/clients/MySQLClient';
import { PostgreSQLClient } from '../libs/clients/PostgreSQLClient'; import { PostgreSQLClient } from '../libs/clients/PostgreSQLClient';

View File

@@ -27,11 +27,7 @@
:title="t('general.cancel')" :title="t('general.cancel')"
@click="killTabQuery()" @click="killTabQuery()"
> >
<BaseIcon <BaseIcon icon-name="mdiWindowClose" :size="24" />
class="mr-1"
icon-name="mdiWindowCLose"
:size="24"
/>
<span class="d-invisible pr-1">{{ t('general.run') }}</span> <span class="d-invisible pr-1">{{ t('general.run') }}</span>
</button> </button>
<button <button

View File

@@ -3,7 +3,7 @@
ref="tableWrapper" ref="tableWrapper"
class="vscroll no-outline" class="vscroll no-outline"
tabindex="0" tabindex="0"
:style="{'height': resultsSize+'px'}" :style="{ 'height': resultsSize + 'px' }"
@blur="deselectRows" @blur="deselectRows"
@focus="hasFocus = true" @focus="hasFocus = true"
@keyup.delete="showDeleteConfirmModal" @keyup.delete="showDeleteConfirmModal"
@@ -28,7 +28,7 @@
v-for="(result, index) in resultsWithRows" v-for="(result, index) in resultsWithRows"
:key="index" :key="index"
class="tab-item" class="tab-item"
:class="{'active': resultsetIndex === index}" :class="{ 'active': resultsetIndex === index }"
@click="selectResultset(index)" @click="selectResultset(index)"
> >
<a>{{ result.fields ? result.fields[0]?.table : '' }} ({{ result.rows.length }})</a> <a>{{ result.fields ? result.fields[0]?.table : '' }} ({{ result.rows.length }})</a>
@@ -57,7 +57,7 @@
<span>{{ field.alias || field.name }}</span> <span>{{ field.alias || field.name }}</span>
<BaseIcon <BaseIcon
v-if="isSortable && currentSort === field.name || currentSort === `${field.table}.${field.name}`" v-if="isSortable && currentSort === field.name || currentSort === `${field.table}.${field.name}`"
:icon-name="currentSortDir === 'asc' ? 'mdiSortAscending':'mdiSortDescending'" :icon-name="currentSortDir === 'asc' ? 'mdiSortAscending' : 'mdiSortDescending'"
:size="18" :size="18"
class="sort-icon ml-1" class="sort-icon ml-1"
/> />
@@ -90,7 +90,7 @@
:fields="fieldsObj" :fields="fieldsObj"
:key-usage="keyUsage" :key-usage="keyUsage"
:element-type="elementType" :element-type="elementType"
:class="{'selected': selectedRows.includes(row._antares_id)}" :class="{ 'selected': selectedRows.includes(row._antares_id) }"
:selected="selectedRows.includes(row._antares_id)" :selected="selectedRows.includes(row._antares_id)"
:selected-cell="selectedRows.length === 1 && selectedRows.includes(row._antares_id) ? selectedField : null" :selected-cell="selectedRows.length === 1 && selectedRows.includes(row._antares_id) ? selectedField : null"
@start-editing="isEditingRow = true" @start-editing="isEditingRow = true"
@@ -163,7 +163,7 @@
<BaseSelect <BaseSelect
v-model="sqlExportOptions.sqlInsertDivider" v-model="sqlExportOptions.sqlInsertDivider"
class="form-select" class="form-select"
:options="[{value: 'bytes', label: 'KiB'}, {value: 'rows', label: t('database.row', 2)}]" :options="[{ value: 'bytes', label: 'KiB' }, { value: 'rows', label: t('database.row', 2) }]"
/> />
</div> </div>
</div> </div>
@@ -208,9 +208,9 @@
v-model="csvExportOptions.stringDelimiter" v-model="csvExportOptions.stringDelimiter"
class="form-select" class="form-select"
:options="[ :options="[
{value: '', label: t('general.none')}, { value: '', label: t('general.none') },
{value: 'single', label: t('general.singleQuote')}, { value: 'single', label: t('general.singleQuote') },
{value: 'double', label: t('general.doubleQuote')} { value: 'double', label: t('general.doubleQuote') }
]" ]"
/> />
</div> </div>
@@ -235,7 +235,10 @@
</label> </label>
</div> </div>
<div class="column col-7"> <div class="column col-7">
<label class="form-switch d-inline-block" @click.prevent="csvExportOptions.header = !csvExportOptions.header"> <label
class="form-switch d-inline-block"
@click.prevent="csvExportOptions.header = !csvExportOptions.header"
>
<input type="checkbox" :checked="csvExportOptions.header"> <input type="checkbox" :checked="csvExportOptions.header">
<i class="form-icon" /> <i class="form-icon" />
</label> </label>
@@ -249,10 +252,10 @@
<script setup lang="ts"> <script setup lang="ts">
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import faker from '@faker-js/faker';
import { BLOB, DATE, DATETIME, LONG_TEXT, TEXT, TIME } from 'common/fieldTypes'; import { BLOB, DATE, DATETIME, LONG_TEXT, TEXT, TIME } from 'common/fieldTypes';
import { QueryResult, TableField } from 'common/interfaces/antares'; import { QueryResult, TableField } from 'common/interfaces/antares';
import { TableUpdateParams } from 'common/interfaces/tableApis'; import { TableUpdateParams } from 'common/interfaces/tableApis';
import { fakerCustom } from 'common/libs/fakerCustom';
import { jsonToSqlInsert } from 'common/libs/sqlUtils'; import { jsonToSqlInsert } from 'common/libs/sqlUtils';
import { uidGen } from 'common/libs/uidGen'; import { uidGen } from 'common/libs/uidGen';
import * as json2php from 'json2php'; import * as json2php from 'json2php';
@@ -299,7 +302,7 @@ const emit = defineEmits([
'duplicate-row' 'duplicate-row'
]); ]);
const resultTable: Ref<Component & {updateWindow: () => void}> = ref(null); const resultTable: Ref<Component & { updateWindow: () => void }> = ref(null);
const tableWrapper: Ref<HTMLDivElement> = ref(null); const tableWrapper: Ref<HTMLDivElement> = ref(null);
const table: Ref<HTMLDivElement> = ref(null); const table: Ref<HTMLDivElement> = ref(null);
const resultsSize = ref(0); const resultsSize = ref(0);
@@ -377,7 +380,7 @@ const keyUsage = computed(() => resultsWithRows.value.length ? resultsWithRows.v
const fieldsObj = computed(() => { const fieldsObj = computed(() => {
if (sortedResults.value.length) { if (sortedResults.value.length) {
const fieldsObj: {[key: string]: TableField} = {}; const fieldsObj: { [key: string]: TableField } = {};
for (const key in sortedResults.value[0]) { for (const key in sortedResults.value[0]) {
if (key === '_antares_id') continue; if (key === '_antares_id') continue;
@@ -483,7 +486,7 @@ const resizeResults = () => {
const refreshScroller = () => resizeResults(); const refreshScroller = () => resizeResults();
const updateField = (payload: { field: string; type: string; content: any }, row: {[key: string]: any}) => { const updateField = (payload: { field: string; type: string; content: any }, row: { [key: string]: any }) => {
const orgRow: any = localResults.value.find((lr: any) => lr._antares_id === row._antares_id); const orgRow: any = localResults.value.find((lr: any) => lr._antares_id === row._antares_id);
Object.keys(orgRow).forEach(key => { // remap the row Object.keys(orgRow).forEach(key => { // remap the row
@@ -598,7 +601,7 @@ const copyRow = (format: string) => {
json: contentToCopy, json: contentToCopy,
client: workspaceClient.value, client: workspaceClient.value,
fields: fieldsObj.value as { fields: fieldsObj.value as {
[key: string]: {type: string; datePrecision: number}; [key: string]: { type: string; datePrecision: number };
}, },
table: getTable(resultsetIndex.value) table: getTable(resultsetIndex.value)
}); });
@@ -670,28 +673,18 @@ const fillCell = (event: { name: string; group: string; type: string }) => {
datePrecision += i === 0 ? '.S' : 'S'; datePrecision += i === 0 ? '.S' : 'S';
} }
if (event.group === 'custom') { fakeValue = (fakerCustom as any)[event.group][event.name]();
if (event.type === 'time' && event.name === 'now') if (['string', 'number'].includes(typeof fakeValue)) {
fakeValue = moment().format(`HH:mm:ss${datePrecision}`); if (typeof fakeValue === 'number')
else if (event.type === 'time' && event.name === 'random') fakeValue = String(fakeValue);
fakeValue = moment(faker.date.recent()).format(`HH:mm:ss${datePrecision}`);
else if (event.type === 'datetime' && event.name === 'now')
fakeValue = moment().format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
}
else {
fakeValue = (faker as any)[event.group][event.name]();
if (['string', 'number'].includes(typeof fakeValue)) {
if (typeof fakeValue === 'number')
fakeValue = String(fakeValue);
if (selectedCell.value.length) if (selectedCell.value.length)
fakeValue = fakeValue.substring(0, selectedCell.value.length < 1024 ? Number(selectedCell.value.length) : 1024); fakeValue = fakeValue.substring(0, selectedCell.value.length < 1024 ? Number(selectedCell.value.length) : 1024);
}
else if ([...DATE, ...DATETIME].includes(selectedCell.value.type))
fakeValue = moment(fakeValue).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
else if (TIME.includes(selectedCell.value.type))
fakeValue = moment(fakeValue).format(`HH:mm:ss${datePrecision}`);
} }
else if ([...DATE, ...DATETIME].includes(selectedCell.value.type))
fakeValue = moment(fakeValue).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
else if (TIME.includes(selectedCell.value.type))
fakeValue = moment(fakeValue).format(`HH:mm:ss${datePrecision}`);
const params = { const params = {
primary: primaryField.value?.name, primary: primaryField.value?.name,
@@ -859,12 +852,12 @@ const downloadTable = (format: 'csv' | 'json' | 'sql' | 'php', table: string, po
type: format, type: format,
content: rows, content: rows,
fields: JSON.parse(JSON.stringify(fieldsObj.value)) as { fields: JSON.parse(JSON.stringify(fieldsObj.value)) as {
[key: string]: {type: string; datePrecision: number}; [key: string]: { type: string; datePrecision: number };
}, },
client: workspaceClient.value, client: workspaceClient.value,
table, table,
sqlOptions: popup ? { ...sqlExportOptions.value }: null, sqlOptions: popup ? { ...sqlExportOptions.value } : null,
csvOptions: popup ? { ...csvExportOptions.value }: null csvOptions: popup ? { ...csvExportOptions.value } : null
}); });
}; };
@@ -897,7 +890,7 @@ const onKey = async (e: KeyboardEvent) => {
if (!(e.ctrlKey || e.metaKey) && (e.code.includes('Arrow') || e.code === 'Tab') && sortedResults.value.length > 0 && !e.altKey) { if (!(e.ctrlKey || e.metaKey) && (e.code.includes('Arrow') || e.code === 'Tab') && sortedResults.value.length > 0 && !e.altKey) {
e.preventDefault(); e.preventDefault();
const aviableFields= Object.keys(sortedResults.value[0]).slice(0, -1); // removes _antares_id const aviableFields = Object.keys(sortedResults.value[0]).slice(0, -1); // removes _antares_id
if (!selectedField.value) if (!selectedField.value)
selectedField.value = aviableFields[0]; selectedField.value = aviableFields[0];
@@ -914,8 +907,8 @@ const onKey = async (e: KeyboardEvent) => {
nextIndex = selectedIndex + 1; nextIndex = selectedIndex + 1;
nextFieldIndex = selectedFieldIndex; nextFieldIndex = selectedFieldIndex;
if (nextIndex > sortedResults.value.length -1) if (nextIndex > sortedResults.value.length - 1)
nextIndex = sortedResults.value.length -1; nextIndex = sortedResults.value.length - 1;
break; break;
case 'ArrowUp': case 'ArrowUp':
@@ -931,7 +924,7 @@ const onKey = async (e: KeyboardEvent) => {
nextIndex = selectedIndex; nextIndex = selectedIndex;
nextFieldIndex = selectedFieldIndex + 1; nextFieldIndex = selectedFieldIndex + 1;
if (nextFieldIndex > aviableFields.length -1) if (nextFieldIndex > aviableFields.length - 1)
nextFieldIndex = 0; nextFieldIndex = 0;
break; break;
@@ -941,7 +934,7 @@ const onKey = async (e: KeyboardEvent) => {
nextFieldIndex = selectedFieldIndex - 1; nextFieldIndex = selectedFieldIndex - 1;
if (nextFieldIndex < 0) if (nextFieldIndex < 0)
nextFieldIndex = aviableFields.length -1; nextFieldIndex = aviableFields.length - 1;
break; break;
@@ -950,11 +943,11 @@ const onKey = async (e: KeyboardEvent) => {
if (e.shiftKey) { if (e.shiftKey) {
nextFieldIndex = selectedFieldIndex - 1; nextFieldIndex = selectedFieldIndex - 1;
if (nextFieldIndex < 0) if (nextFieldIndex < 0)
nextFieldIndex = aviableFields.length -1; nextFieldIndex = aviableFields.length - 1;
} }
else { else {
nextFieldIndex = selectedFieldIndex + 1; nextFieldIndex = selectedFieldIndex + 1;
if (nextFieldIndex > aviableFields.length -1) if (nextFieldIndex > aviableFields.length - 1)
nextFieldIndex = 0; nextFieldIndex = 0;
} }
} }
@@ -1049,32 +1042,33 @@ onUnmounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.vscroll { .vscroll {
height: 1000px; height: 1000px;
overflow: auto; overflow: auto;
overflow-anchor: none; overflow-anchor: none;
} }
.column-resizable { .column-resizable {
&:hover,
&:active { &:hover,
resize: horizontal; &:active {
overflow: hidden; resize: horizontal;
} overflow: hidden;
}
} }
.table-column-title { .table-column-title {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.sort-icon { .sort-icon {
font-size: 0.7rem; font-size: 0.7rem;
line-height: 1; line-height: 1;
margin-left: 0.2rem; margin-left: 0.2rem;
} }
.result-tabs { .result-tabs {
background: transparent !important; background: transparent !important;
margin: 0; margin: 0;
} }
</style> </style>

View File

@@ -197,13 +197,13 @@ const fakerMethods = {
{ name: 'amount', group: 'finance' } { name: 'amount', group: 'finance' }
], ],
datetime: [ datetime: [
{ name: 'now', group: 'custom' }, { name: 'now', group: 'date' },
{ name: 'past', group: 'date' }, { name: 'past', group: 'date' },
{ name: 'future', group: 'date' } { name: 'future', group: 'date' }
], ],
time: [ time: [
{ name: 'now', group: 'custom' }, { name: 'now', group: 'time' },
{ name: 'random', group: 'custom' } { name: 'random', group: 'time' }
], ],
uuid: [ uuid: [
{ name: 'uuid', group: 'random' } { name: 'uuid', group: 'random' }

View File

@@ -183,6 +183,7 @@
<WorkspaceTabTableFilters <WorkspaceTabTableFilters
v-if="isSearch" v-if="isSearch"
:fields="fields" :fields="fields"
:is-quering="isQuering"
:conn-client="connection.client" :conn-client="connection.client"
@filter="updateFilters" @filter="updateFilters"
@filter-change="onFilterChange" @filter-change="onFilterChange"

View File

@@ -9,6 +9,7 @@
<input <input
v-model="row.active" v-model="row.active"
type="checkbox" type="checkbox"
:disabled="isQuering"
@change="doFilter" @change="doFilter"
><i class="form-icon" /> ><i class="form-icon" />
</label> </label>
@@ -18,11 +19,13 @@
:options="fields" :options="fields"
option-track-by="name" option-track-by="name"
option-label="name" option-label="name"
:disabled="isQuering"
/> />
<BaseSelect <BaseSelect
v-model="row.op" v-model="row.op"
class="form-select ml-2 col-auto select-sm" class="form-select ml-2 col-auto select-sm"
:options="operators" :options="operators"
:disabled="isQuering"
/> />
<div class="workspace-table-filters-row-value ml-2"> <div class="workspace-table-filters-row-value ml-2">
<input <input
@@ -30,12 +33,14 @@
v-model="row.value" v-model="row.value"
type="text" type="text"
class="form-input input-sm" class="form-input input-sm"
:disabled="isQuering"
> >
<input <input
v-if="row.op === 'BETWEEN'" v-if="row.op === 'BETWEEN'"
v-model="row.value2" v-model="row.value2"
type="text" type="text"
class="form-input ml-2 input-sm" class="form-input ml-2 input-sm"
:disabled="isQuering"
> >
</div> </div>
<button <button
@@ -87,15 +92,14 @@ const { t } = useI18n();
const props = defineProps({ const props = defineProps({
fields: Array as Prop<TableField[]>, fields: Array as Prop<TableField[]>,
connClient: String as Prop<ClientCode> connClient: String as Prop<ClientCode>,
isQuering: Boolean
}); });
const emit = defineEmits(['filter-change', 'filter']); const emit = defineEmits(['filter-change', 'filter']);
const rows = ref([]); const rows = ref([]);
const operators = ref<TableFilterOperator[]>([ const operators: TableFilterOperator[] = customizations[props.connClient].operators;
'=', '!=', '>', '<', '>=', '<=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE', 'BETWEEN', 'IS NULL', 'IS NOT NULL'
]);
const clientCustomizations = computed(() => customizations[props.connClient]); const clientCustomizations = computed(() => customizations[props.connClient]);
@@ -122,7 +126,7 @@ const createClausole = (filter: TableFilterClausole) => {
const { elementsWrapper: ew, stringsWrapper: sw } = clientCustomizations.value; const { elementsWrapper: ew, stringsWrapper: sw } = clientCustomizations.value;
let value; let value;
if (isNumeric) { if (isNumeric && !['IN', 'NOT IN', 'RLIKE', 'NOT RLIKE'].includes(filter.op)) {
if (isNaN(Number(filter.value))) if (isNaN(Number(filter.value)))
filter.value = ''; filter.value = '';
if (isNaN(Number(filter.value2))) if (isNaN(Number(filter.value2)))
@@ -145,7 +149,7 @@ const createClausole = (filter: TableFilterClausole) => {
val = val.trim(); val = val.trim();
return isNumeric ? val : `${sw}${val}${sw}`; return isNumeric ? val : `${sw}${val}${sw}`;
}).join(','); }).join(',');
value = `(${filter.value})`; value = `(${value})`;
break; break;
case 'IS NULL': case 'IS NULL':
case 'IS NOT NULL': case 'IS NOT NULL':

View File

@@ -4,109 +4,109 @@ declare module '@/App.vue';
declare module 'v-mask'; declare module 'v-mask';
declare module 'json2php'; declare module 'json2php';
declare module 'vuedraggable' {// <- to export as default declare module 'vuedraggable' {// <- to export as default
const draggableComponent: import('vue').DefineComponent<{ const draggableComponent: import('vue').DefineComponent<{
list: { list: {
type: ArrayConstructor; type: ArrayConstructor;
required: boolean; required: boolean;
default: any; default: any;
}; };
modelValue: { modelValue: {
type: ArrayConstructor; type: ArrayConstructor;
required: boolean; required: boolean;
default: any; default: any;
}; };
itemKey: { itemKey: {
type: (FunctionConstructor | StringConstructor)[]; type: (FunctionConstructor | StringConstructor)[];
required: boolean; required: boolean;
}; };
clone: { clone: {
type: FunctionConstructor; type: FunctionConstructor;
default: (original: any) => any; default: (original: any) => any;
}; };
tag: { tag: {
type: StringConstructor; type: StringConstructor;
default: string; default: string;
}; };
move: { move: {
type: FunctionConstructor; type: FunctionConstructor;
default: any; default: any;
}; };
componentData: { componentData: {
type: ObjectConstructor; type: ObjectConstructor;
required: boolean; required: boolean;
default: any; default: any;
}; };
}, unknown, { }, unknown, {
error: boolean; error: boolean;
}, { }, {
realList(): any; realList(): any;
getKey(): any; getKey(): any;
}, { }, {
getUnderlyingVm(domElement: any): any; getUnderlyingVm(domElement: any): any;
getUnderlyingPotencialDraggableComponent(htmElement: any): any; getUnderlyingPotencialDraggableComponent(htmElement: any): any;
emitChanges(evt: any): void; emitChanges(evt: any): void;
alterList(onList: any): void; alterList(onList: any): void;
spliceList(): void; spliceList(): void;
updatePosition(oldIndex: any, newIndex: any): void; updatePosition(oldIndex: any, newIndex: any): void;
getRelatedContextFromMoveEvent({ to, related }: { getRelatedContextFromMoveEvent({ to, related }: {
to: any; to: any;
related: any; related: any;
}): any; }): any;
getVmIndexFromDomIndex(domIndex: any): any; getVmIndexFromDomIndex(domIndex: any): any;
onDragStart(evt: any): void; onDragStart(evt: any): void;
onDragAdd(evt: any): void; onDragAdd(evt: any): void;
onDragRemove(evt: any): void; onDragRemove(evt: any): void;
onDragUpdate(evt: any): void; onDragUpdate(evt: any): void;
computeFutureIndex(relatedContext: any, evt: any): any; computeFutureIndex(relatedContext: any, evt: any): any;
onDragMove(evt: any, originalEvent: any): any; onDragMove(evt: any, originalEvent: any): any;
onDragEnd(): void; onDragEnd(): void;
}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, any[], any, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<{ }, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, any[], any, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<{
move: Function; move: Function;
tag: string; tag: string;
clone: Function; clone: Function;
list: unknown[]; list: unknown[];
modelValue: unknown[]; modelValue: unknown[];
componentData: Record<string, any>; componentData: Record<string, any>;
} & { } & {
itemKey?: string | Function; itemKey?: string | Function;
}>, { }>, {
move: Function; move: Function;
tag: string; tag: string;
clone: Function; clone: Function;
list: unknown[]; list: unknown[];
modelValue: unknown[]; modelValue: unknown[];
componentData: Record<string, any>; componentData: Record<string, any>;
}>; }>;
export = draggableComponent; export = draggableComponent;
} }
declare const SvgIcon: import('vue').DefineComponent<{ declare const SvgIcon: import('vue').DefineComponent<{
type: { type: {
type: StringConstructor; type: StringConstructor;
default: string; default: string;
}; };
path: { path: {
type: StringConstructor; type: StringConstructor;
default: string; default: string;
}; };
size: { size: {
type: NumberConstructor; type: NumberConstructor;
optional: boolean; optional: boolean;
}; };
viewbox: { viewbox: {
type: StringConstructor; type: StringConstructor;
optional: boolean; optional: boolean;
}; };
flip: { flip: {
type: StringConstructor; type: StringConstructor;
optional: boolean; optional: boolean;
}; };
rotate: { rotate: {
type: NumberConstructor; type: NumberConstructor;
optional: boolean; optional: boolean;
}; };
}>; }>;
declare module '@jamescoyle/vue-icon' { declare module '@jamescoyle/vue-icon' {
export default SvgIcon; export default SvgIcon;
} }