diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 3c1a994a..3439bc42 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -29,14 +29,3 @@ jobs: - uses: extractions/setup-just@v1 - name: license checker run: 'cd backend && npx license-checker --onlyAllow="MIT;ISC;Python-2.0;Apache-2.0;BSD;MPL;CC;Custom: http://github.com/dscape/statsd-parser;" --excludePrivatePackages' - lint: - runs-on: - labels: ubuntu-latest-4-cores - steps: - - uses: actions/checkout@v3 - - uses: extractions/setup-just@v1 - - uses: actions/setup-node@v3 - with: - node-version: '18' - - run: cd backend && yarn install - - run: cd backend && yarn run lint diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 00000000..5588a072 --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,22 @@ +name: Code quality + +on: + push: + pull_request: + +jobs: + quality: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + persist-credentials: false + - name: Setup Biome + uses: biomejs/setup-biome@v2 + with: + version: latest + - name: Run Biome + run: biome ci --formatter-enabled=false --assist-enabled=false . diff --git a/autoadmin-ws-server/src/index.js b/autoadmin-ws-server/src/index.js index 6a040965..6c296eba 100644 --- a/autoadmin-ws-server/src/index.js +++ b/autoadmin-ws-server/src/index.js @@ -1,4 +1,3 @@ -'use strict'; import express, { Router, json } from 'express'; import axios from 'axios'; const app = express(); diff --git a/backend/package.json b/backend/package.json index 79d59303..cccadd23 100644 --- a/backend/package.json +++ b/backend/package.json @@ -14,7 +14,6 @@ "start:dev": "nest start --watch --preserveWatchOutput", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", - "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "ava test/ava-tests/non-saas-tests/* --serial", "test-all": "ava --timeout=5m", "test-saas": "ava test/ava-tests/saas-tests/* ", diff --git a/backend/src/exceptions/custom-exceptions/validation-exception.ts b/backend/src/exceptions/custom-exceptions/validation-exception.ts index 8b24c77e..1ed547c9 100644 --- a/backend/src/exceptions/custom-exceptions/validation-exception.ts +++ b/backend/src/exceptions/custom-exceptions/validation-exception.ts @@ -15,8 +15,6 @@ export class ValidationException extends HttpException { ).join(', ')}`; }) .join('.\n'); - } else { - originalMessage = originalMessage; } super(originalMessage, HttpStatus.BAD_REQUEST); this.internalCode = ExceptionsInternalCodes.VALIDATOR_EXCEPTION; diff --git a/backend/src/helpers/constants/constants.ts b/backend/src/helpers/constants/constants.ts index fa4f3e48..569f0c12 100644 --- a/backend/src/helpers/constants/constants.ts +++ b/backend/src/helpers/constants/constants.ts @@ -92,7 +92,7 @@ export const Constants = { }, ONE_DAY_AGO: (): Date => { - return new Date(new Date().getTime() - 24 * 60 * 60 * 1000); + return new Date(Date.now() - 24 * 60 * 60 * 1000); }, CRON_SHEDULE: '30 5 13 * * *', @@ -274,6 +274,7 @@ export const Constants = { // break; case type.toLowerCase().includes('dynamodb'): connection = parseTestDynamoDBConnectionString(connection_string) as CreateConnectionDto; + break; default: break; } diff --git a/backend/src/helpers/encryption/encryptor.ts b/backend/src/helpers/encryption/encryptor.ts index 8f47a9a9..212b70b9 100644 --- a/backend/src/helpers/encryption/encryptor.ts +++ b/backend/src/helpers/encryption/encryptor.ts @@ -140,15 +140,17 @@ export class Encryptor { hash = CryptoJS.SHA384(data); return hash.toString(CryptoJS.enc.Hex); - case EncryptionAlgorithmEnum.pbkdf2: + case EncryptionAlgorithmEnum.pbkdf2: { const salt = CryptoJS.lib.WordArray.random(128 / 8); return CryptoJS.PBKDF2(data, salt, { keySize: 256 / 32, }).toString(); + } - case EncryptionAlgorithmEnum.bcrypt: + case EncryptionAlgorithmEnum.bcrypt: { const bSalt = await bcrypt.genSalt(); return await bcrypt.hash(data, bSalt); + } case EncryptionAlgorithmEnum.argon2: return await argon2.hash(data); diff --git a/backend/src/helpers/validators/validation-helper.ts b/backend/src/helpers/validators/validation-helper.ts index e0bd7976..87d016f4 100644 --- a/backend/src/helpers/validators/validation-helper.ts +++ b/backend/src/helpers/validators/validation-helper.ts @@ -56,10 +56,6 @@ export class ValidationHelper { return countries.isValid(countryCode); } - public isValidUrl(url: string): boolean { - return validator.isURL(url); - } - public static validateOrThrowHttpExceptionEmail(email: string): boolean { const isEmailValid = ValidationHelper.isValidEmail(email); if (isEmailValid) { diff --git a/backend/test/mock.factory.ts b/backend/test/mock.factory.ts index 8afaa68b..7754b728 100644 --- a/backend/test/mock.factory.ts +++ b/backend/test/mock.factory.ts @@ -335,10 +335,11 @@ export class MockFactory { return this.generateConnectionToSchemaOracleDBInDocker(); case 'mssql': return this.generateConnectionToTestMsSQlDBInDocker(); - case 'mysql': + case 'mysql': { const config = this.generateConnectionToTestMySQLDBInDocker(); config.type = 'mysql2'; return config; + } } } diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..db9e07e7 --- /dev/null +++ b/biome.json @@ -0,0 +1,222 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.8/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false + }, + "formatter": { + "enabled": true, + "indentStyle": "tab" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": false, + "a11y": { + "noAccessKey": "error", + "noAriaHiddenOnFocusable": "error", + "noAriaUnsupportedElements": "error", + "noAutofocus": "error", + "noDistractingElements": "error", + "noHeaderScope": "error", + "noInteractiveElementToNoninteractiveRole": "error", + "noLabelWithoutControl": "error", + "noNoninteractiveElementToInteractiveRole": "error", + "noNoninteractiveTabindex": "error", + "noPositiveTabindex": "error", + "noRedundantAlt": "error", + "noRedundantRoles": "error", + "noStaticElementInteractions": "error", + "noSvgWithoutTitle": "error", + "useAltText": "error", + "useAnchorContent": "error", + "useAriaActivedescendantWithTabindex": "error", + "useAriaPropsForRole": "error", + "useAriaPropsSupportedByRole": "error", + "useButtonType": "error", + "useFocusableInteractive": "error", + "useHeadingContent": "error", + "useHtmlLang": "error", + "useIframeTitle": "error", + "useKeyWithClickEvents": "error", + "useKeyWithMouseEvents": "error", + "useMediaCaption": "error", + "useSemanticElements": "error", + "useValidAnchor": "error", + "useValidAriaProps": "error", + "useValidAriaRole": "error", + "useValidAriaValues": "error", + "useValidAutocomplete": "error", + "useValidLang": "error" + }, + "complexity": { + "noAdjacentSpacesInRegex": "error", + "noArguments": "error", + "noBannedTypes": "off", + "noCommaOperator": "off", + "noEmptyTypeParameters": "error", + "noExtraBooleanCast": "error", + "noFlatMapIdentity": "error", + "noStaticOnlyClass": "off", + "noThisInStatic": "off", + "noUselessCatch": "off", + "noUselessConstructor": "off", + "noUselessContinue": "off", + "noUselessEmptyExport": "error", + "noUselessEscapeInRegex": "error", + "noUselessFragments": "error", + "noUselessLabel": "error", + "noUselessLoneBlockStatements": "error", + "noUselessRename": "error", + "noUselessStringRaw": "error", + "noUselessSwitchCase": "error", + "noUselessTernary": "off", + "noUselessThisAlias": "error", + "noUselessTypeConstraint": "error", + "noUselessUndefinedInitialization": "off", + "noVoid": "error", + "useArrowFunction": "off", + "useDateNow": "error", + "useFlatMap": "off", + "useIndexOf": "off", + "useLiteralKeys": "off", + "useNumericLiterals": "error", + "useOptionalChain": "off", + "useRegexLiterals": "error", + "useSimpleNumberKeys": "error" + }, + "correctness": { + "noConstAssign": "error", + "noConstantCondition": "error", + "noConstantMathMinMaxClamp": "error", + "noConstructorReturn": "error", + "noEmptyCharacterClassInRegex": "error", + "noEmptyPattern": "error", + "noGlobalObjectCalls": "error", + "noInnerDeclarations": "error", + "noInvalidBuiltinInstantiation": "error", + "noInvalidConstructorSuper": "error", + "noInvalidUseBeforeDeclaration": "off", + "noNonoctalDecimalEscape": "error", + "noPrecisionLoss": "error", + "noSelfAssign": "error", + "noSetterReturn": "error", + "noStringCaseMismatch": "error", + "noSwitchDeclarations": "error", + "noUnreachable": "error", + "noUnreachableSuper": "error", + "noUnsafeFinally": "error", + "noUnsafeOptionalChaining": "error", + "noUnusedFunctionParameters": "off", + "noUnusedImports": "off", + "noUnusedLabels": "error", + "noUnusedPrivateClassMembers": "off", + "noUnusedVariables": "off", + "noVoidElementsWithChildren": "error", + "noVoidTypeReturn": "error", + "useIsNan": "error", + "useParseIntRadix": "off", + "useValidForDirection": "error", + "useValidTypeof": "error", + "useYield": "error" + }, + "performance": { + "noAccumulatingSpread": "error", + "noDynamicNamespaceImportAccess": "error" + }, + "security": { + "noBlankTarget": "error", + "noGlobalEval": "error" + }, + "suspicious": { + "noApproximativeNumericConstant": "error", + "noAssignInExpressions": "off", + "noAsyncPromiseExecutor": "off", + "noCatchAssign": "error", + "noClassAssign": "error", + "noCommentText": "error", + "noCompareNegZero": "error", + "noConfusingLabels": "error", + "noConfusingVoidType": "off", + "noConstEnum": "error", + "noControlCharactersInRegex": "off", + "noDebugger": "error", + "noDocumentCookie": "off", + "noDoubleEquals": "off", + "noDuplicateCase": "error", + "noDuplicateClassMembers": "error", + "noDuplicateElseIf": "error", + "noDuplicateJsxProps": "error", + "noDuplicateObjectKeys": "error", + "noDuplicateParameters": "error", + "noEmptyInterface": "error", + "noExplicitAny": "off", + "noExtraNonNullAssertion": "error", + "noFallthroughSwitchClause": "error", + "noFunctionAssign": "error", + "noGlobalAssign": "error", + "noGlobalIsFinite": "error", + "noGlobalIsNan": "off", + "noHeadImportInDocument": "error", + "noImplicitAnyLet": "off", + "noImportAssign": "error", + "noIrregularWhitespace": "error", + "noLabelVar": "error", + "noMisleadingCharacterClass": "error", + "noMisleadingInstantiator": "error", + "noMisrefactoredShorthandAssign": "error", + "noNonNullAssertedOptionalChain": "error", + "noOctalEscape": "error", + "noPrototypeBuiltins": "off", + "noRedeclare": "error", + "noRedundantUseStrict": "error", + "noSelfCompare": "error", + "noShadowRestrictedNames": "error", + "noSparseArray": "error", + "noSuspiciousSemicolonInJsx": "error", + "noTemplateCurlyInString": "error", + "noThenProperty": "error", + "noTsIgnore": "off", + "noUnsafeDeclarationMerging": "error", + "noUnsafeNegation": "error", + "noUselessEscapeInString": "error", + "noUselessRegexBackrefs": "error", + "noWith": "error", + "useAdjacentOverloadSignatures": "error", + "useAwait": "off", + "useDefaultSwitchClauseLast": "error", + "useGetterReturn": "error", + "useGoogleFontDisplay": "error", + "useIsArray": "error", + "useIterableCallbackReturn": "off", + "useNamespaceKeyword": "error" + + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + }, + "parser": { + "unsafeParameterDecoratorsEnabled": true + } + }, + "html": { + "parser": { + "interpolation": true + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/frontend/src/app/components/audit/audit.component.spec.ts b/frontend/src/app/components/audit/audit.component.spec.ts index 232cba39..4c0e054e 100644 --- a/frontend/src/app/components/audit/audit.component.spec.ts +++ b/frontend/src/app/components/audit/audit.component.spec.ts @@ -150,7 +150,7 @@ describe('AuditComponent', () => { const fakeLog = { Action: "received rows", Date: "09/09/2021 5:47 PM", -​ Status: LogStatus.Successfully, + Status: LogStatus.Successfully, Table: "Customers", User: "lyubov+ytrsdzxfcgvhb@voloshko.com", createdAt: "2021-09-09T14:47:44.160Z", diff --git a/frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.html b/frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.html index 1897bdb9..4d6c97d8 100644 --- a/frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.html +++ b/frontend/src/app/components/dashboard/db-tables-list/db-tables-list.component.html @@ -188,3 +188,4 @@ + diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts index 51379695..b255a7fb 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts @@ -631,7 +631,7 @@ export class DbTableRowEditComponent implements OnInit { this._tableRow.addTableRow(this.connectionID, this.tableName, formattedUpdatedRow) .subscribe((res) => { this.keyAttributesFromURL = {}; - for (var i = 0; i < res.primaryColumns.length; i++) { + for (let i = 0; i < res.primaryColumns.length; i++) { this.keyAttributesFromURL[res.primaryColumns[i].column_name] = res.row[res.primaryColumns[i].column_name]; } this.ngZone.run(() => { diff --git a/frontend/src/app/components/ui-components/record-edit-fields/color/color.component.ts b/frontend/src/app/components/ui-components/record-edit-fields/color/color.component.ts index ce38d366..8f8ee870 100644 --- a/frontend/src/app/components/ui-components/record-edit-fields/color/color.component.ts +++ b/frontend/src/app/components/ui-components/record-edit-fields/color/color.component.ts @@ -47,7 +47,7 @@ export class ColorEditComponent extends BaseEditFieldComponent { return colorString.to.hex(r, g, b, a); case 'rgb': return colorString.to.rgb(r, g, b, a); - case 'hsl': + case 'hsl': { // Convert RGB to HSL using built-in conversion const hex = colorString.to.hex(r, g, b, a); const hslParsed = colorString.get.hsl(hex); @@ -56,6 +56,7 @@ export class ColorEditComponent extends BaseEditFieldComponent { return colorString.to.hsl(h, s, l, alpha); } return hex; + } default: return colorString.to.hex(r, g, b, a); } @@ -102,7 +103,7 @@ export class ColorEditComponent extends BaseEditFieldComponent { case 'rgb': this.value = colorString.to.rgb(r, g, b, a); break; - case 'hsl': + case 'hsl': { // Convert RGB to HSL using built-in conversion const hex = colorString.to.hex(r, g, b, a); const hslParsed = colorString.get.hsl(hex); @@ -113,6 +114,7 @@ export class ColorEditComponent extends BaseEditFieldComponent { this.value = hex; } break; + } default: this.value = colorString.to.hex(r, g, b, a); } diff --git a/frontend/src/app/components/ui-components/record-view-fields/text/text.component.ts b/frontend/src/app/components/ui-components/record-view-fields/text/text.component.ts index 68cb8dc1..de30d490 100644 --- a/frontend/src/app/components/ui-components/record-view-fields/text/text.component.ts +++ b/frontend/src/app/components/ui-components/record-view-fields/text/text.component.ts @@ -38,6 +38,7 @@ export class TextRecordViewComponent extends BaseRecordViewFieldComponent { } // Check if validator has this method + // biome-ignore lint: it is expected to import all exports of validator const validatorMethod = validator[validateType]; if (typeof validatorMethod !== 'function') { console.warn(`Unknown validator method: ${validateType}`); diff --git a/frontend/src/app/components/ui-components/table-display-fields/text/text.component.ts b/frontend/src/app/components/ui-components/table-display-fields/text/text.component.ts index ca94c015..4b42ebe1 100644 --- a/frontend/src/app/components/ui-components/table-display-fields/text/text.component.ts +++ b/frontend/src/app/components/ui-components/table-display-fields/text/text.component.ts @@ -42,6 +42,7 @@ export class TextDisplayComponent extends BaseTableDisplayFieldComponent { } // Check if validator has this method + // biome-ignore lint: it is expected to import all exports of validator const validatorMethod = validator[validateType]; if (typeof validatorMethod !== 'function') { console.warn(`Unknown validator method: ${validateType}`); diff --git a/frontend/src/app/components/users/users.component.spec.ts b/frontend/src/app/components/users/users.component.spec.ts index 08eb3dab..0d3ee032 100644 --- a/frontend/src/app/components/users/users.component.spec.ts +++ b/frontend/src/app/components/users/users.component.spec.ts @@ -100,6 +100,7 @@ describe('UsersComponent', () => { it('should open create group dialog', () => { const fakeCreateUsersGroupOpen = spyOn(dialog, 'open'); + // biome-ignore lint/suspicious/noGlobalAssign: mock global event in test event = jasmine.createSpyObj('event', [ 'preventDefault', 'stopImmediatePropagation' ]); component.openCreateUsersGroupDialog(event); diff --git a/frontend/src/app/consts/code-snippets.ts b/frontend/src/app/consts/code-snippets.ts index 728671b3..1c1fc980 100644 --- a/frontend/src/app/consts/code-snippets.ts +++ b/frontend/src/app/consts/code-snippets.ts @@ -82,7 +82,7 @@ public class RocketAdminController { php: { langName: 'PHP', mode: 'php', - snippet: ` { } } } - diff --git a/frontend/src/app/models/connection.ts b/frontend/src/app/models/connection.ts index 45554fd3..ab6d5d1d 100644 --- a/frontend/src/app/models/connection.ts +++ b/frontend/src/app/models/connection.ts @@ -22,7 +22,7 @@ export interface Connection { id: string | null, database: string, authSource?: string, -​​ title: string, + title: string, host: string, port: string, sid: string | null, @@ -73,4 +73,4 @@ export interface ConnectionSettings { company_name?: string, tables_audit?: boolean, table_categories?: TableCategory[] -} \ No newline at end of file +} diff --git a/frontend/src/app/services/notifications.service.spec.ts b/frontend/src/app/services/notifications.service.spec.ts index c8c73b7f..ccdc13ef 100644 --- a/frontend/src/app/services/notifications.service.spec.ts +++ b/frontend/src/app/services/notifications.service.spec.ts @@ -92,7 +92,7 @@ describe('NotificationsService', () => { service.dismissAlert(); expect(service.alert).toBeNull(); - }), + }); it('should reset alert', () => { service.alert = alert; diff --git a/frontend/src/app/validators/text.validator.ts b/frontend/src/app/validators/text.validator.ts index f40ddf7f..3618d828 100644 --- a/frontend/src/app/validators/text.validator.ts +++ b/frontend/src/app/validators/text.validator.ts @@ -33,6 +33,7 @@ export function textValidation(validateType: string, regexPattern: string):Valid } // Check if validator has this method + // biome-ignore lint: it is expected to import all exports of validator const validatorMethod = validator[validateType]; if (typeof validatorMethod !== 'function') { console.warn(`Unknown validator method: ${validateType}`); diff --git a/frontend/src/index.saas.html b/frontend/src/index.saas.html index bf019522..e1b56691 100644 --- a/frontend/src/index.saas.html +++ b/frontend/src/index.saas.html @@ -26,6 +26,7 @@ @@ -35,6 +36,7 @@ diff --git a/package.json b/package.json index b191c1ff..38371600 100644 --- a/package.json +++ b/package.json @@ -13,5 +13,11 @@ "resolutions": { "cipher-base": "1.0.7", "tar-fs": "1.16.6" + }, + "scripts": { + "lint": "biome lint" + }, + "devDependencies": { + "@biomejs/biome": "2.3.8" } } diff --git a/shared-code/src/data-access-layer/data-access-objects/data-access-object-agent.ts b/shared-code/src/data-access-layer/data-access-objects/data-access-object-agent.ts index 8dae5a86..57104092 100644 --- a/shared-code/src/data-access-layer/data-access-objects/data-access-object-agent.ts +++ b/shared-code/src/data-access-layer/data-access-objects/data-access-object-agent.ts @@ -823,7 +823,7 @@ export class DataAccessObjectAgent implements IDataAccessObjectAgent { ): Promise>> { const tableStructure = await this.getTableStructure(tableName, userEmail); switch (this.connection.type) { - case ConnectionTypesEnum.agent_postgres: + case ConnectionTypesEnum.agent_postgres: { const timestampColumnNamesPg = tableStructure .filter((column) => { return isPostgresDateOrTimeType(column.data_type); @@ -832,8 +832,9 @@ export class DataAccessObjectAgent implements IDataAccessObjectAgent { return column.column_name; }); return this.processPostgresDateColumnsInRows(rows, timestampColumnNamesPg); + } - case ConnectionTypesEnum.agent_mysql: + case ConnectionTypesEnum.agent_mysql: { const timestampColumnNamesMySQL = tableStructure .filter((column) => { return isMySqlDateOrTimeType(column.data_type); @@ -842,8 +843,9 @@ export class DataAccessObjectAgent implements IDataAccessObjectAgent { return column.column_name; }); return this.processMySQLDateColumnsInRows(rows, timestampColumnNamesMySQL); + } - case ConnectionTypesEnum.agent_mssql: + case ConnectionTypesEnum.agent_mssql: { const timestampColumnNamesMSSQL = tableStructure .filter((column) => { return isMSSQLDateOrTimeType(column.data_type); @@ -852,8 +854,9 @@ export class DataAccessObjectAgent implements IDataAccessObjectAgent { return column.column_name; }); return this.processMSSQLDateColumnsInRows(rows, timestampColumnNamesMSSQL); + } - case ConnectionTypesEnum.agent_oracledb: + case ConnectionTypesEnum.agent_oracledb: { const timestampColumnNamesOracle = tableStructure .filter((column) => { return isOracleDateStringByRegexp(column.data_type); @@ -862,6 +865,7 @@ export class DataAccessObjectAgent implements IDataAccessObjectAgent { return column.column_name; }); return this.processOracleDateColumnsInRows(rows, timestampColumnNamesOracle); + } default: return rows; } diff --git a/shared-code/src/data-access-layer/data-access-objects/data-access-object-redis.ts b/shared-code/src/data-access-layer/data-access-objects/data-access-object-redis.ts index 498e3792..22a94053 100644 --- a/shared-code/src/data-access-layer/data-access-objects/data-access-object-redis.ts +++ b/shared-code/src/data-access-layer/data-access-objects/data-access-object-redis.ts @@ -694,22 +694,26 @@ export class DataAccessObjectRedis extends BasicDataAccessObject implements IDat rowData.key = keyPart; switch (type) { - case 'list': + case 'list': { const listData = await redisClient.lRange(key, 0, -1); rowData.value = listData; break; - case 'set': + } + case 'set': { const setData = await redisClient.sMembers(key); rowData.value = setData; break; - case 'zset': + } + case 'zset': { const zsetData = await redisClient.zRangeWithScores(key, 0, -1); rowData.value = zsetData; break; - case 'hash': + } + case 'hash': { const hashData = await redisClient.hGetAll(key); rowData = { key: keyPart, ...hashData }; break; + } default: rowData.value = `[${type}]`; break; @@ -799,14 +803,14 @@ export class DataAccessObjectRedis extends BasicDataAccessObject implements IDat case RedisTableType.STRING: return [{ column_name: 'value', data_type: 'string' }]; - case RedisTableType.HASH: + case RedisTableType.HASH: { const structure = await this.getTableStructure(tableName); if (structure.length > 0) { return [{ column_name: structure[0].column_name, data_type: structure[0].data_type }]; } return [{ column_name: 'field', data_type: 'string' }]; + } - case RedisTableType.PREFIXED_KEYS: default: return [{ column_name: 'key', data_type: 'string' }]; } @@ -1292,19 +1296,22 @@ export class DataAccessObjectRedis extends BasicDataAccessObject implements IDat const command = parts[0].toUpperCase(); switch (command) { - case 'GET': + case 'GET': { if (parts.length !== 2) throw new Error('GET requires exactly one key'); const value = await redisClient.get(parts[1]); return [{ key: parts[1], value }]; + } - case 'KEYS': + case 'KEYS': { if (parts.length !== 2) throw new Error('KEYS requires exactly one pattern'); const keys = await redisClient.keys(parts[1]); return keys.map((key) => ({ key })); + } - case 'PING': + case 'PING': { const response = await redisClient.ping(); return [{ response }]; + } default: throw new Error(`Unsupported command: ${command}`); diff --git a/shared-code/src/data-access-layer/shared/create-data-access-object.ts b/shared-code/src/data-access-layer/shared/create-data-access-object.ts index 8e20457c..b0abedf0 100644 --- a/shared-code/src/data-access-layer/shared/create-data-access-object.ts +++ b/shared-code/src/data-access-layer/shared/create-data-access-object.ts @@ -40,45 +40,57 @@ export function getDataAccessObject( throw new Error(ERROR_MESSAGES.PROPERTY_TYPE_REQUIRED); } switch (connectionParams.type) { - case ConnectionTypesEnum.postgres: + case ConnectionTypesEnum.postgres: { const connectionParamsPostgres = buildConnectionParams(connectionParams); return new DataAccessObjectPostgres(connectionParamsPostgres); - case ConnectionTypesEnum.mysql: + } + case ConnectionTypesEnum.mysql: { const connectionParamsMysql = buildConnectionParams(connectionParams); return new DataAccessObjectMysql(connectionParamsMysql); - case ConnectionTypesEnum.mssql: + } + case ConnectionTypesEnum.mssql: { const connectionParamsMssql = buildConnectionParams(connectionParams); return new DataAccessObjectMssql(connectionParamsMssql); - case ConnectionTypesEnum.oracledb: + } + case ConnectionTypesEnum.oracledb: { const connectionParamsOracle = buildConnectionParams(connectionParams); return new DataAccessObjectOracle(connectionParamsOracle); - case ConnectionTypesEnum.ibmdb2: + } + case ConnectionTypesEnum.ibmdb2: { const connectionParamsToIbmDB2 = buildConnectionParams(connectionParams); return new DataAccessObjectIbmDb2(connectionParamsToIbmDB2); - case ConnectionTypesEnum.mongodb: + } + case ConnectionTypesEnum.mongodb: { const connectionParamsMongo = buildConnectionParams(connectionParams); return new DataAccessObjectMongo(connectionParamsMongo); - case ConnectionTypesEnum.dynamodb: + } + case ConnectionTypesEnum.dynamodb: { const connectionParamsDynamoDB = buildConnectionParams(connectionParams); return new DataAccessObjectDynamoDB(connectionParamsDynamoDB); - case ConnectionTypesEnum.elasticsearch: + } + case ConnectionTypesEnum.elasticsearch: { const connectionParamsElasticsearch = buildConnectionParams(connectionParams); return new DataAccessObjectElasticsearch(connectionParamsElasticsearch); - case ConnectionTypesEnum.cassandra: + } + case ConnectionTypesEnum.cassandra: { const connectionParamsCassandra = buildConnectionParams(connectionParams); return new DataAccessObjectCassandra(connectionParamsCassandra); - case ConnectionTypesEnum.redis: + } + case ConnectionTypesEnum.redis: { const connectionParamsRedis = buildConnectionParams(connectionParams); return new DataAccessObjectRedis(connectionParamsRedis); - case ConnectionTypesEnum.clickhouse: + } + case ConnectionTypesEnum.clickhouse: { const connectionParamsClickHouse = buildConnectionParams(connectionParams); return new DataAccessObjectClickHouse(connectionParamsClickHouse); - default: + } + default: { if (!agentTypes.includes(connectionParams.type)) { throw new Error(ERROR_MESSAGES.CONNECTION_TYPE_INVALID); } const connectionParamsAgent = buildAgentConnectionParams(connectionParams); return new DataAccessObjectAgent(connectionParamsAgent); + } } } diff --git a/yarn.lock b/yarn.lock index ec1bfbfb..e533f8fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1008,6 +1008,97 @@ __metadata: languageName: node linkType: hard +"@biomejs/biome@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/biome@npm:2.3.8" + dependencies: + "@biomejs/cli-darwin-arm64": 2.3.8 + "@biomejs/cli-darwin-x64": 2.3.8 + "@biomejs/cli-linux-arm64": 2.3.8 + "@biomejs/cli-linux-arm64-musl": 2.3.8 + "@biomejs/cli-linux-x64": 2.3.8 + "@biomejs/cli-linux-x64-musl": 2.3.8 + "@biomejs/cli-win32-arm64": 2.3.8 + "@biomejs/cli-win32-x64": 2.3.8 + dependenciesMeta: + "@biomejs/cli-darwin-arm64": + optional: true + "@biomejs/cli-darwin-x64": + optional: true + "@biomejs/cli-linux-arm64": + optional: true + "@biomejs/cli-linux-arm64-musl": + optional: true + "@biomejs/cli-linux-x64": + optional: true + "@biomejs/cli-linux-x64-musl": + optional: true + "@biomejs/cli-win32-arm64": + optional: true + "@biomejs/cli-win32-x64": + optional: true + bin: + biome: bin/biome + checksum: a6fc82184279eda9d04012d6c0b307baf8910753854c497f0f8b7ff2d385b1ae74ea5e4e0c534b2bae123e8dd965c21f8c60b513cb46877aa1023a971009ecb6 + languageName: node + linkType: hard + +"@biomejs/cli-darwin-arm64@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-darwin-arm64@npm:2.3.8" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@biomejs/cli-darwin-x64@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-darwin-x64@npm:2.3.8" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@biomejs/cli-linux-arm64-musl@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-linux-arm64-musl@npm:2.3.8" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@biomejs/cli-linux-arm64@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-linux-arm64@npm:2.3.8" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@biomejs/cli-linux-x64-musl@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-linux-x64-musl@npm:2.3.8" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@biomejs/cli-linux-x64@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-linux-x64@npm:2.3.8" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@biomejs/cli-win32-arm64@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-win32-arm64@npm:2.3.8" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@biomejs/cli-win32-x64@npm:2.3.8": + version: 2.3.8 + resolution: "@biomejs/cli-win32-x64@npm:2.3.8" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@borewit/text-codec@npm:^0.1.0": version: 0.1.1 resolution: "@borewit/text-codec@npm:0.1.1" @@ -11226,6 +11317,7 @@ __metadata: version: 0.0.0-use.local resolution: "root@workspace:." dependencies: + "@biomejs/biome": 2.3.8 monaco-editor: ^0.53.0 languageName: unknown linkType: soft