diff --git a/package.json b/package.json
index 42227d0ac..47d863002 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,8 @@
"version": "4.1.0",
"name": "dbgate-all",
"workspaces": [
- "packages/*"
+ "packages/*",
+ "plugins/*"
],
"scripts": {
"start:api": "yarn workspace dbgate-api start",
@@ -22,6 +23,7 @@
"build:app": "cd app && yarn install && yarn build",
"build:api": "yarn workspace dbgate-api build",
"build:web:docker": "yarn workspace dbgate-web build",
+ "build:plugins:frontend": "yarn workspace dbgate-plugin-csv build:frontend && yarn workspace dbgate-plugin-excel build:frontend && yarn workspace dbgate-plugin-mysql build:frontend && yarn workspace dbgate-plugin-mssql build:frontend && yarn workspace dbgate-plugin-mongo build:frontend && yarn workspace dbgate-plugin-postgres build:frontend &&",
"build:app:local": "cd app && yarn build:local",
"start:app:local": "cd app && yarn start:local",
"setCurrentVersion": "node setCurrentVersion",
diff --git a/plugins/dbgate-plugin-csv/LICENSE b/plugins/dbgate-plugin-csv/LICENSE
new file mode 100644
index 000000000..c15ede038
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Jan Prochazka
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-csv/README.md b/plugins/dbgate-plugin-csv/README.md
new file mode 100644
index 000000000..3bf17fecf
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/README.md
@@ -0,0 +1,60 @@
+[](https://github.com/prettier/prettier)
+[](https://paypal.me/JanProchazkaCz/30eur)
+[](https://www.npmjs.com/package/dbgate-plugin-csv)
+
+# dbgate-plugin-csv
+
+CSV import/export plugin for DbGate
+
+## Usage without DbGate
+
+Export from fake object reader into CSV file. Fake object file can be replaced with other reader/writer factory functions, as described in
+[dbgate-api package](https://www.npmjs.com/package/dbgate-api)
+
+```javascript
+const dbgateApi = require('dbgate-api');
+const dbgatePluginCsv = require("dbgate-plugin-csv");
+
+dbgateApi.registerPlugins(dbgatePluginCsv);
+
+
+async function run() {
+ const reader = await dbgateApi.fakeObjectReader();
+ const writer = await dbgatePluginCsv.shellApi.writer({ fileName: 'myfile1.csv', separator: ';' });
+ await dbgateApi.copyStream(reader, writer);
+
+ console.log('Finished job script');
+}
+dbgateApi.runScript(run);
+
+
+```
+
+## Factory functions
+
+### shellApi.reader
+Reads CSV file
+```js
+ const dbgatePluginCsv = require("dbgate-plugin-csv");
+ const reader = await dbgatePluginCsv.shellApi.reader({
+ fileName: 'test.csv',
+ encoding: 'utf-8',
+ header: true,
+ delimiter: ',',
+ quoted: false,
+ limitRows: null
+ });
+```
+
+### shellApi.writer
+Writes CSV file
+```js
+ const dbgatePluginCsv = require("dbgate-plugin-csv");
+ const writer = await dbgatePluginCsv.shellApi.writer({
+ fileName: 'test.csv',
+ encoding: 'utf-8',
+ header: true,
+ delimiter: ',',
+ quoted: false
+ });
+```
diff --git a/plugins/dbgate-plugin-csv/icon.svg b/plugins/dbgate-plugin-csv/icon.svg
new file mode 100644
index 000000000..cfe0335e5
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/icon.svg
@@ -0,0 +1,35 @@
+
+
+
diff --git a/plugins/dbgate-plugin-csv/package.json b/plugins/dbgate-plugin-csv/package.json
new file mode 100644
index 000000000..64e96e929
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "dbgate-plugin-csv",
+ "main": "dist/backend.js",
+ "version": "1.0.9",
+ "homepage": "https://github.com/dbgate/dbgate-plugin-csv",
+ "description": "CSV import/export plugin for DbGate",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/dbgate/dbgate-plugin-csv.git"
+ },
+ "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur",
+ "author": "Jan Prochazka",
+ "license": "GPL",
+ "keywords": [
+ "csv",
+ "import",
+ "export",
+ "dbgate",
+ "dbgateplugin"
+ ],
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build:frontend": "webpack --config webpack-frontend.config",
+ "build:backend": "webpack --config webpack-backend.config.js",
+ "build": "yarn build:frontend && yarn build:backend",
+ "plugin": "yarn build && yarn pack && dbgate-plugin dbgate-plugin-csv",
+ "plugout": "dbgate-plugout dbgate-plugin-csv",
+ "prepublishOnly": "yarn build"
+ },
+ "devDependencies": {
+ "csv": "^5.3.2",
+ "dbgate-plugin-tools": "^1.0.4",
+ "lodash": "^4.17.20",
+ "webpack": "^4.42.0",
+ "webpack-cli": "^3.3.11"
+ }
+}
diff --git a/plugins/dbgate-plugin-csv/prettier.config.js b/plugins/dbgate-plugin-csv/prettier.config.js
new file mode 100644
index 000000000..406484074
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/prettier.config.js
@@ -0,0 +1,8 @@
+module.exports = {
+ trailingComma: 'es5',
+ tabWidth: 2,
+ semi: true,
+ singleQuote: true,
+ arrowParen: 'avoid',
+ printWidth: 120,
+};
diff --git a/plugins/dbgate-plugin-csv/src/backend/index.js b/plugins/dbgate-plugin-csv/src/backend/index.js
new file mode 100644
index 000000000..460beba4e
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/src/backend/index.js
@@ -0,0 +1,13 @@
+const reader = require('./reader');
+const writer = require('./writer');
+
+module.exports = {
+ packageName: 'dbgate-plugin-csv',
+ shellApi: {
+ reader,
+ writer,
+ },
+ initialize(dbgateEnv) {
+ reader.initialize(dbgateEnv);
+ },
+};
diff --git a/plugins/dbgate-plugin-csv/src/backend/reader.js b/plugins/dbgate-plugin-csv/src/backend/reader.js
new file mode 100644
index 000000000..6c07518f5
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/src/backend/reader.js
@@ -0,0 +1,67 @@
+const zipObject = require('lodash/zipObject');
+const csv = require('csv');
+const fs = require('fs');
+const stream = require('stream');
+
+let dbgateApi;
+class CsvPrepareStream extends stream.Transform {
+ constructor({ header }) {
+ super({ objectMode: true });
+ this.structure = null;
+ this.header = header;
+ }
+ _transform(chunk, encoding, done) {
+ if (this.structure) {
+ this.push(
+ zipObject(
+ this.structure.columns.map((x) => x.columnName),
+ chunk
+ )
+ );
+ done();
+ } else {
+ if (this.header) {
+ this.structure = {
+ __isStreamHeader: true,
+ columns: chunk.map((columnName) => ({ columnName })),
+ };
+ this.push(this.structure);
+ } else {
+ this.structure = {
+ __isStreamHeader: true,
+ columns: chunk.map((value, index) => ({ columnName: `col${index + 1}` })),
+ };
+ this.push(this.structure);
+ this.push(
+ zipObject(
+ this.structure.columns.map((x) => x.columnName),
+ chunk
+ )
+ );
+ }
+ done();
+ }
+ }
+}
+
+async function reader({ fileName, encoding = 'utf-8', header = true, delimiter, limitRows = undefined }) {
+ console.log(`Reading file ${fileName}`);
+ const csvStream = csv.parse({
+ // @ts-ignore
+ delimiter,
+ skip_lines_with_error: true,
+ to_line: limitRows ? limitRows + 1 : undefined,
+ });
+ const downloadedFile = await dbgateApi.download(fileName);
+ const fileStream = fs.createReadStream(downloadedFile, encoding);
+ const csvPrepare = new CsvPrepareStream({ header });
+ fileStream.pipe(csvStream);
+ csvStream.pipe(csvPrepare);
+ return csvPrepare;
+}
+
+reader.initialize = (dbgateEnv) => {
+ dbgateApi = dbgateEnv.dbgateApi;
+};
+
+module.exports = reader;
diff --git a/plugins/dbgate-plugin-csv/src/backend/writer.js b/plugins/dbgate-plugin-csv/src/backend/writer.js
new file mode 100644
index 000000000..8e1dbeaff
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/src/backend/writer.js
@@ -0,0 +1,36 @@
+const csv = require('csv');
+const fs = require('fs');
+const stream = require('stream');
+
+class CsvPrepareStream extends stream.Transform {
+ constructor({ header }) {
+ super({ objectMode: true });
+ this.structure = null;
+ this.header = header;
+ }
+ _transform(chunk, encoding, done) {
+ if (this.structure) {
+ this.push(this.structure.columns.map((col) => chunk[col.columnName]));
+ done();
+ } else {
+ this.structure = chunk;
+ if (this.header) {
+ this.push(chunk.columns.map((x) => x.columnName));
+ }
+ done();
+ }
+ }
+}
+
+async function writer({ fileName, encoding = 'utf-8', header = true, delimiter, quoted }) {
+ console.log(`Writing file ${fileName}`);
+ const csvPrepare = new CsvPrepareStream({ header });
+ const csvStream = csv.stringify({ delimiter, quoted });
+ const fileStream = fs.createWriteStream(fileName, encoding);
+ csvPrepare.pipe(csvStream);
+ csvStream.pipe(fileStream);
+ csvPrepare['finisher'] = fileStream;
+ return csvPrepare;
+}
+
+module.exports = writer;
diff --git a/plugins/dbgate-plugin-csv/src/frontend/index.js b/plugins/dbgate-plugin-csv/src/frontend/index.js
new file mode 100644
index 000000000..33b0f6a17
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/src/frontend/index.js
@@ -0,0 +1,46 @@
+const fileFormat = {
+ packageName: 'dbgate-plugin-csv',
+ // file format identifier
+ storageType: 'csv',
+ // file extension without leading dot
+ extension: 'csv',
+ // human readable file format name
+ name: 'CSV',
+ // function name from backend, which contains reader factory, postfixed by package name
+ readerFunc: 'reader@dbgate-plugin-csv',
+ // function name from backend, which contains writer factory, postfixed by package name
+ writerFunc: 'writer@dbgate-plugin-csv',
+ // optional list of format arguments, which can be edited from UI
+ args: [
+ {
+ type: 'select',
+ name: 'delimiter',
+ label: 'Delimiter',
+ options: [
+ { name: 'Comma (,)', value: ',' },
+ { name: 'Semicolon (;)', value: ';' },
+ { name: 'Tab', value: '\t' },
+ { name: 'Pipe (|)', value: '|' },
+ ],
+ apiName: 'delimiter',
+ },
+ {
+ type: 'checkbox',
+ name: 'quoted',
+ label: 'Quoted',
+ apiName: 'quoted',
+ direction: 'target',
+ },
+ {
+ type: 'checkbox',
+ name: 'header',
+ label: 'Has header row',
+ apiName: 'header',
+ default: true,
+ },
+ ],
+};
+
+export default {
+ fileFormats: [fileFormat],
+};
diff --git a/plugins/dbgate-plugin-csv/webpack-backend.config.js b/plugins/dbgate-plugin-csv/webpack-backend.config.js
new file mode 100644
index 000000000..e75357dff
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/webpack-backend.config.js
@@ -0,0 +1,23 @@
+var webpack = require('webpack');
+var path = require('path');
+
+var config = {
+ context: __dirname + '/src/backend',
+
+ entry: {
+ app: './index.js',
+ },
+ target: 'node',
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: 'backend.js',
+ libraryTarget: 'commonjs2',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-csv/webpack-frontend.config.js b/plugins/dbgate-plugin-csv/webpack-frontend.config.js
new file mode 100644
index 000000000..db07de291
--- /dev/null
+++ b/plugins/dbgate-plugin-csv/webpack-frontend.config.js
@@ -0,0 +1,24 @@
+var webpack = require("webpack");
+var path = require("path");
+
+var config = {
+ context: __dirname + "/src/frontend",
+
+ entry: {
+ app: "./index.js",
+ },
+ target: "web",
+ output: {
+ path: path.resolve(__dirname, "dist"),
+ filename: "frontend.js",
+ libraryTarget: "var",
+ library: 'plugin',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-excel/LICENSE b/plugins/dbgate-plugin-excel/LICENSE
new file mode 100644
index 000000000..c15ede038
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Jan Prochazka
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-excel/README.md b/plugins/dbgate-plugin-excel/README.md
new file mode 100644
index 000000000..aaf7b0b28
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/README.md
@@ -0,0 +1,52 @@
+[](https://github.com/prettier/prettier)
+[](https://paypal.me/JanProchazkaCz/30eur)
+[](https://www.npmjs.com/package/dbgate-plugin-excel)
+
+# dbgate-plugin-excel
+
+MS Excel import/export plugin for DbGate
+
+
+## Usage without DbGate
+
+Export from fake object reader into MS Excel file. Fake object file can be replaced with other reader/writer factory functions, as described in
+[dbgate-api package](https://www.npmjs.com/package/dbgate-api)
+
+```javascript
+const dbgateApi = require('dbgate-api');
+const dbgatePluginExcel = require("dbgate-plugin-excel");
+
+dbgateApi.registerPlugins(dbgatePluginExcel);
+
+
+async function run() {
+ const reader = await dbgateApi.fakeObjectReader();
+ const writer = await dbgatePluginExcel.shellApi.writer({ fileName: 'myfile1.xlsx', sheetName: 'Sheet 1' });
+ await dbgateApi.copyStream(reader, writer);
+ console.log('Finished job script');
+}
+dbgateApi.runScript(run);
+
+
+```
+
+## Factory functions
+
+### shellApi.reader
+Reads tabular data from one sheet in MS Excel file.
+```js
+ const reader = await dbgatePluginExcel.shellApi.reader({
+ fileName: 'test.xlsx',
+ sheetName: 'Album',
+ limitRows: null
+ });
+```
+
+### shellApi.writer
+Writes tabular data into MS excel file. There could be more writes into the some file in one script, if property sheetName is different.
+```js
+ const reader = await dbgatePluginExcel.shellApi.writer({
+ fileName: 'test.xlsx',
+ sheetName: 'Album',
+ });
+```
diff --git a/plugins/dbgate-plugin-excel/icon.svg b/plugins/dbgate-plugin-excel/icon.svg
new file mode 100644
index 000000000..11492442b
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/icon.svg
@@ -0,0 +1,33 @@
+
+
+
diff --git a/plugins/dbgate-plugin-excel/package.json b/plugins/dbgate-plugin-excel/package.json
new file mode 100644
index 000000000..6a07c6c7b
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "dbgate-plugin-excel",
+ "main": "dist/backend.js",
+ "version": "1.0.8",
+ "homepage": "https://github.com/dbgate/dbgate-plugin-excel",
+ "description": "MS Excel import/export plugin for DbGate",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/dbgate/dbgate-plugin-excel.git"
+ },
+ "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur",
+ "author": "Jan Prochazka",
+ "license": "GPL",
+ "keywords": [
+ "excel",
+ "import",
+ "export",
+ "dbgate",
+ "dbgateplugin"
+ ],
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build:frontend": "webpack --config webpack-frontend.config",
+ "build:backend": "webpack --config webpack-backend.config.js",
+ "build": "yarn build:frontend && yarn build:backend",
+ "plugin": "yarn build && dbgate-plugin dbgate-plugin-excel",
+ "plugout": "dbgate-plugout dbgate-plugin-excel",
+ "prepublishOnly": "yarn build"
+ },
+ "devDependencies": {
+ "dbgate-plugin-tools": "^1.0.0",
+ "lodash": "^4.17.20",
+ "webpack": "^4.42.0",
+ "webpack-cli": "^3.3.11",
+ "xlsx": "^0.16.8"
+ }
+}
diff --git a/plugins/dbgate-plugin-excel/prettier.config.js b/plugins/dbgate-plugin-excel/prettier.config.js
new file mode 100644
index 000000000..406484074
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/prettier.config.js
@@ -0,0 +1,8 @@
+module.exports = {
+ trailingComma: 'es5',
+ tabWidth: 2,
+ semi: true,
+ singleQuote: true,
+ arrowParen: 'avoid',
+ printWidth: 120,
+};
diff --git a/plugins/dbgate-plugin-excel/src/backend/index.js b/plugins/dbgate-plugin-excel/src/backend/index.js
new file mode 100644
index 000000000..2a1b19239
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/src/backend/index.js
@@ -0,0 +1,26 @@
+const xlsx = require('xlsx');
+const reader = require('./reader');
+const writer = require('./writer');
+
+let dbgateApi;
+
+module.exports = {
+ packageName: 'dbgate-plugin-excel',
+ shellApi: {
+ reader,
+ writer,
+ },
+
+ commands: {
+ analyse: async ({ fileName }) => {
+ const downloadedFile = await dbgateApi.download(fileName);
+ const workbook = xlsx.readFile(downloadedFile, { bookSheets: true });
+ return workbook.SheetNames;
+ },
+ },
+ initialize(dbgateEnv) {
+ dbgateApi = dbgateEnv.dbgateApi;
+ writer.initialize(dbgateEnv);
+ reader.initialize(dbgateEnv);
+ },
+};
diff --git a/plugins/dbgate-plugin-excel/src/backend/reader.js b/plugins/dbgate-plugin-excel/src/backend/reader.js
new file mode 100644
index 000000000..3535e40f9
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/src/backend/reader.js
@@ -0,0 +1,67 @@
+const xlsx = require('xlsx');
+const stream = require('stream');
+const _ = require('lodash');
+
+const loadedWorkbooks = {};
+let dbgateApi;
+
+async function loadWorkbook(fileName) {
+ let workbook = loadedWorkbooks[fileName];
+ if (workbook) return workbook;
+ console.log(`Loading excel ${fileName}`);
+ const downloadedFile = await dbgateApi.download(fileName);
+ workbook = xlsx.readFile(downloadedFile);
+ loadedWorkbooks[fileName] = workbook;
+ return workbook;
+}
+
+async function waitForDrain(stream) {
+ return new Promise((resolve) => {
+ stream.once('drain', () => {
+ resolve();
+ });
+ });
+}
+
+async function reader({ fileName, sheetName, limitRows = undefined }) {
+ const pass = new stream.PassThrough({
+ objectMode: true,
+ highWaterMark: 100,
+ });
+
+ const workbook = await loadWorkbook(fileName);
+ const sheet = workbook.Sheets[sheetName];
+
+ const rows = xlsx.utils.sheet_to_json(sheet, {
+ header: 1,
+ blankrows: false,
+ });
+ const header = rows[0];
+ const structure = {
+ __isStreamHeader: true,
+ columns: _.range(header.length).map((index) => ({ columnName: header[index] })),
+ };
+ if (!pass.write(structure)) await waitForDrain(pass);
+
+ const sendAsync = async () => {
+ for (let rowIndex = 1; rowIndex < rows.length; rowIndex++) {
+ if (limitRows && rowIndex > limitRows) break;
+ const row = rows[rowIndex];
+ const rowData = _.fromPairs(structure.columns.map((col, index) => [col.columnName, row[index]]));
+ if (_.isEmpty(_.omitBy(rowData, (v) => v == null || v.toString().trim().length == 0))) continue;
+ if (!pass.write(rowData)) await waitForDrain(pass);
+ }
+ pass.end();
+ };
+
+ // don't wait for sending
+ sendAsync();
+
+ return pass;
+}
+
+reader.initialize = (dbgateEnv) => {
+ dbgateApi = dbgateEnv.dbgateApi;
+};
+
+module.exports = reader;
diff --git a/plugins/dbgate-plugin-excel/src/backend/writer.js b/plugins/dbgate-plugin-excel/src/backend/writer.js
new file mode 100644
index 000000000..d8f6a2096
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/src/backend/writer.js
@@ -0,0 +1,57 @@
+const xlsx = require('xlsx');
+const stream = require('stream');
+
+const writingWorkbooks = {};
+
+async function saveExcelFiles() {
+ for (const file in writingWorkbooks) {
+ xlsx.writeFile(writingWorkbooks[file], file);
+ }
+}
+
+function createWorkbook(fileName) {
+ let workbook = writingWorkbooks[fileName];
+ if (workbook) return workbook;
+ workbook = xlsx.utils.book_new();
+ writingWorkbooks[fileName] = workbook;
+ return workbook;
+}
+
+class ExcelSheetWriterStream extends stream.Writable {
+ constructor({ fileName, sheetName }) {
+ super({ objectMode: true });
+ this.rows = [];
+ this.structure = null;
+ this.fileName = fileName;
+ this.sheetName = sheetName;
+ }
+ _write(chunk, enc, next) {
+ if (this.structure) {
+ this.rows.push(this.structure.columns.map((col) => chunk[col.columnName]));
+ } else {
+ this.structure = chunk;
+ this.rows.push(chunk.columns.map((x) => x.columnName));
+ }
+
+ next();
+ }
+
+ _final(callback) {
+ const workbook = createWorkbook(this.fileName);
+ xlsx.utils.book_append_sheet(workbook, xlsx.utils.aoa_to_sheet(this.rows), this.sheetName || 'Sheet 1');
+ callback();
+ }
+}
+
+async function writer({ fileName, sheetName }) {
+ return new ExcelSheetWriterStream({
+ fileName,
+ sheetName,
+ });
+}
+
+writer.initialize = ({ dbgateApi }) => {
+ dbgateApi.finalizer.register(saveExcelFiles);
+};
+
+module.exports = writer;
diff --git a/plugins/dbgate-plugin-excel/src/frontend/index.js b/plugins/dbgate-plugin-excel/src/frontend/index.js
new file mode 100644
index 000000000..94d515376
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/src/frontend/index.js
@@ -0,0 +1,68 @@
+let axios;
+
+function initialize(dbgateEnv) {
+ axios = dbgateEnv.axios;
+}
+
+const fileFormat = {
+ packageName: 'dbgate-plugin-excel',
+ // file format identifier
+ storageType: 'excel',
+ // file extension without leading dot
+ extension: 'xlsx',
+ // human readable file format name
+ name: 'MS Excel',
+ // function name from backend, which contains reader factory, postfixed by package name
+ readerFunc: 'reader@dbgate-plugin-excel',
+ // function name from backend, which contains writer factory, postfixed by package name
+ writerFunc: 'writer@dbgate-plugin-excel',
+
+ addFileToSourceList: async ({ fileName }, newSources, newValues) => {
+ const resp = await axios.post('plugins/command', {
+ command: 'analyse',
+ packageName: 'dbgate-plugin-excel',
+ args: {
+ fileName,
+ },
+ });
+ const sheetNames = resp.data;
+ for (const sheetName of sheetNames) {
+ newSources.push(sheetName);
+ newValues[`sourceFile_${sheetName}`] = {
+ fileName,
+ sheetName,
+ };
+ }
+ },
+
+ args: [
+ {
+ type: 'checkbox',
+ name: 'singleFile',
+ label: 'Create single file',
+ direction: 'target',
+ },
+ ],
+
+ getDefaultOutputName: (sourceName, values) => {
+ if (values.target_excel_singleFile) {
+ return sourceName;
+ }
+ return null;
+ },
+
+ getOutputParams: (sourceName, values) => {
+ if (values.target_excel_singleFile) {
+ return {
+ sheetName: values[`targetName_${sourceName}`] || sourceName,
+ fileName: 'data.xlsx',
+ };
+ }
+ return null;
+ },
+};
+
+export default {
+ fileFormats: [fileFormat],
+ initialize,
+};
diff --git a/plugins/dbgate-plugin-excel/webpack-backend.config.js b/plugins/dbgate-plugin-excel/webpack-backend.config.js
new file mode 100644
index 000000000..e75357dff
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/webpack-backend.config.js
@@ -0,0 +1,23 @@
+var webpack = require('webpack');
+var path = require('path');
+
+var config = {
+ context: __dirname + '/src/backend',
+
+ entry: {
+ app: './index.js',
+ },
+ target: 'node',
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: 'backend.js',
+ libraryTarget: 'commonjs2',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-excel/webpack-frontend.config.js b/plugins/dbgate-plugin-excel/webpack-frontend.config.js
new file mode 100644
index 000000000..db07de291
--- /dev/null
+++ b/plugins/dbgate-plugin-excel/webpack-frontend.config.js
@@ -0,0 +1,24 @@
+var webpack = require("webpack");
+var path = require("path");
+
+var config = {
+ context: __dirname + "/src/frontend",
+
+ entry: {
+ app: "./index.js",
+ },
+ target: "web",
+ output: {
+ path: path.resolve(__dirname, "dist"),
+ filename: "frontend.js",
+ libraryTarget: "var",
+ library: 'plugin',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-mongo/LICENSE b/plugins/dbgate-plugin-mongo/LICENSE
new file mode 100644
index 000000000..bb0e9add4
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 DbGate
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/plugins/dbgate-plugin-mongo/README.md b/plugins/dbgate-plugin-mongo/README.md
new file mode 100644
index 000000000..133cbb7f2
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/README.md
@@ -0,0 +1,6 @@
+[](https://github.com/prettier/prettier)
+[](https://www.npmjs.com/package/dbgate-plugin-mongo)
+
+# dbgate-plugin-mongo
+
+Use DbGate for install of this plugin
diff --git a/plugins/dbgate-plugin-mongo/icon.svg b/plugins/dbgate-plugin-mongo/icon.svg
new file mode 100644
index 000000000..90fe17b70
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/icon.svg
@@ -0,0 +1,6 @@
+
diff --git a/plugins/dbgate-plugin-mongo/package.json b/plugins/dbgate-plugin-mongo/package.json
new file mode 100644
index 000000000..33cac471f
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "dbgate-plugin-mongo",
+ "main": "dist/backend.js",
+ "version": "1.0.1",
+ "license": "MIT",
+ "author": "Jan Prochazka",
+ "homepage": "https://github.com/dbgate/dbgate-plugin-mongo",
+ "description": "MongoDB connect plugin for DbGate",
+ "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur",
+ "keywords": [
+ "dbgate",
+ "dbgateplugin",
+ "mongo",
+ "mongodb"
+ ],
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build:frontend": "webpack --config webpack-frontend.config",
+ "build:backend": "webpack --config webpack-backend.config.js",
+ "build": "yarn build:frontend && yarn build:backend",
+ "plugin": "yarn build && yarn pack && dbgate-plugin dbgate-plugin-mongo",
+ "plugout": "dbgate-plugout dbgate-plugin-mongo",
+ "prepublishOnly": "yarn build"
+ },
+ "devDependencies": {
+ "byline": "^5.0.0",
+ "dbgate-plugin-tools": "^1.0.4",
+ "dbgate-tools": "^4.1.0-rc.1",
+ "is-promise": "^4.0.0",
+ "mongodb": "^3.6.5",
+ "webpack": "^4.42.0",
+ "webpack-cli": "^3.3.11"
+ }
+}
diff --git a/plugins/dbgate-plugin-mongo/prettier.config.js b/plugins/dbgate-plugin-mongo/prettier.config.js
new file mode 100644
index 000000000..406484074
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/prettier.config.js
@@ -0,0 +1,8 @@
+module.exports = {
+ trailingComma: 'es5',
+ tabWidth: 2,
+ semi: true,
+ singleQuote: true,
+ arrowParen: 'avoid',
+ printWidth: 120,
+};
diff --git a/plugins/dbgate-plugin-mongo/src/backend/Analyser.js b/plugins/dbgate-plugin-mongo/src/backend/Analyser.js
new file mode 100644
index 000000000..667a895df
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/src/backend/Analyser.js
@@ -0,0 +1,24 @@
+const { DatabaseAnalyser } = require('dbgate-tools');
+
+class Analyser extends DatabaseAnalyser {
+ constructor(pool, driver) {
+ super(pool, driver);
+ }
+
+ async _runAnalysis() {
+ const collections = await this.pool.__getDatabase().listCollections().toArray();
+
+ const res = this.mergeAnalyseResult(
+ {
+ collections: collections.map((x) => ({
+ pureName: x.name,
+ })),
+ },
+ (x) => x.pureName
+ );
+ // console.log('MERGED', res);
+ return res;
+ }
+}
+
+module.exports = Analyser;
diff --git a/plugins/dbgate-plugin-mongo/src/backend/createBulkInsertStream.js b/plugins/dbgate-plugin-mongo/src/backend/createBulkInsertStream.js
new file mode 100644
index 000000000..a5257a272
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/src/backend/createBulkInsertStream.js
@@ -0,0 +1,58 @@
+export function createBulkInsertStream(driver, stream, pool, name, options) {
+ const collectionName = name.pureName;
+ const db = pool.__getDatabase();
+
+ const writable = new stream.Writable({
+ objectMode: true,
+ });
+
+ writable.buffer = [];
+ writable.wasHeader = false;
+
+ writable.addRow = (row) => {
+ if (!writable.wasHeader) {
+ writable.wasHeader = true;
+ if (row.__isStreamHeader ||
+ // TODO remove isArray test
+ Array.isArray(row.columns)) return;
+ }
+ writable.buffer.push(row);
+ };
+
+ writable.checkStructure = async () => {
+ if (options.dropIfExists || options.truncate) {
+ console.log(`Dropping collection ${collectionName}`);
+ await db.collection(collectionName).drop();
+ }
+ if (options.truncate) {
+ console.log(`Truncating collection ${collectionName}`);
+ await db.collection(collectionName).deleteMany({});
+ }
+ };
+
+ writable.send = async () => {
+ const rows = writable.buffer;
+ writable.buffer = [];
+
+ await db.collection(collectionName).insertMany(rows);
+ };
+
+ writable.sendIfFull = async () => {
+ if (writable.buffer.length > 100) {
+ await writable.send();
+ }
+ };
+
+ writable._write = async (chunk, encoding, callback) => {
+ writable.addRow(chunk);
+ await writable.sendIfFull();
+ callback();
+ };
+
+ writable._final = async (callback) => {
+ await writable.send();
+ callback();
+ };
+
+ return writable;
+}
diff --git a/plugins/dbgate-plugin-mongo/src/backend/driver.js b/plugins/dbgate-plugin-mongo/src/backend/driver.js
new file mode 100644
index 000000000..9379c8892
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/src/backend/driver.js
@@ -0,0 +1,260 @@
+const _ = require('lodash');
+const stream = require('stream');
+const isPromise = require('is-promise');
+const driverBase = require('../frontend/driver');
+const Analyser = require('./Analyser');
+const MongoClient = require('mongodb').MongoClient;
+const ObjectId = require('mongodb').ObjectId;
+const Cursor = require('mongodb').Cursor;
+const { createBulkInsertStream } = require('./createBulkInsertStream');
+
+function readCursor(cursor, options) {
+ return new Promise((resolve) => {
+ options.recordset({ __isDynamicStructure: true });
+
+ cursor.on('data', (data) => options.row(data));
+ cursor.on('end', () => resolve());
+ });
+}
+
+const mongoIdRegex = /^[0-9a-f]{24}$/;
+function convertCondition(condition) {
+ if (condition && _.isString(condition._id) && condition._id.match(mongoIdRegex)) {
+ return {
+ _id: ObjectId(condition._id),
+ };
+ }
+ return condition;
+}
+
+function findArrayResult(resValue) {
+ if (!_.isPlainObject(resValue)) return null;
+ const arrays = _.values(resValue).filter((x) => _.isArray(x));
+ if (arrays.length == 1) return arrays[0];
+ return null;
+}
+
+async function getScriptableDb(pool) {
+ const db = pool.__getDatabase();
+ const collections = await db.listCollections().toArray();
+ for (const collection of collections) {
+ db[collection.name] = db.collection(collection.name);
+ }
+ return db;
+}
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ analyserClass: Analyser,
+ async connect({ server, port, user, password, database, useDatabaseUrl, databaseUrl, ssl }) {
+ // let mongoUrl = databaseUrl;
+ // if (!useDatabaseUrl) {
+ // mongoUrl = user ? `mongodb://${user}:${password}@${server}:${port}` : `mongodb://${server}:${port}`;
+ // if (database) mongoUrl += '/' + database;
+ // }
+ const mongoUrl = useDatabaseUrl
+ ? databaseUrl
+ : user
+ ? `mongodb://${user}:${password}@${server}:${port}`
+ : `mongodb://${server}:${port}`;
+
+ const options = {};
+ if (ssl) {
+ options.tls = true;
+ options.tlsCAFile = ssl.ca;
+ options.tlsCertificateKeyFile = ssl.cert || ssl.key;
+ options.tlsCertificateKeyFilePassword = ssl.password;
+ options.tlsAllowInvalidCertificates = !ssl.rejectUnauthorized;
+ }
+
+ const pool = new MongoClient(mongoUrl, options);
+ await pool.connect();
+ // const pool = await MongoClient.connect(mongoUrl);
+ pool.__getDatabase = database ? () => pool.db(database) : () => pool.db();
+ pool.__databaseName = database;
+ return pool;
+ },
+ // @ts-ignore
+ async query(pool, sql) {
+ return {
+ rows: [],
+ columns: [],
+ };
+ },
+ async stream(pool, sql, options) {
+ let func;
+ try {
+ func = eval(`(db,ObjectId) => ${sql}`);
+ } catch (err) {
+ options.info({
+ message: 'Error compiling expression: ' + err.message,
+ time: new Date(),
+ severity: 'error',
+ });
+ options.done();
+ return;
+ }
+ const db = await getScriptableDb(pool);
+
+ let exprValue;
+ try {
+ exprValue = func(db, ObjectId);
+ } catch (err) {
+ options.info({
+ message: 'Error evaluating expression: ' + err.message,
+ time: new Date(),
+ severity: 'error',
+ });
+ options.done();
+ return;
+ }
+
+ if (exprValue instanceof Cursor) {
+ await readCursor(exprValue, options);
+ } else if (isPromise(exprValue)) {
+ try {
+ const resValue = await exprValue;
+
+ options.info({
+ message: 'Command succesfully executed',
+ time: new Date(),
+ severity: 'info',
+ });
+ options.info({
+ message: JSON.stringify(resValue),
+ time: new Date(),
+ severity: 'info',
+ });
+
+ const arrayRes = findArrayResult(resValue);
+ if (arrayRes) {
+ options.recordset({ __isDynamicStructure: true });
+ for (const row of arrayRes) {
+ options.row(row);
+ }
+ }
+ } catch (err) {
+ options.info({
+ message: 'Error when running command: ' + err.message,
+ time: new Date(),
+ severity: 'error',
+ });
+ }
+ }
+
+ options.done();
+ },
+ async readQuery(pool, sql, structure) {
+ try {
+ const json = JSON.parse(sql);
+ if (json && json.pureName) {
+ sql = `db.${json.pureName}.find()`;
+ }
+ } catch (err) {
+ // query is not JSON serialized collection name
+ }
+
+ // const pass = new stream.PassThrough({
+ // objectMode: true,
+ // highWaterMark: 100,
+ // });
+
+ func = eval(`(db,ObjectId) => ${sql}`);
+ const db = await getScriptableDb(pool);
+ exprValue = func(db, ObjectId);
+
+ // return directly stream without header row
+ return exprValue;
+
+ // pass.write(structure || { __isDynamicStructure: true });
+ // exprValue.on('data', (row) => pass.write(row));
+ // exprValue.on('end', () => pass.end());
+
+ // return pass;
+ },
+ async writeTable(pool, name, options) {
+ return createBulkInsertStream(this, stream, pool, name, options);
+ },
+ async getVersion(pool) {
+ const status = await pool.__getDatabase().admin().serverInfo();
+ return status;
+ },
+ async listDatabases(pool) {
+ const res = await pool.__getDatabase().admin().listDatabases();
+ return res.databases;
+ },
+ async readCollection(pool, options) {
+ try {
+ const collection = pool.__getDatabase().collection(options.pureName);
+ if (options.countDocuments) {
+ const count = await collection.countDocuments(options.condition || {});
+ return { count };
+ } else {
+ let cursor = await collection.find(options.condition || {});
+ if (options.sort) cursor = cursor.sort(options.sort);
+ if (options.skip) cursor = cursor.skip(options.skip);
+ if (options.limit) cursor = cursor.limit(options.limit);
+ const rows = await cursor.toArray();
+ return { rows };
+ }
+ } catch (err) {
+ return { errorMessage: err.message };
+ }
+ },
+ async updateCollection(pool, changeSet) {
+ const res = {
+ inserted: [],
+ updated: [],
+ deleted: [],
+ replaced: [],
+ };
+ try {
+ const db = pool.__getDatabase();
+ for (const insert of changeSet.inserts) {
+ const collection = db.collection(insert.pureName);
+ const document = {
+ ...insert.document,
+ ...insert.fields,
+ };
+ const resdoc = await collection.insert(document);
+ res.inserted.push(resdoc._id);
+ }
+ for (const update of changeSet.updates) {
+ const collection = db.collection(update.pureName);
+ if (update.document) {
+ const document = {
+ ...update.document,
+ ...update.fields,
+ };
+ const doc = await collection.findOne(convertCondition(update.condition));
+ if (doc) {
+ const resdoc = await collection.replaceOne(convertCondition(update.condition), {
+ ...document,
+ _id: doc._id,
+ });
+ res.replaced.push(resdoc._id);
+ }
+ } else {
+ const resdoc = await collection.updateOne(convertCondition(update.condition), { $set: update.fields });
+ res.updated.push(resdoc._id);
+ }
+ }
+ for (const del of changeSet.deletes) {
+ const collection = db.collection(del.pureName);
+ const resdoc = await collection.deleteOne(convertCondition(del.condition));
+ res.deleted.push(resdoc._id);
+ }
+ return res;
+ } catch (err) {
+ return { errorMessage: err.message };
+ }
+ },
+
+ async createDatabase(pool, name) {
+ const db = pool.db(name);
+ await db.createCollection('collection1');
+ },
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-mongo/src/backend/index.js b/plugins/dbgate-plugin-mongo/src/backend/index.js
new file mode 100644
index 000000000..34eb83d74
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/src/backend/index.js
@@ -0,0 +1,6 @@
+const driver = require('./driver');
+
+module.exports = {
+ packageName: 'dbgate-plugin-mongo',
+ driver,
+};
diff --git a/plugins/dbgate-plugin-mongo/src/frontend/Dumper.js b/plugins/dbgate-plugin-mongo/src/frontend/Dumper.js
new file mode 100644
index 000000000..afcc64731
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/src/frontend/Dumper.js
@@ -0,0 +1,6 @@
+const { SqlDumper } = require('dbgate-tools');
+
+class Dumper extends SqlDumper {
+}
+
+module.exports = Dumper;
diff --git a/plugins/dbgate-plugin-mongo/src/frontend/driver.js b/plugins/dbgate-plugin-mongo/src/frontend/driver.js
new file mode 100644
index 000000000..9dfd38cd4
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/src/frontend/driver.js
@@ -0,0 +1,76 @@
+const { driverBase } = require('dbgate-tools');
+const Dumper = require('./Dumper');
+
+const mongoIdRegex = /^[0-9a-f]{24}$/;
+
+function getConditionPreview(condition) {
+ if (condition && _.isString(condition._id) && condition._id.match(mongoIdRegex)) {
+ return `{ _id: ObjectId('${condition._id}') }`;
+ }
+ return JSON.stringify(condition);
+}
+
+/** @type {import('dbgate-types').SqlDialect} */
+const dialect = {
+ limitSelect: true,
+ rangeSelect: true,
+ offsetFetchRangeSyntax: true,
+ stringEscapeChar: "'",
+ fallbackDataType: 'nvarchar(max)',
+ nosql: true,
+ quoteIdentifier(s) {
+ return `[${s}]`;
+ },
+};
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ dumperClass: Dumper,
+ dialect,
+ engine: 'mongo@dbgate-plugin-mongo',
+ title: 'MongoDB',
+ defaultPort: 27017,
+ supportsDatabaseUrl: true,
+ databaseUrlPlaceholder: 'e.g. mongodb://username:password@mongodb.mydomain.net/dbname',
+
+ getCollectionUpdateScript(changeSet) {
+ let res = '';
+ for (const insert of changeSet.inserts) {
+ res += `db.${insert.pureName}.insert(${JSON.stringify(
+ {
+ ...insert.document,
+ ...insert.fields,
+ },
+ undefined,
+ 2
+ )});\n`;
+ }
+ for (const update of changeSet.updates) {
+ if (update.document) {
+ res += `db.${update.pureName}.replaceOne(${getConditionPreview(update.condition)}, ${JSON.stringify(
+ {
+ ...update.document,
+ ...update.fields,
+ },
+ undefined,
+ 2
+ )});\n`;
+ } else {
+ res += `db.${update.pureName}.updateOne(${getConditionPreview(update.condition)}, ${JSON.stringify(
+ {
+ $set: update.fields,
+ },
+ undefined,
+ 2
+ )});\n`;
+ }
+ }
+ for (const del of changeSet.deletes) {
+ res += `db.${del.pureName}.deleteOne(${getConditionPreview(del.condition)});\n`;
+ }
+ return res;
+ },
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-mongo/src/frontend/index.js b/plugins/dbgate-plugin-mongo/src/frontend/index.js
new file mode 100644
index 000000000..b8b61e8d6
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/src/frontend/index.js
@@ -0,0 +1,6 @@
+import driver from './driver';
+
+export default {
+ packageName: 'dbgate-plugin-mongo',
+ driver,
+};
diff --git a/plugins/dbgate-plugin-mongo/webpack-backend.config.js b/plugins/dbgate-plugin-mongo/webpack-backend.config.js
new file mode 100644
index 000000000..e75357dff
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/webpack-backend.config.js
@@ -0,0 +1,23 @@
+var webpack = require('webpack');
+var path = require('path');
+
+var config = {
+ context: __dirname + '/src/backend',
+
+ entry: {
+ app: './index.js',
+ },
+ target: 'node',
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: 'backend.js',
+ libraryTarget: 'commonjs2',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-mongo/webpack-frontend.config.js b/plugins/dbgate-plugin-mongo/webpack-frontend.config.js
new file mode 100644
index 000000000..db07de291
--- /dev/null
+++ b/plugins/dbgate-plugin-mongo/webpack-frontend.config.js
@@ -0,0 +1,24 @@
+var webpack = require("webpack");
+var path = require("path");
+
+var config = {
+ context: __dirname + "/src/frontend",
+
+ entry: {
+ app: "./index.js",
+ },
+ target: "web",
+ output: {
+ path: path.resolve(__dirname, "dist"),
+ filename: "frontend.js",
+ libraryTarget: "var",
+ library: 'plugin',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-mssql/LICENSE b/plugins/dbgate-plugin-mssql/LICENSE
new file mode 100644
index 000000000..c15ede038
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Jan Prochazka
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-mssql/README.md b/plugins/dbgate-plugin-mssql/README.md
new file mode 100644
index 000000000..bac440d28
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/README.md
@@ -0,0 +1,7 @@
+[](https://github.com/prettier/prettier)
+[](https://paypal.me/JanProchazkaCz/30eur)
+[](https://www.npmjs.com/package/dbgate-plugin-mssql)
+
+# dbgate-plugin-mssql
+
+MS SQL connector plugin for DbGate
diff --git a/plugins/dbgate-plugin-mssql/icon.svg b/plugins/dbgate-plugin-mssql/icon.svg
new file mode 100644
index 000000000..50644e26c
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/icon.svg
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-mssql/package.json b/plugins/dbgate-plugin-mssql/package.json
new file mode 100644
index 000000000..a0e2db43e
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "dbgate-plugin-mssql",
+ "main": "dist/backend.js",
+ "version": "1.2.2",
+ "homepage": "https://github.com/dbgate/dbgate-plugin-mssql",
+ "description": "MS SQL connect plugin for DbGate",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/dbgate/dbgate-plugin-mssql.git"
+ },
+ "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur",
+ "author": "Jan Prochazka",
+ "license": "GPL",
+ "keywords": [
+ "sql",
+ "mssql",
+ "dbgate",
+ "dbgateplugin"
+ ],
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build:frontend": "webpack --config webpack-frontend.config",
+ "build:backend": "webpack --config webpack-backend.config.js",
+ "build": "yarn build:frontend && yarn build:backend",
+ "prepublishOnly": "yarn build",
+ "plugin": "yarn build && yarn pack && dbgate-plugin dbgate-plugin-mssql",
+ "plugout": "dbgate-plugout dbgate-plugin-mssql"
+ },
+ "devDependencies": {
+ "async-lock": "^1.2.6",
+ "dbgate-plugin-tools": "^1.0.4",
+ "dbgate-tools": "^4.0.3-rc.1",
+ "tedious": "^9.2.3",
+ "webpack": "^4.42.0",
+ "webpack-cli": "^3.3.11"
+ }
+}
diff --git a/plugins/dbgate-plugin-mssql/prettier.config.js b/plugins/dbgate-plugin-mssql/prettier.config.js
new file mode 100644
index 000000000..c05d71875
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/prettier.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ trailingComma: 'es5',
+ tabWidth: 2,
+ semi: true,
+ singleQuote: true,
+ arrowParen: 'avoid',
+ arrowParens: 'avoid',
+ printWidth: 120,
+};
diff --git a/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js b/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js
new file mode 100644
index 000000000..e7f700423
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js
@@ -0,0 +1,208 @@
+const fp = require('lodash/fp');
+const _ = require('lodash');
+const sql = require('./sql');
+
+const { DatabaseAnalyser } = require('dbgate-tools');
+const { isTypeString, isTypeNumeric } = require('dbgate-tools');
+
+function objectTypeToField(type) {
+ switch (type.trim()) {
+ case 'U':
+ return 'tables';
+ case 'V':
+ return 'views';
+ case 'P':
+ return 'procedures';
+ case 'IF':
+ case 'FN':
+ case 'TF':
+ return 'functions';
+ case 'TR':
+ return 'triggers';
+ default:
+ return null;
+ }
+}
+
+function getColumnInfo({
+ isNullable,
+ isIdentity,
+ columnName,
+ dataType,
+ charMaxLength,
+ numericPrecision,
+ numericScale,
+}) {
+ let fullDataType = dataType;
+ if (charMaxLength && isTypeString(dataType)) fullDataType = `${dataType}(${charMaxLength})`;
+ if (numericPrecision && numericScale && isTypeNumeric(dataType))
+ fullDataType = `${dataType}(${numericPrecision},${numericScale})`;
+ return {
+ columnName,
+ dataType: fullDataType,
+ notNull: !isNullable,
+ autoIncrement: !!isIdentity,
+ };
+}
+
+class MsSqlAnalyser extends DatabaseAnalyser {
+ constructor(pool, driver) {
+ super(pool, driver);
+ this.singleObjectId = null;
+ }
+
+ createQuery(resFileName, typeFields) {
+ let res = sql[resFileName];
+ if (this.singleObjectFilter) {
+ const { typeField } = this.singleObjectFilter;
+ if (!this.singleObjectId) return null;
+ if (!typeFields || !typeFields.includes(typeField)) return null;
+ return res.replace('=[OBJECT_ID_CONDITION]', ` = ${this.singleObjectId}`);
+ }
+ if (!this.modifications || !typeFields || this.modifications.length == 0) {
+ res = res.replace('=[OBJECT_ID_CONDITION]', ' is not null');
+ } else {
+ const filterIds = this.modifications
+ .filter((x) => typeFields.includes(x.objectTypeField) && (x.action == 'add' || x.action == 'change'))
+ .map((x) => x.objectId);
+ if (filterIds.length == 0) {
+ res = res.replace('=[OBJECT_ID_CONDITION]', ' = 0');
+ } else {
+ res = res.replace('=[OBJECT_ID_CONDITION]', ` in (${filterIds.join(',')})`);
+ }
+ }
+ return res;
+ }
+
+ async getSingleObjectId() {
+ if (this.singleObjectFilter) {
+ const { schemaName, pureName, typeField } = this.singleObjectFilter;
+ const fullName = schemaName ? `[${schemaName}].[${pureName}]` : pureName;
+ const resId = await this.driver.query(this.pool, `SELECT OBJECT_ID('${fullName}') AS id`);
+ this.singleObjectId = resId.rows[0].id;
+ }
+ }
+
+ async _runAnalysis() {
+ await this.getSingleObjectId();
+ const tablesRows = await this.driver.query(this.pool, this.createQuery('tables', ['tables']));
+ const columnsRows = await this.driver.query(this.pool, this.createQuery('columns', ['tables']));
+ const pkColumnsRows = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables']));
+ const fkColumnsRows = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables']));
+ const schemaRows = await this.driver.query(this.pool, this.createQuery('getSchemas'));
+
+ const schemas = schemaRows.rows;
+
+ const sqlCodeRows = await this.driver.query(
+ this.pool,
+ this.createQuery('loadSqlCode', ['views', 'procedures', 'functions', 'triggers'])
+ );
+ const getCreateSql = (row) =>
+ sqlCodeRows.rows
+ .filter((x) => x.pureName == row.pureName && x.schemaName == row.schemaName)
+ .map((x) => x.codeText)
+ .join('');
+ const viewsRows = await this.driver.query(this.pool, this.createQuery('views', ['views']));
+ const programmableRows = await this.driver.query(
+ this.pool,
+ this.createQuery('programmables', ['procedures', 'functions'])
+ );
+ const viewColumnRows = await this.driver.query(this.pool, this.createQuery('viewColumns', ['views']));
+
+ const tables = tablesRows.rows.map((row) => ({
+ ...row,
+ columns: columnsRows.rows.filter((col) => col.objectId == row.objectId).map(getColumnInfo),
+ primaryKey: DatabaseAnalyser.extractPrimaryKeys(row, pkColumnsRows.rows),
+ foreignKeys: DatabaseAnalyser.extractForeignKeys(row, fkColumnsRows.rows),
+ }));
+
+ const views = viewsRows.rows.map((row) => ({
+ ...row,
+ createSql: getCreateSql(row),
+ columns: viewColumnRows.rows.filter((col) => col.objectId == row.objectId).map(getColumnInfo),
+ }));
+
+ const procedures = programmableRows.rows
+ .filter((x) => x.sqlObjectType.trim() == 'P')
+ .map((row) => ({
+ ...row,
+ createSql: getCreateSql(row),
+ }));
+
+ const functions = programmableRows.rows
+ .filter((x) => ['FN', 'IF', 'TF'].includes(x.sqlObjectType.trim()))
+ .map((row) => ({
+ ...row,
+ createSql: getCreateSql(row),
+ }));
+
+ return this.mergeAnalyseResult({
+ tables,
+ views,
+ procedures,
+ functions,
+ schemas,
+ });
+ }
+
+ getDeletedObjectsForField(idArray, objectTypeField) {
+ return this.structure[objectTypeField]
+ .filter((x) => !idArray.includes(x.objectId))
+ .map((x) => ({
+ oldName: _.pick(x, ['schemaName', 'pureName']),
+ objectId: x.objectId,
+ action: 'remove',
+ objectTypeField,
+ }));
+ }
+
+ getDeletedObjects(idArray) {
+ return [
+ ...this.getDeletedObjectsForField(idArray, 'tables'),
+ ...this.getDeletedObjectsForField(idArray, 'views'),
+ ...this.getDeletedObjectsForField(idArray, 'procedures'),
+ ...this.getDeletedObjectsForField(idArray, 'functions'),
+ ...this.getDeletedObjectsForField(idArray, 'triggers'),
+ ];
+ }
+
+ async getModifications() {
+ const modificationsQueryData = await this.driver.query(this.pool, this.createQuery('modifications'));
+ // console.log('MOD - SRC', modifications);
+ // console.log(
+ // 'MODs',
+ // this.structure.tables.map((x) => x.modifyDate)
+ // );
+ const modifications = modificationsQueryData.rows.map((x) => {
+ const { type, objectId, modifyDate, schemaName, pureName } = x;
+ const field = objectTypeToField(type);
+ if (!this.structure[field]) return null;
+ // @ts-ignore
+ const obj = this.structure[field].find((x) => x.objectId == objectId);
+
+ // object not modified
+ if (obj && Math.abs(new Date(modifyDate).getTime() - new Date(obj.modifyDate).getTime()) < 1000) return null;
+
+ /** @type {import('dbgate-types').DatabaseModification} */
+ const action = obj
+ ? {
+ newName: { schemaName, pureName },
+ oldName: _.pick(obj, ['schemaName', 'pureName']),
+ action: 'change',
+ objectTypeField: field,
+ objectId,
+ }
+ : {
+ newName: { schemaName, pureName },
+ action: 'add',
+ objectTypeField: field,
+ objectId,
+ };
+ return action;
+ });
+
+ return [..._.compact(modifications), ...this.getDeletedObjects(modificationsQueryData.rows.map((x) => x.objectId))];
+ }
+}
+
+module.exports = MsSqlAnalyser;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/createNativeBulkInsertStream.js b/plugins/dbgate-plugin-mssql/src/backend/createNativeBulkInsertStream.js
new file mode 100644
index 000000000..03930bf0f
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/createNativeBulkInsertStream.js
@@ -0,0 +1,34 @@
+const { createBulkInsertStreamBase } = require('dbgate-tools');
+
+function runBulkInsertBatch(pool, tableName, writable, rows) {
+ return new Promise((resolve, reject) => {
+ const tableMgr = pool.tableMgr();
+ tableMgr.bind(tableName, bulkMgr => {
+ bulkMgr.insertRows(rows, err => {
+ if (err) reject(err);
+ resolve();
+ });
+ });
+ });
+}
+
+/**
+ *
+ * @param {import('dbgate-types').EngineDriver} driver
+ */
+function createNativeBulkInsertStream(driver, stream, pool, name, options) {
+ const writable = createBulkInsertStreamBase(driver, stream, pool, name, options);
+
+ const fullName = name.schemaName ? `[${name.schemaName}].[${name.pureName}]` : name.pureName;
+
+ writable.send = async () => {
+ const rows = writable.buffer;
+ writable.buffer = [];
+
+ await runBulkInsertBatch(pool, fullName, writable, rows);
+ };
+
+ return writable;
+}
+
+module.exports = createNativeBulkInsertStream;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/createTediousBulkInsertStream.js b/plugins/dbgate-plugin-mssql/src/backend/createTediousBulkInsertStream.js
new file mode 100644
index 000000000..9dfbd00d5
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/createTediousBulkInsertStream.js
@@ -0,0 +1,70 @@
+const { createBulkInsertStreamBase } = require('dbgate-tools');
+const tedious = require('tedious');
+const getConcreteType = require('./getConcreteType');
+
+function runBulkInsertBatch(pool, tableName, writable, rows) {
+ return new Promise((resolve, reject) => {
+ var options = { keepNulls: true };
+
+ // instantiate - provide the table where you'll be inserting to, options and a callback
+ var bulkLoad = pool.newBulkLoad(tableName, options, (error, rowCount) => {
+ if (error) reject(error);
+ else resolve();
+ });
+
+ for (const column of writable.columnNames) {
+ const tcol = writable.templateColumns.find((x) => x.columnName == column);
+
+ bulkLoad.addColumn(
+ column,
+ tcol
+ ? getConcreteType(tcol.driverNativeColumn.type, tcol.driverNativeColumn.dataLength)
+ : tedious.TYPES.NVarChar,
+ {
+ nullable: tcol ? !tcol.notNull : true,
+ length: tcol ? tcol.driverNativeColumn.dataLength : undefined,
+ precision: tcol ? tcol.driverNativeColumn.precision : undefined,
+ scale: tcol ? tcol.driverNativeColumn.scale : undefined,
+ }
+ );
+ }
+
+ for (const row of rows) {
+ bulkLoad.addRow(row);
+ }
+
+ pool.execBulkLoad(bulkLoad);
+ });
+}
+
+/**
+ *
+ * @param {import('dbgate-types').EngineDriver} driver
+ */
+function createTediousBulkInsertStream(driver, stream, pool, name, options) {
+ const writable = createBulkInsertStreamBase(driver, stream, pool, name, options);
+
+ const fullName = name.schemaName ? `[${name.schemaName}].[${name.pureName}]` : name.pureName;
+
+ writable.send = async () => {
+ if (!writable.templateColumns) {
+ const fullNameQuoted = name.schemaName
+ ? `${driver.dialect.quoteIdentifier(name.schemaName)}.${driver.dialect.quoteIdentifier(name.pureName)}`
+ : driver.dialect.quoteIdentifier(name.pureName);
+
+ const respTemplate = await driver.query(pool, `SELECT * FROM ${fullNameQuoted} WHERE 1=0`, {
+ addDriverNativeColumn: true,
+ });
+ writable.templateColumns = respTemplate.columns;
+ }
+
+ const rows = writable.buffer;
+ writable.buffer = [];
+
+ await runBulkInsertBatch(pool, fullName, writable, rows);
+ };
+
+ return writable;
+}
+
+module.exports = createTediousBulkInsertStream;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/driver.js b/plugins/dbgate-plugin-mssql/src/backend/driver.js
new file mode 100644
index 000000000..8be12fe70
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/driver.js
@@ -0,0 +1,98 @@
+const _ = require('lodash');
+const stream = require('stream');
+const driverBase = require('../frontend/driver');
+const MsSqlAnalyser = require('./MsSqlAnalyser');
+const createTediousBulkInsertStream = require('./createTediousBulkInsertStream');
+const createNativeBulkInsertStream = require('./createNativeBulkInsertStream');
+const AsyncLock = require('async-lock');
+const nativeDriver = require('./nativeDriver');
+const lock = new AsyncLock();
+const { tediousConnect, tediousQueryCore, tediousReadQuery, tediousStream } = require('./tediousDriver');
+const { nativeConnect, nativeQueryCore, nativeReadQuery, nativeStream } = nativeDriver;
+let msnodesqlv8;
+
+const windowsAuthTypes = [
+ {
+ title: 'Windows',
+ name: 'sspi',
+ disabledFields: ['password', 'port', 'user'],
+ },
+ {
+ title: 'SQL Server',
+ name: 'sql',
+ disabledFields: ['port'],
+ },
+ {
+ title: 'Tedious driver',
+ name: 'tedious',
+ },
+];
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ analyserClass: MsSqlAnalyser,
+
+ getAuthTypes() {
+ return msnodesqlv8 ? windowsAuthTypes : null;
+ },
+
+ async connect(conn) {
+ const { authType } = conn;
+ if (msnodesqlv8 && (authType == 'sspi' || authType == 'sql')) {
+ return nativeConnect(conn);
+ }
+
+ return tediousConnect(conn);
+ },
+ async queryCore(pool, sql, options) {
+ if (pool._connectionType == 'msnodesqlv8') {
+ return nativeQueryCore(pool, sql, options);
+ } else {
+ return tediousQueryCore(pool, sql, options);
+ }
+ },
+ async query(pool, sql, options) {
+ return lock.acquire('connection', async () => {
+ return this.queryCore(pool, sql, options);
+ });
+ },
+ async stream(pool, sql, options) {
+ if (pool._connectionType == 'msnodesqlv8') {
+ return nativeStream(pool, sql, options);
+ } else {
+ return tediousStream(pool, sql, options);
+ }
+ },
+ async readQuery(pool, sql, structure) {
+ if (pool._connectionType == 'msnodesqlv8') {
+ return nativeReadQuery(pool, sql, structure);
+ } else {
+ return tediousReadQuery(pool, sql, structure);
+ }
+ },
+ async writeTable(pool, name, options) {
+ if (pool._connectionType == 'msnodesqlv8') {
+ return createNativeBulkInsertStream(this, stream, pool, name, options);
+ } else {
+ return createTediousBulkInsertStream(this, stream, pool, name, options);
+ }
+ },
+ async getVersion(pool) {
+ const { version } = (await this.query(pool, 'SELECT @@VERSION AS version')).rows[0];
+ return { version };
+ },
+ async listDatabases(pool) {
+ const { rows } = await this.query(pool, 'SELECT name FROM sys.databases order by name');
+ return rows;
+ },
+};
+
+driver.initialize = dbgateEnv => {
+ if (dbgateEnv.nativeModules && dbgateEnv.nativeModules.msnodesqlv8) {
+ msnodesqlv8 = dbgateEnv.nativeModules.msnodesqlv8();
+ }
+ nativeDriver.initialize(dbgateEnv);
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/getConcreteType.js b/plugins/dbgate-plugin-mssql/src/backend/getConcreteType.js
new file mode 100644
index 000000000..c82f3bfba
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/getConcreteType.js
@@ -0,0 +1,41 @@
+const tedious = require('tedious');
+
+const { TYPES } = tedious;
+
+const N_TYPES = {
+ BitN: 0x68,
+ DateTimeN: 0x6f,
+ DecimalN: 0x6a,
+ FloatN: 0x6d,
+ IntN: 0x26,
+ MoneyN: 0x6e,
+ NumericN: 0x6c,
+};
+
+function getConcreteType(type, length) {
+ switch (type.id) {
+ case N_TYPES.BitN:
+ return TYPES.Bit;
+ case N_TYPES.NumericN:
+ return TYPES.Numeric;
+ case N_TYPES.DecimalN:
+ return TYPES.Decimal;
+ case N_TYPES.IntN:
+ if (length === 8) return TYPES.BigInt;
+ if (length === 4) return TYPES.Int;
+ if (length === 2) return TYPES.SmallInt;
+ return TYPES.TinyInt;
+ case N_TYPES.FloatN:
+ if (length === 8) return TYPES.Float;
+ return TYPES.Real;
+ case N_TYPES.MoneyN:
+ if (length === 8) return TYPES.Money;
+ return TYPES.SmallMoney;
+ case N_TYPES.DateTimeN:
+ if (length === 8) return TYPES.DateTime;
+ return TYPES.SmallDateTime;
+ }
+ return type;
+}
+
+module.exports = getConcreteType;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/index.js b/plugins/dbgate-plugin-mssql/src/backend/index.js
new file mode 100644
index 000000000..4277c5283
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/index.js
@@ -0,0 +1,9 @@
+const driver = require('./driver');
+
+module.exports = {
+ packageName: 'dbgate-plugin-mssql',
+ driver,
+ initialize(dbgateEnv) {
+ driver.initialize(dbgateEnv);
+ },
+};
diff --git a/plugins/dbgate-plugin-mssql/src/backend/makeUniqueColumnNames.js b/plugins/dbgate-plugin-mssql/src/backend/makeUniqueColumnNames.js
new file mode 100644
index 000000000..19587dc3d
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/makeUniqueColumnNames.js
@@ -0,0 +1,13 @@
+function makeUniqueColumnNames(res) {
+ const usedNames = new Set();
+ for (let i = 0; i < res.length; i++) {
+ if (usedNames.has(res[i].columnName)) {
+ let suffix = 2;
+ while (usedNames.has(`${res[i].columnName}${suffix}`)) suffix++;
+ res[i].columnName = `${res[i].columnName}${suffix}`;
+ }
+ usedNames.add(res[i].columnName);
+ }
+}
+
+module.exports = makeUniqueColumnNames;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/nativeDriver.js b/plugins/dbgate-plugin-mssql/src/backend/nativeDriver.js
new file mode 100644
index 000000000..914c0ccb4
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/nativeDriver.js
@@ -0,0 +1,211 @@
+const _ = require('lodash');
+const stream = require('stream');
+const makeUniqueColumnNames = require('./makeUniqueColumnNames');
+let msnodesqlv8;
+
+// async function nativeQueryCore(pool, sql, options) {
+// if (sql == null) {
+// return Promise.resolve({
+// rows: [],
+// columns: [],
+// });
+// }
+// return new Promise((resolve, reject) => {
+// pool.query(sql, (err, rows) => {
+// if (err) reject(err);
+// resolve({
+// rows,
+// });
+// });
+// });
+// }
+
+function extractNativeColumns(meta) {
+ const res = meta.map(col => {
+ const resCol = {
+ columnName: col.name,
+ dataType: col.sqlType.toLowerCase(),
+ notNull: !col.nullable,
+ };
+
+ if (resCol.dataType.endsWith(' identity')) {
+ resCol.dataType = resCol.dataType.replace(' identity', '');
+ resCol.autoIncrement = true;
+ }
+ if (col.size && resCol.dataType.includes('char')) {
+ resCol.dataType += `(${col.size})`;
+ }
+ return resCol;
+ });
+
+ makeUniqueColumnNames(res);
+
+ return res;
+}
+
+async function nativeConnect({ server, port, user, password, database, authType }) {
+ let connectionString = `server=${server}`;
+ if (port && !server.includes('\\')) connectionString += `,${port}`;
+ connectionString += ';Driver={SQL Server Native Client 11.0}';
+ if (authType == 'sspi') connectionString += ';Trusted_Connection=Yes';
+ else connectionString += `;UID=${user};PWD=${password}`;
+ if (database) connectionString += `;Database=${database}`;
+ return new Promise((resolve, reject) => {
+ msnodesqlv8.open(connectionString, (err, conn) => {
+ if (err) reject(err);
+ conn._connectionType = 'msnodesqlv8';
+ resolve(conn);
+ });
+ });
+}
+
+async function nativeQueryCore(pool, sql, options) {
+ if (sql == null) {
+ return Promise.resolve({
+ rows: [],
+ columns: [],
+ });
+ }
+ return new Promise((resolve, reject) => {
+ let columns = null;
+ let currentRow = null;
+ const q = pool.query(sql);
+ const rows = [];
+
+ q.on('meta', meta => {
+ columns = extractNativeColumns(meta);
+ });
+
+ q.on('column', (index, data) => {
+ currentRow[columns[index].columnName] = data;
+ });
+
+ q.on('row', index => {
+ if (currentRow) rows.push(currentRow);
+ currentRow = {};
+ });
+
+ q.on('error', err => {
+ reject(err);
+ });
+
+ q.on('done', () => {
+ if (currentRow) rows.push(currentRow);
+ resolve({
+ columns,
+ rows,
+ });
+ });
+ });
+}
+
+async function nativeReadQuery(pool, sql, structure) {
+ const pass = new stream.PassThrough({
+ objectMode: true,
+ highWaterMark: 100,
+ });
+
+ let columns = null;
+ let currentRow = null;
+ const q = pool.query(sql);
+
+ q.on('meta', meta => {
+ columns = extractNativeColumns(meta);
+ pass.write({
+ __isStreamHeader: true,
+ ...(structure || { columns }),
+ });
+ });
+
+ q.on('column', (index, data) => {
+ currentRow[columns[index].columnName] = data;
+ });
+
+ q.on('row', index => {
+ if (currentRow) pass.write(currentRow);
+ currentRow = {};
+ });
+
+ q.on('error', err => {
+ console.error(err);
+ pass.end();
+ });
+
+ q.on('done', () => {
+ if (currentRow) pass.write(currentRow);
+ pass.end();
+ });
+
+ return pass;
+}
+
+async function nativeStream(pool, sql, options) {
+ const handleInfo = info => {
+ const { message, lineNumber, procName } = info;
+ options.info({
+ message,
+ line: lineNumber,
+ procedure: procName,
+ time: new Date(),
+ severity: 'info',
+ });
+ };
+ const handleError = error => {
+ const { message, lineNumber, procName } = error;
+ options.info({
+ message,
+ line: lineNumber,
+ procedure: procName,
+ time: new Date(),
+ severity: 'error',
+ });
+ };
+
+ let columns = null;
+ let currentRow = null;
+ const q = pool.query(sql);
+
+ q.on('meta', meta => {
+ if (currentRow) options.row(currentRow);
+ currentRow = null;
+ columns = extractNativeColumns(meta);
+ options.recordset(columns);
+ });
+
+ q.on('column', (index, data) => {
+ currentRow[columns[index].columnName] = data;
+ });
+
+ q.on('row', index => {
+ if (currentRow) options.row(currentRow);
+ currentRow = {};
+ });
+
+ q.on('error', err => {
+ handleError(err);
+ options.done();
+ });
+
+ q.on('info', info => {
+ handleInfo(info);
+ });
+
+ q.on('done', () => {
+ if (currentRow) options.row(currentRow);
+ options.done();
+ });
+}
+
+const initialize = dbgateEnv => {
+ if (dbgateEnv.nativeModules && dbgateEnv.nativeModules.msnodesqlv8) {
+ msnodesqlv8 = dbgateEnv.nativeModules.msnodesqlv8();
+ }
+};
+
+module.exports = {
+ nativeConnect,
+ nativeQueryCore,
+ nativeReadQuery,
+ nativeStream,
+ initialize,
+};
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/columns.js b/plugins/dbgate-plugin-mssql/src/backend/sql/columns.js
new file mode 100644
index 000000000..3de7ceffa
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/columns.js
@@ -0,0 +1,20 @@
+module.exports = `
+select c.name as columnName, t.name as dataType, c.object_id as objectId, c.is_identity as isIdentity,
+ c.max_length as maxLength, c.precision, c.scale, c.is_nullable as isNullable,
+ col.CHARACTER_MAXIMUM_LENGTH as charMaxLength,
+ d.definition as defaultValue, d.name as defaultConstraint,
+ m.definition as computedExpression, m.is_persisted as isPersisted, c.column_id as columnId,
+ col.NUMERIC_PRECISION as numericPrecision,
+ col.NUMERIC_SCALE as numericScale,
+ -- TODO only if version >= 2008
+ c.is_sparse as isSparse
+from sys.columns c
+inner join sys.types t on c.system_type_id = t.system_type_id and c.user_type_id = t.user_type_id
+inner join sys.objects o on c.object_id = o.object_id
+INNER JOIN sys.schemas u ON u.schema_id=o.schema_id
+INNER JOIN INFORMATION_SCHEMA.COLUMNS col ON col.TABLE_NAME = o.name AND col.TABLE_SCHEMA = u.name and col.COLUMN_NAME = c.name
+left join sys.default_constraints d on c.default_object_id = d.object_id
+left join sys.computed_columns m on m.object_id = c.object_id and m.column_id = c.column_id
+where o.type = 'U' and o.object_id =[OBJECT_ID_CONDITION]
+order by c.column_id
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/foreignKeys.js b/plugins/dbgate-plugin-mssql/src/backend/sql/foreignKeys.js
new file mode 100644
index 000000000..568117b77
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/foreignKeys.js
@@ -0,0 +1,40 @@
+module.exports = `
+SELECT
+ schemaName = FK.TABLE_SCHEMA,
+ pureName = FK.TABLE_NAME,
+ columnName = CU.COLUMN_NAME,
+
+ refSchemaName = ISNULL(IXS.name, PK.TABLE_SCHEMA),
+ refTableName = ISNULL(IXT.name, PK.TABLE_NAME),
+ refColumnName = IXCC.name,
+
+ constraintName = C.CONSTRAINT_NAME,
+ updateAction = rc.UPDATE_RULE,
+ deleteAction = rc.DELETE_RULE,
+
+ objectId = o.object_id
+
+FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
+INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
+
+LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
+LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
+--LEFT JOIN (
+--SELECT i1.TABLE_NAME, i2.COLUMN_NAME
+--FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
+--INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
+--WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
+--) PT ON PT.TABLE_NAME = PK.TABLE_NAME
+INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc ON FK.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
+
+LEFT JOIN sys.indexes IX ON IX.name = C.UNIQUE_CONSTRAINT_NAME
+LEFT JOIN sys.objects IXT ON IXT.object_id = IX.object_id
+LEFT JOIN sys.index_columns IXC ON IX.index_id = IXC.index_id and IX.object_id = IXC.object_id
+LEFT JOIN sys.columns IXCC ON IXCC.column_id = IXC.column_id AND IXCC.object_id = IXC.object_id
+LEFT JOIN sys.schemas IXS ON IXT.schema_id = IXS.schema_id
+
+inner join sys.objects o on FK.TABLE_NAME = o.name
+inner join sys.schemas s on o.schema_id = s.schema_id and FK.TABLE_SCHEMA = s.name
+
+where o.object_id =[OBJECT_ID_CONDITION]
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/getSchemas.js b/plugins/dbgate-plugin-mssql/src/backend/sql/getSchemas.js
new file mode 100644
index 000000000..a7cb0a4de
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/getSchemas.js
@@ -0,0 +1 @@
+module.exports = `select schema_id as objectId, name as schemaName from sys.schemas`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/index.js b/plugins/dbgate-plugin-mssql/src/backend/sql/index.js
new file mode 100644
index 000000000..cb40e88a5
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/index.js
@@ -0,0 +1,23 @@
+const columns = require('./columns');
+const foreignKeys = require('./foreignKeys');
+const primaryKeys = require('./primaryKeys');
+const tables = require('./tables');
+const modifications = require('./modifications');
+const loadSqlCode = require('./loadSqlCode');
+const views = require('./views');
+const programmables = require('./programmables');
+const viewColumns = require('./viewColumns');
+const getSchemas = require('./getSchemas');
+
+module.exports = {
+ columns,
+ tables,
+ foreignKeys,
+ primaryKeys,
+ modifications,
+ loadSqlCode,
+ views,
+ programmables,
+ viewColumns,
+ getSchemas,
+};
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/loadSqlCode.js b/plugins/dbgate-plugin-mssql/src/backend/sql/loadSqlCode.js
new file mode 100644
index 000000000..c5f8ee87d
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/loadSqlCode.js
@@ -0,0 +1,8 @@
+module.exports = `
+select s.name as pureName, u.name as schemaName, c.text AS codeText
+ from sys.objects s
+ inner join sys.syscomments c on s.object_id = c.id
+ inner join sys.schemas u on u.schema_id = s.schema_id
+where (s.object_id =[OBJECT_ID_CONDITION])
+order by u.name, s.name, c.colid
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/modifications.js b/plugins/dbgate-plugin-mssql/src/backend/sql/modifications.js
new file mode 100644
index 000000000..4389fd6ca
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/modifications.js
@@ -0,0 +1,6 @@
+module.exports = `
+select o.object_id as objectId, o.modify_date as modifyDate, o.type, o.name as pureName, s.name as schemaName
+from sys.objects o
+inner join sys.schemas s on o.schema_id = s.schema_id
+where o.type in ('U', 'V', 'P', 'IF', 'FN', 'TF') -- , 'TR' - triggers disabled
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/primaryKeys.js b/plugins/dbgate-plugin-mssql/src/backend/sql/primaryKeys.js
new file mode 100644
index 000000000..f67beb7f2
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/primaryKeys.js
@@ -0,0 +1,14 @@
+module.exports = `
+select o.object_id, pureName = t.Table_Name, schemaName = t.Table_Schema, columnName = c.Column_Name, constraintName=t.constraint_name from
+ INFORMATION_SCHEMA.TABLE_CONSTRAINTS t,
+ sys.objects o,
+ sys.schemas s,
+ INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE c
+where
+ c.Constraint_Name = t.Constraint_Name
+ and t.table_name = o.name
+ and o.schema_id = s.schema_id and t.Table_Schema = s.name
+ and c.Table_Name = t.Table_Name
+ and Constraint_Type = 'PRIMARY KEY'
+ and o.object_id =[OBJECT_ID_CONDITION]
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/programmables.js b/plugins/dbgate-plugin-mssql/src/backend/sql/programmables.js
new file mode 100644
index 000000000..8e651d3ec
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/programmables.js
@@ -0,0 +1,6 @@
+module.exports = `
+select o.name as pureName, s.name as schemaName, o.object_id as objectId, o.create_date as createDate, o.modify_date as modifyDate, o.type as sqlObjectType
+from sys.objects o
+inner join sys.schemas s on o.schema_id = s.schema_id
+where o.type in ('P', 'IF', 'FN', 'TF') and o.object_id =[OBJECT_ID_CONDITION]
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/tables.js b/plugins/dbgate-plugin-mssql/src/backend/sql/tables.js
new file mode 100644
index 000000000..46ab78440
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/tables.js
@@ -0,0 +1,8 @@
+module.exports = `
+select
+ o.name as pureName, s.name as schemaName, o.object_id as objectId,
+ o.create_date as createDate, o.modify_date as modifyDate
+from sys.tables o
+inner join sys.schemas s on o.schema_id = s.schema_id
+where o.object_id =[OBJECT_ID_CONDITION]
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/viewColumns.js b/plugins/dbgate-plugin-mssql/src/backend/sql/viewColumns.js
new file mode 100644
index 000000000..0868c43ae
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/viewColumns.js
@@ -0,0 +1,18 @@
+module.exports = `
+select
+ o.object_id AS objectId,
+ col.TABLE_SCHEMA as schemaName,
+ col.TABLE_NAME as pureName,
+ col.COLUMN_NAME as columnName,
+ col.IS_NULLABLE as isNullable,
+ col.DATA_TYPE as dataType,
+ col.CHARACTER_MAXIMUM_LENGTH as charMaxLength,
+ col.NUMERIC_PRECISION as precision,
+ col.NUMERIC_SCALE as scale,
+ col.COLUMN_DEFAULT
+FROM sys.objects o
+INNER JOIN sys.schemas u ON u.schema_id=o.schema_id
+INNER JOIN INFORMATION_SCHEMA.COLUMNS col ON col.TABLE_NAME = o.name AND col.TABLE_SCHEMA = u.name
+WHERE o.type in ('V') and o.object_id =[OBJECT_ID_CONDITION]
+order by col.ORDINAL_POSITION
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/sql/views.js b/plugins/dbgate-plugin-mssql/src/backend/sql/views.js
new file mode 100644
index 000000000..f0edb498f
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/sql/views.js
@@ -0,0 +1,10 @@
+module.exports = `
+SELECT
+ o.name as pureName,
+ u.name as schemaName,
+ o.object_id as objectId,
+ o.create_date as createDate,
+ o.modify_date as modifyDate
+FROM sys.objects o INNER JOIN sys.schemas u ON u.schema_id=o.schema_id
+WHERE type in ('V') and o.object_id =[OBJECT_ID_CONDITION]
+`;
diff --git a/plugins/dbgate-plugin-mssql/src/backend/tediousDriver.js b/plugins/dbgate-plugin-mssql/src/backend/tediousDriver.js
new file mode 100644
index 000000000..2964642b4
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/backend/tediousDriver.js
@@ -0,0 +1,180 @@
+const _ = require('lodash');
+const stream = require('stream');
+const tedious = require('tedious');
+const makeUniqueColumnNames = require('./makeUniqueColumnNames');
+
+function extractTediousColumns(columns, addDriverNativeColumn = false) {
+ const res = columns.map(col => {
+ const resCol = {
+ columnName: col.colName,
+ dataType: col.type.name.toLowerCase(),
+ driverNativeColumn: addDriverNativeColumn ? col : undefined,
+
+ notNull: !(col.flags & 0x01),
+ autoIncrement: !!(col.flags & 0x10),
+ };
+ if (col.dataLength) resCol.dataType += `(${col.dataLength})`;
+ return resCol;
+ });
+
+ makeUniqueColumnNames(res);
+
+ return res;
+}
+
+async function tediousConnect({ server, port, user, password, database, ssl }) {
+ return new Promise((resolve, reject) => {
+ const connection = new tedious.Connection({
+ server,
+
+ authentication: {
+ type: 'default',
+ options: {
+ userName: user,
+ password: password,
+ },
+ },
+
+ options: {
+ encrypt: !!ssl,
+ cryptoCredentialsDetails: ssl ? _.pick(ssl, ['ca', 'cert', 'key']) : undefined,
+ trustServerCertificate: ssl ? (!ssl.ca && !ssl.cert && !ssl.key ? true : ssl.rejectUnauthorized) : undefined,
+ enableArithAbort: true,
+ validateBulkLoadParameters: false,
+ requestTimeout: 1000 * 3600,
+ database,
+ port: port ? parseInt(port) : undefined,
+ },
+ });
+ connection.on('connect', function (err) {
+ if (err) {
+ reject(err);
+ }
+ connection._connectionType = 'tedious';
+ resolve(connection);
+ });
+ connection.connect();
+ });
+}
+
+async function tediousQueryCore(pool, sql, options) {
+ if (sql == null) {
+ return Promise.resolve({
+ rows: [],
+ columns: [],
+ });
+ }
+ const { addDriverNativeColumn } = options || {};
+ return new Promise((resolve, reject) => {
+ const result = {
+ rows: [],
+ columns: [],
+ };
+ const request = new tedious.Request(sql, (err, rowCount) => {
+ if (err) reject(err);
+ else resolve(result);
+ });
+ request.on('columnMetadata', function (columns) {
+ result.columns = extractTediousColumns(columns, addDriverNativeColumn);
+ });
+ request.on('row', function (columns) {
+ result.rows.push(
+ _.zipObject(
+ result.columns.map(x => x.columnName),
+ columns.map(x => x.value)
+ )
+ );
+ });
+ pool.execSql(request);
+ });
+}
+
+async function tediousReadQuery(pool, sql, structure) {
+ const pass = new stream.PassThrough({
+ objectMode: true,
+ highWaterMark: 100,
+ });
+ let currentColumns = [];
+
+ const request = new tedious.Request(sql, (err, rowCount) => {
+ if (err) console.error(err);
+ pass.end();
+ });
+ request.on('columnMetadata', function (columns) {
+ currentColumns = extractTediousColumns(columns);
+ pass.write({
+ __isStreamHeader: true,
+ ...(structure || { columns: currentColumns }),
+ });
+ });
+ request.on('row', function (columns) {
+ const row = _.zipObject(
+ currentColumns.map(x => x.columnName),
+ columns.map(x => x.value)
+ );
+ pass.write(row);
+ });
+ pool.execSql(request);
+
+ return pass;
+}
+
+async function tediousStream(pool, sql, options) {
+ let currentColumns = [];
+
+ const handleInfo = info => {
+ const { message, lineNumber, procName } = info;
+ options.info({
+ message,
+ line: lineNumber,
+ procedure: procName,
+ time: new Date(),
+ severity: 'info',
+ });
+ };
+ const handleError = error => {
+ const { message, lineNumber, procName } = error;
+ options.info({
+ message,
+ line: lineNumber,
+ procedure: procName,
+ time: new Date(),
+ severity: 'error',
+ });
+ };
+
+ pool.on('infoMessage', handleInfo);
+ pool.on('errorMessage', handleError);
+ const request = new tedious.Request(sql, (err, rowCount) => {
+ // if (err) reject(err);
+ // else resolve(result);
+ options.done();
+ pool.off('infoMessage', handleInfo);
+ pool.off('errorMessage', handleError);
+
+ options.info({
+ message: `${rowCount} rows affected`,
+ time: new Date(),
+ severity: 'info',
+ });
+ });
+ request.on('columnMetadata', function (columns) {
+ currentColumns = extractTediousColumns(columns);
+ options.recordset(currentColumns);
+ });
+ request.on('row', function (columns) {
+ const row = _.zipObject(
+ currentColumns.map(x => x.columnName),
+ columns.map(x => x.value)
+ );
+ options.row(row);
+ });
+ pool.execSqlBatch(request);
+}
+
+module.exports = {
+ tediousConnect,
+ tediousQueryCore,
+ tediousReadQuery,
+ tediousStream,
+};
diff --git a/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js
new file mode 100644
index 000000000..8b6459b82
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/frontend/MsSqlDumper.js
@@ -0,0 +1,113 @@
+const { SqlDumper } = require('dbgate-tools');
+
+class MsSqlDumper extends SqlDumper {
+ autoIncrement() {
+ this.put(' ^identity');
+ }
+
+ putStringValue(value) {
+ if (/[^\u0000-\u00ff]/.test(value)) {
+ this.putRaw('N');
+ }
+ super.putStringValue(value);
+ }
+
+ allowIdentityInsert(table, allow) {
+ this.putCmd('^set ^identity_insert %f %k', table, allow ? 'on' : 'off');
+ }
+
+ /** @param type {import('dbgate-types').TransformType} */
+ transform(type, dumpExpr) {
+ switch (type) {
+ case 'GROUP:YEAR':
+ case 'YEAR':
+ this.put('^datepart(^year, %c)', dumpExpr);
+ break;
+ case 'MONTH':
+ this.put('^datepart(^month, %c)', dumpExpr);
+ break;
+ case 'DAY':
+ this.put('^datepart(^day, %c)', dumpExpr);
+ break;
+ case 'GROUP:MONTH':
+ this.put(
+ "^convert(^varchar(100), ^datepart(^year, %c)) + '-' + right('0' + ^convert(^varchar(100), ^datepart(^month, %c)), 2)",
+ dumpExpr,
+ dumpExpr
+ );
+ break;
+ case 'GROUP:DAY':
+ this.put(
+ "^^convert(^varchar(100), ^datepart(^year, %c)) + '-' + ^right('0' + ^convert(^varchar(100), ^datepart(^month, %c)), 2)+'-' + ^right('0' + ^convert(^varchar(100), ^datepart(^day, %c)), 2)",
+ dumpExpr,
+ dumpExpr,
+ dumpExpr
+ );
+ break;
+ default:
+ dumpExpr();
+ break;
+ }
+ }
+
+ renameObject(obj, newname) {
+ this.putCmd("^execute sp_rename '%f', '%s', 'OBJECT'", obj, newname);
+ }
+
+ changeObjectSchema(obj, newschema) {
+ this.putCmd("^execute sp_changeobjectowner '%f', '%s'", obj, newschema);
+ }
+
+ dropTable(obj, options = {}) {
+ if (options.testIfExists) {
+ this.put("IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'%f') AND type in (N'U'))&n", obj);
+ }
+ super.dropTable(obj, options);
+ }
+
+ dropDefault(col) {
+ if (col.defaultConstraint) {
+ this.putCmd("^alter ^table %f ^drop ^constraint %i", col, col.defaultConstraint);
+ }
+ }
+
+ guessDefaultName(col) {
+ return col.defaultConstraint || `DF${col.schemaName || 'dbo'}_${col.pureName}_col.columnName`
+ }
+
+ createDefault(col) {
+ if (!col.defaultValue) return;
+ const defsql = col.defaultValue;
+ if (!defsql) {
+ const defname = this.guessDefaultName(col);
+ this.putCmd("^alter ^table %f ^add ^constraint %i ^default %s for %i", col, defname, defsql, col.columnName);
+ }
+ }
+
+ renameColumn(column, newcol) {
+ this.putCmd("^execute sp_rename '%f.%i', '%s', 'COLUMN'", column, column.columnName, newcol);
+ }
+
+ renameConstraint(cnt, newname) {
+ if (cnt.constraintType == 'index') this.putCmd("^execute sp_rename '%f.%i', '%s', 'INDEX'", cnt, cnt.constraintName, newname);
+ else this.putCmd("^execute sp_rename '%f', '%s', 'OBJECT'", { schemaName: cnt.schemaName, pureName: cnt.constraintName }, newname);
+ }
+}
+
+MsSqlDumper.prototype.renameView = MsSqlDumper.prototype.renameObject;
+MsSqlDumper.prototype.changeViewSchema = MsSqlDumper.prototype.changeObjectSchema;
+
+MsSqlDumper.prototype.renameProcedure = MsSqlDumper.prototype.renameObject;
+MsSqlDumper.prototype.changeProcedureSchema = MsSqlDumper.prototype.changeObjectSchema;
+
+MsSqlDumper.prototype.renameFunction = MsSqlDumper.prototype.renameObject;
+MsSqlDumper.prototype.changeFunctionSchema = MsSqlDumper.prototype.changeObjectSchema;
+
+MsSqlDumper.prototype.renameTrigger = MsSqlDumper.prototype.renameObject;
+MsSqlDumper.prototype.changeTriggerSchema = MsSqlDumper.prototype.changeObjectSchema;
+
+MsSqlDumper.prototype.renameTable = MsSqlDumper.prototype.renameObject;
+MsSqlDumper.prototype.changeTableSchema = MsSqlDumper.prototype.changeObjectSchema;
+
+
+module.exports = MsSqlDumper;
diff --git a/plugins/dbgate-plugin-mssql/src/frontend/driver.js b/plugins/dbgate-plugin-mssql/src/frontend/driver.js
new file mode 100644
index 000000000..0c20c5745
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/frontend/driver.js
@@ -0,0 +1,29 @@
+const { driverBase } = require('dbgate-tools');
+const MsSqlDumper = require('./MsSqlDumper');
+
+/** @type {import('dbgate-types').SqlDialect} */
+const dialect = {
+ limitSelect: true,
+ rangeSelect: true,
+ offsetFetchRangeSyntax: true,
+ stringEscapeChar: "'",
+ fallbackDataType: 'nvarchar(max)',
+ explicitDropConstraint: false,
+ enableConstraintsPerTable: true,
+ anonymousPrimaryKey: false,
+ quoteIdentifier(s) {
+ return `[${s}]`;
+ },
+};
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ dumperClass: MsSqlDumper,
+ dialect,
+ engine: 'mssql@dbgate-plugin-mssql',
+ title: 'Microsoft SQL Server',
+ defaultPort: 1433,
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-mssql/src/frontend/index.js b/plugins/dbgate-plugin-mssql/src/frontend/index.js
new file mode 100644
index 000000000..841ed051a
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/src/frontend/index.js
@@ -0,0 +1,5 @@
+import driver from './driver';
+
+export default {
+ driver,
+};
diff --git a/plugins/dbgate-plugin-mssql/webpack-backend.config.js b/plugins/dbgate-plugin-mssql/webpack-backend.config.js
new file mode 100644
index 000000000..c00656b5f
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/webpack-backend.config.js
@@ -0,0 +1,22 @@
+var webpack = require('webpack');
+var path = require('path');
+
+var config = {
+ context: __dirname + '/src/backend',
+
+ entry: {
+ app: './index.js',
+ },
+ target: 'node',
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: 'backend.js',
+ libraryTarget: 'commonjs2',
+ },
+
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-mssql/webpack-frontend.config.js b/plugins/dbgate-plugin-mssql/webpack-frontend.config.js
new file mode 100644
index 000000000..2703ab7e6
--- /dev/null
+++ b/plugins/dbgate-plugin-mssql/webpack-frontend.config.js
@@ -0,0 +1,23 @@
+var webpack = require("webpack");
+var path = require("path");
+
+var config = {
+ context: __dirname + "/src/frontend",
+
+ entry: {
+ app: "./index.js",
+ },
+ target: "web",
+ output: {
+ path: path.resolve(__dirname, "dist"),
+ filename: "frontend.js",
+ libraryTarget: "var",
+ library: 'plugin',
+ },
+
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-mysql/LICENSE b/plugins/dbgate-plugin-mysql/LICENSE
new file mode 100644
index 000000000..c15ede038
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Jan Prochazka
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-mysql/README.md b/plugins/dbgate-plugin-mysql/README.md
new file mode 100644
index 000000000..b3e4fc850
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/README.md
@@ -0,0 +1,6 @@
+[](https://github.com/prettier/prettier)
+[](https://www.npmjs.com/package/dbgate-plugin-mysql)
+
+# dbgate-plugin-mysql
+
+Use DbGate for install of this plugin
diff --git a/plugins/dbgate-plugin-mysql/icon.svg b/plugins/dbgate-plugin-mysql/icon.svg
new file mode 100644
index 000000000..a31893f5e
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/icon.svg
@@ -0,0 +1,47 @@
+
+
+
diff --git a/plugins/dbgate-plugin-mysql/package.json b/plugins/dbgate-plugin-mysql/package.json
new file mode 100644
index 000000000..e5ecb59bf
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "dbgate-plugin-mysql",
+ "main": "dist/backend.js",
+ "version": "1.2.2",
+ "homepage": "https://github.com/dbgate/dbgate-plugin-mysql",
+ "description": "MySQL connect plugin for DbGate",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/dbgate/dbgate-plugin-mysql.git"
+ },
+ "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur",
+ "author": "Jan Prochazka",
+ "license": "MIT",
+ "keywords": [
+ "sql",
+ "dbgate",
+ "dbgateplugin",
+ "mysql"
+ ],
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build:frontend": "webpack --config webpack-frontend.config",
+ "build:backend": "webpack --config webpack-backend.config.js",
+ "build": "yarn build:frontend && yarn build:backend",
+ "plugin": "yarn build && yarn pack && dbgate-plugin dbgate-plugin-mysql",
+ "plugout": "dbgate-plugout dbgate-plugin-mysql",
+ "prepublishOnly": "yarn build"
+ },
+ "devDependencies": {
+ "@verycrazydog/mysql-parser": "^1.2.0",
+ "dbgate-plugin-tools": "^1.0.4",
+ "dbgate-tools": "^4.0.3-rc.1",
+ "mysql2": "^2.2.5",
+ "webpack": "^4.42.0",
+ "webpack-cli": "^3.3.11"
+ }
+}
diff --git a/plugins/dbgate-plugin-mysql/prettier.config.js b/plugins/dbgate-plugin-mysql/prettier.config.js
new file mode 100644
index 000000000..c05d71875
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/prettier.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ trailingComma: 'es5',
+ tabWidth: 2,
+ semi: true,
+ singleQuote: true,
+ arrowParen: 'avoid',
+ arrowParens: 'avoid',
+ printWidth: 120,
+};
diff --git a/plugins/dbgate-plugin-mysql/src/backend/Analyser.js b/plugins/dbgate-plugin-mysql/src/backend/Analyser.js
new file mode 100644
index 000000000..9e1f043bb
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/Analyser.js
@@ -0,0 +1,222 @@
+const fp = require('lodash/fp');
+const _ = require('lodash');
+const sql = require('./sql');
+
+const { DatabaseAnalyser } = require('dbgate-tools');
+const { isTypeString, isTypeNumeric } = require('dbgate-tools');
+const { rangeStep } = require('lodash/fp');
+
+function getColumnInfo({
+ isNullable,
+ extra,
+ columnName,
+ dataType,
+ charMaxLength,
+ numericPrecision,
+ numericScale,
+ defaultValue,
+}) {
+ let fullDataType = dataType;
+ if (charMaxLength && isTypeString(dataType)) fullDataType = `${dataType}(${charMaxLength})`;
+ if (numericPrecision && numericScale && isTypeNumeric(dataType))
+ fullDataType = `${dataType}(${numericPrecision},${numericScale})`;
+ return {
+ notNull: !isNullable || isNullable == 'NO' || isNullable == 'no',
+ autoIncrement: extra && extra.toLowerCase().includes('auto_increment'),
+ columnName,
+ dataType: fullDataType,
+ defaultValue,
+ };
+}
+
+function objectTypeToField(type) {
+ if (type == 'VIEW') return 'views';
+ if (type == 'BASE TABLE') return 'tables';
+ return null;
+}
+
+class Analyser extends DatabaseAnalyser {
+ constructor(pool, driver) {
+ super(pool, driver);
+ }
+
+ createQuery(resFileName, typeFields) {
+ let res = sql[resFileName];
+ if (this.singleObjectFilter) {
+ const { typeField, pureName } = this.singleObjectFilter;
+ if (!typeFields || !typeFields.includes(typeField)) return null;
+ res = res.replace('=[OBJECT_NAME_CONDITION]', ` = '${pureName}'`).replace('#DATABASE#', this.pool._database_name);
+ return res;
+ }
+ if (!this.modifications || !typeFields || this.modifications.length == 0) {
+ res = res.replace('=[OBJECT_NAME_CONDITION]', ' is not null');
+ } else {
+ const filterNames = this.modifications
+ .filter(x => typeFields.includes(x.objectTypeField) && (x.action == 'add' || x.action == 'change'))
+ .map(x => x.newName && x.newName.pureName)
+ .filter(Boolean);
+ if (filterNames.length == 0) {
+ res = res.replace('=[OBJECT_NAME_CONDITION]', ' IS NULL');
+ } else {
+ res = res.replace('=[OBJECT_NAME_CONDITION]', ` in (${filterNames.map(x => `'${x}'`).join(',')})`);
+ }
+ }
+ res = res.replace('#DATABASE#', this.pool._database_name);
+ return res;
+ }
+
+ getRequestedViewNames(allViewNames) {
+ if (this.singleObjectFilter) {
+ const { typeField, pureName } = this.singleObjectFilter;
+ if (typeField == 'views') return [pureName];
+ }
+ if (this.modifications) {
+ return this.modifications.filter(x => x.objectTypeField == 'views').map(x => x.newName.pureName);
+ }
+ return allViewNames;
+ }
+
+ async getViewTexts(allViewNames) {
+ const res = {};
+ for (const viewName of this.getRequestedViewNames(allViewNames)) {
+ const resp = await this.driver.query(this.pool, `SHOW CREATE VIEW \`${viewName}\``);
+ res[viewName] = resp.rows[0]['Create View'];
+ }
+ return res;
+ }
+
+ async _runAnalysis() {
+ const tables = await this.driver.query(this.pool, this.createQuery('tables', ['tables']));
+ const columns = await this.driver.query(this.pool, this.createQuery('columns', ['tables', 'views']));
+ const pkColumns = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables']));
+ const fkColumns = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables']));
+ const views = await this.driver.query(this.pool, this.createQuery('views', ['views']));
+ const programmables = await this.driver.query(
+ this.pool,
+ this.createQuery('programmables', ['procedures', 'functions'])
+ );
+
+ const viewTexts = await this.getViewTexts(views.rows.map(x => x.pureName));
+
+ return this.mergeAnalyseResult({
+ tables: tables.rows.map(table => ({
+ ...table,
+ objectId: table.pureName,
+ columns: columns.rows.filter(col => col.pureName == table.pureName).map(getColumnInfo),
+ primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows),
+ foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows),
+ })),
+ views: views.rows.map(view => ({
+ ...view,
+ objectId: view.pureName,
+ columns: columns.rows.filter(col => col.pureName == view.pureName).map(getColumnInfo),
+ createSql: viewTexts[view.pureName],
+ requiresFormat: true,
+ })),
+ procedures: programmables.rows
+ .filter(x => x.objectType == 'PROCEDURE')
+ .map(fp.omit(['objectType']))
+ .map(x => ({ ...x, objectId: x.pureName })),
+ functions: programmables.rows
+ .filter(x => x.objectType == 'FUNCTION')
+ .map(fp.omit(['objectType']))
+ .map(x => ({ ...x, objectId: x.pureName })),
+ });
+ }
+
+ getDeletedObjectsForField(nameArray, objectTypeField) {
+ return this.structure[objectTypeField]
+ .filter(x => !nameArray.includes(x.pureName))
+ .map(x => ({
+ oldName: _.pick(x, ['pureName']),
+ action: 'remove',
+ objectTypeField,
+ objectId: x.pureName,
+ }));
+ }
+
+ getDeletedObjects(nameArray) {
+ return [
+ ...this.getDeletedObjectsForField(nameArray, 'tables'),
+ ...this.getDeletedObjectsForField(nameArray, 'views'),
+ ...this.getDeletedObjectsForField(nameArray, 'procedures'),
+ ...this.getDeletedObjectsForField(nameArray, 'functions'),
+ ...this.getDeletedObjectsForField(nameArray, 'triggers'),
+ ];
+ }
+
+ async getModifications() {
+ const tableModificationsQueryData = await this.driver.query(this.pool, this.createQuery('tableModifications'));
+ const procedureModificationsQueryData = await this.driver.query(
+ this.pool,
+ this.createQuery('procedureModifications')
+ );
+ const functionModificationsQueryData = await this.driver.query(
+ this.pool,
+ this.createQuery('functionModifications')
+ );
+
+ const allModifications = _.compact([
+ ...tableModificationsQueryData.rows.map(x => {
+ if (x.objectType == 'BASE TABLE') return { ...x, objectTypeField: 'tables' };
+ if (x.objectType == 'VIEW') return { ...x, objectTypeField: 'views' };
+ return null;
+ }),
+ ...procedureModificationsQueryData.rows.map(x => ({
+ objectTypeField: 'procedures',
+ modifyDate: x.Modified,
+ pureName: x.Name,
+ })),
+ ...functionModificationsQueryData.rows.map(x => ({
+ objectTypeField: 'functions',
+ modifyDate: x.Modified,
+ pureName: x.Name,
+ })),
+ ]);
+
+ // console.log('allModifications', allModifications);
+ // console.log(
+ // 'DATES',
+ // this.structure.procedures.map((x) => x.modifyDate)
+ // );
+ // console.log('MOD - SRC', modifications);
+ // console.log(
+ // 'MODs',
+ // this.structure.tables.map((x) => x.modifyDate)
+ // );
+ const modifications = allModifications.map(x => {
+ const { objectType, modifyDate, pureName } = x;
+ const field = objectTypeToField(objectType);
+
+ if (!field || !this.structure[field]) return null;
+ // @ts-ignore
+ const obj = this.structure[field].find(x => x.pureName == pureName);
+
+ // object not modified
+ if (obj && Math.abs(new Date(modifyDate).getTime() - new Date(obj.modifyDate).getTime()) < 1000) return null;
+
+ // console.log('MODIFICATION OF ', field, pureName, modifyDate, obj.modifyDate);
+
+ /** @type {import('dbgate-types').DatabaseModification} */
+ const action = obj
+ ? {
+ newName: { pureName },
+ oldName: _.pick(obj, ['pureName']),
+ action: 'change',
+ objectTypeField: field,
+ objectId: pureName,
+ }
+ : {
+ newName: { pureName },
+ action: 'add',
+ objectTypeField: field,
+ objectId: pureName,
+ };
+ return action;
+ });
+
+ return [..._.compact(modifications), ...this.getDeletedObjects([...allModifications.map(x => x.pureName)])];
+ }
+}
+
+module.exports = Analyser;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/driver.js b/plugins/dbgate-plugin-mysql/src/backend/driver.js
new file mode 100644
index 000000000..3a3120836
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/driver.js
@@ -0,0 +1,186 @@
+const _ = require('lodash');
+const stream = require('stream');
+const driverBase = require('../frontend/driver');
+const Analyser = require('./Analyser');
+const mysql2 = require('mysql2');
+const { createBulkInsertStreamBase, makeUniqueColumnNames } = require('dbgate-tools');
+const mysqlSplitter = require('@verycrazydog/mysql-parser');
+
+function extractColumns(fields) {
+ if (fields) {
+ const res = fields.map(col => ({
+ columnName: col.name,
+ }));
+ makeUniqueColumnNames(res);
+ return res;
+ }
+ return null;
+}
+
+function zipDataRow(rowArray, columns) {
+ return _.zipObject(
+ columns.map(x => x.columnName),
+ rowArray
+ );
+}
+
+async function runQueryItem(connection, sql) {
+ return new Promise((resolve, reject) => {
+ connection.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 });
+ });
+ });
+}
+
+async function runStreamItem(connection, sql, options) {
+ return new Promise((resolve, reject) => {
+ const query = connection.query(sql);
+ let columns = [];
+
+ // const handleInfo = (info) => {
+ // const { message, lineNumber, procName } = info;
+ // options.info({
+ // message,
+ // line: lineNumber,
+ // procedure: procName,
+ // time: new Date(),
+ // severity: 'info',
+ // });
+ // };
+
+ const handleEnd = () => {
+ resolve();
+ };
+
+ const handleRow = row => {
+ if (row && row.constructor && row.constructor.name == 'OkPacket') {
+ options.info({
+ message: `${row.affectedRows} rows affected`,
+ time: new Date(),
+ severity: 'info',
+ });
+ } else {
+ if (columns) {
+ options.row(zipDataRow(row, columns));
+ }
+ }
+ };
+
+ const handleFields = fields => {
+ columns = extractColumns(fields);
+ if (columns) options.recordset(columns);
+ };
+
+ const handleError = error => {
+ console.log('ERROR', error);
+ const { message, lineNumber, procName } = error;
+ options.info({
+ message,
+ line: lineNumber,
+ procedure: procName,
+ time: new Date(),
+ severity: 'error',
+ });
+ };
+
+ query.on('error', handleError).on('fields', handleFields).on('result', handleRow).on('end', handleEnd);
+ });
+}
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ analyserClass: Analyser,
+
+ async connect({ server, port, user, password, database, ssl }) {
+ const connection = mysql2.createConnection({
+ host: server,
+ port,
+ user,
+ password,
+ database,
+ ssl,
+ rowsAsArray: true,
+ supportBigNumbers: true,
+ bigNumberStrings: true,
+ // TODO: test following options
+ // multipleStatements: true,
+ // dateStrings: true,
+ });
+ connection._database_name = database;
+ return connection;
+ },
+ async query(connection, sql) {
+ if (sql == null) {
+ return {
+ rows: [],
+ columns: [],
+ };
+ }
+
+ const sqlSplitted = mysqlSplitter.split(sql);
+ let res = {
+ rows: [],
+ columns: [],
+ };
+ for (const sqlItem of sqlSplitted) {
+ const resultItem = await runQueryItem(connection, sqlItem);
+ if (resultItem.rows && resultItem.columns && resultItem.columns.length > 0) {
+ res = resultItem;
+ }
+ }
+ return res;
+ },
+ async stream(connection, sql, options) {
+ const sqlSplitted = mysqlSplitter.split(sql);
+
+ for (const sqlItem of sqlSplitted) {
+ await runStreamItem(connection, sqlItem, options);
+ }
+
+ options.done();
+ },
+ async readQuery(connection, sql, structure) {
+ const query = connection.query(sql);
+
+ const pass = new stream.PassThrough({
+ objectMode: true,
+ highWaterMark: 100,
+ });
+
+ let columns = [];
+ query
+ .on('error', err => {
+ console.error(err);
+ pass.end();
+ })
+ .on('fields', fields => {
+ columns = extractColumns(fields);
+ pass.write({
+ __isStreamHeader: true,
+ ...(structure || { columns }),
+ });
+ })
+ .on('result', row => pass.write(zipDataRow(row, columns)))
+ .on('end', () => pass.end());
+
+ return pass;
+ },
+ async getVersion(connection) {
+ const { rows } = await this.query(connection, "show variables like 'version'");
+ const version = rows[0].Value;
+ return { version };
+ },
+ async listDatabases(connection) {
+ const { rows } = await this.query(connection, 'show databases');
+ return rows.map(x => ({ name: x.Database }));
+ },
+ async writeTable(pool, name, options) {
+ // @ts-ignore
+ return createBulkInsertStreamBase(this, stream, pool, name, options);
+ },
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/index.js b/plugins/dbgate-plugin-mysql/src/backend/index.js
new file mode 100644
index 000000000..ef1600fd9
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/index.js
@@ -0,0 +1,6 @@
+const driver = require('./driver');
+
+module.exports = {
+ packageName: 'dbgate-plugin-mysql',
+ driver,
+};
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/columns.js b/plugins/dbgate-plugin-mysql/src/backend/sql/columns.js
new file mode 100644
index 000000000..0adb27e2b
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/columns.js
@@ -0,0 +1,15 @@
+module.exports = `
+select
+ TABLE_NAME as pureName,
+ COLUMN_NAME as columnName,
+ IS_NULLABLE as isNullable,
+ DATA_TYPE as dataType,
+ CHARACTER_MAXIMUM_LENGTH as charMaxLength,
+ NUMERIC_PRECISION as numericPrecision,
+ NUMERIC_SCALE as numericScale,
+ COLUMN_DEFAULT as defaultValue,
+ EXTRA as extra
+from INFORMATION_SCHEMA.COLUMNS
+where TABLE_SCHEMA = '#DATABASE#' and TABLE_NAME =[OBJECT_NAME_CONDITION]
+order by ORDINAL_POSITION
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/foreignKeys.js b/plugins/dbgate-plugin-mysql/src/backend/sql/foreignKeys.js
new file mode 100644
index 000000000..5b43b4031
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/foreignKeys.js
@@ -0,0 +1,17 @@
+module.exports = `
+select
+ REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME as constraintName,
+ REFERENTIAL_CONSTRAINTS.TABLE_NAME as pureName,
+ REFERENTIAL_CONSTRAINTS.UPDATE_RULE as updateAction,
+ REFERENTIAL_CONSTRAINTS.DELETE_RULE as deleteAction,
+ REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME as refTableName,
+ KEY_COLUMN_USAGE.COLUMN_NAME as columnName,
+ KEY_COLUMN_USAGE.REFERENCED_COLUMN_NAME as refColumnName
+from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
+inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE
+ on REFERENTIAL_CONSTRAINTS.TABLE_NAME = KEY_COLUMN_USAGE.TABLE_NAME
+ and REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME = KEY_COLUMN_USAGE.CONSTRAINT_NAME
+ and REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA = KEY_COLUMN_USAGE.CONSTRAINT_SCHEMA
+where REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA = '#DATABASE#' and REFERENTIAL_CONSTRAINTS.TABLE_NAME =[OBJECT_NAME_CONDITION]
+order by KEY_COLUMN_USAGE.ORDINAL_POSITION
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/functionModifications.js b/plugins/dbgate-plugin-mysql/src/backend/sql/functionModifications.js
new file mode 100644
index 000000000..f422a219a
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/functionModifications.js
@@ -0,0 +1,3 @@
+module.exports = `
+SHOW FUNCTION STATUS WHERE Db = '#DATABASE#'
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/index.js b/plugins/dbgate-plugin-mysql/src/backend/sql/index.js
new file mode 100644
index 000000000..f5a4992ec
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/index.js
@@ -0,0 +1,21 @@
+const columns = require('./columns');
+const tables = require('./tables');
+const primaryKeys = require('./primaryKeys');
+const foreignKeys = require('./foreignKeys');
+const tableModifications = require('./tableModifications');
+const views = require('./views');
+const programmables = require('./programmables');
+const procedureModifications = require('./procedureModifications');
+const functionModifications = require('./functionModifications');
+
+module.exports = {
+ columns,
+ tables,
+ primaryKeys,
+ foreignKeys,
+ tableModifications,
+ views,
+ programmables,
+ procedureModifications,
+ functionModifications,
+};
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/primaryKeys.js b/plugins/dbgate-plugin-mysql/src/backend/sql/primaryKeys.js
new file mode 100644
index 000000000..2b1b346e8
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/primaryKeys.js
@@ -0,0 +1,12 @@
+module.exports = `select
+ TABLE_CONSTRAINTS.CONSTRAINT_NAME as constraintName,
+ TABLE_CONSTRAINTS.TABLE_NAME as pureName,
+ KEY_COLUMN_USAGE.COLUMN_NAME as columnName
+from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
+inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE
+ on TABLE_CONSTRAINTS.TABLE_NAME = KEY_COLUMN_USAGE.TABLE_NAME
+ and TABLE_CONSTRAINTS.CONSTRAINT_NAME = KEY_COLUMN_USAGE.CONSTRAINT_NAME
+ and TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA = KEY_COLUMN_USAGE.CONSTRAINT_SCHEMA
+where TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA = '#DATABASE#' and TABLE_CONSTRAINTS.TABLE_NAME =[OBJECT_NAME_CONDITION] AND TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'PRIMARY KEY'
+order by KEY_COLUMN_USAGE.ORDINAL_POSITION
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/procedureModifications.js b/plugins/dbgate-plugin-mysql/src/backend/sql/procedureModifications.js
new file mode 100644
index 000000000..0ccbd49f8
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/procedureModifications.js
@@ -0,0 +1,3 @@
+module.exports = `
+SHOW PROCEDURE STATUS WHERE Db = '#DATABASE#'
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/programmables.js b/plugins/dbgate-plugin-mysql/src/backend/sql/programmables.js
new file mode 100644
index 000000000..dd1b36021
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/programmables.js
@@ -0,0 +1,9 @@
+module.exports = `
+select
+ ROUTINE_NAME as pureName,
+ ROUTINE_TYPE as objectType,
+ COALESCE(LAST_ALTERED, CREATED) as modifyDate,
+ ROUTINE_DEFINITION as createSql
+from information_schema.routines
+where ROUTINE_SCHEMA = '#DATABASE#' and ROUTINE_NAME =[OBJECT_NAME_CONDITION]
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/tableModifications.js b/plugins/dbgate-plugin-mysql/src/backend/sql/tableModifications.js
new file mode 100644
index 000000000..6382ea5ae
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/tableModifications.js
@@ -0,0 +1,8 @@
+module.exports = `
+select
+ TABLE_NAME as pureName,
+ TABLE_TYPE as objectType,
+ case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate
+from information_schema.tables
+where TABLE_SCHEMA = '#DATABASE#'
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/tables.js b/plugins/dbgate-plugin-mysql/src/backend/sql/tables.js
new file mode 100644
index 000000000..eed928431
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/tables.js
@@ -0,0 +1,7 @@
+module.exports = `
+select
+ TABLE_NAME as pureName,
+ case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate
+from information_schema.tables
+where TABLE_SCHEMA = '#DATABASE#' and TABLE_TYPE='BASE TABLE' and TABLE_NAME =[OBJECT_NAME_CONDITION];
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/backend/sql/views.js b/plugins/dbgate-plugin-mysql/src/backend/sql/views.js
new file mode 100644
index 000000000..ea4d8ef35
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/backend/sql/views.js
@@ -0,0 +1,7 @@
+module.exports = `
+select
+ TABLE_NAME as pureName,
+ coalesce(UPDATE_TIME, CREATE_TIME) as modifyDate
+from information_schema.tables
+where TABLE_SCHEMA = '#DATABASE#' and TABLE_NAME =[OBJECT_NAME_CONDITION] and TABLE_TYPE = 'VIEW';
+`;
diff --git a/plugins/dbgate-plugin-mysql/src/frontend/Dumper.js b/plugins/dbgate-plugin-mysql/src/frontend/Dumper.js
new file mode 100644
index 000000000..993cf8249
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/frontend/Dumper.js
@@ -0,0 +1,68 @@
+const { SqlDumper } = require('dbgate-tools');
+
+class Dumper extends SqlDumper {
+ /** @param type {import('dbgate-types').TransformType} */
+ transform(type, dumpExpr) {
+ switch (type) {
+ case 'GROUP:YEAR':
+ case 'YEAR':
+ this.put('^year(%c)', dumpExpr);
+ break;
+ case 'MONTH':
+ this.put('^month(%c)', dumpExpr);
+ break;
+ case 'DAY':
+ this.put('^day(%c)', dumpExpr);
+ break;
+ case 'GROUP:MONTH':
+ this.put("^date_format(%c, '%s')", dumpExpr, '%Y-%m');
+ break;
+ case 'GROUP:DAY':
+ this.put("^date_format(%c, '%s')", dumpExpr, '%Y-%m-%d');
+ break;
+ default:
+ dumpExpr();
+ break;
+ }
+ }
+
+ renameTable(obj, newName) {
+ this.putCmd('^rename ^table %f ^to %i', obj, newName);
+ }
+
+ changeColumn(oldcol, newcol, constraints) {
+ this.put('^alter ^table %f ^change ^column %i %i ', oldcol, oldcol.columnName, newcol.columnName);
+ this.columnDefinition(newcol, true, true, true);
+ this.inlineConstraints(constraints);
+ this.endCommand();
+ }
+
+ renameColumn(column, newcol) {
+ this.changeColumn(
+ column,
+ {
+ ...column,
+ columnName: newcol,
+ },
+ []
+ );
+ }
+
+ enableConstraints(table, enabled) {
+ this.putCmd('^set FOREIGN_KEY_CHECKS = %s', enabled ? '1' : '0');
+ }
+
+ comment(value) {
+ this.put('/* %s */', value);
+ }
+
+ beginTransaction() {
+ this.putCmd('^start ^transaction');
+ }
+
+ selectTableIntoNewTable(sourceName, targetName) {
+ this.putCmd('^create ^table %f (^select * ^from %f)', targetName, sourceName);
+ }
+}
+
+module.exports = Dumper;
diff --git a/plugins/dbgate-plugin-mysql/src/frontend/driver.js b/plugins/dbgate-plugin-mysql/src/frontend/driver.js
new file mode 100644
index 000000000..93465e2d6
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/frontend/driver.js
@@ -0,0 +1,27 @@
+const { driverBase } = require('dbgate-tools');
+const Dumper = require('./Dumper');
+
+/** @type {import('dbgate-types').SqlDialect} */
+const dialect = {
+ rangeSelect: true,
+ stringEscapeChar: '\\',
+ fallbackDataType: 'longtext',
+ enableConstraintsPerTable: false,
+ anonymousPrimaryKey: true,
+ explicitDropConstraint: true,
+ quoteIdentifier(s) {
+ return '`' + s + '`';
+ },
+};
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ dumperClass: Dumper,
+ dialect,
+ engine: 'mysql@dbgate-plugin-mysql',
+ title: 'MySQL / MariaDB',
+ defaultPort: 3306,
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-mysql/src/frontend/index.js b/plugins/dbgate-plugin-mysql/src/frontend/index.js
new file mode 100644
index 000000000..424f70e0a
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/src/frontend/index.js
@@ -0,0 +1,6 @@
+import driver from './driver';
+
+export default {
+ packageName: 'dbgate-plugin-mysql',
+ driver,
+};
diff --git a/plugins/dbgate-plugin-mysql/test/testdb.sql b/plugins/dbgate-plugin-mysql/test/testdb.sql
new file mode 100644
index 000000000..45f2e834f
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/test/testdb.sql
@@ -0,0 +1,33 @@
+DROP DATABASE IF EXISTS `TestDb`;
+
+
+/*******************************************************************************
+ Create database
+********************************************************************************/
+CREATE DATABASE `TestDb`;
+
+
+USE `TestDb`;
+
+
+CREATE TABLE `ValuesTest`
+(
+ `ID` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ `col_nvarchar` NVARCHAR(160),
+ `col_int` INT(160),
+ `col_numeric` NUMERIC(10,2),
+ `col_bool` BOOLEAN,
+ `col_bit` BIT
+);
+
+CREATE TABLE `ImageTest`
+(
+ `ID` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ `col_image` LONGBLOB
+);
+
+INSERT INTO ValuesTest (col_nvarchar, col_int, col_numeric, col_bool, col_bit) VALUES ('value 0', 0, 0, 0, 0);
+INSERT INTO ValuesTest (col_nvarchar, col_int, col_numeric, col_bool, col_bit) VALUES ('value 1', 1, 1, 1, 1);
+INSERT INTO ValuesTest (col_nvarchar, col_int, col_numeric, col_bool, col_bit) VALUES ('value any', 1241, 14.56, 1, 1);
+
+INSERT INTO ImageTest (col_image) VALUES (X'FFD8FFE000104A46494600010200006400640000FFEC00114475636B7900010004000000500000FFEE002641646F62650064C0000000010300150403060A0D00000A63000010E8000019F4000027A4FFDB0084000202020202020202020203020202030403020203040504040404040506050505050505060607070807070609090A0A09090C0C0C0C0C0C0C0C0C0C0C0C0C0C0C01030303050405090606090D0B090B0D0F0E0E0E0E0F0F0C0C0C0C0C0F0F0C0C0C0C0C0C0F0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC2001108006E00AF03011100021101031101FFC400E800000104030101000000000000000000000503040607000208010901000203010101000000000000000000000203000104050607100001040103030401030403000000000001000203041110120520211331221406303223154133250724341611000200030505040704080701000000000102001103213141120451712232131061810591A1425262231420C1723330F0B1E18292B234D1F1A2C2D24393241200000503040301000000000000000000003001112120403110501222410232611301000202020103030501010000000000010011213141516110718191A1B120F0C1D1E130F1FFDA000C03010002110311000001EC3E66DE66CE0DDB4FD476C69EAF0BA3DC4DAF2FD20EB7CCD681E948BADB53974AC46A2178F553DE7280A568326F76E124494661F4B40EB6F59C9135685C38755FABA9C89CDF6B267E0ED1DDE21CDAF2E46C4A38FD872EE16AD54279AB85E414CAC7B2DC09375DAB54B507D17F65C6C9324F6E654C9324C93C93DB952D3646DD3E4A6F194871F455FCB3D2AC5558049B308B10BE88FA3BEC39046EB24C9324C9324C93248E2DF5BD6C96E958D160807263548F1DB5CE178851B796A9D081E615C19FE86FB4875A87760A90FB2649A0DB51646336BA8B27509EFC8C0CA5ED134684408625B0CCCF10323C12A5C7511C182D6E6F57A4BDAF375022D624AC5C4A6C251D53E148D7071D0B38263D0E72F6E91C3E77F3DEBA0187A8396FF4E1C359C66784EBF1B30E4A0C73D9D1FEFF00931A1B182D6744344C7D10D13640C771920808ED45A4EAE69F29EE2969DE1AF3B08B14753A0711CA495B1F93B0F8DC4268BE90F79C58C8D85AB130C551B084D166929C621CA1D9E37A6F6E2FA2E6DE6FB001A9C91510B5D9ECC751AB6958B611135C7E1EC0E5BFAAFE85E5A309B0B0C44B154C428DB81E0B0D18DC5D0E7560BD7CEFE57DFD757DE62DAF60EB77BDAF7259334AE6A885653290FA7FEB3E62090C4C24696D4288229A285A9D11221B177E11EBDB42E0F4143F27D88CBD09332129180B5A1A3094848909BB067D5AF5DF1C6EB81E16956DA44EAE038F43923936851460AD2A87E57AA129D754A3A8C036B24696A7684192B33F869416134D3C6EDCF45E14C02E1C6C36228541F4CF60C629E56A3D91894E6AE5FA5439FDAD964BB89D184685CEAE8F9E71CB60CCDA0DE9E6F64FA4F9F0C85BDD28337AA670811316A882DAE2E87DDD358BA94EE0EFADCCEDA39DCAB45D315E4A484DB2D8E4D72DEEF98ED4EBF8B1D716905AD8B4ACB85EC01939094981B2BAE47E37A28F67DC217D68A61EE3B30D2EBCBA56EB6926FB3892EDDC3FFFDA0008010100010502E4EBBA4AF3C4D134A3626F1B7AD55FB3F3527D6380E4677D2ADF58E767FADDE8E46CACD398693C7F2BF5BE339F15DB38ADCB1CC1363717273C806D809B36147C86145CC4DB9DCBE64C052D0A9391C5D04D63183ECDF5D83EC9C73FFD65F63649C7FF00ABB90F99144D863D39899B5B89E3237C3C6FA2BB039E2CE4344B95238BDAF39779D4927664CF0BCCD7B3F173C7F92B01F95929F1EF5CD52304AFA16A479E3EE84FA3794ADB109F2E136505794E20B50D8FC36ED3C36092BC6985AE6CF7638899EE58069CE5BCAF1B2432399B53DA9966D5722F0B0AECD523745565F8FE786491B295BDBD05C0274ED0AE723142DBBCABAC9A6CDD0FCF99D3C14618DBB8045CC538E3E512D0FAD4A9FC07012A9FE94D9472FC1DDE0A1E2299711186B677E248EFCB126F30D4DE56AAFE56B27F2F50297EC15D8ACFD8A7914966494C5DCDBE44F1BC4F154BE1D7E4AFFC282FFDA2E6E9B9FBB223C95B726F313B1B5EF58B0D8F92E4ABAFB0F3373937556889BB9591FB8F28BD3A44E94A7CA9D22DC98A11DF903E4E545A6D6ADCCF2D35974B2B9C557AF0CD44B1D2337CB5DF07312B572AE8A49602D737B2B3FDC913D3D39393820144D55DAE0B9D7FC4E67EC1C8358DB5397B89D2AD975499F4E1B1C7EFCBFE47B8B7CC38BE4C2F3B0AB2C7191E14813DA56C28B11620C5137BB61AB141F68A8DB15B969E574AF39450EE3D56E7B14514B3282FCF564E479417220F21CDE4AEB5A62B4D5F24B5D6A932588420835D8A588B1CE8D062635548248E1E4A2F2D5E4F8E6D98ECD596BBD9812BE230D9B354D4B73C12577C67F7266491B9CE696B46508C95E43E4B75C491536CAC5256638FC5187578653244637C553728A0898BDF23DCD0E6D6B31BE4B35DA55CE132FBBC7D835F95DD2436EF41721A0DACE2E8A32BE0BEDB7F847EE8B898990CAC21EC76F6C9BD93319BD9FA4420992591813F3BA26FB429243BBEC7567A9760E48588FDAE921E56E51966E5AB4C1DFF009F72AF3F0555E79DAEA6E77909C44EF73642E6D86FEE47278DD6A3DE22F68DBB8C8CDED7537B5C611B236E0CFDA3970D64DCDC6FB17EAFF1B71B3EE06C32478DA578EB95E2AA9CC856435424CB21D8A6FD6EC23E877E5BE74376FEDF1D9E9EC526C530ADE1E636FC993FEAC5B97FC8CE7945FE517F9343F9444DFC70DA7FFFDA00080102000105027B501DC85E3241F63507ED39D4A2DCE93FA3B5C223404ADE74C2C68F6EE4617042158D4EAE190F1AEED31A63F3CCC458578CAD851042CACADC3F1176130E99D0B72A48F0B6E81C420FCA700B0B2B3D594E916729BE9958D328BDAB31ADB1946B829F096A7232649D3795BD7917911951712B1A37D1A148FDA1F69C512E2B0B6ADA50DC107922670EAC2C2C6A11F42EC09642F2D1A6DD30B2BFA4C3BA3D47560EF22B32A637A0B7B2C2F453316111F80040613CA95843C74808144E85835731616163A1A148DECE6870734B50EB3D18585844656106203A09C2D80A2D3A1282CE9B50C7E495B82E4C3DFCA42F205B9AB73579423315940E47E3749DDE308B70B72CAECBB2256534171DBD87E1EDA58FD43D0AECBDABDABDABDABDAA1C69FFDA00080103000105020ED72A9D7F9123C6C6CF4D92B1C3074614C94847D51EAC2C69959D2A5A3039BCA4443F956E1CEDC741AB7A31F9DA350EC7463528FE26B328B71A06656D016421A616D0B6A965C20C2B6A2D58E9DA99120CC27A6B517E98418E5E37AC3D79084E9BB451AC6BB178D78D788A1121181A15EA5EA18B798E9B536B342F105E208C61181855F8430B074E565656752A319219B9D5E00D40684F75EA8B17211F61F806AF2A12A9C49ADD5C32B3DD654AC0F6EC20EDEB1A651254632A9B83988A1AB8A2347B37AF169840E9959E82EC985D8746E31BA199B202B2B3900A27567747034051D32B38595B913A8F468CA6592D4D91B96A6B709C1611700BCF84EDC5DD27AAABFDAD6A93F4981AE02B90836508B252BE33936AB023D93863AC159E88E3F6C32640F70D8B0565CB2E432B6A79D80BFBFE1EEBBAA9FA7FAB33D76B3A7FFFDA0008010202063F02BC9DE6445A458C55218D7B66B6936099136AC2475B8C0C0C0C1FC54A6B7FFFDA0008010302063F02A27081BD507E86A1BC1EFA750FBCB20731D6B9D1ED518E62114E7219436C6E822D7920741DC669C8EA1D7263510AA83E87D09F65D64CE49929EDFF00FFDA0008010101063F02AF213F96D60DD19189A672D931057A641F695AEDE0C1A1A5A072E79A33599B74E293E9D65ADD44A969F35A158DAC4EE851A14CD57CCF4DD4D66A5AD2E6A4F3485C251A02287D3E93CC55535D41ADCC0192D559F1084A88668E26A7B754EA26F469B544DEA2714BCD943E9FCD3A4B5343AD46E5696649A34D48F08A0BAA75ABAA14D46A2A2890679711037C0F81E09ECB3085CF5002E6437EC89E689030C0A4917DAB2DDD0B3E5174EF9F666A9411985B3947F6A965B2944954281808FA3A953A1569B7534D5EFCADDE364044D4E9AA209F49C3B593EE2B6452ADE6DE614DE8AB035169166632C26D284A4962531251DBE65A87E5A3A5AAC7C14C79751A963D2D352471DE1003D9552CC847CB18CE1E5788BEE82B32B3F68586118DB92D5EE3B62D11C17C4E766C31D49F0ADA0E167E8E8793536969A9BA6A7CE1FE1539A9D1FE32267BB7F6EC30C40E0ADCBBF18CF4B4954CC5AD90CA38A905DEE9FF002832D3B34BDD21BFA498F9945D06D6523B2D1197D8C441E9939979E9BA9471BD5A47F42C9A66556F6F52DCA9BB69FD7BA1A9D207206CCD50DACECDCCEC71262686621917E6D65136A6BECF7B9B946F8F92B9A78A9E9D3FFD08CC7F844716A7A350F3350591FE66CCD07AAEF59BD977626712EC26857A94BF0311046B34E959AF1593E5D4F12A247C4422E89EA5466E7A751790EC983C5EA8AB51E7D52A4AA6339471F0554E47FDF16F177C5F2FB1699459C507AD5028F705F19138688B962A36218454D0689A597FBCD58FFAFE04F8CFAA1465B14E614C998CDEF19F337798B4C5AE137C65D45547118EF5631C1A8A94E7DF04E87CC15FE178A9A9D52008CD955B34C16C251F52F6BBDAB046D129C3458D31B23E62C620C7E718B6A93072A13B208A47A63BA26ED32604546A5FDE6A9FA3A41F111CDE114A9F33CF3D56C59CDE6198101B02DB60CAB112D96448EA180F447E7B7A6245986C9E305A95504ADEA6C3135CFDF94CE3CBFCBEAD46E9062EC97714003012EC6FB17FD911E5FA76E5D321AD23F17F943EA585A01C820BD47B4F2AE0076BD6A673550B6A2CEC6EFB63A62B639A4C25EBB62F34DC6C895651506DB8C7966AD4D932BE9BA04BC7B1BF42CCAB99C0F96BDF1A4AAF757D2B229C33A5A2134E9CAA8334A0F6AD45B56EA94F065D915ABE92A75594F569627BD0C677E3B78BBE32F4688960CB15180C8AA2765CA677C74EAD8EBC2EB19834C6D86E13E8EDBA2EFB0A2E04DA611688E2B0B3FBDE31A632E2A55785BD7F744EA5E40FB1283958A871C5237C37490D428B9980BE0D4A8895E763AD6133677DF6453A54687D2A4CB5645B98E18080F94671EDDB05455B0DE2422A4D81A865282B5E92D495F985B1F53A31F8E8FF00845A2DC62E8CA7C3EC67AC72AB7E521BF7C3FC0438F08B049AF53DF192AACB61C0EE84CDCB98669EC834AA83256B7BC40A2E66848937C2D069D4B089C2DAC0319365BE46F808C99325CA409C8DA337EF85013295E669CE7D8632B5BB218E5F98A384E313B95B082C2C0701072FA4C0A4E264581B6435337A9946673946CC604904F69B626E730864373020F8C56F2CD59C95A9B1142B9BACDB0F475148348F123081F466D7325A2C71D818FDF0AF5F4EF4355A4196B071CCA310718F2FD4133CF472B6F1099F4D2D6280A6B86B0F843AD5D2D5D5B9E5A74C7EA60E97E9D69D336297CD5186DCAC16174B4F474D0ACB3EB29A939945D9719ED8BBA482C0A6D7F1C22A2E2C84587F69869C03E9870703C3BB081BA0CF08CDB2F86C85733893D93F5F603D924C2F3035817E4D694AA0F785E0C04A9CE97137CA16466030FDB1528AD77E95362A00D80C7FF479669758CD633BD255697E2494717902A9F82BD61FEE8EAD0F2529545CDF5157D6271C3E55A7B394BA9A9FD64C65150504F769009FB2335462619828016F261A24794C4C732C2CF011286A23E58C76C364E24494DF7C4B1DBD83DEA8722FA270CE7D81387F2EF33A2ADA1AEB26AA27359E319695515E81E3D36A05A194EE89F75B05B309B45F16D7FF00498FCF6FE58E0666F0946C85A69693EAEF85A62CA62C9E3BE1A38A5E3D965D1C3F741CDCD8C3FE2E3DD0DEB8B21337BDC1BE462AF55C84CA736EF442DB3E0FBCC0152C59FC86EFC44196CB638413BE2C53EA8B9E3DB8B9E3E72F06315E5F992B7F0F67FFDA0008010103013F21714B51FB3D4C67326CBEF1B83452415903A0AB29BDD2B356B35E770E3E1085A8B4ED46AFC434807986FD79E8B95555BD92F98BBA73E2AAA97DC1F51E4337B47F12D9D3AB40C311ABFBA513C4768E80610AF83E6E79921F6996BB971A6963D449038DACA169F4816CAE6D4FF260994D0E3504A8638AB3D0CE2BA9640195F634458A4B3A8716147CAAB3DC1D6715158BEF30469805460EA466195C168C24A905A92368151BCD8F2B153558BF885FD0F58347ABCA1737C2F9860785AFBE046A08C3BA578B25FCCA5AAB697C47CACBB5C76770D1CCC884B3E8743CE6160DDCD46C963DCA0B6C793F30DFD7E69E4FF9B9E8519C7F7340E0F844B2732CE67668E6553D2CD55F4134CA823F252A7C2257B83344D337EC22740FFE449006A9F012F4C1E7995D0161C9FC54248ABCA4E9000F0D67FE261118B65CD3EDE8E7B67E7325AB4B28CC3D77D303A4A50029626BC85EC3049DA3297591F1BEF287DD7ABE2F4FACBC196D72F0AE2677494DCC09DEC7DC1958A3045DE0BE5DF30CB3E3070561ADEDEC9703A970C0E655D0D0B09666BF22563575DFF507E3E0E3F468DF733932F1AFACECB53E5E18BB34C1CF5739CC07DABFD983EA3156FAB30FD0DDCC4FDAF22E6D724F278A8D3C17A2294AADDEA0903C86A9F0CD951D455B58C157F32808F087DCA835647744D07C7136F659C03957CC283965EE8BF03F130FE412B065E522295FA2A94F0FCB3E8D5B9EF6133C5348CC40965AB301DB3219E1BCE5E0E7DEA166B39E55B47B6292FC6665A0396288D74627EBB65824B603FCA5A5A1CEE64BE20B36707CA2F10A721E63776DDA7C444677F262D3C1708DA294BCFB5FE0955C73D1ED25B2E975965F4841948345AC3F643A7608C550686240DD5C56012D15E3AB2D7CDEBC4D009514DD55D204436356739E254F41FF00F197BF4AEE88FD08CBD97411D23FB3F827283730B89607D05B8AD4E74E0D2F05F8CCB4F5EDC8D7E6ABE6534EDACAA5B2CAF9974DC38B996C6D410E9D1844DDCE3822B726C16BD988212A2704305ED073C40A24117680067B87BD03412B9094B05CA3411607D72E89BCE6291C349F68AF3FA7A8E7D435AD41B68EE72A69E58738D7766804D40CE784AAB3E92C2BCC507459C40500B5C01018A7C18074D6E3A544C800E436E7A9790745671DB1FDAA1912682DD5B1A2007B364FBE6A5330E84CAF6007E6036E1657C7B4B43F0020F1750162D63CA770238161C7BC6F5F23FDC55D22BB1D32CE21DC096524BE33F02099BD43B7FD4BE6CE9E4E4F91E49939B92C876A63F1EE46599524B29BB767B92E149ECAB3EF4C20ED87AB1E3DCA6301425FA7801EE4BA975894D032FED8950FCE726D71A3E3D2088168B62F692A09E2E64DAD1F4CD798237A79BE5C6311485B72C02CBE58E8468DCF2C37C4CE6BDF9AE7E62D50BAE4FEA5F985BD8B3DE535D4E15E7CC117E9D0A84E5D7D64C0FCF716C115C64E7FD817EAC18178B4E7FF0052CE08815ACD4F70CC91882F3DBF23F696BD8E3236B5DB330E2BEC1DA58F8968E698FF0002293811E751D354B91814D1CBF339EE9217072F45EBED2BBE9686CDD16FD2BC4C5CE3F04EE5D7BA5D36AFF7B3160F057DE558F708A1682AF795AC535127C1A651534E4967218E9A97980F90C7E0DED00ABA0B57006B0AD278BC9E38E22D68CDF202FEB2E983ED28AA7091F5717B5F2316759D0FD17284E2998AE4D92532ABB023DE1FDA5AB1C552BE24DAC85DB6AB0E8136378D1E63349D7E09903BFC7994657F70EA6233006BC11043973ED298D837E5E6C8301224C17C261991F7C6F1730155D37CD93F4198214BD3477027488144A5BC0F264DCB6AE6A9D99C2CD3050E0B57930C655B5A0F3F316E55D99FEA7313C12FDBFF00B8032BC581F99CCAF26234272DE9CAF69B93EF90ED799C6DE3F04D35F0C2537C33372E9532BF547E604E057DDC399DAEA936D3E272D5FB07C5C5D94B25E39694028D0CF8C0CCF112799EA7EF89EC56F8453ED423C4FC7FA97FF9BFB9EDFB62E0BF48CCA391AF8E66BD5539EFF7DCCDCFFFDA0008010203013F214CCA3D16008E8A9858DEE4A4BF5ED730824C2150BFA75D421B997713D149504D443132C107EAC65F41823519494CED0952BF557A73FA2B62F8F458F0108210C7FC822CB611ACB589CA343488CE4A0689B1A46EDE8FCCF385A5FE8B23246E5A4C58C10A7A248DDB15F49B2413319CE88BE0F45A4A279CAC4C5E3D38922A8E4837446A366CBF7070F48AD784254951F4A95EBBEBC99840FA6809E95A851E8112ED136F8827FC07D609C5F40F42036F4BCB84A9622FEA7D40188055EA38FA20A811F41F41080CC5545B2A5F72CCFAB69E81E8F5996454BE111AF42A566A2543D70972A25C292929061772DDC125FA76A6A6447F8884327A5917A37A26D98698F4E7D398FAB065FA25BC469ED0E0C0966C33F6D81FFA9D0237C4CA5C56A1E8465C2312557A1297A20AAE25DB217819EE97DA0466B1027E88FA139FD0C4A4764F295E95454D7A1D1E9FFFDA0008010303013F21C5E970804F79E65FF840713123130C565B3D6866659E929A6A07307E83D11E8BF52E50E58EE5B1B3E20551BF31916DF5DBD08B1E84A8454A951FF9D9FA20DCA95E8A95E84113FE2914EA546CB886D7FB1E29484031F49E41156B71EBE85BF4541B118466D05382332A0E700874CA764E0210EB72D6DB95A844195E25A5E10EDF4EC7A130C5C7A3D6D4E1A07C45982D9372432E529257A8C20F4081FD114A901A251E8A67399881751BC17D350F425FEA6395B2DCE507AD08548CD4A7715734125B2117E87A0C3D171710C62D6CCC3C9C6FDE11D1163D1F449949369DC054B2784AF0CBF417972E5CD47A47D7D9DCB47D1C9E92D2F612E3D0DEA370C62DF3125115CBF45BD559000975997A7CD361A660CE3B8FC041B22AF11FDA7699163150B62225F0E883184D4DCD207A54A9505ED20B925EDDC04A667E53269BED260DFB65D0645CFBCA8A258393C423063E9703D47A3B7E12E70C650CC4944A389E296EE1056457F478988C37E998431693AC502D45F12FC4BF12FC4B62C6F51B9FFFDA000C0301000211031100001009CCE8E3F307D1E02D403E0EC85FFD389B20492811FEA747B60000000A04ADFA45A74012BA857F0D683CB8BA68EFCC5D152412FC91D53E7A0ECCDF9C66610B29B3F92E6F081C5E9D2FC044B5ED24511E7B872C983CA1BBF3A258D77550407880D497C65E69C331486C1F53BBEEC7A977DD41756FFFDA0008010103013F10AF3BAC2BCC40BCB84CBCE7D470B25AD801AA235CC8C6B5AA655A8D4966DCD0102433D10F3332E738152A42D4BBB0A8CB3C50CD2AE2ED3E23686675C406CBA1D695016607E8763F497F4F4BC317D49C35BB4C132F2A9B416694A9714F55EF8ADDAA50E23B88054AE01982E00BF1FE9666AC46C7564336042B4F4CA8DF264D02B2D3C1D46AC5C84C0B7540283063DE2AD256C8C0AB33DEEE36B8A4C05442AA2C46CABCC71BA2A8745800380DCAD14294589D54A6C9DB74C74D2B87183908BF9AA0B62C9C706B3A97CCE0B25D5D01CD1034CA875772D4D8D64A4186B7C5E83ADCED5A77A56387A9CFF4BF612156B9422242940E80E00C109CFF0031F4A0A01B60BE5507962116A6EC38DD384812EE5F62475199178426E3118C1ACB7D5F35116F20B6D393B8CA6AD6104C135754F8814B7253891B2A8138BB993052EC36F66BEF1E5052A8BD25D022B5759330CB003928EF7A7B4648DF0A14B4DD598DEA1A254AFD15E95DFA2C09000B98315EA6F4D256A976B7CC5907447818589D55917BA6C141101C2E4F7943105C719C2E959583A2768540720E9127631B3CA915ED3740E15BE930660CA40004A038D930B9AD31A3C2408CA1585E002E292EDB3E78C12F4C9A4E9CA5383FF14C00E42C5882AC5AECB688E569E965AD01ACBEC514439D781ECE11A47DE27C309190D633414D8A2638A287F2DE9D393BD653891AEED15BF69BE88F14C883AB9AE193FF0066A5948DF8C71328198AC22F4F2CA8108E30C6428DA34B6D173EC4894395D6C05642D8C73014E0C559165A65AC13832EAC3A87904AB30F22420E5855423B4295F8A848BD8511F59655DE3D6AB35A00BAEAE04847656163B5FC5CA61D6215B8286F9CE894FB9B3926133F130EAA2BC17F1EE2007A3B442B2D73B443034228D736035F146D757044587542ABE0332BE32F2873485B15BFE4DBDD6F8F98A59AE01EABD94E7A82D3E85C94C675FA44D8E42CAE97039388BDF9D32E9716250F97B8502E928A07409DBF06620E5E3E14E3AFDDCC9B49FC70D79995D08560F68D4A9F73F4BACF881566D8A93BC950DA074D9F985507E08FCC35B8058A1C675D7503A11D65129B5A658F700ADBBCB98D71C10BEECD0098E83F600398754210451D5B651047A0021D0FEE3C06621E105C26ECDD59C0D130CEBE079ABC9AF68584C1D1001F632E91175BD942A1871BE49562E38B8A5253C372B64230855C095531D420893A140A2AD10756CAC5E06F556DFC4B735825544CCF2C11A73A894DB097A3AB6A28ABBAE238732E29954B2EA37C7C67F88880E178317CF010B614A29701BAE6BF11C19A67D3C81A1AAD16CC0052D0B7CEDDB056CAC17C5A317B0B5B3031B4CC01938CCB28A38712A67F8000052B488C7C84060F794CBE9F32BB585ADB3CD580E76C21B8E19C2EF3EF72C70CE2254EF9C88DA55090AE30C438CC4AE630A73348C4A26DB0D715CE416A55064A065669C903C220387B000AEF36E7E222A1B754CB59D57B444AC58C952F008470D9AB30E623061A6B94A1938130360333C0A6540E6D4428AC68D4278B6D4141908366D6AE2714F0D00DB05C295DCB40153C8559193DA612ECA50CAAF550558EE21F111AD0A0D23C32C14C731380F058F2B4F76899B3319B2A103CA1DB7344320A0DD198D96882068DB4529BB28A87F562A5AD42A737C0CCA680EB9A7F0163F1DC75194AFBB1F352E11C8BB67DEA2927D15AAE0023FA06603114033A661A1294219A1180ACE0EAECB382C182DA3E11F215790573306ECCE3A223E661935DE19BE4826DF66D0889C37A090B2D41C0154B699C57DE0AA957ABA1D3DC63C9D8250348E5C3B3E4EA2EBF7B042C3A71EF2EC5274DB3EE3ED0A6CD1CA0D617D9FD404A46D0D432510212235AD9774D7A39DFBD5896E2F91F1663EA984AB5481F08CDE4CE23C71FE398E13BE4D34C6C9500324173D9600015EF456D2F292DC35356156AB01F025F51358ECE897B140F4C51D3026426A16894E3B949102D9A0ACA8F9551C085EF001264AA011A0739BAB949120131EA2E836B5C4B5A0C2D44EF2DB5CCCD3F9B978B90978EE3CB6459C85314DF399822CA005E5ABBE639EF5DE614DE28226B0B14D28C844B4225F106EB2809928039AD885E500CA0CE6DC7D0DC007112E404CABE26E162C9713073835C543EC88F685F66668E1E152FB004AE179C592E0323A855834DD6823D32F88CE85000053811EF7114054BD83CB8691036E750959E9091119767374AA35539393B032A2B2E2F78087278181C4A618A64F578C29284158AE186B42DD394157F448C2EE200DE11B6D528D5E2F04716B345AD691995CF72B0649CF824152E357F8A1A68B30D60E1F6EE01A12EBC960FB7DE7165F4945EA540382F263DE0922A7305130F6FF70BA82038AE45E429311393014FD33F2445722D9ECA4524511E95DA42DE40B38950C58A014CD0A3B35A6ABC14FA9354341D8BB70C4A88012C145041A073097008A1083681A65B38E96CD2ABF58E3BC0D62F80CFA41B9A06B7021BA582DAB242E05E59C436303998D955EC82DCB02DA2C2D6F79CC430C53884B8CB44BC97A85C9D54E03DB8A7E6BF8877D0B136BBF8392509511E4D1B78B9BCCB19C726EA55684D68E15C88C2D552D4946EDBFBEAEE0B05BFED435A99A19E9F88A84252762378A74450172A61752B51EE7FE64046C3BC0942EA559380118156BD32B39A0495556F6DAD1C71D621265B402BDCAABE63789D13ED5FCA00BF320FD6E57C8F855F787C05AB38EF367ED14E41D95F998BD3A0839A9C0B581D90AC6510BC656EAA8D4BF334C95F339FA4BAB97FC21BB989DF2DEDCEB31E1AF5F7EB734372F371F15D54799B4C2B46BB6EAA02D06728305E1179BEA06D57DBFC428B4B617DED7DEFCC36228B64111630670412B416296311C591074D9F09D4B6936B472E232537B5D77DCB6117918BE369F796189C2D15B61ECCAEDC321CB1D2FF0062535D259BFD09DCDFBAAAB4B9878C30F1789D97778F79FFDA0008010203013F10441D09B2355562605A0EF98DCE3F6EE146F365ABB610746C7F304CC3E8F4C2987814EC40D17B978F129583300CB12E9326258DA5F3E8EA381A437300EC259C1001896DE200159DC7A2AC2504C20B750350D4711DC956512A67CFA490998A372A311B65323F4152A25C0A9E5E853487AAA2699454E07C7DC9D7FC4D923E22752CC4CD1CE28F787FC48BE25B4884C42C36C601334F6FF63D957E58C36C26982614431BE4298F2C70CAE3F7EF299E1E7F873316A2A599257F425B609820B4B3D117E75D4A94B9CCFE21025CDDB3000CDC54E3BF7F466E88AF11C70FBC9FC10F298263E60B619430DECC4EC4F0CA78333404F024B9B63065DBD4473E63A5E9032CB3B14194257BC5E9CC5A97E2368BC0F2C168BA890B99BC423094CC4C4C2620B52827022A8AE65C1D4ADDE2090082B7684495532CCF272A3787E8CB6EDA0040C4DA54A8912BD3020CD91198CA622D5FB4A123416EE008151D37150D903144AB9824517DFB7994D5AD8CE719622253E94D5C73895E9A80D5CAC6911E434CEF665767AC1531C7A08EA2992E50815363C8F10235A8D0C44DD0BF42748F84454C4B82EE1E20ECE88BED660A6A79752807CF0C71A40974B95054D6E62381AD10A421551A546166A60120111328D2914EE39C304BD91C30D55E07F89B17CBFB99285625E45735F88035983C8B02E12BDE526BE522DB3A3AE6098314DBCFA55425CA081F4F433C438961083B9D8286539FC251F5194B818FE305457FD23767DE81FF00AA604A1E08A56B1B840DBF11D912E5B984F996AA87312344C706A34CCB708C97371C6D4C31A022CCBBCC214F28070DFA2486A263AAAFACD3D6D79F4B71335BEBD1AE655A78C1477516269C3FBCC05416E595DBF30E47F33C9F9876FE625709F7872E5FC7A7FFDA0008010303013F102C23316A11F0C2458AE9E541E079654D08D0553BFA67AF128B4A28C251A7B3C3ABC6728E3494FC7AE01D301A0E6471CD3C7889B4D5B1E0971941E612AE524B4018A95208828A8A633A0A8765DE3C91603748BF8CB7055E8A2807D97DE6D24B7D7110D41701A9BE62430A95E80FD0C6C7FCEF5BA8FA22CC73613CD253B87942308311405E621FF17F24A8114302345CBFC1CCE97F7FA344672AF3FE46F204A24DF7A0B061BF782EAB9350D0B3DF895159100D6225C7E813A26FB11D10F97F897EDBDC775F13862D1DC49AFDF83A3DA5971B8BC02C6EC879775823291A20DB1500A7A36D16CA8BE9B9E32712A772651CB00189AC738131D12A0AB2F3043F282E0DFB4D30964A23F50D69F485681B7A25AE10875E8BC2B3BE241B8A8970F8608E6770287CF70C4BA800D25D59220789908C45C0FCEA1C4BB34F450A306C81515C19751CA8E600DF224CA0CAE3DA1628C733191C855E18A1F11FFD111FC0C7BF0C34D129FEFE626710109841B6714136F490B8C9619F187C4DC86039205625A24B72DCBB8473529021BBAEA27BB5F7EA16050E6295EFB97399472AA5AFBB3683210B2187A12198341BADC12F38FACDA93E83FB96BB3CAD9E497AB08ABCC08ECA81771FBB96445DA8AB2AB64B815580F2AD07CCE62588103D5CB770159A858DCBC71965583304A9B33F481654429DF997BC2531F59B79C0FF0024CAE0F9CFB435AB98829CB8863083B6618375D626BF1D3C4465472EA521C44725E3EF2C20A60C4729B4CC4B92F47A611E908076FE88CAB4F5C3012AA149032E037AFC4FB0A24FA3308A9E521BA1ED8ECAF9AFC45E8B792FE61A0CE5442BE5858880732AC333835302E7225AF3A8D246AF88B507500EBDB886028D939D10558E222C54702AFCCF07EB07008EE562D709AD88FD1B98807A18E7713BCAD1D4A6B18758B2A8A998ECEAE617CDE498B4627171FF00F52FC0FB7F717D3EA45F4FA90E0227057C22F97FB3FFD900')
diff --git a/plugins/dbgate-plugin-mysql/webpack-backend.config.js b/plugins/dbgate-plugin-mysql/webpack-backend.config.js
new file mode 100644
index 000000000..87b665d56
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/webpack-backend.config.js
@@ -0,0 +1,23 @@
+var webpack = require('webpack');
+var path = require('path');
+
+var config = {
+ context: __dirname + '/src/backend',
+
+ entry: {
+ app: './index.js',
+ },
+ target: 'node',
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: 'backend.js',
+ libraryTarget: 'commonjs2',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-mysql/webpack-frontend.config.js b/plugins/dbgate-plugin-mysql/webpack-frontend.config.js
new file mode 100644
index 000000000..db07de291
--- /dev/null
+++ b/plugins/dbgate-plugin-mysql/webpack-frontend.config.js
@@ -0,0 +1,24 @@
+var webpack = require("webpack");
+var path = require("path");
+
+var config = {
+ context: __dirname + "/src/frontend",
+
+ entry: {
+ app: "./index.js",
+ },
+ target: "web",
+ output: {
+ path: path.resolve(__dirname, "dist"),
+ filename: "frontend.js",
+ libraryTarget: "var",
+ library: 'plugin',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-postgres/LICENSE b/plugins/dbgate-plugin-postgres/LICENSE
new file mode 100644
index 000000000..c15ede038
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Jan Prochazka
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-postgres/README.md b/plugins/dbgate-plugin-postgres/README.md
new file mode 100644
index 000000000..b12dfd03d
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/README.md
@@ -0,0 +1,6 @@
+[](https://github.com/prettier/prettier)
+[](https://www.npmjs.com/package/dbgate-plugin-postgres)
+
+# dbgate-plugin-postgres
+
+Use DbGate for install of this plugin
diff --git a/plugins/dbgate-plugin-postgres/icon.svg b/plugins/dbgate-plugin-postgres/icon.svg
new file mode 100644
index 000000000..6b65997a9
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/icon.svg
@@ -0,0 +1,22 @@
+
+
+
+
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-postgres/package.json b/plugins/dbgate-plugin-postgres/package.json
new file mode 100644
index 000000000..25033b085
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "dbgate-plugin-postgres",
+ "main": "dist/backend.js",
+ "version": "1.2.2",
+ "license": "MIT",
+ "description": "PostgreSQL connector plugin for DbGate",
+ "homepage": "https://github.com/dbgate/dbgate-plugin-postgres",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/dbgate/dbgate-plugin-postgres.git"
+ },
+ "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur",
+ "author": "Jan Prochazka",
+ "keywords": [
+ "dbgate",
+ "dbgateplugin",
+ "postgresql"
+ ],
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build:frontend": "webpack --config webpack-frontend.config",
+ "build:backend": "webpack --config webpack-backend.config.js",
+ "build": "yarn build:frontend && yarn build:backend",
+ "plugin": "yarn build && yarn pack && dbgate-plugin dbgate-plugin-postgres",
+ "plugout": "dbgate-plugout dbgate-plugin-postgres",
+ "prepublishOnly": "yarn build"
+ },
+ "devDependencies": {
+ "dbgate-plugin-tools": "^1.0.4",
+ "dbgate-tools": "^4.0.3-rc.1",
+ "lodash": "^4.17.15",
+ "pg": "^7.17.0",
+ "pg-query-stream": "^3.1.1",
+ "webpack": "^4.42.0",
+ "webpack-cli": "^3.3.11"
+ }
+}
diff --git a/plugins/dbgate-plugin-postgres/prettier.config.js b/plugins/dbgate-plugin-postgres/prettier.config.js
new file mode 100644
index 000000000..c05d71875
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/prettier.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ trailingComma: 'es5',
+ tabWidth: 2,
+ semi: true,
+ singleQuote: true,
+ arrowParen: 'avoid',
+ arrowParens: 'avoid',
+ printWidth: 120,
+};
diff --git a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js
new file mode 100644
index 000000000..8f3d92b15
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js
@@ -0,0 +1,185 @@
+const fp = require('lodash/fp');
+const _ = require('lodash');
+const sql = require('./sql');
+
+const { DatabaseAnalyser } = require('dbgate-tools');
+const { isTypeString, isTypeNumeric } = require('dbgate-tools');
+
+function normalizeTypeName(dataType) {
+ if (dataType == 'character varying') return 'varchar';
+ if (dataType == 'timestamp without time zone') return 'timestamp';
+ return dataType;
+}
+
+function getColumnInfo({
+ isNullable,
+ isIdentity,
+ columnName,
+ dataType,
+ charMaxLength,
+ numericPrecision,
+ numericScale,
+ defaultValue,
+}) {
+ const normDataType = normalizeTypeName(dataType);
+ let fullDataType = normDataType;
+ if (charMaxLength && isTypeString(normDataType)) fullDataType = `${normDataType}(${charMaxLength})`;
+ if (numericPrecision && numericScale && isTypeNumeric(normDataType))
+ fullDataType = `${normDataType}(${numericPrecision},${numericScale})`;
+ return {
+ columnName,
+ dataType: fullDataType,
+ notNull: !isNullable || isNullable == 'NO' || isNullable == 'no',
+ autoIncrement: !!isIdentity,
+ defaultValue,
+ };
+}
+
+class Analyser extends DatabaseAnalyser {
+ constructor(pool, driver) {
+ super(pool, driver);
+ }
+
+ createQuery(resFileName, typeFields) {
+ let res = sql[resFileName];
+
+ if (this.singleObjectFilter) {
+ const { typeField, schemaName, pureName } = this.singleObjectFilter;
+ if (!typeFields || !typeFields.includes(typeField)) return null;
+ res = res.replace(/=OBJECT_ID_CONDITION/g, ` = '${typeField}:${schemaName || 'public'}.${pureName}'`);
+ return res;
+ }
+ if (!this.modifications || !typeFields || this.modifications.length == 0) {
+ res = res.replace(/=OBJECT_ID_CONDITION/g, ' is not null');
+ } else {
+ const filterNames = this.modifications
+ .filter(x => typeFields.includes(x.objectTypeField) && (x.action == 'add' || x.action == 'change'))
+ .filter(x => x.newName)
+ .map(x => `${x.objectTypeField}:${x.newName.schemaName}.${x.newName.pureName}`);
+ if (filterNames.length == 0) {
+ res = res.replace(/=OBJECT_ID_CONDITION/g, ' IS NULL');
+ } else {
+ res = res.replace(/=OBJECT_ID_CONDITION/g, ` in (${filterNames.map(x => `'${x}'`).join(',')})`);
+ }
+ }
+ return res;
+
+ // let res = sql[resFileName];
+ // res = res.replace('=[OBJECT_ID_CONDITION]', ' is not null');
+ // return res;
+ }
+ async _runAnalysis() {
+ const tables = await this.driver.query(this.pool, this.createQuery('tableModifications', ['tables']));
+ const columns = await this.driver.query(this.pool, this.createQuery('columns', ['tables']));
+ const pkColumns = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables']));
+ const fkColumns = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables']));
+ const views = await this.driver.query(this.pool, this.createQuery('views', ['views']));
+ const routines = await this.driver.query(this.pool, this.createQuery('routines', ['procedures', 'functions']));
+ // console.log('PG fkColumns', fkColumns.rows);
+
+ return this.mergeAnalyseResult({
+ tables: tables.rows.map(table => ({
+ ...table,
+ objectId: `tables:${table.schemaName}.${table.pureName}`,
+ columns: columns.rows
+ .filter(col => col.pureName == table.pureName && col.schemaName == table.schemaName)
+ .map(getColumnInfo),
+ primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows),
+ foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows),
+ })),
+ views: views.rows.map(view => ({
+ ...view,
+ objectId: `views:${view.schemaName}.${view.pureName}`,
+ columns: columns.rows
+ .filter(col => col.pureName == view.pureName && col.schemaName == view.schemaName)
+ .map(getColumnInfo),
+ })),
+ procedures: routines.rows
+ .filter(x => x.objectType == 'PROCEDURE')
+ .map(proc => ({
+ objectId: `procedures:${proc.schemaName}.${proc.pureName}`,
+ ...proc,
+ })),
+ functions: routines.rows
+ .filter(x => x.objectType == 'FUNCTION')
+ .map(func => ({
+ objectId: `functions:${func.schemaName}.${func.pureName}`,
+ ...func,
+ })),
+ });
+ }
+
+ async getModifications() {
+ const tableModificationsQueryData = await this.driver.query(this.pool, this.createQuery('tableModifications'));
+ const viewModificationsQueryData = await this.driver.query(this.pool, this.createQuery('viewModifications'));
+ const routineModificationsQueryData = await this.driver.query(this.pool, this.createQuery('routineModifications'));
+
+ const allModifications = _.compact([
+ ...tableModificationsQueryData.rows.map(x => ({ ...x, objectTypeField: 'tables' })),
+ ...viewModificationsQueryData.rows.map(x => ({ ...x, objectTypeField: 'views' })),
+ ...routineModificationsQueryData.rows
+ .filter(x => x.objectType == 'PROCEDURE')
+ .map(x => ({ ...x, objectTypeField: 'procedures' })),
+ ...routineModificationsQueryData.rows
+ .filter(x => x.objectType == 'FUNCTION')
+ .map(x => ({ ...x, objectTypeField: 'functions' })),
+ ]);
+
+ const modifications = allModifications.map(x => {
+ const { objectTypeField, hashCode, pureName, schemaName } = x;
+
+ if (!objectTypeField || !this.structure[objectTypeField]) return null;
+ const obj = this.structure[objectTypeField].find(x => x.pureName == pureName && x.schemaName == schemaName);
+
+ // object not modified
+ if (obj && obj.hashCode == hashCode) return null;
+
+ // console.log('MODIFICATION OF ', objectTypeField, schemaName, pureName);
+
+ /** @type {import('dbgate-types').DatabaseModification} */
+ const action = obj
+ ? {
+ newName: { schemaName, pureName },
+ oldName: _.pick(obj, ['schemaName', 'pureName']),
+ action: 'change',
+ objectTypeField,
+ objectId: `${objectTypeField}:${schemaName}.${pureName}`,
+ }
+ : {
+ newName: { schemaName, pureName },
+ action: 'add',
+ objectTypeField,
+ objectId: `${objectTypeField}:${schemaName}.${pureName}`,
+ };
+ return action;
+ });
+
+ return [
+ ..._.compact(modifications),
+ ...this.getDeletedObjects([...allModifications.map(x => `${x.schemaName}.${x.pureName}`)]),
+ ];
+ }
+
+ getDeletedObjectsForField(nameArray, objectTypeField) {
+ return this.structure[objectTypeField]
+ .filter(x => !nameArray.includes(`${x.schemaName}.${x.pureName}`))
+ .map(x => ({
+ oldName: _.pick(x, ['schemaName', 'pureName']),
+ action: 'remove',
+ objectTypeField,
+ objectId: `${objectTypeField}:${x.schemaName}.${x.pureName}`,
+ }));
+ }
+
+ getDeletedObjects(nameArray) {
+ return [
+ ...this.getDeletedObjectsForField(nameArray, 'tables'),
+ ...this.getDeletedObjectsForField(nameArray, 'views'),
+ ...this.getDeletedObjectsForField(nameArray, 'procedures'),
+ ...this.getDeletedObjectsForField(nameArray, 'functions'),
+ ...this.getDeletedObjectsForField(nameArray, 'triggers'),
+ ];
+ }
+}
+
+module.exports = Analyser;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/driver.js b/plugins/dbgate-plugin-postgres/src/backend/driver.js
new file mode 100644
index 000000000..087c9a332
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/driver.js
@@ -0,0 +1,213 @@
+const _ = require('lodash');
+const stream = require('stream');
+const driverBase = require('../frontend/driver');
+const Analyser = require('./Analyser');
+const pg = require('pg');
+const pgQueryStream = require('pg-query-stream');
+const { createBulkInsertStreamBase, splitPostgresQuery, makeUniqueColumnNames } = require('dbgate-tools');
+
+function extractPostgresColumns(result) {
+ if (!result || !result.fields) return [];
+ const res = result.fields.map(fld => ({
+ columnName: fld.name,
+ }));
+ makeUniqueColumnNames(res);
+ return res;
+}
+
+function zipDataRow(rowArray, columns) {
+ return _.zipObject(
+ columns.map(x => x.columnName),
+ rowArray
+ );
+}
+
+async function runStreamItem(client, sql, options) {
+ return new Promise((resolve, reject) => {
+ const query = new pgQueryStream(sql, undefined, { rowMode: 'array' });
+ const stream = client.query(query);
+
+ // const handleInfo = (info) => {
+ // const { message, lineNumber, procName } = info;
+ // options.info({
+ // message,
+ // line: lineNumber,
+ // procedure: procName,
+ // time: new Date(),
+ // severity: 'info',
+ // });
+ // };
+
+ let wasHeader = false;
+
+ const handleEnd = result => {
+ // console.log('RESULT', result);
+ resolve();
+ };
+
+ let columns = null;
+ const handleReadable = () => {
+ if (!wasHeader) {
+ columns = extractPostgresColumns(query._result);
+ if (columns && columns.length > 0) {
+ options.recordset(columns);
+ }
+ wasHeader = true;
+ }
+
+ for (;;) {
+ const row = stream.read();
+ if (!row) break;
+
+ options.row(zipDataRow(row, columns));
+ }
+ };
+
+ // const handleFields = (columns) => {
+ // // console.log('FIELDS', columns[0].name);
+ // options.recordset(columns);
+ // // options.recordset(extractColumns(columns));
+ // };
+
+ const handleError = error => {
+ console.log('ERROR', error);
+ const { message, lineNumber, procName } = error;
+ options.info({
+ message,
+ line: lineNumber,
+ procedure: procName,
+ time: new Date(),
+ severity: 'error',
+ });
+ resolve();
+ };
+
+ stream.on('error', handleError);
+ stream.on('readable', handleReadable);
+ // stream.on('result', handleRow)
+ // stream.on('data', handleRow)
+ stream.on('end', handleEnd);
+ });
+}
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ analyserClass: Analyser,
+
+ async connect({ server, port, user, password, database, ssl }) {
+ const client = new pg.Client({
+ host: server,
+ port,
+ user,
+ password,
+ database: database || 'postgres',
+ ssl,
+ });
+ await client.connect();
+ return client;
+ },
+ async query(client, sql) {
+ if (sql == null) {
+ return {
+ rows: [],
+ columns: [],
+ };
+ }
+ const res = await client.query({ text: sql, rowMode: 'array' });
+ const columns = extractPostgresColumns(res);
+ return { rows: res.rows.map(row => zipDataRow(row, columns)), columns };
+ },
+ async stream(client, sql, options) {
+ const sqlSplitted = splitPostgresQuery(sql);
+
+ for (const sqlItem of sqlSplitted) {
+ await runStreamItem(client, sqlItem, options);
+ }
+
+ options.done();
+ // return stream;
+ },
+ // async analyseSingleObject(pool, name, typeField = 'tables') {
+ // const analyser = new PostgreAnalyser(pool, this);
+ // analyser.singleObjectFilter = { ...name, typeField };
+ // const res = await analyser.fullAnalysis();
+ // return res.tables[0];
+ // },
+ // // @ts-ignore
+ // analyseSingleTable(pool, name) {
+ // return this.analyseSingleObject(pool, name, 'tables');
+ // },
+ async getVersion(client) {
+ const { rows } = await this.query(client, 'SELECT version()');
+ const { version } = rows[0];
+ return { version };
+ },
+ // async analyseFull(pool) {
+ // const analyser = new PostgreAnalyser(pool, this);
+ // return analyser.fullAnalysis();
+ // },
+ // async analyseIncremental(pool, structure) {
+ // const analyser = new PostgreAnalyser(pool, this);
+ // return analyser.incrementalAnalysis(structure);
+ // },
+ async readQuery(client, sql, structure) {
+ const query = new pgQueryStream(sql, undefined, { rowMode: 'array' });
+
+ const queryStream = client.query(query);
+
+ let wasHeader = false;
+
+ const pass = new stream.PassThrough({
+ objectMode: true,
+ highWaterMark: 100,
+ });
+
+ const handleEnd = result => {
+ pass.end();
+ };
+
+ let columns = null;
+ const handleReadable = () => {
+ if (!wasHeader) {
+ columns = extractPostgresColumns(query._result);
+ pass.write({
+ __isStreamHeader: true,
+ ...(structure || { columns }),
+ });
+ wasHeader = true;
+ }
+
+ for (;;) {
+ const row = queryStream.read();
+ if (!row) break;
+
+ pass.write(zipDataRow(row, columns));
+ }
+ };
+
+ const handleError = error => {
+ console.error(error);
+ pass.end();
+ };
+
+ queryStream.on('error', handleError);
+ queryStream.on('readable', handleReadable);
+ queryStream.on('end', handleEnd);
+
+ return pass;
+ },
+ // createDumper() {
+ // return new PostgreDumper(this);
+ // },
+ async writeTable(pool, name, options) {
+ // @ts-ignore
+ return createBulkInsertStreamBase(this, stream, pool, name, options);
+ },
+ async listDatabases(client) {
+ const { rows } = await this.query(client, 'SELECT datname AS name FROM pg_database WHERE datistemplate = false');
+ return rows;
+ },
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/index.js b/plugins/dbgate-plugin-postgres/src/backend/index.js
new file mode 100644
index 000000000..4a2c8d0cd
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/index.js
@@ -0,0 +1,6 @@
+const driver = require('./driver');
+
+module.exports = {
+ packageName: 'dbgate-plugin-postgres',
+ driver,
+};
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/columns.js b/plugins/dbgate-plugin-postgres/src/backend/sql/columns.js
new file mode 100644
index 000000000..841eda6b9
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/columns.js
@@ -0,0 +1,19 @@
+module.exports = `
+select
+ table_schema as "schemaName",
+ table_name as "pureName",
+ column_name as "columnName",
+ is_nullable as "isNullable",
+ data_type as "dataType",
+ character_maximum_length as "charMaxLength",
+ numeric_precision as "numericPrecision",
+ numeric_scale as "numericScale",
+ column_default as "defaultValue"
+from information_schema.columns
+where
+ table_schema <> 'information_schema'
+ and table_schema <> 'pg_catalog'
+ and table_schema !~ '^pg_toast'
+ and 'tables:' || table_schema || '.' || table_name =OBJECT_ID_CONDITION
+order by ordinal_position
+`;
\ No newline at end of file
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeys.js b/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeys.js
new file mode 100644
index 000000000..fadcf5e78
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeys.js
@@ -0,0 +1,24 @@
+module.exports = `
+select
+ fk.constraint_name as "constraintName",
+ fk.constraint_schema as "constraintSchema",
+ base.table_name as "pureName",
+ base.table_schema as "schemaName",
+ fk.update_rule as "updateAction",
+ fk.delete_rule as "deleteAction",
+ ref.table_name as "refTableName",
+ ref.table_schema as "refSchemaName",
+ basecol.column_name as "columnName",
+ refcol.column_name as "refColumnName"
+from information_schema.referential_constraints fk
+inner join information_schema.table_constraints base on fk.constraint_name = base.constraint_name and fk.constraint_schema = base.constraint_schema
+inner join information_schema.table_constraints ref on fk.unique_constraint_name = ref.constraint_name and fk.unique_constraint_schema = ref.constraint_schema
+inner join information_schema.key_column_usage basecol on base.table_name = basecol.table_name and base.constraint_name = basecol.constraint_name
+inner join information_schema.key_column_usage refcol on ref.table_name = refcol.table_name and ref.constraint_name = refcol.constraint_name and basecol.ordinal_position = refcol.ordinal_position
+where
+ base.table_schema <> 'information_schema'
+ and base.table_schema <> 'pg_catalog'
+ and base.table_schema !~ '^pg_toast'
+ and 'tables:' || base.table_schema || '.' || base.table_name =OBJECT_ID_CONDITION
+order by basecol.ordinal_position
+`;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/index.js b/plugins/dbgate-plugin-postgres/src/backend/sql/index.js
new file mode 100644
index 000000000..7cc2141e9
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/index.js
@@ -0,0 +1,19 @@
+const columns = require('./columns');
+const tableModifications = require('./tableModifications');
+const viewModifications = require('./viewModifications');
+const primaryKeys = require('./primaryKeys');
+const foreignKeys = require('./foreignKeys');
+const views = require('./views');
+const routines = require('./routines');
+const routineModifications = require('./routineModifications');
+
+module.exports = {
+ columns,
+ tableModifications,
+ viewModifications,
+ primaryKeys,
+ foreignKeys,
+ views,
+ routines,
+ routineModifications,
+};
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/primaryKeys.js b/plugins/dbgate-plugin-postgres/src/backend/sql/primaryKeys.js
new file mode 100644
index 000000000..204ff8478
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/primaryKeys.js
@@ -0,0 +1,17 @@
+module.exports = `
+select
+ table_constraints.constraint_schema as "constraintSchema",
+ table_constraints.constraint_name as "constraintName",
+ table_constraints.table_schema as "schemaName",
+ table_constraints.table_name as "pureName",
+ key_column_usage.column_name as "columnName"
+from information_schema.table_constraints
+inner join information_schema.key_column_usage on table_constraints.table_name = key_column_usage.table_name and table_constraints.constraint_name = key_column_usage.constraint_name
+where
+ table_constraints.table_schema <> 'information_schema'
+ and table_constraints.table_schema <> 'pg_catalog'
+ and table_constraints.table_schema !~ '^pg_toast'
+ and table_constraints.constraint_type = 'PRIMARY KEY'
+ and 'tables:' || table_constraints.table_schema || '.' || table_constraints.table_name =OBJECT_ID_CONDITION
+order by key_column_usage.ordinal_position
+`;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/routineModifications.js b/plugins/dbgate-plugin-postgres/src/backend/sql/routineModifications.js
new file mode 100644
index 000000000..879a1195c
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/routineModifications.js
@@ -0,0 +1,10 @@
+module.exports = `
+select
+ routine_name as "pureName",
+ routine_schema as "schemaName",
+ md5(routine_definition) as "hashCode",
+ routine_type as "objectType"
+from
+ information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog'
+ and routine_type in ('PROCEDURE', 'FUNCTION')
+`;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/routines.js b/plugins/dbgate-plugin-postgres/src/backend/sql/routines.js
new file mode 100644
index 000000000..80c189604
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/routines.js
@@ -0,0 +1,15 @@
+module.exports = `
+select
+ routine_name as "pureName",
+ routine_schema as "schemaName",
+ routine_definition as "createSql",
+ md5(routine_definition) as "hashCode",
+ routine_type as "objectType"
+from
+ information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog'
+ and (
+ (routine_type = 'PROCEDURE' and ('procedures:' || routine_schema || '.' || routine_schema) =OBJECT_ID_CONDITION)
+ or
+ (routine_type = 'FUNCTION' and ('functions:' || routine_schema || '.' || routine_schema) =OBJECT_ID_CONDITION)
+ )
+`;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/tableModifications.js b/plugins/dbgate-plugin-postgres/src/backend/sql/tableModifications.js
new file mode 100644
index 000000000..b34bf292b
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/tableModifications.js
@@ -0,0 +1,52 @@
+module.exports = `
+with pkey as
+(
+ select cc.conrelid, format(E'create constraint %I primary key(%s);\\n', cc.conname,
+ string_agg(a.attname, ', '
+ order by array_position(cc.conkey, a.attnum))) pkey
+ from pg_catalog.pg_constraint cc
+ join pg_catalog.pg_class c on c.oid = cc.conrelid
+ join pg_catalog.pg_attribute a on a.attrelid = cc.conrelid
+ and a.attnum = any(cc.conkey)
+ where cc.contype = 'p'
+ group by cc.conrelid, cc.conname
+)
+
+
+SELECT oid as "objectId", nspname as "schemaName", relname as "pureName",
+ md5('CREATE TABLE ' || nspname || '.' || relname || E'\\n(\\n' ||
+ array_to_string(
+ array_agg(
+ ' ' || column_name || ' ' || type || ' '|| not_null
+ )
+ , E',\\n'
+ ) || E'\\n);\\n' || coalesce((select pkey from pkey where pkey.conrelid = oid),'NO_PK')) as "hashCode"
+from
+(
+ SELECT
+ c.relname, a.attname AS column_name, c.oid,
+ n.nspname,
+ pg_catalog.format_type(a.atttypid, a.atttypmod) as type,
+ case
+ when a.attnotnull
+ then 'NOT NULL'
+ else 'NULL'
+ END as not_null
+ FROM pg_class c,
+ pg_namespace n,
+ pg_attribute a,
+ pg_type t
+
+ WHERE c.relkind = 'r'
+ AND a.attnum > 0
+ AND a.attrelid = c.oid
+ AND a.atttypid = t.oid
+ AND n.oid = c.relnamespace
+ AND n.nspname <> 'pg_catalog'
+ AND n.nspname <> 'information_schema'
+ AND n.nspname !~ '^pg_toast'
+ ORDER BY a.attnum
+) as tabledefinition
+where ('tables:' || nspname || '.' || relname) =OBJECT_ID_CONDITION
+group by relname, nspname, oid
+`;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/viewModifications.js b/plugins/dbgate-plugin-postgres/src/backend/sql/viewModifications.js
new file mode 100644
index 000000000..a74c01a3f
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/viewModifications.js
@@ -0,0 +1,8 @@
+module.exports = `
+select
+ table_name as "pureName",
+ table_schema as "schemaName",
+ md5(view_definition) as "hashCode"
+from
+ information_schema.views where table_schema != 'information_schema' and table_schema != 'pg_catalog'
+`;
diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/views.js b/plugins/dbgate-plugin-postgres/src/backend/sql/views.js
new file mode 100644
index 000000000..8d18ee557
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/backend/sql/views.js
@@ -0,0 +1,11 @@
+module.exports = `
+select
+ table_name as "pureName",
+ table_schema as "schemaName",
+ view_definition as "createSql",
+ md5(view_definition) as "hashCode"
+from
+ information_schema.views
+where table_schema != 'information_schema' and table_schema != 'pg_catalog'
+ and ('views:' || table_schema || '.' || table_name) =OBJECT_ID_CONDITION
+`;
diff --git a/plugins/dbgate-plugin-postgres/src/frontend/Dumper.js b/plugins/dbgate-plugin-postgres/src/frontend/Dumper.js
new file mode 100644
index 000000000..fb86e4c42
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/frontend/Dumper.js
@@ -0,0 +1,66 @@
+const { SqlDumper } = require('dbgate-tools');
+
+class Dumper extends SqlDumper {
+ /** @param type {import('dbgate-types').TransformType} */
+ transform(type, dumpExpr) {
+ switch (type) {
+ case 'GROUP:YEAR':
+ case 'YEAR':
+ this.put('^extract(^year ^from %c)', dumpExpr);
+ break;
+ case 'MONTH':
+ this.put('^extract(^month ^from %c)', dumpExpr);
+ break;
+ case 'DAY':
+ this.put('^extract(^day ^from %c)', dumpExpr);
+ break;
+ case 'GROUP:MONTH':
+ this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM');
+ break;
+ case 'GROUP:DAY':
+ this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM-DD');
+ break;
+ default:
+ dumpExpr();
+ break;
+ }
+ }
+
+ dropRecreatedTempTable(tmptable) {
+ this.putCmd('^drop ^table %i ^cascade', tmptable);
+ }
+
+ renameTable(obj, newname) {
+ this.putCmd('^alter ^table %f ^rename ^to %i', obj, newname);
+ }
+
+ renameColumn(column, newcol) {
+ this.putCmd('^alter ^table %f ^rename ^column %i ^to %i', column, column.columnName, newcol);
+ }
+
+ dropTable(obj, options = {}) {
+ this.put('^drop ^table');
+ if (options.testIfExists) this.put(' ^if ^exists');
+ this.put(' %f', obj.FullName);
+ this.endCommand();
+ }
+
+ //public override void CreateIndex(IndexInfo ix)
+ //{
+ //}
+
+ enableConstraints(table, enabled) {
+ this.putCmd('^alter ^table %f %k ^trigger ^all', table, enabled ? 'enable' : 'disable');
+ }
+
+ columnDefinition(col, options) {
+ const { autoIncrement } = options || {};
+ if (col.autoIncrement) {
+ this.put('^serial');
+ return;
+ }
+ super.columnDefinition(col, options);
+ }
+}
+
+module.exports = Dumper;
diff --git a/plugins/dbgate-plugin-postgres/src/frontend/driver.js b/plugins/dbgate-plugin-postgres/src/frontend/driver.js
new file mode 100644
index 000000000..425f6a6a6
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/frontend/driver.js
@@ -0,0 +1,27 @@
+const { driverBase } = require('dbgate-tools');
+const Dumper = require('./Dumper');
+
+/** @type {import('dbgate-types').SqlDialect} */
+const dialect = {
+ rangeSelect: true,
+ // stringEscapeChar: '\\',
+ stringEscapeChar: "'",
+ fallbackDataType: 'varchar',
+ anonymousPrimaryKey: true,
+ enableConstraintsPerTable: true,
+ quoteIdentifier(s) {
+ return '"' + s + '"';
+ },
+};
+
+/** @type {import('dbgate-types').EngineDriver} */
+const driver = {
+ ...driverBase,
+ dumperClass: Dumper,
+ dialect,
+ engine: 'postgres@dbgate-plugin-postgres',
+ title: 'Postgre SQL',
+ defaultPort: 5432,
+};
+
+module.exports = driver;
diff --git a/plugins/dbgate-plugin-postgres/src/frontend/index.js b/plugins/dbgate-plugin-postgres/src/frontend/index.js
new file mode 100644
index 000000000..c7606431f
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/src/frontend/index.js
@@ -0,0 +1,6 @@
+import driver from './driver';
+
+export default {
+ packageName: 'dbgate-plugin-postgres',
+ driver,
+};
diff --git a/plugins/dbgate-plugin-postgres/test/testdb.sql b/plugins/dbgate-plugin-postgres/test/testdb.sql
new file mode 100644
index 000000000..ccd36c610
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/test/testdb.sql
@@ -0,0 +1,23 @@
+DROP TABLE IF EXISTS "ValuesTest";
+DROP TABLE IF EXISTS "ImageTest";
+
+CREATE TABLE "ValuesTest"
+(
+ "ID" SERIAL NOT NULL PRIMARY KEY,
+ "col_nvarchar" NVARCHAR(160),
+ "col_int" INT(160),
+ "col_numeric" NUMERIC(10,2),
+ "col_bool" BOOLEAN
+);
+
+CREATE TABLE "ImageTest"
+(
+ "ID" SERIAL NOT NULL PRIMARY KEY,
+ "col_image" bytea
+);
+
+INSERT INTO ValuesTest (col_nvarchar, col_int, col_numeric, col_bool, col_bit) VALUES ('value 0', 0, 0, 0);
+INSERT INTO ValuesTest (col_nvarchar, col_int, col_numeric, col_bool, col_bit) VALUES ('value 1', 1, 1, 1);
+INSERT INTO ValuesTest (col_nvarchar, col_int, col_numeric, col_bool, col_bit) VALUES ('value any', 1241, 14.56, 1);
+
+INSERT INTO ImageTest (col_image) VALUES (X'FFD8FFE000104A46494600010200006400640000FFEC00114475636B7900010004000000500000FFEE002641646F62650064C0000000010300150403060A0D00000A63000010E8000019F4000027A4FFDB0084000202020202020202020203020202030403020203040504040404040506050505050505060607070807070609090A0A09090C0C0C0C0C0C0C0C0C0C0C0C0C0C0C01030303050405090606090D0B090B0D0F0E0E0E0E0F0F0C0C0C0C0C0F0F0C0C0C0C0C0C0F0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC2001108006E00AF03011100021101031101FFC400E800000104030101000000000000000000000503040607000208010901000203010101000000000000000000000203000104050607100001040103030401030403000000000001000203041110120520211331221406303223154133250724341611000200030505040704080701000000000102001103213141120451712232131061810591A1425262231420C1723330F0B1E18292B234D1F1A2C2D24393241200000503040301000000000000000000003001112120403110501222410232611301000202020103030501010000000000010011213141516110718191A1B120F0C1D1E130F1FFDA000C03010002110311000001EC3E66DE66CE0DDB4FD476C69EAF0BA3DC4DAF2FD20EB7CCD681E948BADB53974AC46A2178F553DE7280A568326F76E124494661F4B40EB6F59C9135685C38755FABA9C89CDF6B267E0ED1DDE21CDAF2E46C4A38FD872EE16AD54279AB85E414CAC7B2DC09375DAB54B507D17F65C6C9324F6E654C9324C93C93DB952D3646DD3E4A6F194871F455FCB3D2AC5558049B308B10BE88FA3BEC39046EB24C9324C9324C93248E2DF5BD6C96E958D160807263548F1DB5CE178851B796A9D081E615C19FE86FB4875A87760A90FB2649A0DB51646336BA8B27509EFC8C0CA5ED134684408625B0CCCF10323C12A5C7511C182D6E6F57A4BDAF375022D624AC5C4A6C251D53E148D7071D0B38263D0E72F6E91C3E77F3DEBA0187A8396FF4E1C359C66784EBF1B30E4A0C73D9D1FEFF00931A1B182D6744344C7D10D13640C771920808ED45A4EAE69F29EE2969DE1AF3B08B14753A0711CA495B1F93B0F8DC4268BE90F79C58C8D85AB130C551B084D166929C621CA1D9E37A6F6E2FA2E6DE6FB001A9C91510B5D9ECC751AB6958B611135C7E1EC0E5BFAAFE85E5A309B0B0C44B154C428DB81E0B0D18DC5D0E7560BD7CEFE57DFD757DE62DAF60EB77BDAF7259334AE6A885653290FA7FEB3E62090C4C24696D4288229A285A9D11221B177E11EBDB42E0F4143F27D88CBD09332129180B5A1A3094848909BB067D5AF5DF1C6EB81E16956DA44EAE038F43923936851460AD2A87E57AA129D754A3A8C036B24696A7684192B33F869416134D3C6EDCF45E14C02E1C6C36228541F4CF60C629E56A3D91894E6AE5FA5439FDAD964BB89D184685CEAE8F9E71CB60CCDA0DE9E6F64FA4F9F0C85BDD28337AA670811316A882DAE2E87DDD358BA94EE0EFADCCEDA39DCAB45D315E4A484DB2D8E4D72DEEF98ED4EBF8B1D716905AD8B4ACB85EC01939094981B2BAE47E37A28F67DC217D68A61EE3B30D2EBCBA56EB6926FB3892EDDC3FFFDA0008010100010502E4EBBA4AF3C4D134A3626F1B7AD55FB3F3527D6380E4677D2ADF58E767FADDE8E46CACD398693C7F2BF5BE339F15DB38ADCB1CC1363717273C806D809B36147C86145CC4DB9DCBE64C052D0A9391C5D04D63183ECDF5D83EC9C73FFD65F63649C7FF00ABB90F99144D863D39899B5B89E3237C3C6FA2BB039E2CE4344B95238BDAF39779D4927664CF0BCCD7B3F173C7F92B01F95929F1EF5CD52304AFA16A479E3EE84FA3794ADB109F2E136505794E20B50D8FC36ED3C36092BC6985AE6CF7638899EE58069CE5BCAF1B2432399B53DA9966D5722F0B0AECD523745565F8FE786491B295BDBD05C0274ED0AE723142DBBCABAC9A6CDD0FCF99D3C14618DBB8045CC538E3E512D0FAD4A9FC07012A9FE94D9472FC1DDE0A1E2299711186B677E248EFCB126F30D4DE56AAFE56B27F2F50297EC15D8ACFD8A7914966494C5DCDBE44F1BC4F154BE1D7E4AFFC282FFDA2E6E9B9FBB223C95B726F313B1B5EF58B0D8F92E4ABAFB0F3373937556889BB9591FB8F28BD3A44E94A7CA9D22DC98A11DF903E4E545A6D6ADCCF2D35974B2B9C557AF0CD44B1D2337CB5DF07312B572AE8A49602D737B2B3FDC913D3D39393820144D55DAE0B9D7FC4E67EC1C8358DB5397B89D2AD975499F4E1B1C7EFCBFE47B8B7CC38BE4C2F3B0AB2C7191E14813DA56C28B11620C5137BB61AB141F68A8DB15B969E574AF39450EE3D56E7B14514B3282FCF564E479417220F21CDE4AEB5A62B4D5F24B5D6A932588420835D8A588B1CE8D062635548248E1E4A2F2D5E4F8E6D98ECD596BBD9812BE230D9B354D4B73C12577C67F7266491B9CE696B46508C95E43E4B75C491536CAC5256638FC5187578653244637C553728A0898BDF23DCD0E6D6B31BE4B35DA55CE132FBBC7D835F95DD2436EF41721A0DACE2E8A32BE0BEDB7F847EE8B898990CAC21EC76F6C9BD93319BD9FA4420992591813F3BA26FB429243BBEC7567A9760E48588FDAE921E56E51966E5AB4C1DFF009F72AF3F0555E79DAEA6E77909C44EF73642E6D86FEE47278DD6A3DE22F68DBB8C8CDED7537B5C611B236E0CFDA3970D64DCDC6FB17EAFF1B71B3EE06C32478DA578EB95E2AA9CC856435424CB21D8A6FD6EC23E877E5BE74376FEDF1D9E9EC526C530ADE1E636FC993FEAC5B97FC8CE7945FE517F9343F9444DFC70DA7FFFDA00080102000105027B501DC85E3241F63507ED39D4A2DCE93FA3B5C223404ADE74C2C68F6EE4617042158D4EAE190F1AEED31A63F3CCC458578CAD851042CACADC3F1176130E99D0B72A48F0B6E81C420FCA700B0B2B3D594E916729BE9958D328BDAB31ADB1946B829F096A7232649D3795BD7917911951712B1A37D1A148FDA1F69C512E2B0B6ADA50DC107922670EAC2C2C6A11F42EC09642F2D1A6DD30B2BFA4C3BA3D47560EF22B32A637A0B7B2C2F453316111F80040613CA95843C74808144E85835731616163A1A148DECE6870734B50EB3D18585844656106203A09C2D80A2D3A1282CE9B50C7E495B82E4C3DFCA42F205B9AB73579423315940E47E3749DDE308B70B72CAECBB2256534171DBD87E1EDA58FD43D0AECBDABDABDABDABDAA1C69FFDA00080103000105020ED72A9D7F9123C6C6CF4D92B1C3074614C94847D51EAC2C69959D2A5A3039BCA4443F956E1CEDC741AB7A31F9DA350EC7463528FE26B328B71A06656D016421A616D0B6A965C20C2B6A2D58E9DA99120CC27A6B517E98418E5E37AC3D79084E9BB451AC6BB178D78D788A1121181A15EA5EA18B798E9B536B342F105E208C61181855F8430B074E565656752A319219B9D5E00D40684F75EA8B17211F61F806AF2A12A9C49ADD5C32B3DD654AC0F6EC20EDEB1A651254632A9B83988A1AB8A2347B37AF169840E9959E82EC985D8746E31BA199B202B2B3900A27567747034051D32B38595B913A8F468CA6592D4D91B96A6B709C1611700BCF84EDC5DD27AAABFDAD6A93F4981AE02B90836508B252BE33936AB023D93863AC159E88E3F6C32640F70D8B0565CB2E432B6A79D80BFBFE1EEBBAA9FA7FAB33D76B3A7FFFDA0008010202063F02BC9DE6445A458C55218D7B66B6936099136AC2475B8C0C0C0C1FC54A6B7FFFDA0008010302063F02A27081BD507E86A1BC1EFA750FBCB20731D6B9D1ED518E62114E7219436C6E822D7920741DC669C8EA1D7263510AA83E87D09F65D64CE49929EDFF00FFDA0008010101063F02AF213F96D60DD19189A672D931057A641F695AEDE0C1A1A5A072E79A33599B74E293E9D65ADD44A969F35A158DAC4EE851A14CD57CCF4DD4D66A5AD2E6A4F3485C251A02287D3E93CC55535D41ADCC0192D559F1084A88668E26A7B754EA26F469B544DEA2714BCD943E9FCD3A4B5343AD46E5696649A34D48F08A0BAA75ABAA14D46A2A2890679711037C0F81E09ECB3085CF5002E6437EC89E689030C0A4917DAB2DDD0B3E5174EF9F666A9411985B3947F6A965B2944954281808FA3A953A1569B7534D5EFCADDE364044D4E9AA209F49C3B593EE2B6452ADE6DE614DE8AB035169166632C26D284A4962531251DBE65A87E5A3A5AAC7C14C79751A963D2D352471DE1003D9552CC847CB18CE1E5788BEE82B32B3F68586118DB92D5EE3B62D11C17C4E766C31D49F0ADA0E167E8E8793536969A9BA6A7CE1FE1539A9D1FE32267BB7F6EC30C40E0ADCBBF18CF4B4954CC5AD90CA38A905DEE9FF002832D3B34BDD21BFA498F9945D06D6523B2D1197D8C441E9939979E9BA9471BD5A47F42C9A66556F6F52DCA9BB69FD7BA1A9D207206CCD50DACECDCCEC71262686621917E6D65136A6BECF7B9B946F8F92B9A78A9E9D3FFD08CC7F844716A7A350F3350591FE66CCD07AAEF59BD977626712EC26857A94BF0311046B34E959AF1593E5D4F12A247C4422E89EA5466E7A751790EC983C5EA8AB51E7D52A4AA6339471F0554E47FDF16F177C5F2FB1699459C507AD5028F705F19138688B962A36218454D0689A597FBCD58FFAFE04F8CFAA1465B14E614C998CDEF19F337798B4C5AE137C65D45547118EF5631C1A8A94E7DF04E87CC15FE178A9A9D52008CD955B34C16C251F52F6BBDAB046D129C3458D31B23E62C620C7E718B6A93072A13B208A47A63BA26ED32604546A5FDE6A9FA3A41F111CDE114A9F33CF3D56C59CDE6198101B02DB60CAB112D96448EA180F447E7B7A6245986C9E305A95504ADEA6C3135CFDF94CE3CBFCBEAD46E9062EC97714003012EC6FB17FD911E5FA76E5D321AD23F17F943EA585A01C820BD47B4F2AE0076BD6A673550B6A2CEC6EFB63A62B639A4C25EBB62F34DC6C895651506DB8C7966AD4D932BE9BA04BC7B1BF42CCAB99C0F96BDF1A4AAF757D2B229C33A5A2134E9CAA8334A0F6AD45B56EA94F065D915ABE92A75594F569627BD0C677E3B78BBE32F4688960CB15180C8AA2765CA677C74EAD8EBC2EB19834C6D86E13E8EDBA2EFB0A2E04DA611688E2B0B3FBDE31A632E2A55785BD7F744EA5E40FB1283958A871C5237C37490D428B9980BE0D4A8895E763AD6133677DF6453A54687D2A4CB5645B98E18080F94671EDDB05455B0DE2422A4D81A865282B5E92D495F985B1F53A31F8E8FF00845A2DC62E8CA7C3EC67AC72AB7E521BF7C3FC0438F08B049AF53DF192AACB61C0EE84CDCB98669EC834AA83256B7BC40A2E66848937C2D069D4B089C2DAC0319365BE46F808C99325CA409C8DA337EF85013295E669CE7D8632B5BB218E5F98A384E313B95B082C2C0701072FA4C0A4E264581B6435337A9946673946CC604904F69B626E730864373020F8C56F2CD59C95A9B1142B9BACDB0F475148348F123081F466D7325A2C71D818FDF0AF5F4EF4355A4196B071CCA310718F2FD4133CF472B6F1099F4D2D6280A6B86B0F843AD5D2D5D5B9E5A74C7EA60E97E9D69D336297CD5186DCAC16174B4F474D0ACB3EB29A939945D9719ED8BBA482C0A6D7F1C22A2E2C84587F69869C03E9870703C3BB081BA0CF08CDB2F86C85733893D93F5F603D924C2F3035817E4D694AA0F785E0C04A9CE97137CA16466030FDB1528AD77E95362A00D80C7FF479669758CD633BD255697E2494717902A9F82BD61FEE8EAD0F2529545CDF5157D6271C3E55A7B394BA9A9FD64C65150504F769009FB2335462619828016F261A24794C4C732C2CF011286A23E58C76C364E24494DF7C4B1DBD83DEA8722FA270CE7D81387F2EF33A2ADA1AEB26AA27359E319695515E81E3D36A05A194EE89F75B05B309B45F16D7FF00498FCF6FE58E0666F0946C85A69693EAEF85A62CA62C9E3BE1A38A5E3D965D1C3F741CDCD8C3FE2E3DD0DEB8B21337BDC1BE462AF55C84CA736EF442DB3E0FBCC0152C59FC86EFC44196CB638413BE2C53EA8B9E3DB8B9E3E72F06315E5F992B7F0F67FFDA0008010103013F21714B51FB3D4C67326CBEF1B83452415903A0AB29BDD2B356B35E770E3E1085A8B4ED46AFC434807986FD79E8B95555BD92F98BBA73E2AAA97DC1F51E4337B47F12D9D3AB40C311ABFBA513C4768E80610AF83E6E79921F6996BB971A6963D449038DACA169F4816CAE6D4FF260994D0E3504A8638AB3D0CE2BA9640195F634458A4B3A8716147CAAB3DC1D6715158BEF30469805460EA466195C168C24A905A92368151BCD8F2B153558BF885FD0F58347ABCA1737C2F9860785AFBE046A08C3BA578B25FCCA5AAB697C47CACBB5C76770D1CCC884B3E8743CE6160DDCD46C963DCA0B6C793F30DFD7E69E4FF9B9E8519C7F7340E0F844B2732CE67668E6553D2CD55F4134CA823F252A7C2257B83344D337EC22740FFE449006A9F012F4C1E7995D0161C9FC54248ABCA4E9000F0D67FE261118B65CD3EDE8E7B67E7325AB4B28CC3D77D303A4A50029626BC85EC3049DA3297591F1BEF287DD7ABE2F4FACBC196D72F0AE2677494DCC09DEC7DC1958A3045DE0BE5DF30CB3E3070561ADEDEC9703A970C0E655D0D0B09666BF22563575DFF507E3E0E3F468DF733932F1AFACECB53E5E18BB34C1CF5739CC07DABFD983EA3156FAB30FD0DDCC4FDAF22E6D724F278A8D3C17A2294AADDEA0903C86A9F0CD951D455B58C157F32808F087DCA835647744D07C7136F659C03957CC283965EE8BF03F130FE412B065E522295FA2A94F0FCB3E8D5B9EF6133C5348CC40965AB301DB3219E1BCE5E0E7DEA166B39E55B47B6292FC6665A0396288D74627EBB65824B603FCA5A5A1CEE64BE20B36707CA2F10A721E63776DDA7C444677F262D3C1708DA294BCFB5FE0955C73D1ED25B2E975965F4841948345AC3F643A7608C550686240DD5C56012D15E3AB2D7CDEBC4D009514DD55D204436356739E254F41FF00F197BF4AEE88FD08CBD97411D23FB3F827283730B89607D05B8AD4E74E0D2F05F8CCB4F5EDC8D7E6ABE6534EDACAA5B2CAF9974DC38B996C6D410E9D1844DDCE3822B726C16BD988212A2704305ED073C40A24117680067B87BD03412B9094B05CA3411607D72E89BCE6291C349F68AF3FA7A8E7D435AD41B68EE72A69E58738D7766804D40CE784AAB3E92C2BCC507459C40500B5C01018A7C18074D6E3A544C800E436E7A9790745671DB1FDAA1912682DD5B1A2007B364FBE6A5330E84CAF6007E6036E1657C7B4B43F0020F1750162D63CA770238161C7BC6F5F23FDC55D22BB1D32CE21DC096524BE33F02099BD43B7FD4BE6CE9E4E4F91E49939B92C876A63F1EE46599524B29BB767B92E149ECAB3EF4C20ED87AB1E3DCA6301425FA7801EE4BA975894D032FED8950FCE726D71A3E3D2088168B62F692A09E2E64DAD1F4CD798237A79BE5C6311485B72C02CBE58E8468DCF2C37C4CE6BDF9AE7E62D50BAE4FEA5F985BD8B3DE535D4E15E7CC117E9D0A84E5D7D64C0FCF716C115C64E7FD817EAC18178B4E7FF0052CE08815ACD4F70CC91882F3DBF23F696BD8E3236B5DB330E2BEC1DA58F8968E698FF0002293811E751D354B91814D1CBF339EE9217072F45EBED2BBE9686CDD16FD2BC4C5CE3F04EE5D7BA5D36AFF7B3160F057DE558F708A1682AF795AC535127C1A651534E4967218E9A97980F90C7E0DED00ABA0B57006B0AD278BC9E38E22D68CDF202FEB2E983ED28AA7091F5717B5F2316759D0FD17284E2998AE4D92532ABB023DE1FDA5AB1C552BE24DAC85DB6AB0E8136378D1E63349D7E09903BFC7994657F70EA6233006BC11043973ED298D837E5E6C8301224C17C261991F7C6F1730155D37CD93F4198214BD3477027488144A5BC0F264DCB6AE6A9D99C2CD3050E0B57930C655B5A0F3F316E55D99FEA7313C12FDBFF00B8032BC581F99CCAF26234272DE9CAF69B93EF90ED799C6DE3F04D35F0C2537C33372E9532BF547E604E057DDC399DAEA936D3E272D5FB07C5C5D94B25E39694028D0CF8C0CCF112799EA7EF89EC56F8453ED423C4FC7FA97FF9BFB9EDFB62E0BF48CCA391AF8E66BD5539EFF7DCCDCFFFDA0008010203013F214CCA3D16008E8A9858DEE4A4BF5ED730824C2150BFA75D421B997713D149504D443132C107EAC65F41823519494CED0952BF557A73FA2B62F8F458F0108210C7FC822CB611ACB589CA343488CE4A0689B1A46EDE8FCCF385A5FE8B23246E5A4C58C10A7A248DDB15F49B2413319CE88BE0F45A4A279CAC4C5E3D38922A8E4837446A366CBF7070F48AD784254951F4A95EBBEBC99840FA6809E95A851E8112ED136F8827FC07D609C5F40F42036F4BCB84A9622FEA7D40188055EA38FA20A811F41F41080CC5545B2A5F72CCFAB69E81E8F5996454BE111AF42A566A2543D70972A25C292929061772DDC125FA76A6A6447F8884327A5917A37A26D98698F4E7D398FAB065FA25BC469ED0E0C0966C33F6D81FFA9D0237C4CA5C56A1E8465C2312557A1297A20AAE25DB217819EE97DA0466B1027E88FA139FD0C4A4764F295E95454D7A1D1E9FFFDA0008010303013F21C5E970804F79E65FF840713123130C565B3D6866659E929A6A07307E83D11E8BF52E50E58EE5B1B3E20551BF31916DF5DBD08B1E84A8454A951FF9D9FA20DCA95E8A95E84113FE2914EA546CB886D7FB1E29484031F49E41156B71EBE85BF4541B118466D05382332A0E700874CA764E0210EB72D6DB95A844195E25A5E10EDF4EC7A130C5C7A3D6D4E1A07C45982D9372432E529257A8C20F4081FD114A901A251E8A67399881751BC17D350F425FEA6395B2DCE507AD08548CD4A7715734125B2117E87A0C3D171710C62D6CCC3C9C6FDE11D1163D1F449949369DC054B2784AF0CBF417972E5CD47A47D7D9DCB47D1C9E92D2F612E3D0DEA370C62DF3125115CBF45BD559000975997A7CD361A660CE3B8FC041B22AF11FDA7699163150B62225F0E883184D4DCD207A54A9505ED20B925EDDC04A667E53269BED260DFB65D0645CFBCA8A258393C423063E9703D47A3B7E12E70C650CC4944A389E296EE1056457F478988C37E998431693AC502D45F12FC4BF12FC4B62C6F51B9FFFDA000C0301000211031100001009CCE8E3F307D1E02D403E0EC85FFD389B20492811FEA747B60000000A04ADFA45A74012BA857F0D683CB8BA68EFCC5D152412FC91D53E7A0ECCDF9C66610B29B3F92E6F081C5E9D2FC044B5ED24511E7B872C983CA1BBF3A258D77550407880D497C65E69C331486C1F53BBEEC7A977DD41756FFFDA0008010103013F10AF3BAC2BCC40BCB84CBCE7D470B25AD801AA235CC8C6B5AA655A8D4966DCD0102433D10F3332E738152A42D4BBB0A8CB3C50CD2AE2ED3E23686675C406CBA1D695016607E8763F497F4F4BC317D49C35BB4C132F2A9B416694A9714F55EF8ADDAA50E23B88054AE01982E00BF1FE9666AC46C7564336042B4F4CA8DF264D02B2D3C1D46AC5C84C0B7540283063DE2AD256C8C0AB33DEEE36B8A4C05442AA2C46CABCC71BA2A8745800380DCAD14294589D54A6C9DB74C74D2B87183908BF9AA0B62C9C706B3A97CCE0B25D5D01CD1034CA875772D4D8D64A4186B7C5E83ADCED5A77A56387A9CFF4BF612156B9422242940E80E00C109CFF0031F4A0A01B60BE5507962116A6EC38DD384812EE5F62475199178426E3118C1ACB7D5F35116F20B6D393B8CA6AD6104C135754F8814B7253891B2A8138BB993052EC36F66BEF1E5052A8BD25D022B5759330CB003928EF7A7B4648DF0A14B4DD598DEA1A254AFD15E95DFA2C09000B98315EA6F4D256A976B7CC5907447818589D55917BA6C141101C2E4F7943105C719C2E959583A2768540720E9127631B3CA915ED3740E15BE930660CA40004A038D930B9AD31A3C2408CA1585E002E292EDB3E78C12F4C9A4E9CA5383FF14C00E42C5882AC5AECB688E569E965AD01ACBEC514439D781ECE11A47DE27C309190D633414D8A2638A287F2DE9D393BD653891AEED15BF69BE88F14C883AB9AE193FF0066A5948DF8C71328198AC22F4F2CA8108E30C6428DA34B6D173EC4894395D6C05642D8C73014E0C559165A65AC13832EAC3A87904AB30F22420E5855423B4295F8A848BD8511F59655DE3D6AB35A00BAEAE04847656163B5FC5CA61D6215B8286F9CE894FB9B3926133F130EAA2BC17F1EE2007A3B442B2D73B443034228D736035F146D757044587542ABE0332BE32F2873485B15BFE4DBDD6F8F98A59AE01EABD94E7A82D3E85C94C675FA44D8E42CAE97039388BDF9D32E9716250F97B8502E928A07409DBF06620E5E3E14E3AFDDCC9B49FC70D79995D08560F68D4A9F73F4BACF881566D8A93BC950DA074D9F985507E08FCC35B8058A1C675D7503A11D65129B5A658F700ADBBCB98D71C10BEECD0098E83F600398754210451D5B651047A0021D0FEE3C06621E105C26ECDD59C0D130CEBE079ABC9AF68584C1D1001F632E91175BD942A1871BE49562E38B8A5253C372B64230855C095531D420893A140A2AD10756CAC5E06F556DFC4B735825544CCF2C11A73A894DB097A3AB6A28ABBAE238732E29954B2EA37C7C67F88880E178317CF010B614A29701BAE6BF11C19A67D3C81A1AAD16CC0052D0B7CEDDB056CAC17C5A317B0B5B3031B4CC01938CCB28A38712A67F8000052B488C7C84060F794CBE9F32BB585ADB3CD580E76C21B8E19C2EF3EF72C70CE2254EF9C88DA55090AE30C438CC4AE630A73348C4A26DB0D715CE416A55064A065669C903C220387B000AEF36E7E222A1B754CB59D57B444AC58C952F008470D9AB30E623061A6B94A1938130360333C0A6540E6D4428AC68D4278B6D4141908366D6AE2714F0D00DB05C295DCB40153C8559193DA612ECA50CAAF550558EE21F111AD0A0D23C32C14C731380F058F2B4F76899B3319B2A103CA1DB7344320A0DD198D96882068DB4529BB28A87F562A5AD42A737C0CCA680EB9A7F0163F1DC75194AFBB1F352E11C8BB67DEA2927D15AAE0023FA06603114033A661A1294219A1180ACE0EAECB382C182DA3E11F215790573306ECCE3A223E661935DE19BE4826DF66D0889C37A090B2D41C0154B699C57DE0AA957ABA1D3DC63C9D8250348E5C3B3E4EA2EBF7B042C3A71EF2EC5274DB3EE3ED0A6CD1CA0D617D9FD404A46D0D432510212235AD9774D7A39DFBD5896E2F91F1663EA984AB5481F08CDE4CE23C71FE398E13BE4D34C6C9500324173D9600015EF456D2F292DC35356156AB01F025F51358ECE897B140F4C51D3026426A16894E3B949102D9A0ACA8F9551C085EF001264AA011A0739BAB949120131EA2E836B5C4B5A0C2D44EF2DB5CCCD3F9B978B90978EE3CB6459C85314DF399822CA005E5ABBE639EF5DE614DE28226B0B14D28C844B4225F106EB2809928039AD885E500CA0CE6DC7D0DC007112E404CABE26E162C9713073835C543EC88F685F66668E1E152FB004AE179C592E0323A855834DD6823D32F88CE85000053811EF7114054BD83CB8691036E750959E9091119767374AA35539393B032A2B2E2F78087278181C4A618A64F578C29284158AE186B42DD394157F448C2EE200DE11B6D528D5E2F04716B345AD691995CF72B0649CF824152E357F8A1A68B30D60E1F6EE01A12EBC960FB7DE7165F4945EA540382F263DE0922A7305130F6FF70BA82038AE45E429311393014FD33F2445722D9ECA4524511E95DA42DE40B38950C58A014CD0A3B35A6ABC14FA9354341D8BB70C4A88012C145041A073097008A1083681A65B38E96CD2ABF58E3BC0D62F80CFA41B9A06B7021BA582DAB242E05E59C436303998D955EC82DCB02DA2C2D6F79CC430C53884B8CB44BC97A85C9D54E03DB8A7E6BF8877D0B136BBF8392509511E4D1B78B9BCCB19C726EA55684D68E15C88C2D552D4946EDBFBEAEE0B05BFED435A99A19E9F88A84252762378A74450172A61752B51EE7FE64046C3BC0942EA559380118156BD32B39A0495556F6DAD1C71D621265B402BDCAABE63789D13ED5FCA00BF320FD6E57C8F855F787C05AB38EF367ED14E41D95F998BD3A0839A9C0B581D90AC6510BC656EAA8D4BF334C95F339FA4BAB97FC21BB989DF2DEDCEB31E1AF5F7EB734372F371F15D54799B4C2B46BB6EAA02D06728305E1179BEA06D57DBFC428B4B617DED7DEFCC36228B64111630670412B416296311C591074D9F09D4B6936B472E232537B5D77DCB6117918BE369F796189C2D15B61ECCAEDC321CB1D2FF0062535D259BFD09DCDFBAAAB4B9878C30F1789D97778F79FFDA0008010203013F10441D09B2355562605A0EF98DCE3F6EE146F365ABB610746C7F304CC3E8F4C2987814EC40D17B978F129583300CB12E9326258DA5F3E8EA381A437300EC259C1001896DE200159DC7A2AC2504C20B750350D4711DC956512A67CFA490998A372A311B65323F4152A25C0A9E5E853487AAA2699454E07C7DC9D7FC4D923E22752CC4CD1CE28F787FC48BE25B4884C42C36C601334F6FF63D957E58C36C26982614431BE4298F2C70CAE3F7EF299E1E7F873316A2A599257F425B609820B4B3D117E75D4A94B9CCFE21025CDDB3000CDC54E3BF7F466E88AF11C70FBC9FC10F298263E60B619430DECC4EC4F0CA78333404F024B9B63065DBD4473E63A5E9032CB3B14194257BC5E9CC5A97E2368BC0F2C168BA890B99BC423094CC4C4C2620B52827022A8AE65C1D4ADDE2090082B7684495532CCF272A3787E8CB6EDA0040C4DA54A8912BD3020CD91198CA622D5FB4A123416EE008151D37150D903144AB9824517DFB7994D5AD8CE719622253E94D5C73895E9A80D5CAC6911E434CEF665767AC1531C7A08EA2992E50815363C8F10235A8D0C44DD0BF42748F84454C4B82EE1E20ECE88BED660A6A79752807CF0C71A40974B95054D6E62381AD10A421551A546166A60120111328D2914EE39C304BD91C30D55E07F89B17CBFB99285625E45735F88035983C8B02E12BDE526BE522DB3A3AE6098314DBCFA55425CA081F4F433C438961083B9D8286539FC251F5194B818FE305457FD23767DE81FF00AA604A1E08A56B1B840DBF11D912E5B984F996AA87312344C706A34CCB708C97371C6D4C31A022CCBBCC214F28070DFA2486A263AAAFACD3D6D79F4B71335BEBD1AE655A78C1477516269C3FBCC05416E595DBF30E47F33C9F9876FE625709F7872E5FC7A7FFDA0008010303013F102C23316A11F0C2458AE9E541E079654D08D0553BFA67AF128B4A28C251A7B3C3ABC6728E3494FC7AE01D301A0E6471CD3C7889B4D5B1E0971941E612AE524B4018A95208828A8A633A0A8765DE3C91603748BF8CB7055E8A2807D97DE6D24B7D7110D41701A9BE62430A95E80FD0C6C7FCEF5BA8FA22CC73613CD253B87942308311405E621FF17F24A8114302345CBFC1CCE97F7FA344672AF3FE46F204A24DF7A0B061BF782EAB9350D0B3DF895159100D6225C7E813A26FB11D10F97F897EDBDC775F13862D1DC49AFDF83A3DA5971B8BC02C6EC879775823291A20DB1500A7A36D16CA8BE9B9E32712A772651CB00189AC738131D12A0AB2F3043F282E0DFB4D30964A23F50D69F485681B7A25AE10875E8BC2B3BE241B8A8970F8608E6770287CF70C4BA800D25D59220789908C45C0FCEA1C4BB34F450A306C81515C19751CA8E600DF224CA0CAE3DA1628C733191C855E18A1F11FFD111FC0C7BF0C34D129FEFE626710109841B6714136F490B8C9619F187C4DC86039205625A24B72DCBB8473529021BBAEA27BB5F7EA16050E6295EFB97399472AA5AFBB3683210B2187A12198341BADC12F38FACDA93E83FB96BB3CAD9E497AB08ABCC08ECA81771FBB96445DA8AB2AB64B815580F2AD07CCE62588103D5CB770159A858DCBC71965583304A9B33F481654429DF997BC2531F59B79C0FF0024CAE0F9CFB435AB98829CB8863083B6618375D626BF1D3C4465472EA521C44725E3EF2C20A60C4729B4CC4B92F47A611E908076FE88CAB4F5C3012AA149032E037AFC4FB0A24FA3308A9E521BA1ED8ECAF9AFC45E8B792FE61A0CE5442BE5858880732AC333835302E7225AF3A8D246AF88B507500EBDB886028D939D10558E222C54702AFCCF07EB07008EE562D709AD88FD1B98807A18E7713BCAD1D4A6B18758B2A8A998ECEAE617CDE498B4627171FF00F52FC0FB7F717D3EA45F4FA90E0227057C22F97FB3FFD900')
diff --git a/plugins/dbgate-plugin-postgres/webpack-backend.config.js b/plugins/dbgate-plugin-postgres/webpack-backend.config.js
new file mode 100644
index 000000000..fb19d92d1
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/webpack-backend.config.js
@@ -0,0 +1,40 @@
+var webpack = require('webpack');
+var path = require('path');
+
+var config = {
+ context: __dirname + '/src/backend',
+
+ entry: {
+ app: './index.js',
+ },
+ target: 'node',
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: 'backend.js',
+ libraryTarget: 'commonjs2',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+
+ plugins: [
+ new webpack.IgnorePlugin({
+ checkResource(resource) {
+ const lazyImports = ['pg-native', 'uws'];
+ if (!lazyImports.includes(resource)) {
+ return false;
+ }
+ try {
+ require.resolve(resource);
+ } catch (err) {
+ return true;
+ }
+ return false;
+ },
+ }),
+ ],
+};
+
+module.exports = config;
diff --git a/plugins/dbgate-plugin-postgres/webpack-frontend.config.js b/plugins/dbgate-plugin-postgres/webpack-frontend.config.js
new file mode 100644
index 000000000..db07de291
--- /dev/null
+++ b/plugins/dbgate-plugin-postgres/webpack-frontend.config.js
@@ -0,0 +1,24 @@
+var webpack = require("webpack");
+var path = require("path");
+
+var config = {
+ context: __dirname + "/src/frontend",
+
+ entry: {
+ app: "./index.js",
+ },
+ target: "web",
+ output: {
+ path: path.resolve(__dirname, "dist"),
+ filename: "frontend.js",
+ libraryTarget: "var",
+ library: 'plugin',
+ },
+
+ // uncomment for disable minimalization
+ // optimization: {
+ // minimize: false,
+ // },
+};
+
+module.exports = config;
diff --git a/yarn.lock b/yarn.lock
index 8f31afac6..330e9962f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9,6 +9,50 @@
dependencies:
"@ctrl/tinycolor" "^3.3.1"
+"@azure/abort-controller@^1.0.0":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.4.tgz#fd3c4d46c8ed67aace42498c8e2270960250eafd"
+ integrity sha512-lNUmDRVGpanCsiUN3NWxFTdwmdFI53xwhkTFfHDGTYk46ca7Ind3nanJc+U6Zj9Tv+9nTCWRBscWEW1DyKOpTw==
+ dependencies:
+ tslib "^2.0.0"
+
+"@azure/core-auth@^1.1.4":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.3.0.tgz#0d55517cf0650aefe755669aca8a2f3724fcf536"
+ integrity sha512-kSDSZBL6c0CYdhb+7KuutnKGf2geeT+bCJAgccB0DD7wmNJSsQPcF7TcuoZX83B7VK4tLz/u+8sOO/CnCsYp8A==
+ dependencies:
+ "@azure/abort-controller" "^1.0.0"
+ tslib "^2.0.0"
+
+"@azure/ms-rest-azure-env@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-2.0.0.tgz#45809f89763a480924e21d3c620cd40866771625"
+ integrity sha512-dG76W7ElfLi+fbTjnZVGj+M9e0BIEJmRxU6fHaUQ12bZBe8EJKYb2GV50YWNaP2uJiVQ5+7nXEVj1VN1UQtaEw==
+
+"@azure/ms-rest-js@^2.0.4":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-2.3.0.tgz#035bdd2b0f64de2f1b5f9d42ac146d4afdf54434"
+ integrity sha512-8NOnHgovi61NpcUld53zRkY/IcQJBBO48VeMntNTUtaPo8yYYTnu1hWRvp6b6vpBnur7HGmuj692J9li5Kx6/Q==
+ dependencies:
+ "@azure/core-auth" "^1.1.4"
+ abort-controller "^3.0.0"
+ form-data "^2.5.0"
+ node-fetch "^2.6.0"
+ tough-cookie "^3.0.1"
+ tslib "^1.10.0"
+ tunnel "0.0.6"
+ uuid "^3.3.2"
+ xml2js "^0.4.19"
+
+"@azure/ms-rest-nodeauth@^3.0.6":
+ version "3.0.9"
+ resolved "https://registry.yarnpkg.com/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-3.0.9.tgz#29029f990610286d318ff735323e826a95d7e1af"
+ integrity sha512-+GdDHUJlWtIDanRZemFooLy68NsBDhN/Oni9DSFeoXIFNGlSe1IOes8/IRkQdrNXyUvBanuzzR7I5WYYzYQsmA==
+ dependencies:
+ "@azure/ms-rest-azure-env" "^2.0.0"
+ "@azure/ms-rest-js" "^2.0.4"
+ adal-node "^0.1.28"
+
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
@@ -330,6 +374,11 @@
"@types/yargs" "^15.0.0"
chalk "^3.0.0"
+"@js-joda/core@^3.1.0":
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273"
+ integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg==
+
"@mdi/font@^5.9.55":
version "5.9.55"
resolved "https://registry.yarnpkg.com/@mdi/font/-/font-5.9.55.tgz#41acd50b88073ded7095fc3029d8712b6e12f38e"
@@ -356,6 +405,65 @@
"@nodelib/fs.scandir" "2.1.4"
fastq "^1.6.0"
+"@npmcli/ci-detect@^1.0.0":
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz#6c1d2c625fb6ef1b9dea85ad0a5afcbef85ef22a"
+ integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q==
+
+"@npmcli/git@^2.0.1":
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.0.6.tgz#47b97e96b2eede3f38379262fa3bdfa6eae57bf2"
+ integrity sha512-a1MnTfeRPBaKbFY07fd+6HugY1WAkKJzdiJvlRub/9o5xz2F/JtPacZZapx5zRJUQFIzSL677vmTSxEcDMrDbg==
+ dependencies:
+ "@npmcli/promise-spawn" "^1.1.0"
+ lru-cache "^6.0.0"
+ mkdirp "^1.0.3"
+ npm-pick-manifest "^6.0.0"
+ promise-inflight "^1.0.1"
+ promise-retry "^2.0.1"
+ semver "^7.3.2"
+ unique-filename "^1.1.1"
+ which "^2.0.2"
+
+"@npmcli/installed-package-contents@^1.0.6":
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa"
+ integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==
+ dependencies:
+ npm-bundled "^1.1.1"
+ npm-normalize-package-bin "^1.0.1"
+
+"@npmcli/move-file@^1.0.1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674"
+ integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==
+ dependencies:
+ mkdirp "^1.0.4"
+ rimraf "^3.0.2"
+
+"@npmcli/node-gyp@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.2.tgz#3cdc1f30e9736dbc417373ed803b42b1a0a29ede"
+ integrity sha512-yrJUe6reVMpktcvagumoqD9r08fH1iRo01gn1u0zoCApa9lnZGEigVKUd2hzsCId4gdtkZZIVscLhNxMECKgRg==
+
+"@npmcli/promise-spawn@^1.1.0", "@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2":
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5"
+ integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==
+ dependencies:
+ infer-owner "^1.0.4"
+
+"@npmcli/run-script@^1.8.2":
+ version "1.8.4"
+ resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.4.tgz#03ced92503a6fe948cbc0975ce39210bc5e824d6"
+ integrity sha512-Yd9HXTtF1JGDXZw0+SOn+mWLYS0e7bHBHVC/2C8yqs4wUrs/k8rwBSinD7rfk+3WG/MFGRZKxjyoD34Pch2E/A==
+ dependencies:
+ "@npmcli/node-gyp" "^1.0.2"
+ "@npmcli/promise-spawn" "^1.3.2"
+ infer-owner "^1.0.4"
+ node-gyp "^7.1.0"
+ read-package-json-fast "^2.0.1"
+
"@polka/url@^1.0.0-next.9":
version "1.0.0-next.11"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71"
@@ -419,6 +527,11 @@
estree-walker "^1.0.1"
picomatch "^2.2.2"
+"@tootallnate/once@1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
+ integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
+
"@tsconfig/svelte@^1.0.0":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@tsconfig/svelte/-/svelte-1.0.10.tgz#30ec7feeee0bdf38b12a50f0686f8a2e7b6b9dc0"
@@ -546,6 +659,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99"
integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==
+"@types/node@^8.0.47":
+ version "8.10.66"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3"
+ integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==
+
"@types/parsimmon@^1.10.1":
version "1.10.1"
resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.1.tgz#d46015ad91128fce06a1a688ab39a2516507f740"
@@ -594,6 +712,11 @@
dependencies:
"@types/yargs-parser" "*"
+"@verycrazydog/mysql-parser@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@verycrazydog/mysql-parser/-/mysql-parser-1.2.0.tgz#6007a8dc8987c4b7c8fd10357ee52f31df9062bc"
+ integrity sha512-h3zGaAwDYbZwqEIxDLMGaDRhfznTxgLO9C2FUnAfdXKoaw+OAUkMGbkjs2Qi+pnxhrAOt4BXM9JwkMb6bY/iXA==
+
"@webassemblyjs/ast@1.8.5":
version "1.8.5"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
@@ -765,6 +888,13 @@ abbrev@1:
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
+abort-controller@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
+ integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
+ dependencies:
+ event-target-shim "^5.0.0"
+
accepts@~1.3.4, accepts@~1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
@@ -811,11 +941,58 @@ acorn@^7.1.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c"
integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==
+adal-node@^0.1.28:
+ version "0.1.28"
+ resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.1.28.tgz#468c4bb3ebbd96b1270669f4b9cba4e0065ea485"
+ integrity sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU=
+ dependencies:
+ "@types/node" "^8.0.47"
+ async ">=0.6.0"
+ date-utils "*"
+ jws "3.x.x"
+ request ">= 2.52.0"
+ underscore ">= 1.3.1"
+ uuid "^3.1.0"
+ xmldom ">= 0.1.x"
+ xpath.js "~1.1.0"
+
+adler-32@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25"
+ integrity sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=
+ dependencies:
+ exit-on-epipe "~1.0.1"
+ printj "~1.1.0"
+
after@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
+agent-base@6:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
+ integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
+ dependencies:
+ debug "4"
+
+agentkeepalive@^4.1.3:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b"
+ integrity sha512-+V/rGa3EuU74H6wR04plBb7Ks10FbtUQgRj/FQOG7uUIEuaINI+AiqJR1k6t3SVNs7o7ZjIdus6706qqzVq8jQ==
+ dependencies:
+ debug "^4.1.0"
+ depd "^1.1.2"
+ humanize-ms "^1.2.1"
+
+aggregate-error@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
+ integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==
+ dependencies:
+ clean-stack "^2.0.0"
+ indent-string "^4.0.0"
+
ajv-errors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
@@ -841,7 +1018,7 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-ajv@^6.12.5:
+ajv@^6.12.3, ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@@ -1035,11 +1212,21 @@ async-lock@^1.2.4:
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.4.tgz#80d0d612383045dd0c30eb5aad08510c1397cb91"
integrity sha512-UBQJC2pbeyGutIfYmErGc9RaJYnpZ1FHaxuKwb0ahvGiiCkPUf3p67Io+YLPmmv3RHY+mF6JEtNW8FlHsraAaA==
+async-lock@^1.2.6:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.8.tgz#7b02bdfa2de603c0713acecd11184cf97bbc7c4c"
+ integrity sha512-G+26B2jc0Gw0EG/WN2M6IczuGepBsfR1+DtqLnyFSH4p2C668qkOCtEkGNVEaaNAVlYwEMazy1+/jnLxltBkIQ==
+
async@0.2.10:
version "0.2.10"
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
+async@>=0.6.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
+ integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
+
async@^2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
@@ -1205,6 +1392,21 @@ bindings@^1.5.0:
dependencies:
file-uri-to-path "1.0.0"
+bl@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5"
+ integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==
+ dependencies:
+ readable-stream "^2.3.5"
+ safe-buffer "^5.1.1"
+
+bl@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.1.tgz#1cbb439299609e419b5a74d7fce2f8b37d8e5c6f"
+ integrity sha512-jrCW5ZhfQ/Vt07WX1Ngs+yn9BDqPL/gw28S7s9H6QK/gupnizNzJAss5akW20ISgOrbLTlXOOCTJeNUQqruAWQ==
+ dependencies:
+ readable-stream "^3.0.1"
+
bl@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489"
@@ -1379,11 +1581,26 @@ bser@2.1.1:
dependencies:
node-int64 "^0.4.0"
+bson@^1.1.4:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.6.tgz#fb819be9a60cd677e0853aee4ca712a785d6618a"
+ integrity sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==
+
+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 sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
+
buffer-from@1.x, buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
+buffer-writer@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
+ integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
+
buffer-xor@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
@@ -1423,6 +1640,11 @@ builtin-status-codes@^3.0.0:
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
+builtins@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
+ integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
+
busboy@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
@@ -1461,6 +1683,29 @@ cacache@^12.0.2:
unique-filename "^1.1.1"
y18n "^4.0.0"
+cacache@^15.0.5:
+ version "15.0.6"
+ resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099"
+ integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w==
+ dependencies:
+ "@npmcli/move-file" "^1.0.1"
+ chownr "^2.0.0"
+ fs-minipass "^2.0.0"
+ glob "^7.1.4"
+ infer-owner "^1.0.4"
+ lru-cache "^6.0.0"
+ minipass "^3.1.1"
+ minipass-collect "^1.0.2"
+ minipass-flush "^1.0.5"
+ minipass-pipeline "^1.2.2"
+ mkdirp "^1.0.3"
+ p-map "^4.0.0"
+ promise-inflight "^1.0.1"
+ rimraf "^3.0.2"
+ ssri "^8.0.1"
+ tar "^6.0.2"
+ unique-filename "^1.1.1"
+
cache-base@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
@@ -1513,6 +1758,15 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
+cfb@^1.1.4:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.0.tgz#6a4d0872b525ed60349e1ef51fb4b0bf73eca9a8"
+ integrity sha512-sXMvHsKCICVR3Naq+J556K+ExBo9n50iKl6LGarlnvuA2035uMlGA/qVrc0wQtow5P1vJEw9UyrKLCbtIKz+TQ==
+ dependencies:
+ adler-32 "~1.2.0"
+ crc-32 "~1.2.0"
+ printj "~1.1.2"
+
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -1660,6 +1914,11 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
+clean-stack@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
+ integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
+
cli-boxes@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
@@ -1696,6 +1955,14 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
+codepage@~1.14.0:
+ version "1.14.0"
+ resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99"
+ integrity sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=
+ dependencies:
+ commander "~2.14.1"
+ exit-on-epipe "~1.0.1"
+
collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -1750,6 +2017,16 @@ commander@^4.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
+commander@~2.14.1:
+ version "2.14.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
+ integrity sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==
+
+commander@~2.17.1:
+ version "2.17.1"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
+ integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
+
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@@ -1918,6 +2195,14 @@ cors@^2.8.5:
object-assign "^4"
vary "^1"
+crc-32@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
+ integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==
+ dependencies:
+ exit-on-epipe "~1.0.1"
+ printj "~1.1.0"
+
create-ecdh@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff"
@@ -2042,6 +2327,31 @@ cssstyle@^1.0.0:
dependencies:
cssom "0.3.x"
+csv-generate@^3.4.0:
+ version "3.4.0"
+ resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-3.4.0.tgz#360ed73ef8ec7119515a47c3bd5970ac4b988f00"
+ integrity sha512-D6yi7c6lL70cpTx3TQIVWKrfxuLiKa0pBizu0zi7fSRXlhmE7u674gk9k1IjCEnxKq2t6xzbXnxcOmSdBbE8vQ==
+
+csv-parse@^4.15.3:
+ version "4.15.3"
+ resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.15.3.tgz#8a62759617a920c328cb31c351b05053b8f92b10"
+ integrity sha512-jlTqDvLdHnYMSr08ynNfk4IAUSJgJjTKy2U5CQBSu4cN9vQOJonLVZP4Qo4gKKrIgIQ5dr07UwOJdi+lRqT12w==
+
+csv-stringify@^5.6.2:
+ version "5.6.2"
+ resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.2.tgz#e653783e2189c4c797fbb12abf7f4943c787caa9"
+ integrity sha512-n3rIVbX6ylm1YsX2NEug9IaPV8xRnT+9/NNZbrA/bcHgOSSeqtWla6XnI/xmyu57wIw+ASCAoX1oM6EZtqJV0A==
+
+csv@^5.3.2:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/csv/-/csv-5.5.0.tgz#8ef89e9ac22559064aedf3cbbb912ed4c2aaf9ac"
+ integrity sha512-32tcuxdb4HW3zbk8NBcVQb8/7xuJB5sv+q4BuQ6++E/K6JvHvWoCHcGzB5Au95vVikNH4ztE0XNC/Bws950cfA==
+ dependencies:
+ csv-generate "^3.4.0"
+ csv-parse "^4.15.3"
+ csv-stringify "^5.6.2"
+ stream-transform "^2.1.0"
+
cyclist@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
@@ -2068,6 +2378,27 @@ date-fns@^2.0.1:
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.9.0.tgz#d0b175a5c37ed5f17b97e2272bbc1fa5aec677d2"
integrity sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA==
+date-utils@*:
+ version "1.2.21"
+ resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
+ integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=
+
+dbgate-plugin-tools@^1.0.0, dbgate-plugin-tools@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/dbgate-plugin-tools/-/dbgate-plugin-tools-1.0.4.tgz#ab89920126f397550a7e79c5f09fa568f1b83b14"
+ integrity sha512-SWtN2KyptwvMAaoCyaLqvnraBranfd925exdub5Rx9bsPGYQ5v+Hx3v4SWYvK4k7qpqyJglxXaRN8RIMPN6Apg==
+ dependencies:
+ ncp "^2.0.0"
+ pacote "^11.1.13"
+ rimraf "^3.0.2"
+
+dbgate-tools@^4.0.3-rc.1, dbgate-tools@^4.1.0-rc.1:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/dbgate-tools/-/dbgate-tools-4.1.0.tgz#cacc62759fb43a4c2a54d5d0ff795f2f7995a445"
+ integrity sha512-IvvTOvGezUyiz9NP6GnheOU8rO8McQri2BSPBVv/p5MV0+veDLWo16Ag/RqIoMlTcmV/AZz5orwcKd5BLpGaaQ==
+ dependencies:
+ lodash "^4.17.15"
+
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -2075,6 +2406,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
dependencies:
ms "2.0.0"
+debug@4:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
+ integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
+ dependencies:
+ ms "2.1.2"
+
debug@=3.1.0, debug@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -2167,11 +2505,21 @@ delegates@^1.0.0:
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
-depd@~1.1.2:
+denque@^1.4.1:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de"
+ integrity sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==
+
+depd@^1.1.2, depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
+depd@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
+ integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
+
des.js@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
@@ -2287,6 +2635,13 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
+ecdsa-sig-formatter@1.0.11:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
+ integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
+ dependencies:
+ safe-buffer "^5.0.1"
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -2330,6 +2685,13 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
+encoding@^0.1.12:
+ version "0.1.13"
+ resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
+ integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
+ dependencies:
+ iconv-lite "^0.6.2"
+
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
@@ -2403,6 +2765,16 @@ env-cmd@^10.1.0:
commander "^4.0.0"
cross-spawn "^7.0.0"
+env-paths@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
+ integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
+
+err-code@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
+ integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==
+
errno@^0.1.3, errno@~0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@@ -2594,6 +2966,11 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
+event-target-shim@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
+ integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
+
events@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
@@ -2638,6 +3015,11 @@ execa@^1.0.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
+exit-on-epipe@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
+ integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
+
exit@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -2824,6 +3206,11 @@ fb-watchman@^2.0.0:
dependencies:
bser "2.1.1"
+fflate@^0.3.8:
+ version "0.3.11"
+ resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.3.11.tgz#2c440d7180fdeb819e64898d8858af327b042a5d"
+ integrity sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==
+
figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
@@ -2963,6 +3350,15 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
+form-data@^2.5.0:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
+ integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.6"
+ mime-types "^2.1.12"
+
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
@@ -2977,6 +3373,11 @@ forwarded@~0.1.2:
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
+frac@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
+ integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==
+
fragment-cache@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
@@ -3029,7 +3430,7 @@ fs-extra@^8.1.0:
jsonfile "^4.0.0"
universalify "^0.1.0"
-fs-minipass@^2.0.0:
+fs-minipass@^2.0.0, fs-minipass@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
@@ -3093,6 +3494,13 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
+generate-function@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f"
+ integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==
+ dependencies:
+ is-property "^1.0.2"
+
gensync@^1.0.0-beta.1:
version "1.0.0-beta.1"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
@@ -3262,6 +3670,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
+graceful-fs@^4.2.3:
+ version "4.2.6"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
+ integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
+
growly@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
@@ -3280,6 +3693,14 @@ har-validator@~5.1.0:
ajv "^6.5.5"
har-schema "^2.0.0"
+har-validator@~5.1.3:
+ version "5.1.5"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
+ integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
+ dependencies:
+ ajv "^6.12.3"
+ har-schema "^2.0.0"
+
has-binary2@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d"
@@ -3387,6 +3808,13 @@ hosted-git-info@^2.1.4:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c"
integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==
+hosted-git-info@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961"
+ integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==
+ dependencies:
+ lru-cache "^6.0.0"
+
html-encoding-sniffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
@@ -3399,6 +3827,11 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491"
integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==
+http-cache-semantics@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
+ integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
+
http-errors@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
@@ -3421,6 +3854,15 @@ http-errors@~1.7.2:
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
+http-proxy-agent@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a"
+ integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==
+ dependencies:
+ "@tootallnate/once" "1"
+ agent-base "6"
+ debug "4"
+
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
@@ -3440,6 +3882,21 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
+https-proxy-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
+ integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
+ dependencies:
+ agent-base "6"
+ debug "4"
+
+humanize-ms@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
+ integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=
+ dependencies:
+ ms "^2.0.0"
+
iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -3447,6 +3904,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24:
dependencies:
safer-buffer ">= 2.1.2 < 3"
+iconv-lite@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01"
+ integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3.0.0"
+
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
@@ -3467,6 +3931,13 @@ ignore-by-default@^1.0.1:
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
+ignore-walk@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
+ integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
+ dependencies:
+ minimatch "^3.0.4"
+
ignore@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
@@ -3516,12 +3987,17 @@ imurmurhash@^0.1.4:
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+indent-string@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
+ integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
+
indexof@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
-infer-owner@^1.0.3:
+infer-owner@^1.0.3, infer-owner@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==
@@ -3590,6 +4066,16 @@ invert-kv@^2.0.0:
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
+ip-regex@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
+ integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=
+
+ip@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
+ integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=
+
ipaddr.js@1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65"
@@ -3757,6 +4243,11 @@ is-installed-globally@^0.1.0:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
+is-lambda@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5"
+ integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=
+
is-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
@@ -3808,6 +4299,16 @@ is-promise@^2.1.0:
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
+is-promise@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3"
+ integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
+
+is-property@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
+ integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=
+
is-redirect@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
@@ -4332,6 +4833,11 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
+jsbi@^3.1.3:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.1.4.tgz#9654dd02207a66a4911b4e4bb74265bc2cbc9dd0"
+ integrity sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==
+
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@@ -4379,6 +4885,11 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2:
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
+json-parse-even-better-errors@^2.3.0:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
+ integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
@@ -4439,6 +4950,11 @@ jsonify@~0.0.0:
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
+jsonparse@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
+ integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
+
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -4449,6 +4965,23 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
+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==
+ dependencies:
+ buffer-equal-constant-time "1.0.1"
+ ecdsa-sig-formatter "1.0.11"
+ safe-buffer "^5.0.1"
+
+jws@3.x.x:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
+ integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
+ dependencies:
+ jwa "^1.4.1"
+ safe-buffer "^5.0.1"
+
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@@ -4619,6 +5152,16 @@ lodash@^4.16.0, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
+lodash@^4.17.20:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
+long@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
+ integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
+
loose-envify@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -4631,7 +5174,7 @@ lowercase-keys@^1.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
-lru-cache@^4.0.1:
+lru-cache@^4.0.1, lru-cache@^4.1.3:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
@@ -4646,6 +5189,13 @@ lru-cache@^5.1.1:
dependencies:
yallist "^3.0.2"
+lru-cache@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
+ integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+ dependencies:
+ yallist "^4.0.0"
+
magic-string@^0.25.7:
version "0.25.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
@@ -4673,6 +5223,27 @@ make-error@1.x:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+make-fetch-happen@^8.0.9:
+ version "8.0.14"
+ resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222"
+ integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==
+ dependencies:
+ agentkeepalive "^4.1.3"
+ cacache "^15.0.5"
+ http-cache-semantics "^4.1.0"
+ http-proxy-agent "^4.0.1"
+ https-proxy-agent "^5.0.0"
+ is-lambda "^1.0.1"
+ lru-cache "^6.0.0"
+ minipass "^3.1.3"
+ minipass-collect "^1.0.2"
+ minipass-fetch "^1.3.2"
+ minipass-flush "^1.0.5"
+ minipass-pipeline "^1.2.4"
+ promise-retry "^2.0.1"
+ socks-proxy-agent "^5.0.0"
+ ssri "^8.0.0"
+
makeerror@1.0.x:
version "1.0.11"
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
@@ -4748,6 +5319,11 @@ memory-fs@^0.5.0:
errno "^0.1.3"
readable-stream "^2.0.1"
+memory-pager@^1.0.2:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5"
+ integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==
+
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -4877,6 +5453,53 @@ minimist@^1.2.3, minimist@^1.2.5:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+minipass-collect@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617"
+ integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==
+ dependencies:
+ minipass "^3.0.0"
+
+minipass-fetch@^1.3.0, minipass-fetch@^1.3.2:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a"
+ integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==
+ dependencies:
+ minipass "^3.1.0"
+ minipass-sized "^1.0.3"
+ minizlib "^2.0.0"
+ optionalDependencies:
+ encoding "^0.1.12"
+
+minipass-flush@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373"
+ integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==
+ dependencies:
+ minipass "^3.0.0"
+
+minipass-json-stream@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7"
+ integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==
+ dependencies:
+ jsonparse "^1.3.1"
+ minipass "^3.0.0"
+
+minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c"
+ integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==
+ dependencies:
+ minipass "^3.0.0"
+
+minipass-sized@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70"
+ integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==
+ dependencies:
+ minipass "^3.0.0"
+
minipass@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5"
@@ -4884,7 +5507,14 @@ minipass@^3.0.0:
dependencies:
yallist "^4.0.0"
-minizlib@^2.1.1:
+minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd"
+ integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==
+ dependencies:
+ yallist "^4.0.0"
+
+minizlib@^2.0.0, minizlib@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
@@ -4916,6 +5546,11 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
+mixme@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.5.0.tgz#7a7ebbb51251724b18054c63c91f5487c0b030ab"
+ integrity sha512-YyyBIzqe6EEi5xcnN66LXVVvwijMF51liPT9ZqsrHim9s2MgEg4jxI8gsSF6R7pzAotjvBiERC90bbnwAqiDHg==
+
mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
@@ -4935,7 +5570,7 @@ mkdirp@^0.5.5:
dependencies:
minimist "^1.2.5"
-mkdirp@^1.0.3:
+mkdirp@^1.0.3, mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
@@ -4950,6 +5585,19 @@ moment@^2.24.0:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
+mongodb@^3.6.5:
+ version "3.6.6"
+ resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.6.6.tgz#92e3658f45424c34add3003e3046c1535c534449"
+ integrity sha512-WlirMiuV1UPbej5JeCMqE93JRfZ/ZzqE7nJTwP85XzjAF4rRSeq2bGCb1cjfoHLOF06+HxADaPGqT0g3SbVT1w==
+ dependencies:
+ bl "^2.2.1"
+ bson "^1.1.4"
+ denque "^1.4.1"
+ optional-require "^1.0.2"
+ safe-buffer "^5.1.2"
+ optionalDependencies:
+ saslprep "^1.0.0"
+
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -4977,11 +5625,16 @@ ms@2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
-ms@^2.1.1:
+ms@2.1.2, ms@^2.1.1:
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:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
msnodesqlv8@^2.0.10:
version "2.0.10"
resolved "https://registry.yarnpkg.com/msnodesqlv8/-/msnodesqlv8-2.0.10.tgz#47d05157c2d30e5f48fa0aa550a0353ab56a027c"
@@ -4995,6 +5648,27 @@ mute-stream@0.0.8:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
+mysql2@^2.2.5:
+ version "2.2.5"
+ resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-2.2.5.tgz#72624ffb4816f80f96b9c97fedd8c00935f9f340"
+ integrity sha512-XRqPNxcZTpmFdXbJqb+/CtYVLCx14x1RTeNMD4954L331APu75IC74GDqnZMEt1kwaXy6TySo55rF2F3YJS78g==
+ dependencies:
+ denque "^1.4.1"
+ generate-function "^2.3.1"
+ iconv-lite "^0.6.2"
+ long "^4.0.0"
+ lru-cache "^6.0.0"
+ named-placeholders "^1.1.2"
+ seq-queue "^0.0.5"
+ sqlstring "^2.3.2"
+
+named-placeholders@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.2.tgz#ceb1fbff50b6b33492b5cf214ccf5e39cef3d0e8"
+ integrity sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==
+ dependencies:
+ lru-cache "^4.1.3"
+
nan@^2.12.1:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
@@ -5027,6 +5701,11 @@ napi-build-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
+native-duplexpair@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/native-duplexpair/-/native-duplexpair-1.0.0.tgz#7899078e64bf3c8a3d732601b3d40ff05db58fa0"
+ integrity sha1-eJkHjmS/PIo9cyYBs9QP8F21j6A=
+
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -5085,11 +5764,32 @@ node-cron@^2.0.3:
opencollective-postinstall "^2.0.0"
tz-offset "0.0.1"
+node-fetch@^2.6.0:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
+ integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
+
node-gyp-build@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d"
integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==
+node-gyp@^7.1.0:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae"
+ integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==
+ dependencies:
+ env-paths "^2.2.0"
+ glob "^7.1.4"
+ graceful-fs "^4.2.3"
+ nopt "^5.0.0"
+ npmlog "^4.1.2"
+ request "^2.88.2"
+ rimraf "^3.0.2"
+ semver "^7.3.2"
+ tar "^6.0.2"
+ which "^2.0.2"
+
node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -5185,6 +5885,13 @@ noop-logger@^0.1.1:
resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=
+nopt@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88"
+ integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==
+ dependencies:
+ abbrev "1"
+
nopt@~1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
@@ -5214,6 +5921,68 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+npm-bundled@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
+ integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
+ dependencies:
+ npm-normalize-package-bin "^1.0.1"
+
+npm-install-checks@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4"
+ integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==
+ dependencies:
+ semver "^7.1.1"
+
+npm-normalize-package-bin@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
+ integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
+
+npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.2:
+ version "8.1.2"
+ resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.2.tgz#b868016ae7de5619e729993fbd8d11dc3c52ab62"
+ integrity sha512-6Eem455JsSMJY6Kpd3EyWE+n5hC+g9bSyHr9K9U2zqZb7+02+hObQ2c0+8iDk/mNF+8r1MhY44WypKJAkySIYA==
+ dependencies:
+ hosted-git-info "^4.0.1"
+ semver "^7.3.4"
+ validate-npm-package-name "^3.0.0"
+
+npm-packlist@^2.1.4:
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.1.5.tgz#43ef5bbb9f59b7c0ef91e0905f1dd707b4cfb33c"
+ integrity sha512-KCfK3Vi2F+PH1klYauoQzg81GQ8/GGjQRKYY6tRnpQUPKTs/1gBZSRWtTEd7jGdSn1LZL7gpAmJT+BcS55k2XQ==
+ dependencies:
+ glob "^7.1.6"
+ ignore-walk "^3.0.3"
+ npm-bundled "^1.1.1"
+ npm-normalize-package-bin "^1.0.1"
+
+npm-pick-manifest@^6.0.0:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148"
+ integrity sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==
+ dependencies:
+ npm-install-checks "^4.0.0"
+ npm-normalize-package-bin "^1.0.1"
+ npm-package-arg "^8.1.2"
+ semver "^7.3.4"
+
+npm-registry-fetch@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz#86f3feb4ce00313bc0b8f1f8f69daae6face1661"
+ integrity sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==
+ dependencies:
+ "@npmcli/ci-detect" "^1.0.0"
+ lru-cache "^6.0.0"
+ make-fetch-happen "^8.0.9"
+ minipass "^3.1.3"
+ minipass-fetch "^1.3.0"
+ minipass-json-stream "^1.0.1"
+ minizlib "^2.0.0"
+ npm-package-arg "^8.0.0"
+
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@@ -5221,7 +5990,7 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
-npmlog@^4.0.1:
+npmlog@^4.0.1, npmlog@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@@ -5333,6 +6102,11 @@ opencollective-postinstall@^2.0.0:
resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==
+optional-require@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.0.3.tgz#275b8e9df1dc6a17ad155369c2422a440f89cb07"
+ integrity sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==
+
optionator@^0.8.1, optionator@^0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
@@ -5405,6 +6179,13 @@ p-locate@^3.0.0:
dependencies:
p-limit "^2.0.0"
+p-map@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b"
+ integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==
+ dependencies:
+ aggregate-error "^3.0.0"
+
p-reduce@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
@@ -5425,6 +6206,36 @@ package-json@^4.0.0:
registry-url "^3.0.3"
semver "^5.1.0"
+packet-reader@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74"
+ integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==
+
+pacote@^11.1.13:
+ version "11.3.1"
+ resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.3.1.tgz#6ce95dd230db475cbd8789fd1f986bec51b4bf7c"
+ integrity sha512-TymtwoAG12cczsJIrwI/euOQKtjrQHlD0k0oyt9QSmZGpqa+KdlxKdWR/YUjYizkixaVyztxt/Wsfo8bL3A6Fg==
+ dependencies:
+ "@npmcli/git" "^2.0.1"
+ "@npmcli/installed-package-contents" "^1.0.6"
+ "@npmcli/promise-spawn" "^1.2.0"
+ "@npmcli/run-script" "^1.8.2"
+ cacache "^15.0.5"
+ chownr "^2.0.0"
+ fs-minipass "^2.1.0"
+ infer-owner "^1.0.4"
+ minipass "^3.1.3"
+ mkdirp "^1.0.3"
+ npm-package-arg "^8.0.1"
+ npm-packlist "^2.1.4"
+ npm-pick-manifest "^6.0.0"
+ npm-registry-fetch "^9.0.0"
+ promise-retry "^2.0.1"
+ read-package-json-fast "^2.0.1"
+ rimraf "^3.0.2"
+ ssri "^8.0.1"
+ tar "^6.1.0"
+
pako@~1.0.5:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
@@ -5596,6 +6407,70 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+pg-connection-string@0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7"
+ integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=
+
+pg-cursor@^2.5.1:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/pg-cursor/-/pg-cursor-2.5.2.tgz#9217fc989fa64221a02d6ed4b37323267d90abde"
+ integrity sha512-yS0lxXA5WoIVK7BUgJr1uOJDJe5JxVezItTLvqnTXj6bF3di4UtQOrPx8RW3GpFmom2NTQfpEc2N6vvdpopQSw==
+
+pg-int8@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
+ integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
+
+pg-packet-stream@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz#e45c3ae678b901a2873af1e17b92d787962ef914"
+ integrity sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==
+
+pg-pool@^2.0.10:
+ version "2.0.10"
+ resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.10.tgz#842ee23b04e86824ce9d786430f8365082d81c4a"
+ integrity sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==
+
+pg-query-stream@^3.1.1:
+ version "3.4.2"
+ resolved "https://registry.yarnpkg.com/pg-query-stream/-/pg-query-stream-3.4.2.tgz#6cdf8f3086bfe01b2e4d7cc461ad4c8c6a7d0914"
+ integrity sha512-kaTzsi5TQ3XG1KUznEV3MnstM1U4k5Z9cZ02PNmKLMFeYiPEn83FUc2pPVPiKKv93ITI8e5oCh+zEOunjy0ZwQ==
+ dependencies:
+ pg-cursor "^2.5.1"
+
+pg-types@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
+ integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==
+ dependencies:
+ pg-int8 "1.0.1"
+ postgres-array "~2.0.0"
+ postgres-bytea "~1.0.0"
+ postgres-date "~1.0.4"
+ postgres-interval "^1.1.0"
+
+pg@^7.17.0:
+ version "7.18.2"
+ resolved "https://registry.yarnpkg.com/pg/-/pg-7.18.2.tgz#4e219f05a00aff4db6aab1ba02f28ffa4513b0bb"
+ integrity sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==
+ dependencies:
+ buffer-writer "2.0.0"
+ packet-reader "1.0.0"
+ pg-connection-string "0.1.3"
+ pg-packet-stream "^1.1.0"
+ pg-pool "^2.0.10"
+ pg-types "^2.1.0"
+ pgpass "1.x"
+ semver "4.3.2"
+
+pgpass@1.x:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.4.tgz#85eb93a83800b20f8057a2b029bf05abaf94ea9c"
+ integrity sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==
+ dependencies:
+ split2 "^3.1.1"
+
picomatch@^2.0.4, picomatch@^2.0.7:
version "2.2.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a"
@@ -5649,6 +6524,28 @@ posix-character-classes@^0.1.0:
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
+postgres-array@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
+ integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
+
+postgres-bytea@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
+ integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
+
+postgres-date@~1.0.4:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8"
+ integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==
+
+postgres-interval@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695"
+ integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==
+ dependencies:
+ xtend "^4.0.0"
+
prebuild-install@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.0.0.tgz#669022bcde57c710a869e39c5ca6bf9cd207f316"
@@ -5705,6 +6602,11 @@ pretty-format@^25.1.0:
ansi-styles "^4.0.0"
react-is "^16.12.0"
+printj@~1.1.0, printj@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
+ integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -5725,6 +6627,14 @@ promise-inflight@^1.0.1:
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
+promise-retry@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22"
+ integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==
+ dependencies:
+ err-code "^2.0.2"
+ retry "^0.12.0"
+
prompts@^2.0.1:
version "2.3.0"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.0.tgz#a444e968fa4cc7e86689a74050685ac8006c4cc4"
@@ -5893,6 +6803,14 @@ react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
+read-package-json-fast@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.2.tgz#2dcb24d9e8dd50fb322042c8c35a954e6cc7ac9e"
+ integrity sha512-5fyFUyO9B799foVk4n6ylcoAktG/FbE3jwRKxvwaeSrIunaoMc0u81dzXxjeAFKOce7O5KncdfwpGvvs6r5PsQ==
+ dependencies:
+ json-parse-even-better-errors "^2.3.0"
+ npm-normalize-package-bin "^1.0.1"
+
read-pkg-up@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978"
@@ -5919,7 +6837,7 @@ read-pkg@^4.0.1:
parse-json "^4.0.0"
pify "^3.0.0"
-"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
+"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -5932,19 +6850,19 @@ read-pkg@^4.0.1:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@^3.1.1:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.5.0.tgz#465d70e6d1087f6162d079cd0b5db7fbebfd1606"
- integrity sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==
+readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
+ integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
-readable-stream@^3.4.0:
- version "3.6.0"
- resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
- integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
+readable-stream@^3.1.1:
+ version "3.5.0"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.5.0.tgz#465d70e6d1087f6162d079cd0b5db7fbebfd1606"
+ integrity sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
@@ -6049,6 +6967,32 @@ request-promise-native@^1.0.5:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
+"request@>= 2.52.0", request@^2.88.2:
+ version "2.88.2"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
+ integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
+ dependencies:
+ aws-sign2 "~0.7.0"
+ aws4 "^1.8.0"
+ caseless "~0.12.0"
+ combined-stream "~1.0.6"
+ extend "~3.0.2"
+ forever-agent "~0.6.1"
+ form-data "~2.3.2"
+ har-validator "~5.1.3"
+ http-signature "~1.2.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.19"
+ oauth-sign "~0.9.0"
+ performance-now "^2.1.0"
+ qs "~6.5.2"
+ safe-buffer "^5.1.2"
+ tough-cookie "~2.5.0"
+ tunnel-agent "^0.6.0"
+ uuid "^3.3.2"
+
request@^2.87.0:
version "2.88.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
@@ -6165,6 +7109,11 @@ ret@~0.1.10:
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
+retry@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
+ integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=
+
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
@@ -6184,6 +7133,13 @@ rimraf@^2.5.4, rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
+rimraf@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
+ integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
+ dependencies:
+ glob "^7.1.3"
+
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
@@ -6306,7 +7262,7 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
-"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -6326,7 +7282,14 @@ sane@^4.0.3:
minimist "^1.1.1"
walker "~1.0.5"
-sax@^1.2.4:
+saslprep@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
+ integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==
+ dependencies:
+ sparse-bitfield "^3.0.3"
+
+sax@>=0.6.0, sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
@@ -6371,11 +7334,23 @@ semver-diff@^2.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
+semver@4.3.2:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
+ integrity sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=
+
semver@^6.0.0, semver@^6.1.2, semver@^6.2.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+semver@^7.1.1, semver@^7.3.2, semver@^7.3.4:
+ version "7.3.5"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
+ integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
+ dependencies:
+ lru-cache "^6.0.0"
+
send@0.17.1:
version "0.17.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
@@ -6395,6 +7370,11 @@ send@0.17.1:
range-parser "~1.2.1"
statuses "~1.5.0"
+seq-queue@^0.0.5:
+ version "0.0.5"
+ resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e"
+ integrity sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=
+
serialize-javascript@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
@@ -6552,6 +7532,11 @@ slice-ansi@^2.1.0:
astral-regex "^1.0.0"
is-fullwidth-code-point "^2.0.0"
+smart-buffer@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba"
+ integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==
+
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@@ -6637,6 +7622,23 @@ socket.io@^2.3.0:
socket.io-client "2.3.0"
socket.io-parser "~3.4.0"
+socks-proxy-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60"
+ integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA==
+ dependencies:
+ agent-base "6"
+ debug "4"
+ socks "^2.3.3"
+
+socks@^2.3.3:
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.0.tgz#6b984928461d39871b3666754b9000ecf39dfac2"
+ integrity sha512-mNmr9owlinMplev0Wd7UHFlqI4ofnBnNzFuzrm63PPaHgbkqCFe4T5LzwKmtQ/f2tX0NTpcdVLyD/FHxFBstYw==
+ dependencies:
+ ip "^1.1.5"
+ smart-buffer "^4.1.0"
+
source-list-map@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
@@ -6694,6 +7696,13 @@ sourcemap-codec@^1.4.4:
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
+sparse-bitfield@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11"
+ integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE=
+ dependencies:
+ memory-pager "^1.0.2"
+
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
@@ -6732,6 +7741,18 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies:
extend-shallow "^3.0.0"
+split2@^3.1.1:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f"
+ integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==
+ dependencies:
+ readable-stream "^3.0.0"
+
+sprintf-js@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
+ integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
+
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@@ -6744,6 +7765,18 @@ sql-formatter@^2.3.3:
dependencies:
lodash "^4.16.0"
+sqlstring@^2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.2.tgz#cdae7169389a1375b18e885f2e60b3e460809514"
+ integrity sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==
+
+ssf@~0.11.2:
+ version "0.11.2"
+ resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c"
+ integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==
+ dependencies:
+ frac "~1.1.2"
+
ssh2-streams@~0.4.10:
version "0.4.10"
resolved "https://registry.yarnpkg.com/ssh2-streams/-/ssh2-streams-0.4.10.tgz#48ef7e8a0e39d8f2921c30521d56dacb31d23a34"
@@ -6782,6 +7815,13 @@ ssri@^6.0.1:
dependencies:
figgy-pudding "^3.5.1"
+ssri@^8.0.0, ssri@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af"
+ integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==
+ dependencies:
+ minipass "^3.1.1"
+
stack-utils@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"
@@ -6837,6 +7877,13 @@ stream-shift@^1.0.0:
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
+stream-transform@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/stream-transform/-/stream-transform-2.1.0.tgz#e68cc062cced5b8ee669ae97f4be473eee5d9227"
+ integrity sha512-bwQO+75rzQbug7e5OOHnOR3FgbJ0fCjHmDIdynkwUaFzleBXugGmv2dx3sX3aIHUQRLjrcisRPgN9BWl63uGgw==
+ dependencies:
+ mixme "^0.5.0"
+
streamsearch@0.1.2, streamsearch@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
@@ -7085,6 +8132,18 @@ tar-stream@^2.1.4:
inherits "^2.0.3"
readable-stream "^3.1.1"
+tar@^6.0.2, tar@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
+ integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
+ dependencies:
+ chownr "^2.0.0"
+ fs-minipass "^2.0.0"
+ minipass "^3.0.0"
+ minizlib "^2.1.1"
+ mkdirp "^1.0.3"
+ yallist "^4.0.0"
+
tar@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f"
@@ -7097,6 +8156,23 @@ tar@^6.0.5:
mkdirp "^1.0.3"
yallist "^4.0.0"
+tedious@^9.2.3:
+ version "9.2.3"
+ resolved "https://registry.yarnpkg.com/tedious/-/tedious-9.2.3.tgz#ac871f764dbde7b23e35c47379d2796611e52ef1"
+ integrity sha512-+mI2r/5mqxpTHKBZ/SW+NNH2MK5i3Pwwkw0gF5ZrS2wf2uT/03bLSss8nm7xh604abJXyjx0sirhwH63H328qA==
+ dependencies:
+ "@azure/ms-rest-nodeauth" "^3.0.6"
+ "@js-joda/core" "^3.1.0"
+ adal-node "^0.1.28"
+ bl "^3.0.0"
+ depd "^2.0.0"
+ iconv-lite "^0.6.2"
+ jsbi "^3.1.3"
+ native-duplexpair "^1.0.0"
+ punycode "^2.1.0"
+ readable-stream "^3.6.0"
+ sprintf-js "^1.1.2"
+
term-size@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
@@ -7263,7 +8339,7 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"
-tough-cookie@^2.3.3, tough-cookie@^2.3.4:
+tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
@@ -7271,6 +8347,15 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4:
psl "^1.1.28"
punycode "^2.1.1"
+tough-cookie@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2"
+ integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==
+ dependencies:
+ ip-regex "^2.1.0"
+ psl "^1.1.28"
+ punycode "^2.1.1"
+
tough-cookie@~2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
@@ -7307,6 +8392,11 @@ ts-jest@^25.2.1:
semver "^5.5"
yargs-parser "^16.1.0"
+tslib@^1.10.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
+ integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+
tslib@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
@@ -7329,6 +8419,11 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
+tunnel@0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
+ integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
+
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@@ -7386,6 +8481,11 @@ undefsafe@^2.0.2:
dependencies:
debug "^2.2.0"
+"underscore@>= 1.3.1":
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.0.tgz#3ccdcbb824230fc6bf234ad0ddcd83dff4eafe5f"
+ integrity sha512-sCs4H3pCytsb5K7i072FAEC9YlSYFIbosvM0tAKAlpSSUgD7yC1iXSEGdl5XrDKQ1YUB+p/HDzYrSG2H2Vl36g==
+
underscore@~1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
@@ -7532,7 +8632,7 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
-uuid@^3.3.2, uuid@^3.4.0:
+uuid@^3.1.0, uuid@^3.3.2, uuid@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
@@ -7555,6 +8655,13 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
+validate-npm-package-name@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e"
+ integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34=
+ dependencies:
+ builtins "^1.0.3"
+
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
@@ -7703,7 +8810,7 @@ which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1:
dependencies:
isexe "^2.0.0"
-which@^2.0.1:
+which@^2.0.1, which@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
@@ -7724,11 +8831,21 @@ widest-line@^2.0.0:
dependencies:
string-width "^2.1.1"
+wmf@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
+ integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==
+
word-wrap@~1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+word@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
+ integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
+
worker-farm@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
@@ -7806,16 +8923,55 @@ xdg-basedir@^3.0.0:
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=
+xlsx@^0.16.8:
+ version "0.16.9"
+ resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.16.9.tgz#dacd5bb46bda6dd3743940c9c3dc1e2171826256"
+ integrity sha512-gxi1I3EasYvgCX1vN9pGyq920Ron4NO8PNfhuoA3Hpq6Y8f0ECXiy4OLrK4QZBnj1jx3QD+8Fq5YZ/3mPZ5iXw==
+ dependencies:
+ adler-32 "~1.2.0"
+ cfb "^1.1.4"
+ codepage "~1.14.0"
+ commander "~2.17.1"
+ crc-32 "~1.2.0"
+ exit-on-epipe "~1.0.1"
+ fflate "^0.3.8"
+ ssf "~0.11.2"
+ wmf "~1.0.1"
+ word "~0.3.0"
+
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+xml2js@^0.4.19:
+ version "0.4.23"
+ resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
+ integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
+ dependencies:
+ sax ">=0.6.0"
+ xmlbuilder "~11.0.0"
+
+xmlbuilder@~11.0.0:
+ version "11.0.1"
+ resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
+ integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+
+"xmldom@>= 0.1.x":
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.5.0.tgz#193cb96b84aa3486127ea6272c4596354cb4962e"
+ integrity sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==
+
xmlhttprequest-ssl@~1.5.4:
version "1.5.5"
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
+xpath.js@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/xpath.js/-/xpath.js-1.1.0.tgz#3816a44ed4bb352091083d002a383dd5104a5ff1"
+ integrity sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==
+
xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"