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