diff --git a/esbuild.package.js b/esbuild.package.js index abf352dc..3e14673c 100644 --- a/esbuild.package.js +++ b/esbuild.package.js @@ -34,5 +34,6 @@ esbuild }), addReleaseFlag(path.resolve(RELEASE_FOLDER_PATH, 'package.json')), ], + external: ['electron'], }) .catch(() => process.exit(1)); diff --git a/forward_engineering/api.js b/forward_engineering/api.js index 5c7a2c76..aaa87fdd 100644 --- a/forward_engineering/api.js +++ b/forward_engineering/api.js @@ -1,5 +1,6 @@ 'use strict'; +const { get } = require('lodash'); const { GlueClient, CreateDatabaseCommand, CreateTableCommand, GetDatabasesCommand } = require('@aws-sdk/client-glue'); const { getDatabaseStatement } = require('./helpers/databaseHelper'); const { getTableStatement } = require('./helpers/tableHelper'); @@ -9,12 +10,11 @@ const { getGlueDatabaseCreateStatement } = require('./helpers/awsCliScriptHelper const { getGlueTableCreateStatement } = require('./helpers/awsCliScriptHelpers/glueTableHelper'); const { getApiStatements } = require('./helpers/awsCliScriptHelpers/applyToInstanceHelper'); const sqlFormatter = require('./custom_modules/sql-formatter'); -const { setDependencies, dependencies } = require('./appDependencies'); +const { HttpHandler } = require('../shared/httpHandler/httpHandler'); module.exports = { - generateScript(data, logger, callback, app) { + generateScript(data, logger, callback) { try { - setDependencies(app); const jsonSchema = JSON.parse(data.jsonSchema); const modelDefinitions = JSON.parse(data.modelDefinitions); const internalDefinitions = JSON.parse(data.internalDefinitions); @@ -24,9 +24,7 @@ module.exports = { if (data.options.targetScriptOptions && data.options.targetScriptOptions.keyword === 'hiveQl') { const needMinify = ( - dependencies.lodash - .get(data, 'options.additionalOptions', []) - .find(option => option.id === 'minify') || {} + get(data, 'options.additionalOptions', []).find(option => option.id === 'minify') || {} ).value; return callback( @@ -58,9 +56,8 @@ module.exports = { } }, - generateContainerScript(data, logger, callback, app) { + generateContainerScript(data, logger, callback) { try { - setDependencies(app); const containerData = data.containerData; const modelDefinitions = JSON.parse(data.modelDefinitions); const externalDefinitions = JSON.parse(data.externalDefinitions); @@ -69,9 +66,7 @@ module.exports = { const internalDefinitions = parseEntities(data.entities, data.internalDefinitions); if (data.options.targetScriptOptions && data.options.targetScriptOptions.keyword === 'hiveQl') { const needMinify = ( - dependencies.lodash - .get(data, 'options.additionalOptions', []) - .find(option => option.id === 'minify') || {} + get(data, 'options.additionalOptions', []).find(option => option.id === 'minify') || {} ).value; const foreignKeyHashTable = foreignKeyHelper.getForeignKeyHashTable( @@ -124,8 +119,7 @@ module.exports = { } }, - async applyToInstance(data, logger, callback, app) { - setDependencies(app); + async applyToInstance(data, logger, callback) { if (!data.script) { return callback({ message: 'Empty script' }); } @@ -133,7 +127,7 @@ module.exports = { logger.clear(); logger.log('info', data, data.hiddenKeys); - const glueInstance = getGlueInstance(data, app); + const glueInstance = getGlueInstance({ connectionInfo: data, logger }); try { const { db, table } = getApiStatements(data.script); @@ -162,11 +156,10 @@ module.exports = { } }, - async testConnection(connectionInfo, logger, callback, app) { - setDependencies(app); + async testConnection(connectionInfo, logger, callback) { logger.log('info', connectionInfo, 'Test connection', connectionInfo.hiddenKeys); - const glueInstance = getGlueInstance(connectionInfo, app); + const glueInstance = getGlueInstance({ connectionInfo, logger }); try { const command = new GetDatabasesCommand(); @@ -188,13 +181,15 @@ const buildAWSCLIScript = (containerData, tableSchema) => { const buildAWSCLIModelScript = (containerData, tablesSchemas = {}) => { const dbStatement = getGlueDatabaseCreateStatement(containerData[0]); const tablesStatements = Object.entries(tablesSchemas).map(([key, value]) => { - return getGlueTableCreateStatement(value, dependencies.lodash.get(containerData[0], 'name', '')); + return getGlueTableCreateStatement(value, get(containerData[0], 'name', '')); }); return composeCLIStatements([dbStatement, ...tablesStatements]); }; -const getGlueInstance = (connectionInfo, app) => { - const { accessKeyId, secretAccessKey, region, sessionToken } = connectionInfo; +const getGlueInstance = ({ connectionInfo, logger }) => { + const { accessKeyId, secretAccessKey, region, sessionToken, queryRequestTimeout } = connectionInfo; + const httpHandler = new HttpHandler({ logger, requestTimeout: queryRequestTimeout }); + return new GlueClient({ region, credentials: { @@ -202,6 +197,7 @@ const getGlueInstance = (connectionInfo, app) => { secretAccessKey, sessionToken, }, + requestHandler: httpHandler, }); }; diff --git a/forward_engineering/appDependencies.js b/forward_engineering/appDependencies.js deleted file mode 100644 index 287e4ac5..00000000 --- a/forward_engineering/appDependencies.js +++ /dev/null @@ -1,10 +0,0 @@ -let dependencies = {}; - -const setDependencies = app => { - dependencies.lodash = app.require('lodash'); -}; - -module.exports = { - setDependencies, - dependencies, -}; diff --git a/forward_engineering/helpers/generalHelper.js b/forward_engineering/helpers/generalHelper.js index f96b7978..42e3fb70 100644 --- a/forward_engineering/helpers/generalHelper.js +++ b/forward_engineering/helpers/generalHelper.js @@ -1,6 +1,5 @@ 'use strict'; - -const { dependencies } = require('../appDependencies'); +const { partition, findLastIndex } = require('lodash'); const buildStatement = (mainStatement, isActivated) => { let composeStatements = (...statements) => { @@ -84,7 +83,7 @@ const commentDeactivatedStatements = (statement, isActivated = true) => { }; const commentDeactivatedInlineKeys = (keys, deactivatedKeyNames) => { - const [activatedKeys, deactivatedKeys] = dependencies.lodash.partition( + const [activatedKeys, deactivatedKeys] = partition( keys, key => !(deactivatedKeyNames.has(key) || deactivatedKeyNames.has(key.slice(1, -1))), ); @@ -114,7 +113,7 @@ const removeRedundantTrailingCommaFromStatement = statement => { if (splitedStatement.length < 4 || !splitedStatement[splitedStatement.length - 2].trim().startsWith('--')) { return statement; } - const lineWithTrailingCommaIndex = dependencies.lodash.findLastIndex(splitedStatement, line => { + const lineWithTrailingCommaIndex = findLastIndex(splitedStatement, line => { if (line.trim() !== ');' && !line.trim().startsWith('--')) { return true; } diff --git a/forward_engineering/helpers/indexHelper.js b/forward_engineering/helpers/indexHelper.js index b1a4db53..ed531784 100644 --- a/forward_engineering/helpers/indexHelper.js +++ b/forward_engineering/helpers/indexHelper.js @@ -1,6 +1,6 @@ 'use strict'; -const { dependencies } = require('../appDependencies'); +const { partition } = require('lodash'); const { getTab, buildStatement, getName, replaceSpaceWithUnderscore } = require('./generalHelper'); const schemaHelper = require('./jsonSchemaHelper'); const { getItemByPath } = require('./jsonSchemaHelper'); @@ -36,7 +36,7 @@ const getIndexKeys = (keys, jsonSchema, definitions) => { [jsonSchema, ...definitions], ); const idToNameHashTable = schemaHelper.getIdToNameHashTable([jsonSchema, ...definitions]); - const [activatedKeys, deactivatedKeys] = dependencies.lodash.partition(paths, path => { + const [activatedKeys, deactivatedKeys] = partition(paths, path => { const item = getItemByPath(path, jsonSchema); return item ? item.isActivated : true; }); diff --git a/forward_engineering/helpers/tableHelper.js b/forward_engineering/helpers/tableHelper.js index 1e986330..55960d83 100644 --- a/forward_engineering/helpers/tableHelper.js +++ b/forward_engineering/helpers/tableHelper.js @@ -1,5 +1,6 @@ 'use strict'; +const { partition } = require('lodash'); const { buildStatement, getName, @@ -12,7 +13,6 @@ const { } = require('./generalHelper'); const { getColumnsStatement, getColumnStatement, getColumns } = require('./columnHelper'); const keyHelper = require('./keyHelper'); -const { dependencies } = require('../appDependencies'); const getCreateStatement = ({ dbName, @@ -105,7 +105,7 @@ const getSortedKeys = (sortedKeys, deactivatedColumnNames, isParentItemActivated if (!Array.isArray(sortedKeys) || !sortedKeys.length) { return ''; } - const [activatedKeys, deactivatedKeys] = dependencies.lodash.partition( + const [activatedKeys, deactivatedKeys] = partition( sortedKeys, keyData => !deactivatedColumnNames.has(keyData.name), ); @@ -129,7 +129,7 @@ const getPartitionKeyStatement = (keys, isParentActivated) => { return ''; } - const [activatedKeys, deactivatedKeys] = dependencies.lodash.partition(keys, key => key.isActivated); + const [activatedKeys, deactivatedKeys] = partition(keys, key => key.isActivated); if (!isParentActivated || deactivatedKeys.length === 0) { return { isAllKeysDeactivated: false, keysString: getKeysStatement(keys) }; } diff --git a/package-lock.json b/package-lock.json index 2c39f153..e6e72de1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,14 @@ { "name": "Glue", - "version": "0.2.2", + "version": "0.2.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Glue", - "version": "0.2.2", + "version": "0.2.8", "dependencies": { "@aws-sdk/client-glue": "3.613.0", - "@aws-sdk/fetch-http-handler": "3.374.0", "antlr4": "4.8.0", "lodash": "4.17.21" }, @@ -32,6 +31,9 @@ "engines": { "hackolade": "6.9.11", "hackoladePlugin": "1.2.0" + }, + "peerDependencies": { + "electron": "^31" } }, "node_modules/@aws-crypto/sha256-browser": { @@ -495,110 +497,6 @@ "@aws-sdk/client-sts": "^3.609.0" } }, - "node_modules/@aws-sdk/fetch-http-handler": { - "version": "3.374.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.374.0.tgz", - "integrity": "sha512-Xt+4F6tGi/q9Z32kLo8SSm9krLlCY2oTLxCfP3/1SKY2wqWKHjAgpLmPD+GW7fdMjAwhDqzW5ZhcSmvHNvoD/w==", - "deprecated": "This package has moved to @smithy/fetch-http-handler", - "dependencies": { - "@smithy/fetch-http-handler": "^1.0.1", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/fetch-http-handler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-1.1.0.tgz", - "integrity": "sha512-N22C9R44u5WGlcY+Wuv8EXmCAq62wWwriRAuoczMEwAIjPbvHSthyPSLqI4S7kAST1j6niWg8kwpeJ3ReAv3xg==", - "dependencies": { - "@smithy/protocol-http": "^1.2.0", - "@smithy/querystring-builder": "^1.1.0", - "@smithy/types": "^1.2.0", - "@smithy/util-base64": "^1.1.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/is-array-buffer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-1.1.0.tgz", - "integrity": "sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/protocol-http": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-1.2.0.tgz", - "integrity": "sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==", - "dependencies": { - "@smithy/types": "^1.2.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/querystring-builder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-1.1.0.tgz", - "integrity": "sha512-gDEi4LxIGLbdfjrjiY45QNbuDmpkwh9DX4xzrR2AzjjXpxwGyfSpbJaYhXARw9p17VH0h9UewnNQXNwaQyYMDA==", - "dependencies": { - "@smithy/types": "^1.2.0", - "@smithy/util-uri-escape": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/types": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-1.2.0.tgz", - "integrity": "sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/util-base64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-1.1.0.tgz", - "integrity": "sha512-FpYmDmVbOXAxqvoVCwqehUN0zXS+lN8V7VS9O7I8MKeVHdSTsZzlwiMEvGoyTNOXWn8luF4CTDYgNHnZViR30g==", - "dependencies": { - "@smithy/util-buffer-from": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/util-buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-1.1.0.tgz", - "integrity": "sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw==", - "dependencies": { - "@smithy/is-array-buffer": "^1.1.0", - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-sdk/fetch-http-handler/node_modules/@smithy/util-uri-escape": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-1.1.0.tgz", - "integrity": "sha512-/jL/V1xdVRt5XppwiaEU8Etp5WHZj609n0xMTuehmCqdoOFbId1M+aEeDWZsQ+8JbEB/BJ6ynY2SlYmOaKtt8w==", - "dependencies": { - "tslib": "^2.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/@aws-sdk/middleware-host-header": { "version": "3.609.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.609.0.tgz", @@ -759,6 +657,68 @@ } } }, + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@electron/get/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@electron/get/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -1277,6 +1237,18 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@smithy/abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", @@ -1800,12 +1772,79 @@ "node": ">=16.0.0" } }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "peer": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.16.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.2.tgz", + "integrity": "sha512-91s/n4qUPV/wg8eE9KHYW1kouTfDk2FPGjXbBMfRWP/2vg1rCXNQL1OCabwGs0XSdukuK+MwCDXE30QpSeMUhQ==", + "peer": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "7.11.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", @@ -2265,6 +2304,13 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "optional": true, + "peer": true + }, "node_modules/bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", @@ -2292,6 +2338,57 @@ "node": ">=8" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "peer": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "peer": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -2376,6 +2473,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "peer": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2484,7 +2593,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -2497,17 +2605,53 @@ } } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "peer": true, + "engines": { + "node": ">=10" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, + "devOptional": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2524,7 +2668,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, + "devOptional": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -2559,6 +2703,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "optional": true, + "peer": true + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2589,12 +2740,48 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, + "node_modules/electron": { + "version": "31.4.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-31.4.0.tgz", + "integrity": "sha512-YTwKoAA+nrJMlI1TTHnIXLYWoQLKnhbkz0qxZcI7Hadcy0UaFMFs9xzwvH2MnrRpVJy7RKo49kVGuvSdRl8zMA==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "peer": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -2659,7 +2846,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, + "devOptional": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -2671,7 +2858,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 0.4" } @@ -2728,6 +2915,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "optional": true, + "peer": true + }, "node_modules/esbuild": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", @@ -2783,7 +2977,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=10" }, @@ -3164,6 +3358,41 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3246,6 +3475,15 @@ "reusify": "^1.0.4" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "peer": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -3339,7 +3577,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, + "devOptional": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3375,7 +3613,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, + "devOptional": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -3452,6 +3690,24 @@ "node": ">=10.13.0" } }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "optional": true, + "peer": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -3483,7 +3739,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, + "devOptional": true, "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -3519,7 +3775,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, + "devOptional": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -3527,11 +3783,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "peer": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/graphemer": { "version": "1.4.0", @@ -3561,7 +3841,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, + "devOptional": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -3573,7 +3853,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -3585,7 +3865,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 0.4" }, @@ -3612,7 +3892,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, + "devOptional": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -3620,6 +3900,25 @@ "node": ">= 0.4" } }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "peer": true + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/human-signals": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", @@ -4009,8 +4308,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -4024,6 +4322,13 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "optional": true, + "peer": true + }, "node_modules/json5": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", @@ -4052,7 +4357,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -4215,6 +4519,28 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "optional": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4255,6 +4581,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4279,8 +4614,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -4288,6 +4622,18 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npm-run-path": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", @@ -4328,7 +4674,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 0.4" } @@ -4404,7 +4750,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -4441,6 +4786,15 @@ "node": ">= 0.8.0" } }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4540,6 +4894,12 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "peer": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -4609,6 +4969,25 @@ "node": ">=6.0.0" } }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "peer": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4638,6 +5017,18 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -4673,6 +5064,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "peer": true + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4682,6 +5079,18 @@ "node": ">=4" } }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "peer": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/restore-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", @@ -4754,6 +5163,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "optional": true, + "peer": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4822,7 +5249,7 @@ "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, + "devOptional": true, "bin": { "semver": "bin/semver.js" }, @@ -4830,6 +5257,42 @@ "node": ">=10" } }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "optional": true, + "peer": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -4954,6 +5417,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "optional": true, + "peer": true + }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -5106,6 +5576,18 @@ "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "peer": true, + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5319,6 +5801,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "peer": true + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -5455,8 +5943,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/yaml": { "version": "2.3.1", @@ -5467,6 +5954,16 @@ "node": ">= 14" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "peer": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 1ab5ec9d..519bc61d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "description": "Hackolade plugin for AWS Glue Data Catalog", "dependencies": { "@aws-sdk/client-glue": "3.613.0", - "@aws-sdk/fetch-http-handler": "3.374.0", "antlr4": "4.8.0", "lodash": "4.17.21" }, @@ -65,5 +64,8 @@ "lint-staged": "14.0.1", "prettier": "3.2.5", "simple-git-hooks": "2.11.1" - } -} \ No newline at end of file + }, + "peerDependencies": { + "electron": "^31" + } +} diff --git a/reverse_engineering/adaptJsonSchema.js b/reverse_engineering/adaptJsonSchema.js index 43b0a7f6..5efe7a0c 100644 --- a/reverse_engineering/adaptJsonSchema.js +++ b/reverse_engineering/adaptJsonSchema.js @@ -1,16 +1,14 @@ -const { setDependencies } = require('./appDependencies'); +const { uniq } = require('lodash'); const mapJsonSchema = require('./helpers/mapJsonSchema'); -const adaptJsonSchema = (data, logger, callback, app) => { +const adaptJsonSchema = (data, logger, callback) => { try { - setDependencies(app); - const _ = app.require('lodash'); const jsonSchema = JSON.parse(data.jsonSchema); - const result = mapJsonSchema(_)(jsonSchema, {}, (schema, parentJsonSchema, key) => { + const result = mapJsonSchema(jsonSchema, {}, (schema, parentJsonSchema, key) => { if (schema.type === 'array' && !schema.subtype) { return { ...schema, - subtype: getArraySubtypeByChildren(_, schema), + subtype: getArraySubtypeByChildren(schema), }; } else { return schema; @@ -31,14 +29,14 @@ const adaptJsonSchema = (data, logger, callback, app) => { } }; -const getArraySubtypeByChildren = (_, arraySchema) => { +const getArraySubtypeByChildren = arraySchema => { const subtype = type => `array<${type}>`; if (!arraySchema.items) { return; } - if (Array.isArray(arraySchema.items) && _.uniq(arraySchema.items.map(item => item.type)).length > 1) { + if (Array.isArray(arraySchema.items) && uniq(arraySchema.items.map(item => item.type)).length > 1) { return subtype('union'); } diff --git a/reverse_engineering/api.js b/reverse_engineering/api.js index bc375730..23b55e55 100644 --- a/reverse_engineering/api.js +++ b/reverse_engineering/api.js @@ -1,7 +1,7 @@ -'use strict'; -const logHelper = require('./logHelper'); const fs = require('fs'); const antlr4 = require('antlr4'); +const { flatten } = require('lodash'); +const logHelper = require('./logHelper'); const HiveLexer = require('./parser/HiveLexer.js'); const HiveParser = require('./parser/HiveParser.js'); const hqlToCollectionsVisitor = require('./hqlToCollectionsVisitor.js'); @@ -10,25 +10,22 @@ const ExprErrorListener = require('./antlrErrorListener'); const { adaptJsonSchema } = require('./adaptJsonSchema'); const schemaHelper = require('./schemaHelper'); const connectionHelper = require('./helpers/connectionHelper'); -const { setDependencies, dependencies } = require('./appDependencies'); module.exports = { - async connect(connectionInfo) { - return connectionHelper.connect(connectionInfo); + async connect({ connectionInfo, logger }) { + return connectionHelper.connect({ connectionInfo, logger }); }, - disconnect(connectionInfo, logger, cb, app) { + disconnect(connectionInfo, logger, cb) { connectionHelper.close(); - cb(); }, - async testConnection(connectionInfo, logger, cb, app) { - setDependencies(app); + async testConnection(connectionInfo, logger, cb) { logInfo('Test connection', connectionInfo, logger); - const connection = await this.connect(connectionInfo); - const instance = connectionHelper.createInstance({ connection, _: dependencies.lodash, logger }); + const connection = await this.connect({ connectionInfo, logger }); + const instance = connectionHelper.createInstance({ connection, logger }); try { await instance.getDatabases(); @@ -39,14 +36,12 @@ module.exports = { } }, - async getDbCollectionsNames(connectionInfo, logger, cb, app) { - setDependencies(app); - + async getDbCollectionsNames(connectionInfo, logger, cb) { logInfo('Retrieving databases and tables information', connectionInfo, logger); try { - const connection = await this.connect(connectionInfo); - const instance = connectionHelper.createInstance({ connection, _: dependencies.lodash, logger }); + const connection = await this.connect({ connectionInfo, logger }); + const instance = connectionHelper.createInstance({ connection, logger }); const { databaseList, isFullyUploaded } = await instance.getDatabases(); const dbsCollections = databaseList.map(async db => { const dbCollections = await instance.getTables(db.Name); @@ -79,8 +74,7 @@ module.exports = { } }, - async getDbCollectionsData(data, logger, cb, app) { - setDependencies(app); + async getDbCollectionsData(data, logger, cb) { logger.log('info', data, 'Retrieving schema', data.hiddenKeys); const { collectionData } = data; @@ -88,8 +82,8 @@ module.exports = { const tables = collectionData.collections; try { - const connection = await this.connect(data); - const instance = connectionHelper.createInstance({ connection, _: dependencies.lodash, logger }); + const connection = await this.connect({ connectionInfo: data, logger }); + const instance = connectionHelper.createInstance({ connection, logger }); const tablesDataPromise = databases.map(async dbName => { const dbDescription = await instance.getDatabaseDescription(dbName); @@ -139,10 +133,8 @@ module.exports = { } }, - reFromFile: async (data, logger, callback, app) => { + reFromFile: async (data, logger, callback) => { try { - setDependencies(app); - const _ = dependencies.lodash; const input = await handleFileData(data.filePath); const chars = new antlr4.InputStream(input); const lexer = new HiveLexer.HiveLexer(chars); @@ -158,7 +150,7 @@ module.exports = { const commands = tree.accept(hqlToCollectionsGenerator); const { result, info, relationships } = commandsService.convertCommandsToReDocs( - _.flatten(commands).filter(Boolean), + flatten(commands).filter(Boolean), input, ); callback(null, result, info, relationships, 'multipleSchema'); diff --git a/reverse_engineering/appDependencies.js b/reverse_engineering/appDependencies.js deleted file mode 100644 index 287e4ac5..00000000 --- a/reverse_engineering/appDependencies.js +++ /dev/null @@ -1,10 +0,0 @@ -let dependencies = {}; - -const setDependencies = app => { - dependencies.lodash = app.require('lodash'); -}; - -module.exports = { - setDependencies, - dependencies, -}; diff --git a/reverse_engineering/commandsService.js b/reverse_engineering/commandsService.js index f2001b58..40f721da 100644 --- a/reverse_engineering/commandsService.js +++ b/reverse_engineering/commandsService.js @@ -1,4 +1,4 @@ -const { dependencies } = require('./appDependencies'); +const { keys, get, fromPairs, findIndex } = require('lodash'); const { set, findEntityIndex, @@ -49,7 +49,7 @@ const convertCommandsToEntities = (commands, originalScript) => { const bucket = statementData.bucketName || entitiesData.currentBucket; - if (dependencies.lodash.keys(COMMANDS_ACTION_MAP).includes(command)) { + if (keys(COMMANDS_ACTION_MAP).includes(command)) { return COMMANDS_ACTION_MAP[command](entitiesData, bucket, statementData, originalScript); } @@ -182,7 +182,7 @@ const updateField = (entitiesData, bucket, statementData) => { } const entity = entities[index]; - const field = dependencies.lodash.get(entity, 'schema.properties', {})[statementData.name]; + const field = get(entity, 'schema.properties', {})[statementData.name]; if (!field) { return entitiesData; } @@ -348,10 +348,8 @@ const addRelationship = (entitiesData, bucket, statementData) => { }; const updateProperties = (properties, statementData) => { - const _ = dependencies.lodash; - - return _.fromPairs( - _.keys(properties).map(columnName => { + return fromPairs( + keys(properties).map(columnName => { if (!statementData.fields.includes(columnName)) { return [columnName, properties[columnName]]; } @@ -419,9 +417,9 @@ const addToResourcePlan = (entitiesData, bucket, statementData) => { const updatedResourcePlan = { ...resourcePlans[resourcePlanIndex], - [identifier + 's']: dependencies.lodash - .get(resourcePlans, `${resourcePlanIndex}.${identifier + 's'}`, []) - .concat(statementData[identifier]), + [identifier + 's']: get(resourcePlans, `${resourcePlanIndex}.${identifier + 's'}`, []).concat( + statementData[identifier], + ), }; return { @@ -443,7 +441,7 @@ const addMapping = (entitiesData, bucket, statementData) => { } const planPools = resourcePlans[resourceIndex].pools || []; - const poolIndex = dependencies.lodash.findIndex(planPools, ({ name }) => name === statementData.poolName); + const poolIndex = findIndex(planPools, ({ name }) => name === statementData.poolName); if (poolIndex < 0) { return entitiesData; } @@ -639,7 +637,7 @@ const removeMapping = (entitiesData, bucket, statementData) => { } const planPools = resourcePlans[resourceIndex].pools || []; - const poolIndex = dependencies.lodash.findIndex(planPools, ({ mappings }) => + const poolIndex = findIndex(planPools, ({ mappings }) => (mappings || []).find(({ name }) => name === statementData.name), ); if (poolIndex < 0) { @@ -680,11 +678,11 @@ const updateEntityLevelData = (entitiesData, bucket, statementData) => { }; const getResourcePlanIndex = (resourcePlans, resourceName) => { - return dependencies.lodash.findIndex(resourcePlans, plan => plan.name === resourceName); + return findIndex(resourcePlans, plan => plan.name === resourceName); }; const addMappingToPoolByIndex = (pools, poolIndex, mapping) => { - return { ...pools[poolIndex], mappings: dependencies.lodash.get(pools[poolIndex], 'mappings', []).concat(mapping) }; + return { ...pools[poolIndex], mappings: get(pools[poolIndex], 'mappings', []).concat(mapping) }; }; const removeMappingFromPool = (pools, poolIndex, mappingName) => { @@ -692,10 +690,9 @@ const removeMappingFromPool = (pools, poolIndex, mappingName) => { }; const getResourcePlanAndItemIndexes = (resourcePlans, statementData, identifier) => { - const _ = dependencies.lodash; const resourcePlanIndex = getResourcePlanIndex(resourcePlans, statementData.resourceName); - const items = _.get(resourcePlans, `${resourcePlanIndex}.${identifier + 's'}`, []); - const itemIndex = _.findIndex(items, ({ name }) => name === statementData[identifier]); + const items = get(resourcePlans, `${resourcePlanIndex}.${identifier + 's'}`, []); + const itemIndex = findIndex(items, ({ name }) => name === statementData[identifier]); return { resourcePlanIndex, itemIndex }; }; diff --git a/reverse_engineering/connection_settings_modal/connectionSettingsModalConfig.json b/reverse_engineering/connection_settings_modal/connectionSettingsModalConfig.json index 6c0e294f..c3e94b94 100644 --- a/reverse_engineering/connection_settings_modal/connectionSettingsModalConfig.json +++ b/reverse_engineering/connection_settings_modal/connectionSettingsModalConfig.json @@ -121,80 +121,5 @@ "isHiddenKey": true } ] - }, - { - "lowerTab": "SSL", - "structure": [ - { - "inputLabel": "SSL", - "inputKeyword": "sslType", - "inputType": "select", - "options": [ - { - "value": "Off", - "label": "Off" - }, - { - "value": "Server validation", - "label": "Server validation" - }, - { - "value": "Server and client validation", - "label": "Server and client validation" - } - ] - }, - { - "inputLabel": "Certificate Authority", - "inputKeyword": "certAuthorityPath", - "inputType": "file", - "inputPlaceholder": "Certificate Authority", - "extensions": ["pem", "crt", "key", "cer"], - "dependency": { - "key": "sslType", - "value": "Server validation" - } - }, - { - "inputLabel": "Client Certificate", - "inputKeyword": "clientCert", - "inputType": "file", - "inputPlaceholder": "Client Certificate", - "extensions": ["pem", "crt", "key", "cer"], - "dependency": { - "key": "sslType", - "value": "Server and client validation" - }, - "validation": { - "regex": "([^\\s])" - } - }, - { - "inputLabel": "Client Private Key", - "inputKeyword": "clientPrivateKey", - "inputType": "file", - "inputPlaceholder": "Client Private Key", - "dependency": { - "key": "sslType", - "value": "Server and client validation" - }, - "validation": { - "regex": "([^\\s])" - } - }, - { - "inputLabel": "Password", - "inputKeyword": "clientKeyPassword", - "inputType": "password", - "inputPlaceholder": "Password", - "dependency": { - "key": "sslType", - "value": "Server and client validation" - }, - "validation": { - "regex": "([^\\s])" - } - } - ] } ] diff --git a/reverse_engineering/helpers/connectionHelper.js b/reverse_engineering/helpers/connectionHelper.js index 65d59702..74c91b3a 100644 --- a/reverse_engineering/helpers/connectionHelper.js +++ b/reverse_engineering/helpers/connectionHelper.js @@ -8,64 +8,17 @@ const { const fs = require('fs'); const https = require('https'); const { mapTableData } = require('./tablePropertiesHelper'); -const { HttpHandler } = require('../httpHandler/HttpHandler'); +const { HttpHandler } = require('../../shared/httpHandler/httpHandler'); let connection; let databaseLoadContinuationToken; const MAX_RESULTS = 100; -const readCertificateFile = path => { - if (!path) { - return Promise.resolve(''); - } - - return new Promise(resolve => { - fs.readFile(path, 'utf8', (err, data) => { - if (err) { - resolve(''); - } - resolve(data); - }); - }); -}; - -const getSslOptions = async connectionInfo => { - switch (connectionInfo.sslType) { - case 'Server validation': { - const certAuthority = await readCertificateFile(connectionInfo.certAuthorityPath); - return { - ssl: true, - ca: [certAuthority], - }; - } - case 'Server and client validation': { - const certAuthority = await readCertificateFile(connectionInfo.certAuthorityPath); - const key = await readCertificateFile(connectionInfo.clientPrivateKey); - const cert = await readCertificateFile(connectionInfo.clientCert); - return { - ssl: true, - ca: [certAuthority], - key: [key], - cert: [cert], - passphrase: connectionInfo.clientKeyPassword, - }; - } - default: - return { ssl: false }; - } -}; - -const createConnection = async connectionInfo => { - const { accessKeyId, secretAccessKey, region, sessionToken } = connectionInfo; - const sslOptions = await getSslOptions(connectionInfo); - - const agent = new https.Agent({ - rejectUnauthorized: true, - ...sslOptions, - }); +const createConnection = async ({ connectionInfo, logger }) => { + const { accessKeyId, secretAccessKey, region, sessionToken, queryRequestTimeout } = connectionInfo; - const httpHandler = new HttpHandler(agent); + const httpHandler = new HttpHandler({ logger, requestTimeout: queryRequestTimeout }); return new GlueClient({ region, @@ -74,15 +27,15 @@ const createConnection = async connectionInfo => { secretAccessKey, sessionToken, }, - requestHandler: httpHandler.handler, + requestHandler: httpHandler, }); }; -const connect = async connectionInfo => { +const connect = async ({ connectionInfo, logger }) => { if (connection) { return connection; } - connection = await createConnection(connectionInfo); + connection = await createConnection({ connectionInfo, logger }); return connection; }; @@ -97,7 +50,7 @@ const close = () => { } }; -const createInstance = ({ connection, _ = {}, logger = {} }) => { +const createInstance = ({ connection, logger = {} }) => { const getDatabases = async () => { const command = new GetDatabasesCommand({ MaxResults: MAX_RESULTS, NextToken: databaseLoadContinuationToken }); const dbsData = await connection.send(command); @@ -106,7 +59,7 @@ const createInstance = ({ connection, _ = {}, logger = {} }) => { return { databaseList: dbsData.DatabaseList, - isFullyUploaded: !Boolean(dbsData.NextToken), + isFullyUploaded: !dbsData.NextToken, }; }; @@ -138,7 +91,7 @@ const createInstance = ({ connection, _ = {}, logger = {} }) => { const rawTableData = await connection.send(command); - return mapTableData({ tableData: rawTableData, _, logger }); + return mapTableData({ tableData: rawTableData, logger }); }; return { diff --git a/reverse_engineering/helpers/mapJsonSchema.js b/reverse_engineering/helpers/mapJsonSchema.js index 390e4a64..4863732d 100644 --- a/reverse_engineering/helpers/mapJsonSchema.js +++ b/reverse_engineering/helpers/mapJsonSchema.js @@ -1,9 +1,11 @@ -const mapJsonSchema = _ => (jsonSchema, parentJsonSchema, callback, key) => { +const { isEmpty, isPlainObject, has, partial } = require('lodash'); + +const mapJsonSchema = (jsonSchema, parentJsonSchema, callback, key) => { const mapProperties = (properties, mapper) => Object.keys(properties).reduce((newProperties, propertyName) => { const schema = mapper(properties[propertyName], propertyName); - if (_.isEmpty(schema)) { + if (isEmpty(schema)) { return newProperties; } @@ -11,8 +13,8 @@ const mapJsonSchema = _ => (jsonSchema, parentJsonSchema, callback, key) => { }, {}); const mapItems = (items, mapper) => { if (Array.isArray(items)) { - return items.map((jsonSchema, i) => mapper(jsonSchema, i)).filter(item => !_.isEmpty(item)); - } else if (_.isPlainObject(items)) { + return items.map((jsonSchema, i) => mapper(jsonSchema, i)).filter(item => !isEmpty(item)); + } else if (isPlainObject(items)) { return mapper(items, 0); } else { return items; @@ -33,16 +35,16 @@ const mapJsonSchema = _ => (jsonSchema, parentJsonSchema, callback, key) => { const subSchema = subSchemasUpdated[0]; - if (!_.has(subSchema, 'properties')) { + if (!has(subSchema, 'properties')) { return subSchemasUpdated; } - if (!_.has(parentJsonSchema, 'properties')) { + if (!has(parentJsonSchema, 'properties')) { parentJsonSchema.properties = {}; } Object.keys(subSchema.properties).forEach(key => { - if (_.has(parentJsonSchema, 'properties.' + key)) { + if (has(parentJsonSchema, 'properties.' + key)) { return; } @@ -59,7 +61,7 @@ const mapJsonSchema = _ => (jsonSchema, parentJsonSchema, callback, key) => { const schema = mapper(jsonSchema[propertyName], propertyName); - if (_.isEmpty(schema)) { + if (isEmpty(schema)) { const copySchema = Object.assign({}, jsonSchema); delete copySchema[propertyName]; @@ -72,18 +74,30 @@ const mapJsonSchema = _ => (jsonSchema, parentJsonSchema, callback, key) => { }); }, jsonSchema); }; - if (!_.isPlainObject(jsonSchema)) { + if (!isPlainObject(jsonSchema)) { return jsonSchema; } const copyJsonSchema = Object.assign({}, jsonSchema); - const mapper = _.partial(mapJsonSchema(_), _, copyJsonSchema, callback); + const mapper = partial(mapJsonSchema, partial.placeholder, copyJsonSchema, callback); const propertiesLike = ['properties', 'definitions', 'patternProperties']; const itemsLike = ['items', 'not']; const choices = ['oneOf', 'allOf', 'anyOf']; - const jsonSchemaWithNewProperties = applyTo(propertiesLike, copyJsonSchema, _.partial(mapProperties, _, mapper)); - const updatedItems = applyTo(itemsLike, jsonSchemaWithNewProperties, _.partial(mapItems, _, mapper)); - const newJsonSchema = applyTo(choices, updatedItems, _.partial(mapChoices, updatedItems, _, mapper)); + const jsonSchemaWithNewProperties = applyTo( + propertiesLike, + copyJsonSchema, + partial(mapProperties, partial.placeholder, mapper), + ); + const updatedItems = applyTo( + itemsLike, + jsonSchemaWithNewProperties, + partial(mapItems, partial.placeholder, mapper), + ); + const newJsonSchema = applyTo( + choices, + updatedItems, + partial(mapChoices, updatedItems, partial.placeholder, mapper), + ); return callback(newJsonSchema, parentJsonSchema, key); }; diff --git a/reverse_engineering/helpers/tablePropertiesHelper.js b/reverse_engineering/helpers/tablePropertiesHelper.js index b4b1a9db..57819f3c 100644 --- a/reverse_engineering/helpers/tablePropertiesHelper.js +++ b/reverse_engineering/helpers/tablePropertiesHelper.js @@ -1,3 +1,5 @@ +const { get } = require('lodash'); + const mapSortColumns = (items = []) => { return items.map(item => ({ name: item.Column, @@ -9,15 +11,14 @@ const getSerDeLibrary = (data = {}) => { return data.SerializationLibrary; }; -const mapSerDePaths = (_, data = {}) => { - return _.get(data, 'Parameters.paths', '').split(','); +const mapSerDePaths = (data = {}) => { + return get(data, 'Parameters.paths', '').split(','); }; const mapSerDeParameters = (parameters = {}) => { return Object.entries(parameters).reduce((acc, [key, value]) => { if (key !== 'paths') { acc.push({ serDeKey: key, serDeValue: value }); - return acc; } return acc; }, []); @@ -76,7 +77,7 @@ const mapColumns = ({ columns = [], logger = {} }) => { return mapped; }; -const mapTableData = ({ tableData, _, logger }) => { +const mapTableData = ({ tableData, logger }) => { const partitionKeys = mapColumns({ columns: tableData.Table.PartitionKeys, logger }); return { @@ -95,7 +96,7 @@ const mapTableData = ({ tableData, _, logger }) => { inputFormatClassname: tableData.Table.StorageDescriptor?.InputFormat, outputFormatClassname: tableData.Table.StorageDescriptor?.OutputFormat, serDeLibrary: getSerDeLibrary(tableData.Table.StorageDescriptor?.SerdeInfo), - parameterPaths: mapSerDePaths(_, tableData.Table.StorageDescriptor?.SerdeInfo), + parameterPaths: mapSerDePaths(tableData.Table.StorageDescriptor?.SerdeInfo), serDeParameters: mapSerDeParameters(tableData.Table.StorageDescriptor?.SerdeInfo?.Parameters), classification: getClassification(tableData.Table.Parameters), }, diff --git a/reverse_engineering/hqlToCollectionsVisitor.js b/reverse_engineering/hqlToCollectionsVisitor.js index 89cb8280..9f6a31dd 100644 --- a/reverse_engineering/hqlToCollectionsVisitor.js +++ b/reverse_engineering/hqlToCollectionsVisitor.js @@ -1,3 +1,4 @@ +const { pickBy, isNumber, isBoolean, isEmpty, uniq } = require('lodash'); const { HiveParserVisitor } = require('./parser/HiveParserVisitor'); const { HiveParser } = require('./parser/HiveParser'); const { @@ -29,7 +30,6 @@ const { } = require('./commandsService'); const schemaHelper = require('./schemaHelper'); -const { dependencies } = require('./appDependencies'); const ALLOWED_COMMANDS = [ HiveParser.RULE_createTableStatement, @@ -70,7 +70,6 @@ class Visitor extends HiveParserVisitor { } visitCreateTableStatement(ctx) { - const _ = dependencies.lodash; const [tableName, tableLikeName] = this.visit(ctx.tableName()); const compositePartitionKey = this.visitWhenExists(ctx, 'tablePartition', []); const { compositeClusteringKey, numBuckets, sortedByKey } = this.visitWhenExists(ctx, 'tableBuckets', {}); @@ -104,7 +103,7 @@ class Visitor extends HiveParserVisitor { properties: { ...properties, ...convertKeysToProperties(compositePartitionKey) }, }), tableLikeName: (tableLikeName || {}).table, - entityLevelData: _.pickBy( + entityLevelData: pickBy( { temporaryTable, externalTable, @@ -121,7 +120,7 @@ class Visitor extends HiveParserVisitor { ...storedAsTable, ...tableRowFormat, }, - prop => _.isNumber(prop) || _.isBoolean(prop) || !_.isEmpty(prop), + prop => isNumber(prop) || isBoolean(prop) || !isEmpty(prop), ), }, ...tableForeignKeys.map(fkData => ({ @@ -750,7 +749,7 @@ class Visitor extends HiveParserVisitor { if (!complexTypes) { return { - type: dependencies.lodash.uniq(types.map(schema => schema.type)), + type: uniq(types.map(schema => schema.type)), }; } @@ -1022,7 +1021,6 @@ class Visitor extends HiveParserVisitor { } visitCreateIndexStatement(ctx) { - const _ = dependencies.lodash; const { name, database, table, columns, SecIndxHandler } = this.visit(ctx.createIndexMainStatement()); const SecIndxWithDeferredRebuild = Boolean(ctx.KW_WITH() && ctx.KW_DEFERRED() && ctx.KW_REBUILD()); const SecIndxProperties = this.visitWhenExists(ctx, 'tableProperties'); @@ -1035,7 +1033,7 @@ class Visitor extends HiveParserVisitor { collectionName: table, name, columns, - data: _.pickBy( + data: pickBy( { SecIndxWithDeferredRebuild, SecIndxHandler, @@ -1043,7 +1041,7 @@ class Visitor extends HiveParserVisitor { SecIndxTable, SecIndxComments, }, - prop => _.isBoolean(prop) || !_.isEmpty(prop), + prop => isBoolean(prop) || !isEmpty(prop), ), }; } @@ -1100,7 +1098,7 @@ class Visitor extends HiveParserVisitor { } visitRpAssignList(ctx) { - return this.visit(ctx.rpAssign()).find(({ parallelism }) => !dependencies.lodash.isEmpty(parallelism)); + return this.visit(ctx.rpAssign()).find(({ parallelism }) => !isEmpty(parallelism)); } visitRpAssign(ctx) { diff --git a/reverse_engineering/httpHandler/HttpHandler.js b/reverse_engineering/httpHandler/HttpHandler.js deleted file mode 100644 index c08bfac0..00000000 --- a/reverse_engineering/httpHandler/HttpHandler.js +++ /dev/null @@ -1,16 +0,0 @@ -const { FetchHttpHandler } = require('@aws-sdk/fetch-http-handler'); - -class HttpHandler { - handler = null; - - constructor(agent) { - this.agent = agent; - this.handler = new FetchHttpHandler(); - } - - get() { - return this.handler; - } -} - -module.exports = { HttpHandler }; diff --git a/reverse_engineering/schemaHelper.js b/reverse_engineering/schemaHelper.js index d23b19cd..db71d663 100644 --- a/reverse_engineering/schemaHelper.js +++ b/reverse_engineering/schemaHelper.js @@ -1,4 +1,4 @@ -const { dependencies } = require('./appDependencies'); +const { get, uniq } = require('lodash'); const cleanContent = str => { const start = str.indexOf('<'); @@ -188,7 +188,7 @@ const parseSet = ([content], sample = []) => { const parsePrimitive = ([type]) => { const preparedType = type.trim().toLowerCase(); const hiveType = preparedType.replace(/\(.*?\)$/, ''); - const modifiers = dependencies.lodash.get(preparedType.match(/\((.*?)\)$/), '[1]', '').split(','); + const modifiers = get(preparedType.match(/\((.*?)\)$/), '[1]', '').split(','); switch (hiveType) { case 'string': @@ -243,7 +243,7 @@ const parseUnion = (types, sample) => { if (!complexTypes) { return { - type: dependencies.lodash.uniq(jsonSchemas.map(schema => schema.type)), + type: uniq(jsonSchemas.map(schema => schema.type)), }; } diff --git a/shared/httpHandler/httpHandler.js b/shared/httpHandler/httpHandler.js new file mode 100644 index 00000000..9247457b --- /dev/null +++ b/shared/httpHandler/httpHandler.js @@ -0,0 +1,104 @@ +/** + * @typedef {import('@aws-sdk/client-glue/dist-types/GlueClient').ClientDefaults[requestHandler]} RequestHandler + * @typedef {import('@smithy/protocol-http/dist-types').HttpRequest} HttpRequest + * @typedef {import('@smithy/protocol-http/dist-types').HttpResponse} HttpResponse + **/ + +const { net } = require('electron'); +const { isEmpty } = require('lodash'); +const { requestTimeout } = require('./requestTimeout'); + +/** + * @class + * @implements { RequestHandler } + */ +class HttpHandler { + constructor({ requestTimeout, logger } = {}) { + this.requestTimeout = requestTimeout; + this.logger = logger; + } + + getAbortError = () => { + const abortError = new Error('Request aborted'); + abortError.name = 'AbortError'; + return abortError; + }; + + /** + * @param { HttpRequest } request + * @param { Object } [options] + * @param { AbortSignal } [options.abortSignal] + * @returns { Promise<{ response: HttpResponse }> } + */ + async handle(request, { abortSignal } = {}) { + if (abortSignal?.aborted) { + throw this.getAbortError(); + } + + const { method, query, protocol, port, hostname, body, headers: requestHeaders } = request; + + const headers = new Headers(requestHeaders); + const headersToSkip = ['content-length', 'host']; + headersToSkip.forEach(header => headers.delete(header)); + + let { path } = request; + + if (!isEmpty(query) && typeof query === 'object') { + path += `?${new URLSearchParams(query).toString()}`; + } + + const portParam = port ? `:${port}` : ''; + + const url = `${protocol}//${hostname}${portParam}${path}`; + + const methodsWithoutBody = ['GET', 'HEAD']; + + const requestOptions = { + body: methodsWithoutBody.includes(method) ? undefined : body, + headers, + method, + }; + + if (typeof AbortController !== 'undefined') { + requestOptions.signal = abortSignal; + } + + const fetchRequest = new Request(url, requestOptions); + + this.logger?.log('info', { fetchRequest }, 'RE http request'); + + const resultResolver = async result => { + const fetchHeaders = result.headers; + const transformedHeaders = Object.fromEntries(fetchHeaders.entries()); + + const hasReadableStream = result.body !== undefined; + + const response = { + headers: transformedHeaders, + statusCode: result.status, + body: hasReadableStream ? result.body : await result.blob(), + }; + + return { response }; + }; + + const race = [ + net.fetch(fetchRequest).then(resultResolver), + requestTimeout({ requestTimeout: this.requestTimeout }), + ]; + + if (abortSignal) { + race.push( + new Promise((resolve, reject) => { + abortSignal.onabort = () => { + reject(this.getAbortError()); + }; + }), + ); + } + + return Promise.race(race); + } +} + +module.exports = { HttpHandler }; diff --git a/shared/httpHandler/requestTimeout.js b/shared/httpHandler/requestTimeout.js new file mode 100644 index 00000000..98fc7a02 --- /dev/null +++ b/shared/httpHandler/requestTimeout.js @@ -0,0 +1,13 @@ +async function requestTimeout({ requestTimeout = 0 }) { + return new Promise((_, reject) => { + if (requestTimeout) { + setTimeout(() => { + const timeoutError = new Error(`Request did not complete within ${requestTimeout} ms`); + timeoutError.name = 'TimeoutError'; + reject(timeoutError); + }, requestTimeout); + } + }); +} + +module.exports = { requestTimeout };