Repository: redis/RedisInsight Branch: main Commit: 95022ae1f308 Files: 6242 Total size: 18.1 MB Directory structure: gitextract_fr3fg8ca/ ├── .ai/ │ ├── README.md │ ├── commands/ │ │ ├── commit-message.md │ │ ├── e2e-fix.md │ │ ├── e2e-generate.md │ │ ├── generate-release-notes.md │ │ ├── pr-plan.md │ │ └── pull-request-review.md │ ├── rules/ │ │ ├── backend.md │ │ ├── code-quality.md │ │ ├── e2e-testing.md │ │ ├── frontend.md │ │ ├── git-safety.md │ │ └── testing.md │ └── skills/ │ ├── branches/ │ │ └── SKILL.md │ ├── commits/ │ │ └── SKILL.md │ └── pull-requests/ │ └── SKILL.md ├── .cursor/ │ └── agents/ │ └── test-runner.md ├── .cursorignore ├── .dockerignore ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .github/ │ ├── CODEOWNERS │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ ├── actions/ │ │ ├── deploy-test-reports/ │ │ │ └── action.yml │ │ ├── get-current-date/ │ │ │ └── action.yml │ │ ├── install-all-build-libs/ │ │ │ └── action.yml │ │ ├── install-apple-certs/ │ │ │ └── action.yml │ │ ├── install-deps/ │ │ │ └── action.yml │ │ ├── install-windows-certs/ │ │ │ └── action.yml │ │ ├── remove-artifacts/ │ │ │ └── action.yml │ │ └── setup-e2e-playwright/ │ │ └── action.yml │ ├── build/ │ │ ├── build.Dockerfile │ │ ├── build.sh │ │ ├── build_modules.sh │ │ ├── release-docker.sh │ │ └── sum_sha256.sh │ ├── codeql/ │ │ └── config.yml │ ├── copilot-instructions.md │ ├── deps-audit-report.js │ ├── deps-licenses-report.js │ ├── e2e/ │ │ ├── test.app-image.sh │ │ └── test.app-image.sso.sh │ ├── e2e-results.js │ ├── generate-build-summary.js │ ├── generate-checksums-summary.js │ ├── itest-results.js │ ├── lint-report.js │ ├── redisstack/ │ │ ├── app-image.repack.sh │ │ └── dmg.repack.sh │ ├── virustotal-report.js │ └── workflows/ │ ├── approval-dedupe.yml │ ├── aws-upload-dev.yml │ ├── aws-upload-enterprise.yml │ ├── aws-upload-prod.yml │ ├── build.yml │ ├── clean-deployments.yml │ ├── clean-s3-dev-builds.yml │ ├── code-coverage.yml │ ├── codeql-analysis.yml │ ├── compress-images.yml │ ├── enforce-branch-name-rules.yml │ ├── licenses-check.yml │ ├── lint.yml │ ├── manual-build-enterprise.yml │ ├── manual-build.yml │ ├── nightly-virustotal-analyze.yml │ ├── pipeline-build-docker.yml │ ├── pipeline-build-linux.yml │ ├── pipeline-build-macos.yml │ ├── pipeline-build-windows.yml │ ├── publish-stores.yml │ ├── release-prod.yml │ ├── release-stage.yml │ ├── tests-backend.yml │ ├── tests-e2e-appimage.yml │ ├── tests-e2e-docker-critical-path.yml │ ├── tests-e2e-docker-regression.yml │ ├── tests-e2e-docker-smoke.yml │ ├── tests-e2e-playwright-chromium.yml │ ├── tests-e2e-playwright-docker.yml │ ├── tests-e2e-playwright-electron.yml │ ├── tests-e2e-playwright-lint.yml │ ├── tests-e2e-playwright-v2.yml │ ├── tests-e2e-playwright.yml │ ├── tests-e2e.yml │ ├── tests-frontend.yml │ ├── tests-integration.yml │ ├── tests.yml │ ├── virustotal.yml │ └── weekly.yml ├── .gitignore ├── .jit/ │ └── jit-config.yml ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .storybook/ │ ├── RootStoryLayout.tsx │ ├── Story.context.ts │ ├── ThemeContextBridge.tsx │ ├── helpers/ │ │ └── styles.ts │ ├── main.ts │ ├── manager.ts │ ├── preview-head.html │ ├── preview.tsx │ ├── redis-theme.ts │ ├── tsconfig.json │ └── vite.config.ts ├── .vscode/ │ ├── extensions.json │ ├── launch.json │ └── settings.json ├── .yarnrc ├── AGENTS.md ├── CHANGELOG.md ├── CONDUCT ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── api-docker-entry.sh ├── babel.config.cjs ├── configs/ │ ├── .eslintrc │ ├── webpack.config.base.ts │ ├── webpack.config.eslint.js │ ├── webpack.config.main.prod.ts │ ├── webpack.config.main.stage.ts │ ├── webpack.config.preload.dev.ts │ └── webpack.paths.ts ├── dev.provisionprofile ├── docker-entry.sh ├── docs/ │ ├── azure-docker-setup.md │ ├── azure-setup.md │ ├── plugins/ │ │ ├── development.md │ │ ├── installation.md │ │ └── introduction.md │ └── release-notes/ │ └── RELEASE_NOTES_TEMPLATE.md ├── electron-builder-mas.js ├── electron-builder.json ├── embedded.provisionprofile ├── env.mcp.example ├── jest-resolver.js ├── jest.config.cjs ├── mcp.json ├── package.json ├── patches/ │ ├── @elastic+eui+34.6.0.patch │ ├── monaco-yaml+5.1.1.patch │ └── react-vtree+3.0.0-beta.3.patch ├── pull_request_template.md ├── redisinsight/ │ ├── __mocks__/ │ │ ├── brotli-dec-wasm.js │ │ ├── fileMock.js │ │ ├── monacoMock.js │ │ ├── monacoYamlMock.js │ │ ├── rawproto.js │ │ ├── react-children-utilities.js │ │ ├── react-resizable-panels.js │ │ ├── rehypeStringify.js │ │ ├── remarkGfm.js │ │ ├── remarkParse.js │ │ ├── remarkRehype.js │ │ ├── scssRaw.js │ │ ├── svg.js │ │ ├── unified.js │ │ └── unistUtilsVisit.js │ ├── api/ │ │ ├── .dockerignore │ │ ├── .eslintignore │ │ ├── .gitignore │ │ ├── .jest.setup.ts │ │ ├── .prettierignore │ │ ├── .prettierrc │ │ ├── .yarnclean.prod │ │ ├── bruno/ │ │ │ └── RedisInsight/ │ │ │ ├── Query Library/ │ │ │ │ ├── Create/ │ │ │ │ │ ├── Create Query (invalid).bru │ │ │ │ │ ├── Create Query.bru │ │ │ │ │ └── folder.bru │ │ │ │ ├── Delete/ │ │ │ │ │ ├── Delete Query (invalid).bru │ │ │ │ │ ├── Delete Query.bru │ │ │ │ │ └── folder.bru │ │ │ │ ├── Get/ │ │ │ │ │ ├── Get Query (invalid).bru │ │ │ │ │ ├── Get Query.bru │ │ │ │ │ └── folder.bru │ │ │ │ ├── Get Queries/ │ │ │ │ │ ├── Get Queries.bru │ │ │ │ │ ├── Search Queries.bru │ │ │ │ │ └── folder.bru │ │ │ │ ├── Seed/ │ │ │ │ │ ├── Seed Queries.bru │ │ │ │ │ └── folder.bru │ │ │ │ ├── Update/ │ │ │ │ │ ├── Update Query (invalid).bru │ │ │ │ │ ├── Update Query.bru │ │ │ │ │ └── folder.bru │ │ │ │ └── folder.bru │ │ │ ├── bruno.json │ │ │ └── environments/ │ │ │ └── Local.bru │ │ ├── config/ │ │ │ ├── default.ts │ │ │ ├── development.ts │ │ │ ├── features-config.json │ │ │ ├── logger.ts │ │ │ ├── ormconfig.ts │ │ │ ├── production.ts │ │ │ ├── stack.ts │ │ │ ├── staging.ts │ │ │ ├── swagger.ts │ │ │ └── test.ts │ │ ├── data/ │ │ │ ├── common │ │ │ ├── json │ │ │ ├── manifest.json │ │ │ ├── search │ │ │ └── vector-collections/ │ │ │ ├── bikes │ │ │ └── movies │ │ ├── esbuild.js │ │ ├── migration/ │ │ │ ├── 1614164490968-initial-migration.ts │ │ │ ├── 1615480887019-connection-type.ts │ │ │ ├── 1615990079125-database-name-from-provider.ts │ │ │ ├── 1615992183565-remove-database-type.ts │ │ │ ├── 1616520395940-oss-sentinel.ts │ │ │ ├── 1625771635418-agreements.ts │ │ │ ├── 1626086601057-server-info.ts │ │ │ ├── 1626904405170-database-hosting-provider.ts │ │ │ ├── 1627556171227-settings.ts │ │ │ ├── 1629729923740-database-modules.ts │ │ │ ├── 1634219846022-database-db-index.ts │ │ │ ├── 1634557312500-encryption.ts │ │ │ ├── 1641795882696-command-execution.ts │ │ │ ├── 1641805606399-plugin-state.ts │ │ │ ├── 1650278664000-sni.ts │ │ │ ├── 1655821010349-notification.ts │ │ │ ├── 1659687030433-notification-category.ts │ │ │ ├── 1660664717573-workbench-mode.ts │ │ │ ├── 1663093411715-workbench-group-mode.ts │ │ │ ├── 1664785208236-database-analysis.ts │ │ │ ├── 1664886479051-database-analysis-expiration-groups.ts │ │ │ ├── 1667368983699-workbench-execution-time.ts │ │ │ ├── 1667477693934-database.ts │ │ │ ├── 1670252337342-database-new.ts │ │ │ ├── 1673035852335-ssh-options.ts │ │ │ ├── 1673934231410-workbench-and-analysis-db.ts │ │ │ ├── 1674539211397-browser-history.ts │ │ │ ├── 1674660306971-database-analysis-recommendations.ts │ │ │ ├── 1675398140189-database-timeout.ts │ │ │ ├── 1677135091633-custom-tutorials.ts │ │ │ ├── 1678182722874-database-compressor.ts │ │ │ ├── 1681900503586-database-recommendations.ts │ │ │ ├── 1683006064293-database-recommendation-params.ts │ │ │ ├── 1684931530343-feature.ts │ │ │ ├── 1686719451753-database-redis-server.ts │ │ │ ├── 1687166457712-cloud-database-details.ts │ │ │ ├── 1687435940110-database-recommendation-unique.ts │ │ │ ├── 1688989337247-freeCloudDatabase.ts │ │ │ ├── 1691061058385-cloud-capi-keys.ts │ │ │ ├── 1691476419592-feature-sso.ts │ │ │ ├── 1713515657364-ai-history.ts │ │ │ ├── 1714501203616-ai-history-steps.ts │ │ │ ├── 1716370509836-rdi.ts │ │ │ ├── 1718260230164-ai-history.ts │ │ │ ├── 1726058563737-command-execution.ts │ │ │ ├── 1729085495444-cloud-session.ts │ │ │ ├── 1733740794737-database-createdAt.ts │ │ │ ├── 1737362130798-db-settings.ts │ │ │ ├── 1738829743482-database-forceStandalone.ts │ │ │ ├── 1740579711635-rdi-optional-auth.ts │ │ │ ├── 1741610039177-database-tags.ts │ │ │ ├── 1741786803681-pre-setup-databases.ts │ │ │ ├── 1742303245547-key-name-format.ts │ │ │ ├── 1743432519891-cascade-tags.ts │ │ │ ├── 1743606395647-encrypt-tags.ts │ │ │ ├── 1755086732238-update-provider-names.ts │ │ │ ├── 1769785218000-provider-details.ts │ │ │ ├── 1771500000000-query-library.ts │ │ │ └── index.ts │ │ ├── nest-cli.json │ │ ├── package.json │ │ ├── package.tmp.json │ │ ├── patches/ │ │ │ └── redis-parser+3.0.0.patch │ │ ├── scripts/ │ │ │ ├── default-commands.ts │ │ │ ├── default-content.ts │ │ │ └── default-tutorials.ts │ │ ├── src/ │ │ │ ├── __mocks__/ │ │ │ │ ├── ai.ts │ │ │ │ ├── analytics.ts │ │ │ │ ├── app-settings.ts │ │ │ │ ├── autodiscovery.ts │ │ │ │ ├── browser-history.ts │ │ │ │ ├── bulk-actions.ts │ │ │ │ ├── certificates.ts │ │ │ │ ├── cloud-auth.ts │ │ │ │ ├── cloud-autodiscovery.ts │ │ │ │ ├── cloud-capi-key.ts │ │ │ │ ├── cloud-common.ts │ │ │ │ ├── cloud-database.ts │ │ │ │ ├── cloud-job.ts │ │ │ │ ├── cloud-session.ts │ │ │ │ ├── cloud-subscription.ts │ │ │ │ ├── cloud-task.ts │ │ │ │ ├── cloud-user.ts │ │ │ │ ├── commands.ts │ │ │ │ ├── common.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── custom-tutorial.ts │ │ │ │ ├── database-discovery.ts │ │ │ │ ├── database-import.ts │ │ │ │ ├── database-info.ts │ │ │ │ ├── database-recommendation.ts │ │ │ │ ├── database-settings.ts │ │ │ │ ├── databases-client.ts │ │ │ │ ├── databases.ts │ │ │ │ ├── encryption.ts │ │ │ │ ├── errors.ts │ │ │ │ ├── event-emitter.ts │ │ │ │ ├── feature.ts │ │ │ │ ├── index.ts │ │ │ │ ├── notification.ts │ │ │ │ ├── profiler.ts │ │ │ │ ├── rdi.ts │ │ │ │ ├── redis-client.ts │ │ │ │ ├── redis-databases.ts │ │ │ │ ├── redis-enterprise.ts │ │ │ │ ├── redis-info.ts │ │ │ │ ├── redis-rs.ts │ │ │ │ ├── redis-sentinel.ts │ │ │ │ ├── redis-utils.ts │ │ │ │ ├── redis.ts │ │ │ │ ├── redisearch.ts │ │ │ │ ├── server.ts │ │ │ │ ├── session.ts │ │ │ │ ├── ssh.ts │ │ │ │ ├── tags.ts │ │ │ │ ├── triggered-functions.ts │ │ │ │ ├── user.ts │ │ │ │ ├── utm.ts │ │ │ │ └── workbench.ts │ │ │ ├── app.module.ts │ │ │ ├── app.routes.ts │ │ │ ├── common/ │ │ │ │ ├── constants/ │ │ │ │ │ ├── api.ts │ │ │ │ │ ├── general.ts │ │ │ │ │ ├── history.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── recommendations.ts │ │ │ │ │ ├── redis-string.ts │ │ │ │ │ └── user.ts │ │ │ │ ├── decorators/ │ │ │ │ │ ├── client-metadata/ │ │ │ │ │ │ ├── client-metadata.decorator.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── data-as-json-string.decorator.ts │ │ │ │ │ ├── database-management.decorator.ts │ │ │ │ │ ├── default.ts │ │ │ │ │ ├── hidden-field.decorator.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── is-bigger-than.decorator.ts │ │ │ │ │ ├── is-github-link.decorator.ts │ │ │ │ │ ├── is-multi-number.decorator.ts │ │ │ │ │ ├── no-duplicates.decorator.ts │ │ │ │ │ ├── object-as-map.decorator.ts │ │ │ │ │ ├── redis-string/ │ │ │ │ │ │ ├── any-to-redis-string.decorator.ts │ │ │ │ │ │ ├── api-query-redis-string-encoding.decorator.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── is-redis-string.decorator.ts │ │ │ │ │ │ ├── redis-string-to-ascii.decorator.ts │ │ │ │ │ │ ├── redis-string-to-buffer.decorator.ts │ │ │ │ │ │ ├── redis-string-to-utf8.decorator.ts │ │ │ │ │ │ └── redis-string-type.decorator.ts │ │ │ │ │ ├── session/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── session-metadata.decorator.ts │ │ │ │ │ ├── transform-to-map.decorator.spec.ts │ │ │ │ │ ├── transform-to-map.decorator.ts │ │ │ │ │ └── zset-score/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── zset-score.decorator.ts │ │ │ │ ├── exceptions/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── validation.exception.ts │ │ │ │ ├── guards/ │ │ │ │ │ ├── database-management.guard.spec.ts │ │ │ │ │ └── database-management.guard.ts │ │ │ │ ├── interceptors/ │ │ │ │ │ ├── browser-serialize.interceptor.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── timeout.interceptor.ts │ │ │ │ ├── logger/ │ │ │ │ │ ├── app-logger.spec.ts │ │ │ │ │ └── app-logger.ts │ │ │ │ ├── middlewares/ │ │ │ │ │ ├── body-parser.middleware.ts │ │ │ │ │ └── single-user-auth.middleware.ts │ │ │ │ ├── models/ │ │ │ │ │ ├── client-metadata.ts │ │ │ │ │ ├── common.ts │ │ │ │ │ ├── database-index.ts │ │ │ │ │ ├── endpoint.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── session.ts │ │ │ │ ├── pipes/ │ │ │ │ │ ├── database-index.validation.pipe.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── transformers/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── redis-reply/ │ │ │ │ │ │ ├── formatter-manager.spec.ts │ │ │ │ │ │ ├── formatter-manager.ts │ │ │ │ │ │ ├── formatter.interface.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── strategies/ │ │ │ │ │ │ ├── ascii-formatter.strategey.spec.ts │ │ │ │ │ │ ├── ascii-formatter.strategy.ts │ │ │ │ │ │ ├── utf8-formatter.strategy.spec.ts │ │ │ │ │ │ └── utf8-formatter.strategy.ts │ │ │ │ │ └── redis-string/ │ │ │ │ │ ├── any-to-redis-string.transformer.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── redis-string-to-ascii.transformer.ts │ │ │ │ │ ├── redis-string-to-buffer.transformer.ts │ │ │ │ │ └── redis-string-to-utf8.transformer.ts │ │ │ │ ├── utils/ │ │ │ │ │ ├── certificate-import.util.ts │ │ │ │ │ ├── errors.util.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── merge.util.spec.ts │ │ │ │ │ └── merge.util.ts │ │ │ │ └── validators/ │ │ │ │ ├── bigger-than.validator.ts │ │ │ │ ├── github-link.validator.ts │ │ │ │ ├── index.ts │ │ │ │ ├── multi-number.validator.ts │ │ │ │ ├── no-duplicates.validator.ts │ │ │ │ ├── redis-string.validator.ts │ │ │ │ └── zset-score.validator.ts │ │ │ ├── constants/ │ │ │ │ ├── agreements-spec.json │ │ │ │ ├── app-events.ts │ │ │ │ ├── custom-error-codes.ts │ │ │ │ ├── error-messages.ts │ │ │ │ ├── exceptions.ts │ │ │ │ ├── index.ts │ │ │ │ ├── recommendations.ts │ │ │ │ ├── redis-commands.ts │ │ │ │ ├── redis-connection.ts │ │ │ │ ├── redis-error-codes.ts │ │ │ │ ├── redis-keys.ts │ │ │ │ ├── redis-modules.ts │ │ │ │ ├── regex.ts │ │ │ │ ├── sort.ts │ │ │ │ ├── telemetry-events.ts │ │ │ │ └── websocket-rooms.ts │ │ │ ├── core.module.ts │ │ │ ├── decorators/ │ │ │ │ ├── api-endpoint.decorator.ts │ │ │ │ ├── api-redis-instance-operation.decorator.ts │ │ │ │ └── api-redis-params.decorator.ts │ │ │ ├── dto/ │ │ │ │ ├── dto-transformer.spec.ts │ │ │ │ └── dto-transformer.ts │ │ │ ├── exceptions/ │ │ │ │ └── global-exception.filter.ts │ │ │ ├── init-helper.ts │ │ │ ├── local-database.module.ts │ │ │ ├── main.ts │ │ │ ├── middleware/ │ │ │ │ ├── exclude-route.middleware.ts │ │ │ │ ├── redis-connection/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── redis-connection.middleware.ts │ │ │ │ │ └── route-controllers.ts │ │ │ │ ├── subpath-proxy.middleware.ts │ │ │ │ └── x-frame-options.middleware.ts │ │ │ ├── models/ │ │ │ │ ├── index.ts │ │ │ │ ├── redis-client.ts │ │ │ │ └── redis-cluster.ts │ │ │ ├── modules/ │ │ │ │ ├── ai/ │ │ │ │ │ ├── chat/ │ │ │ │ │ │ ├── ai-chat.controller.ts │ │ │ │ │ │ ├── ai-chat.module.ts │ │ │ │ │ │ ├── ai-chat.service.spec.ts │ │ │ │ │ │ ├── ai-chat.service.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ └── send.ai-chat.message.dto.ts │ │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ │ ├── conv-ai.bad-request.exception.ts │ │ │ │ │ │ │ ├── conv-ai.error.handler.spec.ts │ │ │ │ │ │ │ ├── conv-ai.error.handler.ts │ │ │ │ │ │ │ ├── conv-ai.forbidden.exception.ts │ │ │ │ │ │ │ ├── conv-ai.internal-server-error.exception.ts │ │ │ │ │ │ │ ├── conv-ai.not-found.exception.ts │ │ │ │ │ │ │ ├── conv-ai.unauthorized.exception.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── models/ │ │ │ │ │ │ │ ├── ai-chat.message.ts │ │ │ │ │ │ │ ├── ai-chat.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── providers/ │ │ │ │ │ │ ├── conv-ai.provider.spec.ts │ │ │ │ │ │ └── conv-ai.provider.ts │ │ │ │ │ └── query/ │ │ │ │ │ ├── ai-query.controller.ts │ │ │ │ │ ├── ai-query.module.ts │ │ │ │ │ ├── ai-query.service.spec.ts │ │ │ │ │ ├── ai-query.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ └── send.ai-query.message.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── ai-query.message.entity.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── a-queryi.error.handler.spec.ts │ │ │ │ │ │ ├── ai-query.bad-request.exception.ts │ │ │ │ │ │ ├── ai-query.error.handler.ts │ │ │ │ │ │ ├── ai-query.forbidden.exception.ts │ │ │ │ │ │ ├── ai-query.internal-server-error.exception.ts │ │ │ │ │ │ ├── ai-query.not-found.exception.ts │ │ │ │ │ │ ├── ai-query.rate-limit.max-tokens.exception.ts │ │ │ │ │ │ ├── ai-query.rate-limit.request.exception.ts │ │ │ │ │ │ ├── ai-query.rate-limit.token.exception.ts │ │ │ │ │ │ ├── ai-query.unauthorized.exception.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── ai-query.auth-data.ts │ │ │ │ │ │ ├── ai-query.common.ts │ │ │ │ │ │ ├── ai-query.intermediate-step.ts │ │ │ │ │ │ ├── ai-query.message.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── ai-query.provider.spec.ts │ │ │ │ │ │ ├── ai-query.provider.ts │ │ │ │ │ │ └── auth/ │ │ │ │ │ │ ├── ai-query-auth.provider.ts │ │ │ │ │ │ ├── local.ai-query-auth.provider.spec.ts │ │ │ │ │ │ └── local.ai-query-auth.provider.ts │ │ │ │ │ ├── repositories/ │ │ │ │ │ │ ├── ai-query.context.repository.ts │ │ │ │ │ │ ├── ai-query.message.repository.ts │ │ │ │ │ │ ├── in-memory.ai-query.context.repository.spec.ts │ │ │ │ │ │ ├── in-memory.ai-query.context.repository.ts │ │ │ │ │ │ ├── local.ai-query.message.repository.spec.ts │ │ │ │ │ │ └── local.ai-query.message.repository.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── context.util.spec.ts │ │ │ │ │ └── context.util.ts │ │ │ │ ├── analytics/ │ │ │ │ │ ├── analytics.controller.ts │ │ │ │ │ ├── analytics.module.ts │ │ │ │ │ ├── analytics.service.spec.ts │ │ │ │ │ ├── analytics.service.ts │ │ │ │ │ ├── command.telemetry.base.service.spec.ts │ │ │ │ │ ├── command.telemetry.base.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ └── analytics.dto.ts │ │ │ │ │ ├── telemetry.base.service.spec.ts │ │ │ │ │ └── telemetry.base.service.ts │ │ │ │ ├── auth/ │ │ │ │ │ ├── auth.module.ts │ │ │ │ │ ├── session-metadata/ │ │ │ │ │ │ ├── adapters/ │ │ │ │ │ │ │ ├── session-metadata.adapter.spec.ts │ │ │ │ │ │ │ └── session-metadata.adapter.ts │ │ │ │ │ │ └── decorators/ │ │ │ │ │ │ └── ws-session-metadata.decorator.ts │ │ │ │ │ └── window-auth/ │ │ │ │ │ ├── adapters/ │ │ │ │ │ │ └── window-auth.adapter.ts │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── exceptions.ts │ │ │ │ │ ├── middleware/ │ │ │ │ │ │ └── window.auth.middleware.ts │ │ │ │ │ ├── strategies/ │ │ │ │ │ │ └── abstract.window.auth.strategy.ts │ │ │ │ │ ├── window-auth.module.ts │ │ │ │ │ ├── window-auth.service.spec.ts │ │ │ │ │ └── window-auth.service.ts │ │ │ │ ├── azure/ │ │ │ │ │ ├── auth/ │ │ │ │ │ │ ├── azure-auth-callback.template.ts │ │ │ │ │ │ ├── azure-auth.analytics.ts │ │ │ │ │ │ ├── azure-auth.controller.ts │ │ │ │ │ │ ├── azure-auth.service.spec.ts │ │ │ │ │ │ ├── azure-auth.service.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── azure-auth-login.dto.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── models/ │ │ │ │ │ │ ├── azure-auth.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── autodiscovery/ │ │ │ │ │ │ ├── azure-autodiscovery.analytics.ts │ │ │ │ │ │ ├── azure-autodiscovery.controller.ts │ │ │ │ │ │ ├── azure-autodiscovery.service.spec.ts │ │ │ │ │ │ ├── azure-autodiscovery.service.ts │ │ │ │ │ │ └── dto/ │ │ │ │ │ │ ├── import-azure-database.dto.ts │ │ │ │ │ │ ├── import-azure-database.response.ts │ │ │ │ │ │ ├── import-azure-databases.dto.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── azure-token-refresh.manager.spec.ts │ │ │ │ │ ├── azure-token-refresh.manager.ts │ │ │ │ │ ├── azure.module.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── azure-entra-id-token-expired.exception.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── models/ │ │ │ │ │ ├── azure-resource.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── browser/ │ │ │ │ │ ├── __mocks__/ │ │ │ │ │ │ ├── hash.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── keys.ts │ │ │ │ │ │ ├── list.ts │ │ │ │ │ │ ├── set.ts │ │ │ │ │ │ ├── streams.ts │ │ │ │ │ │ └── z-set.ts │ │ │ │ │ ├── browser-history/ │ │ │ │ │ │ ├── browser-history.controller.ts │ │ │ │ │ │ ├── browser-history.module.ts │ │ │ │ │ │ ├── browser-history.service.spec.ts │ │ │ │ │ │ ├── browser-history.service.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── create.browser-history.dto.ts │ │ │ │ │ │ │ ├── delete.browser-history.dto.ts │ │ │ │ │ │ │ ├── delete.browser-history.query.dto.ts │ │ │ │ │ │ │ ├── delete.browser-history.response.dto.ts │ │ │ │ │ │ │ ├── get.browser-history.dto.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── list.browser-history.dto.ts │ │ │ │ │ │ ├── entities/ │ │ │ │ │ │ │ └── browser-history.entity.ts │ │ │ │ │ │ └── repositories/ │ │ │ │ │ │ ├── browser-history.repository.ts │ │ │ │ │ │ ├── local.browser-history.repository.spec.ts │ │ │ │ │ │ └── local.browser-history.repository.ts │ │ │ │ │ ├── browser.base.controller.ts │ │ │ │ │ ├── browser.module.ts │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── browser-tool-commands.ts │ │ │ │ │ ├── decorators/ │ │ │ │ │ │ └── browser-client-metadata.decorator.ts │ │ │ │ │ ├── hash/ │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── add.fields-to-hash.dto.ts │ │ │ │ │ │ │ ├── create.hash-with-expire.dto.ts │ │ │ │ │ │ │ ├── delete.fields-from-hash.dto.ts │ │ │ │ │ │ │ ├── delete.fields-from-hash.response.ts │ │ │ │ │ │ │ ├── get.hash-fields.dto.ts │ │ │ │ │ │ │ ├── get.hash-fields.response.ts │ │ │ │ │ │ │ ├── hash-field-ttl.dto.ts │ │ │ │ │ │ │ ├── hash-field.dto.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── update.hash-fields-ttl.dto.ts │ │ │ │ │ │ ├── hash.controller.ts │ │ │ │ │ │ ├── hash.module.ts │ │ │ │ │ │ ├── hash.service.spec.ts │ │ │ │ │ │ └── hash.service.ts │ │ │ │ │ ├── keys/ │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── delete.keys.dto.ts │ │ │ │ │ │ │ ├── delete.keys.response.ts │ │ │ │ │ │ │ ├── get.keys-info.dto.ts │ │ │ │ │ │ │ ├── get.keys-info.response.ts │ │ │ │ │ │ │ ├── get.keys-with-details.response.ts │ │ │ │ │ │ │ ├── get.keys.dto.ts │ │ │ │ │ │ │ ├── get.namespace-searchable.dto.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── key-with-expire.dto.ts │ │ │ │ │ │ │ ├── key.dto.ts │ │ │ │ │ │ │ ├── rename.key.dto.ts │ │ │ │ │ │ │ ├── rename.key.response.ts │ │ │ │ │ │ │ ├── scan-data-type.dto.ts │ │ │ │ │ │ │ ├── update.key-ttl.dto.ts │ │ │ │ │ │ │ └── update.key-ttl.response.ts │ │ │ │ │ │ ├── key-info/ │ │ │ │ │ │ │ ├── key-info.provider.spec.ts │ │ │ │ │ │ │ ├── key-info.provider.ts │ │ │ │ │ │ │ └── strategies/ │ │ │ │ │ │ │ ├── graph.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── graph.key-info.strategy.ts │ │ │ │ │ │ │ ├── hash.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── hash.key-info.strategy.ts │ │ │ │ │ │ │ ├── key-info.strategy.ts │ │ │ │ │ │ │ ├── list.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── list.key-info.strategy.ts │ │ │ │ │ │ │ ├── rejson-rl.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── rejson-rl.key-info.strategy.ts │ │ │ │ │ │ │ ├── set.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── set.key-info.strategy.ts │ │ │ │ │ │ │ ├── stream.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── stream.key-info.strategy.ts │ │ │ │ │ │ │ ├── string.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── string.key-info.strategy.ts │ │ │ │ │ │ │ ├── ts.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── ts.key-info.strategy.ts │ │ │ │ │ │ │ ├── unsupported.key-info.strategy.spec.ts │ │ │ │ │ │ │ ├── unsupported.key-info.strategy.ts │ │ │ │ │ │ │ ├── z-set.key-info.strategy.spec.ts │ │ │ │ │ │ │ └── z-set.key-info.strategy.ts │ │ │ │ │ │ ├── keys.controller.ts │ │ │ │ │ │ ├── keys.module.ts │ │ │ │ │ │ ├── keys.service.spec.ts │ │ │ │ │ │ ├── keys.service.ts │ │ │ │ │ │ └── scanner/ │ │ │ │ │ │ ├── scanner.interface.ts │ │ │ │ │ │ ├── scanner.spec.ts │ │ │ │ │ │ ├── scanner.ts │ │ │ │ │ │ └── strategies/ │ │ │ │ │ │ ├── cluster.scanner.strategy.spec.ts │ │ │ │ │ │ ├── cluster.scanner.strategy.ts │ │ │ │ │ │ ├── scanner.strategy.ts │ │ │ │ │ │ ├── standalone.scanner.strategy.spec.ts │ │ │ │ │ │ └── standalone.scanner.strategy.ts │ │ │ │ │ ├── list/ │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── create.list-with-expire.dto.ts │ │ │ │ │ │ │ ├── delete.list-elements.dto.ts │ │ │ │ │ │ │ ├── delete.list-elements.response.ts │ │ │ │ │ │ │ ├── get.list-element.response.ts │ │ │ │ │ │ │ ├── get.list-elements.dto.ts │ │ │ │ │ │ │ ├── get.list-elements.response.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── push.element-to-list.dto.ts │ │ │ │ │ │ │ ├── push.list-elements.response.ts │ │ │ │ │ │ │ ├── set.list-element.dto.ts │ │ │ │ │ │ │ └── set.list-element.response.ts │ │ │ │ │ │ ├── list.controller.ts │ │ │ │ │ │ ├── list.module.ts │ │ │ │ │ │ ├── list.service.spec.ts │ │ │ │ │ │ └── list.service.ts │ │ │ │ │ ├── redisearch/ │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── create.redisearch-index.dto.ts │ │ │ │ │ │ │ ├── index.delete.dto.ts │ │ │ │ │ │ │ ├── index.info.dto.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── key-indexes.dto.ts │ │ │ │ │ │ │ ├── list.redisearch-indexes.response.ts │ │ │ │ │ │ │ └── search.redisearch.dto.ts │ │ │ │ │ │ ├── key-indexes.service.spec.ts │ │ │ │ │ │ ├── key-indexes.service.ts │ │ │ │ │ │ ├── redisearch.controller.ts │ │ │ │ │ │ ├── redisearch.module.ts │ │ │ │ │ │ ├── redisearch.service.spec.ts │ │ │ │ │ │ └── redisearch.service.ts │ │ │ │ │ ├── rejson-rl/ │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── create.rejson-rl-with-expire.dto.ts │ │ │ │ │ │ │ ├── create.rejson-rl.dto.ts │ │ │ │ │ │ │ ├── get.rejson-rl.dto.ts │ │ │ │ │ │ │ ├── get.rejson-rl.response.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── modify.rejson-rl-arr-append.dto.ts │ │ │ │ │ │ │ ├── modify.rejson-rl-set.dto.ts │ │ │ │ │ │ │ ├── remove.rejson-rl.dto.ts │ │ │ │ │ │ │ ├── remove.rejson-rl.response.ts │ │ │ │ │ │ │ └── safe.rejson-rl-data.dto.ts │ │ │ │ │ │ ├── rejson-rl.controller.ts │ │ │ │ │ │ ├── rejson-rl.module.ts │ │ │ │ │ │ ├── rejson-rl.service.spec.ts │ │ │ │ │ │ └── rejson-rl.service.ts │ │ │ │ │ ├── set/ │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── add.members-to-set.dto.ts │ │ │ │ │ │ │ ├── create.set-with-expire.dto.ts │ │ │ │ │ │ │ ├── delete.members-from-set.dto.ts │ │ │ │ │ │ │ ├── delete.members-from-set.response.ts │ │ │ │ │ │ │ ├── get.set-members.dto.ts │ │ │ │ │ │ │ ├── get.set-members.response.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── set.controller.ts │ │ │ │ │ │ ├── set.module.ts │ │ │ │ │ │ ├── set.service.spec.ts │ │ │ │ │ │ └── set.service.ts │ │ │ │ │ ├── stream/ │ │ │ │ │ │ ├── controllers/ │ │ │ │ │ │ │ ├── consumer-group.controller.ts │ │ │ │ │ │ │ ├── consumer.controller.ts │ │ │ │ │ │ │ └── stream.controller.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── ack.pending-entries.dto.ts │ │ │ │ │ │ │ ├── ack.pending-entries.response.ts │ │ │ │ │ │ │ ├── add.stream-entries.dto.ts │ │ │ │ │ │ │ ├── add.stream-entries.response.ts │ │ │ │ │ │ │ ├── claim.pending-entries.response.ts │ │ │ │ │ │ │ ├── claim.pending-entry.dto.ts │ │ │ │ │ │ │ ├── create.consumer-groups.dto.ts │ │ │ │ │ │ │ ├── create.stream.dto.ts │ │ │ │ │ │ │ ├── delete.consumer-groups.dto.ts │ │ │ │ │ │ │ ├── delete.consumer-groups.response.ts │ │ │ │ │ │ │ ├── delete.consumers.dto.ts │ │ │ │ │ │ │ ├── delete.stream-entries.dto.ts │ │ │ │ │ │ │ ├── delete.stream-entries.response.ts │ │ │ │ │ │ │ ├── get.consumers.dto.ts │ │ │ │ │ │ │ ├── get.pending-entries.dto.ts │ │ │ │ │ │ │ ├── get.stream-entries.dto.ts │ │ │ │ │ │ │ ├── get.stream-entries.response.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── stream-entry.dto.ts │ │ │ │ │ │ │ └── update.consumer-group.dto.ts │ │ │ │ │ │ ├── services/ │ │ │ │ │ │ │ ├── consumer-group.service.spec.ts │ │ │ │ │ │ │ ├── consumer-group.service.ts │ │ │ │ │ │ │ ├── consumer.service.spec.ts │ │ │ │ │ │ │ ├── consumer.service.ts │ │ │ │ │ │ │ ├── stream.service.spec.ts │ │ │ │ │ │ │ └── stream.service.ts │ │ │ │ │ │ └── stream.module.ts │ │ │ │ │ ├── string/ │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── get.string-info.dto.ts │ │ │ │ │ │ │ ├── get.string-value.response.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── set.string-with-expire.dto.ts │ │ │ │ │ │ │ └── set.string.dto.ts │ │ │ │ │ │ ├── string.controller.ts │ │ │ │ │ │ ├── string.module.ts │ │ │ │ │ │ ├── string.service.spec.ts │ │ │ │ │ │ └── string.service.ts │ │ │ │ │ ├── utils/ │ │ │ │ │ │ ├── checkKeyExistsing.spec.ts │ │ │ │ │ │ ├── checkKeyExistsing.ts │ │ │ │ │ │ ├── clusterCursor.spec.ts │ │ │ │ │ │ ├── clusterCursor.ts │ │ │ │ │ │ ├── getShards.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── redisIndexInfo.ts │ │ │ │ │ └── z-set/ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── add.members-to-z-set.dto.ts │ │ │ │ │ │ ├── create.z-set-with-expire.dto.ts │ │ │ │ │ │ ├── delete.members-from-z-set.dto.ts │ │ │ │ │ │ ├── delete.members-from-z-set.response.ts │ │ │ │ │ │ ├── get.z-set-members.dto.ts │ │ │ │ │ │ ├── get.z-set.response.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── search.z-set-members.dto.ts │ │ │ │ │ │ ├── search.z-set-members.response.ts │ │ │ │ │ │ ├── search.z-set.response.ts │ │ │ │ │ │ ├── update.member-in-z-set.dto.ts │ │ │ │ │ │ └── z-set-member.dto.ts │ │ │ │ │ ├── z-set.controller.ts │ │ │ │ │ ├── z-set.module.ts │ │ │ │ │ ├── z-set.service.spec.ts │ │ │ │ │ └── z-set.service.ts │ │ │ │ ├── bulk-actions/ │ │ │ │ │ ├── bulk-actions.analytics.spec.ts │ │ │ │ │ ├── bulk-actions.analytics.ts │ │ │ │ │ ├── bulk-actions.controller.ts │ │ │ │ │ ├── bulk-actions.gateway.ts │ │ │ │ │ ├── bulk-actions.module.ts │ │ │ │ │ ├── bulk-actions.service.spec.ts │ │ │ │ │ ├── bulk-actions.service.ts │ │ │ │ │ ├── bulk-import.controller.ts │ │ │ │ │ ├── bulk-import.service.spec.ts │ │ │ │ │ ├── bulk-import.service.ts │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── bulk-action-id.dto.ts │ │ │ │ │ │ ├── create-bulk-action.dto.ts │ │ │ │ │ │ └── upload-import-file-by-path.dto.ts │ │ │ │ │ ├── interfaces/ │ │ │ │ │ │ ├── bulk-action-filter-overview.interface.ts │ │ │ │ │ │ ├── bulk-action-overview.interface.ts │ │ │ │ │ │ ├── bulk-action-progress-overview.interface.ts │ │ │ │ │ │ ├── bulk-action-summary-overview.interface.ts │ │ │ │ │ │ ├── bulk-action.interface.ts │ │ │ │ │ │ ├── bulk-action.runner.interface.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── bulk-action-filter.spec.ts │ │ │ │ │ │ ├── bulk-action-filter.ts │ │ │ │ │ │ ├── bulk-action-progress.spec.ts │ │ │ │ │ │ ├── bulk-action-progress.ts │ │ │ │ │ │ ├── bulk-action-summary.spec.ts │ │ │ │ │ │ ├── bulk-action-summary.ts │ │ │ │ │ │ ├── bulk-action.spec.ts │ │ │ │ │ │ ├── bulk-action.ts │ │ │ │ │ │ └── runners/ │ │ │ │ │ │ ├── abstract.bulk-action.runner.spec.ts │ │ │ │ │ │ ├── abstract.bulk-action.runner.ts │ │ │ │ │ │ └── simple/ │ │ │ │ │ │ ├── abstract.bulk-action.simple.runner.spec.ts │ │ │ │ │ │ ├── abstract.bulk-action.simple.runner.ts │ │ │ │ │ │ ├── delete.bulk-action.simple.runner.spec.ts │ │ │ │ │ │ ├── delete.bulk-action.simple.runner.ts │ │ │ │ │ │ ├── unlink.bulk-action.simple.runner.spec.ts │ │ │ │ │ │ └── unlink.bulk-action.simple.runner.ts │ │ │ │ │ └── providers/ │ │ │ │ │ ├── bulk-actions.provider.spec.ts │ │ │ │ │ └── bulk-actions.provider.ts │ │ │ │ ├── certificate/ │ │ │ │ │ ├── ca-certificate.controller.ts │ │ │ │ │ ├── ca-certificate.service.spec.ts │ │ │ │ │ ├── ca-certificate.service.ts │ │ │ │ │ ├── certificate.module.ts │ │ │ │ │ ├── client-certificate.controller.ts │ │ │ │ │ ├── client-certificate.service.spec.ts │ │ │ │ │ ├── client-certificate.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create.ca-certificate.dto.ts │ │ │ │ │ │ ├── create.client-certificate.dto.ts │ │ │ │ │ │ ├── use.ca-certificate.dto.ts │ │ │ │ │ │ └── use.client-certificate.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ ├── ca-certificate.entity.ts │ │ │ │ │ │ └── client-certificate.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── ca-certificate.ts │ │ │ │ │ │ └── client-certificate.ts │ │ │ │ │ ├── repositories/ │ │ │ │ │ │ ├── ca-certificate.repository.ts │ │ │ │ │ │ ├── client-certificate.repository.ts │ │ │ │ │ │ ├── local.ca-certificate.repository.spec.ts │ │ │ │ │ │ ├── local.ca-certificate.repository.ts │ │ │ │ │ │ ├── local.client-certificate.repository.spec.ts │ │ │ │ │ │ └── local.client-certificate.repository.ts │ │ │ │ │ └── transformers/ │ │ │ │ │ ├── ca-cert.transformer.spec.ts │ │ │ │ │ ├── ca-cert.transformer.ts │ │ │ │ │ ├── client-cert.transformer.spec.ts │ │ │ │ │ └── client-cert.transformer.ts │ │ │ │ ├── cli/ │ │ │ │ │ ├── cli.module.ts │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── errors.ts │ │ │ │ │ ├── controllers/ │ │ │ │ │ │ └── cli.controller.ts │ │ │ │ │ ├── decorators/ │ │ │ │ │ │ ├── api-cli-params.decorator.ts │ │ │ │ │ │ └── cli-client-metadata.decorator.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ └── cli.dto.ts │ │ │ │ │ ├── services/ │ │ │ │ │ │ ├── cli-analytics/ │ │ │ │ │ │ │ ├── cli-analytics.service.spec.ts │ │ │ │ │ │ │ └── cli-analytics.service.ts │ │ │ │ │ │ └── cli-business/ │ │ │ │ │ │ ├── cli-business.service.spec.ts │ │ │ │ │ │ ├── cli-business.service.ts │ │ │ │ │ │ └── output-formatter/ │ │ │ │ │ │ ├── output-formatter-manager.spec.ts │ │ │ │ │ │ ├── output-formatter-manager.ts │ │ │ │ │ │ ├── output-formatter.interface.ts │ │ │ │ │ │ └── strategies/ │ │ │ │ │ │ ├── raw-formatter.strategy.spec.ts │ │ │ │ │ │ ├── raw-formatter.strategy.ts │ │ │ │ │ │ ├── text-formatter.strategy.spec.ts │ │ │ │ │ │ ├── text-formatter.strategy.ts │ │ │ │ │ │ └── utf-8-formatter.strategy.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── getUnsupportedCommands.spec.ts │ │ │ │ │ └── getUnsupportedCommands.ts │ │ │ │ ├── cloud/ │ │ │ │ │ ├── auth/ │ │ │ │ │ │ ├── auth-strategy/ │ │ │ │ │ │ │ ├── cloud-auth.strategy.spec.ts │ │ │ │ │ │ │ ├── cloud-auth.strategy.ts │ │ │ │ │ │ │ ├── github-idp.cloud.auth-strategy.ts │ │ │ │ │ │ │ ├── google-idp.cloud.auth-strategy.ts │ │ │ │ │ │ │ ├── sso-idp.cloud.auth-strategy.spec.ts │ │ │ │ │ │ │ ├── sso-idp.cloud.auth-strategy.ts │ │ │ │ │ │ │ └── tcp-cloud.auth.strategy.ts │ │ │ │ │ │ ├── cloud-auth.analytics.spec.ts │ │ │ │ │ │ ├── cloud-auth.analytics.ts │ │ │ │ │ │ ├── cloud-auth.controller.ts │ │ │ │ │ │ ├── cloud-auth.module.ts │ │ │ │ │ │ ├── cloud-auth.service.spec.ts │ │ │ │ │ │ ├── cloud-auth.service.ts │ │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ │ ├── cloud-oauth.canceled.exception.ts │ │ │ │ │ │ │ ├── cloud-oauth.github-email-permission.exception.ts │ │ │ │ │ │ │ ├── cloud-oauth.misconfiguration.exception.ts │ │ │ │ │ │ │ ├── cloud-oauth.missed-required-data.exception.ts │ │ │ │ │ │ │ ├── cloud-oauth.sso-unsupported-email.exception.ts │ │ │ │ │ │ │ ├── cloud-oauth.unexpected-error.exception.ts │ │ │ │ │ │ │ ├── cloud-oauth.unknown-authorization-request.exception.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── models/ │ │ │ │ │ │ ├── cloud-auth-request-info.ts │ │ │ │ │ │ ├── cloud-auth-request.ts │ │ │ │ │ │ ├── cloud-auth-response.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── autodiscovery/ │ │ │ │ │ │ ├── cloud-autodicovery.analytics.spec.ts │ │ │ │ │ │ ├── cloud-autodiscovery.analytics.ts │ │ │ │ │ │ ├── cloud-autodiscovery.service.spec.ts │ │ │ │ │ │ ├── cloud-autodiscovery.service.ts │ │ │ │ │ │ ├── cloud.autodiscovery.controller.ts │ │ │ │ │ │ ├── cloud.autodiscovery.module.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── discover-cloud-databases.dto.ts │ │ │ │ │ │ │ ├── import-cloud-database.dto.ts │ │ │ │ │ │ │ ├── import-cloud-database.response.ts │ │ │ │ │ │ │ ├── import-cloud-databases.dto.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── me.cloud-autodiscovery.service.spec.ts │ │ │ │ │ │ ├── me.cloud-autodiscovery.service.ts │ │ │ │ │ │ ├── me.cloud.autodiscovery.controller.ts │ │ │ │ │ │ └── models/ │ │ │ │ │ │ ├── cloud-autodiscovery-auth-type.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── capi-key/ │ │ │ │ │ │ ├── cloud-capi-key.analytics.spec.ts │ │ │ │ │ │ ├── cloud-capi-key.analytics.ts │ │ │ │ │ │ ├── cloud-capi-key.api.provider.spec.ts │ │ │ │ │ │ ├── cloud-capi-key.api.provider.ts │ │ │ │ │ │ ├── cloud-capi-key.controller.ts │ │ │ │ │ │ ├── cloud-capi-key.module.ts │ │ │ │ │ │ ├── cloud-capi-key.service.spec.ts │ │ │ │ │ │ ├── cloud-capi-key.service.ts │ │ │ │ │ │ ├── entity/ │ │ │ │ │ │ │ └── cloud-capi-key.entity.ts │ │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ │ ├── cloud-capi-key.not-found.exception.ts │ │ │ │ │ │ │ ├── cloud-capi-key.unauthorized.exception.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── model/ │ │ │ │ │ │ │ ├── api.interface.ts │ │ │ │ │ │ │ ├── cloud-capi-key.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── repository/ │ │ │ │ │ │ ├── cloud-capi-key.repository.ts │ │ │ │ │ │ ├── local.cloud-capi-key.repository.spec.ts │ │ │ │ │ │ └── local.cloud-capi-key.repository.ts │ │ │ │ │ ├── cloud-sso.feature.flag.ts │ │ │ │ │ ├── cloud.module.ts │ │ │ │ │ ├── common/ │ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── decorators/ │ │ │ │ │ │ │ └── cloud-auth.decorator.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── cloud.capi.auth.dto.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ │ ├── cloud-api.bad-request.exception.ts │ │ │ │ │ │ │ ├── cloud-api.error.handler.ts │ │ │ │ │ │ │ ├── cloud-api.forbidden.exception.ts │ │ │ │ │ │ │ ├── cloud-api.internal-server-error.exception.ts │ │ │ │ │ │ │ ├── cloud-api.not-found.exception.ts │ │ │ │ │ │ │ ├── cloud-api.unauthorized.exception.ts │ │ │ │ │ │ │ ├── cloud-capi.error.handler.ts │ │ │ │ │ │ │ ├── cloud-capi.unauthorized.exception.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── models/ │ │ │ │ │ │ │ ├── api.interface.ts │ │ │ │ │ │ │ ├── capi.interface.ts │ │ │ │ │ │ │ ├── cloud-request-utm.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── providers/ │ │ │ │ │ │ ├── cloud.api.provider.spec.ts │ │ │ │ │ │ ├── cloud.api.provider.ts │ │ │ │ │ │ ├── cloud.capi.provider.spec.ts │ │ │ │ │ │ └── cloud.capi.provider.ts │ │ │ │ │ ├── database/ │ │ │ │ │ │ ├── cloud-database.analytics.spec.ts │ │ │ │ │ │ ├── cloud-database.analytics.ts │ │ │ │ │ │ ├── cloud-database.capi.provider.spec.ts │ │ │ │ │ │ ├── cloud-database.capi.provider.ts │ │ │ │ │ │ ├── cloud-database.capi.service.spec.ts │ │ │ │ │ │ ├── cloud-database.capi.service.ts │ │ │ │ │ │ ├── cloud-database.module.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── create-free-cloud-database.dto.ts │ │ │ │ │ │ │ ├── get-cloud-subscription-database.dto.ts │ │ │ │ │ │ │ ├── get-cloud-subscription-databases.dto.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── entities/ │ │ │ │ │ │ │ └── cloud-database-details.entity.ts │ │ │ │ │ │ ├── models/ │ │ │ │ │ │ │ ├── capi.interface.ts │ │ │ │ │ │ │ ├── cloud-database-details.ts │ │ │ │ │ │ │ ├── cloud-database.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ ├── cloud-data-converter.spec.ts │ │ │ │ │ │ ├── cloud-data-converter.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── job/ │ │ │ │ │ │ ├── cloud-job.controller.ts │ │ │ │ │ │ ├── cloud-job.factory.ts │ │ │ │ │ │ ├── cloud-job.gateway.ts │ │ │ │ │ │ ├── cloud-job.module.ts │ │ │ │ │ │ ├── cloud-job.provider.ts │ │ │ │ │ │ ├── cloud-job.service.spec.ts │ │ │ │ │ │ ├── cloud-job.service.ts │ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── create-database.cloud-job.data.dto.ts │ │ │ │ │ │ │ ├── create-subscription-and-database.cloud-job.data.dto.ts │ │ │ │ │ │ │ ├── create.cloud-job.dto.ts │ │ │ │ │ │ │ ├── import-database.cloud-job.data.dto.ts │ │ │ │ │ │ │ └── monitor.cloud-job.dto.ts │ │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ │ ├── cloud-database-already-exists-free.exception.ts │ │ │ │ │ │ │ ├── cloud-database-endpoint-invalid.exception.ts │ │ │ │ │ │ │ ├── cloud-database-import-forbidden.exception.ts │ │ │ │ │ │ │ ├── cloud-database-in-failed-state.exception.ts │ │ │ │ │ │ │ ├── cloud-database-in-unexpected-state.exception.ts │ │ │ │ │ │ │ ├── cloud-job-aborted.exception.ts │ │ │ │ │ │ │ ├── cloud-job-not-found.exception.ts │ │ │ │ │ │ │ ├── cloud-job-unexpected-error.exception.ts │ │ │ │ │ │ │ ├── cloud-job-unsupported.exception.ts │ │ │ │ │ │ │ ├── cloud-job.error.handler.ts │ │ │ │ │ │ │ ├── cloud-plan-not-found-free.exception.ts │ │ │ │ │ │ │ ├── cloud-subscription-already-exists-free.exception.ts │ │ │ │ │ │ │ ├── cloud-subscription-in-failed-state.exception.ts │ │ │ │ │ │ │ ├── cloud-subscription-in-unexpected-state.exception.ts │ │ │ │ │ │ │ ├── cloud-subscription-unable-to-determine.exception.ts │ │ │ │ │ │ │ ├── cloud-task-no-resource-id.exception.ts │ │ │ │ │ │ │ ├── cloud-task-not-found.exception.ts │ │ │ │ │ │ │ ├── cloud-task-processing-error.exception.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── jobs/ │ │ │ │ │ │ │ ├── cloud-job.spec.ts │ │ │ │ │ │ │ ├── cloud-job.ts │ │ │ │ │ │ │ ├── create-free-database.cloud-job.ts │ │ │ │ │ │ │ ├── create-free-subscription-and-database.cloud-job.ts │ │ │ │ │ │ │ ├── create-free-subscription.cloud-job.ts │ │ │ │ │ │ │ ├── import-free-database.cloud-job.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── wait-for-active-database.cloud-job.ts │ │ │ │ │ │ │ ├── wait-for-active-subscription.cloud-job.ts │ │ │ │ │ │ │ └── wait-for-task.cloud-job.ts │ │ │ │ │ │ ├── models/ │ │ │ │ │ │ │ ├── cloud-job-info.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── transformers/ │ │ │ │ │ │ ├── cloud-job-data.transformer.spec.ts │ │ │ │ │ │ └── cloud-job-data.transformer.ts │ │ │ │ │ ├── session/ │ │ │ │ │ │ ├── cloud-session.module.ts │ │ │ │ │ │ ├── cloud-session.service.spec.ts │ │ │ │ │ │ ├── cloud-session.service.ts │ │ │ │ │ │ ├── entities/ │ │ │ │ │ │ │ └── cloud.session.entity.ts │ │ │ │ │ │ ├── models/ │ │ │ │ │ │ │ └── cloud-session.ts │ │ │ │ │ │ └── repositories/ │ │ │ │ │ │ ├── cloud.session.repository.ts │ │ │ │ │ │ ├── local.cloud.session.repository.spec.ts │ │ │ │ │ │ └── local.cloud.session.repository.ts │ │ │ │ │ ├── subscription/ │ │ │ │ │ │ ├── cloud-subscription.api.service.spec.ts │ │ │ │ │ │ ├── cloud-subscription.api.service.ts │ │ │ │ │ │ ├── cloud-subscription.capi.service.spec.ts │ │ │ │ │ │ ├── cloud-subscription.capi.service.ts │ │ │ │ │ │ ├── cloud-subscription.controller.ts │ │ │ │ │ │ ├── cloud-subscription.module.ts │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── create-free-cloud-subscription.dto.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── plans.cloud-subscription.dto.ts │ │ │ │ │ │ ├── models/ │ │ │ │ │ │ │ ├── api.interface.ts │ │ │ │ │ │ │ ├── capi.interface.ts │ │ │ │ │ │ │ ├── cloud-subscription-plan.ts │ │ │ │ │ │ │ ├── cloud-subscription-region.ts │ │ │ │ │ │ │ ├── cloud-subscription.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ │ ├── cloud-subscription.api.provider.spec.ts │ │ │ │ │ │ │ ├── cloud-subscription.api.provider.ts │ │ │ │ │ │ │ ├── cloud-subscription.capi.provider.spec.ts │ │ │ │ │ │ │ └── cloud-subscription.capi.provider.ts │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ ├── cloud-data-converter.spec.ts │ │ │ │ │ │ ├── cloud-data-converter.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── task/ │ │ │ │ │ │ ├── cloud-task.capi.service.spec.ts │ │ │ │ │ │ ├── cloud-task.capi.service.ts │ │ │ │ │ │ ├── cloud-task.module.ts │ │ │ │ │ │ ├── models/ │ │ │ │ │ │ │ ├── capi.interface.ts │ │ │ │ │ │ │ ├── cloud-task.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ │ ├── cloud-task.capi.provider.spec.ts │ │ │ │ │ │ │ └── cloud-task.capi.provider.ts │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ ├── cloud-data-converter.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── user/ │ │ │ │ │ ├── cloud-user.api.service.spec.ts │ │ │ │ │ ├── cloud-user.api.service.ts │ │ │ │ │ ├── cloud-user.capi.service.spec.ts │ │ │ │ │ ├── cloud-user.capi.service.ts │ │ │ │ │ ├── cloud-user.controller.ts │ │ │ │ │ ├── cloud-user.module.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── api.interface.ts │ │ │ │ │ │ ├── capi.interface.ts │ │ │ │ │ │ ├── cloud-account-info.ts │ │ │ │ │ │ ├── cloud-user-account.ts │ │ │ │ │ │ ├── cloud-user.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── cloud-user.api.provider.spec.ts │ │ │ │ │ │ ├── cloud-user.api.provider.ts │ │ │ │ │ │ ├── cloud-user.capi.provider.spec.ts │ │ │ │ │ │ └── cloud-user.capi.provider.ts │ │ │ │ │ ├── repositories/ │ │ │ │ │ │ ├── cloud-user.repository.ts │ │ │ │ │ │ ├── in-session.cloud-user.repository.spec.ts │ │ │ │ │ │ └── in-session.cloud-user.repository.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── cloud-data-converter.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── token.spec.ts │ │ │ │ │ └── token.ts │ │ │ │ ├── cluster-monitor/ │ │ │ │ │ ├── cluster-monitor.controller.ts │ │ │ │ │ ├── cluster-monitor.module.ts │ │ │ │ │ ├── cluster-monitor.service.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── cluster-details.ts │ │ │ │ │ │ ├── cluster-node-details.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── strategies/ │ │ │ │ │ ├── abstract.info.strategy.spec.ts │ │ │ │ │ ├── abstract.info.strategy.ts │ │ │ │ │ ├── cluster-nodes.info.strategy.spec.ts │ │ │ │ │ ├── cluster-nodes.info.strategy.ts │ │ │ │ │ ├── cluster-shards.info.strategy.spec.ts │ │ │ │ │ ├── cluster-shards.info.strategy.ts │ │ │ │ │ └── cluster.info.interface.ts │ │ │ │ ├── commands/ │ │ │ │ │ ├── commands-json.provider.spec.ts │ │ │ │ │ ├── commands-json.provider.ts │ │ │ │ │ ├── commands.controller.ts │ │ │ │ │ ├── commands.module.ts │ │ │ │ │ ├── commands.service.spec.ts │ │ │ │ │ └── commands.service.ts │ │ │ │ ├── constants/ │ │ │ │ │ ├── constants.module.ts │ │ │ │ │ └── providers/ │ │ │ │ │ ├── constants.provider.ts │ │ │ │ │ └── local.constants.provider.ts │ │ │ │ ├── custom-tutorial/ │ │ │ │ │ ├── custom-tutorial.analytics.spec.ts │ │ │ │ │ ├── custom-tutorial.analytics.ts │ │ │ │ │ ├── custom-tutorial.controller.ts │ │ │ │ │ ├── custom-tutorial.module.ts │ │ │ │ │ ├── custom-tutorial.service.spec.ts │ │ │ │ │ ├── custom-tutorial.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ └── upload.custom-tutorial.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── custom-tutorial.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── custom-tutorial.manifest.ts │ │ │ │ │ │ └── custom-tutorial.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── custom-tutorial.fs.provider.spec.ts │ │ │ │ │ │ ├── custom-tutorial.fs.provider.ts │ │ │ │ │ │ ├── custom-tutorial.manifest.provider.spec.ts │ │ │ │ │ │ └── custom-tutorial.manifest.provider.ts │ │ │ │ │ └── repositories/ │ │ │ │ │ ├── custom-tutorial.repository.ts │ │ │ │ │ ├── local.custom-tutorial.repository.spec.ts │ │ │ │ │ └── local.custom-tutorial.repository.ts │ │ │ │ ├── database/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ ├── events.ts │ │ │ │ │ │ └── overview.ts │ │ │ │ │ ├── credentials/ │ │ │ │ │ │ ├── credential-strategy.provider.ts │ │ │ │ │ │ ├── credentials.module.ts │ │ │ │ │ │ ├── local.credential-strategy.provider.spec.ts │ │ │ │ │ │ ├── local.credential-strategy.provider.ts │ │ │ │ │ │ └── strategies/ │ │ │ │ │ │ ├── azure-entra-id.credential-strategy.spec.ts │ │ │ │ │ │ ├── azure-entra-id.credential-strategy.ts │ │ │ │ │ │ ├── default.credential-strategy.spec.ts │ │ │ │ │ │ └── default.credential-strategy.ts │ │ │ │ │ ├── database-connection.service.spec.ts │ │ │ │ │ ├── database-connection.service.ts │ │ │ │ │ ├── database-info.controller.ts │ │ │ │ │ ├── database-info.service.spec.ts │ │ │ │ │ ├── database-info.service.ts │ │ │ │ │ ├── database.analytics.spec.ts │ │ │ │ │ ├── database.analytics.ts │ │ │ │ │ ├── database.controller.spec.ts │ │ │ │ │ ├── database.controller.ts │ │ │ │ │ ├── database.module.ts │ │ │ │ │ ├── database.service.spec.ts │ │ │ │ │ ├── database.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create.database.dto.ts │ │ │ │ │ │ ├── database.response.ts │ │ │ │ │ │ ├── delete.databases.dto.ts │ │ │ │ │ │ ├── delete.databases.response.ts │ │ │ │ │ │ ├── export.databases.dto.ts │ │ │ │ │ │ ├── redis-info.dto.ts │ │ │ │ │ │ └── update.database.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── database.entity.ts │ │ │ │ │ ├── exeptions/ │ │ │ │ │ │ ├── database-already-exists.exception.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── middleware/ │ │ │ │ │ │ └── connection.middleware.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── additional.redis.module.ts │ │ │ │ │ │ ├── database-overview.ts │ │ │ │ │ │ ├── database.ts │ │ │ │ │ │ ├── export-database.ts │ │ │ │ │ │ └── provider-details.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── database-info.provider.spec.ts │ │ │ │ │ │ ├── database-info.provider.ts │ │ │ │ │ │ ├── database-overview.provider.spec.ts │ │ │ │ │ │ ├── database-overview.provider.ts │ │ │ │ │ │ ├── database.client.factory.spec.ts │ │ │ │ │ │ ├── database.client.factory.ts │ │ │ │ │ │ ├── database.factory.spec.ts │ │ │ │ │ │ └── database.factory.ts │ │ │ │ │ └── repositories/ │ │ │ │ │ ├── database.repository.ts │ │ │ │ │ ├── local.database.repository.spec.ts │ │ │ │ │ ├── local.database.repository.ts │ │ │ │ │ ├── stack.database.repository.spec.ts │ │ │ │ │ └── stack.databases.repository.ts │ │ │ │ ├── database-analysis/ │ │ │ │ │ ├── database-analysis.controller.ts │ │ │ │ │ ├── database-analysis.module.ts │ │ │ │ │ ├── database-analysis.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create-database-analysis.dto.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── recommendation-vote.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── database-analysis.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── analysis-progress.ts │ │ │ │ │ │ ├── database-analysis.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── key.ts │ │ │ │ │ │ ├── nsp-summary.ts │ │ │ │ │ │ ├── nsp-type-summary.ts │ │ │ │ │ │ ├── recommendation.ts │ │ │ │ │ │ ├── scan-filter.ts │ │ │ │ │ │ ├── short-database-analysis.ts │ │ │ │ │ │ ├── simple-summary.ts │ │ │ │ │ │ ├── simple-type-summary.ts │ │ │ │ │ │ └── sum-group.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── database-analysis.provider.spec.ts │ │ │ │ │ │ ├── database-analysis.provider.ts │ │ │ │ │ │ ├── database-analyzer.spec.ts │ │ │ │ │ │ └── database-analyzer.ts │ │ │ │ │ └── scanner/ │ │ │ │ │ ├── key-info/ │ │ │ │ │ │ ├── key-info.provider.spec.ts │ │ │ │ │ │ ├── key-info.provider.ts │ │ │ │ │ │ ├── key-info.strategy.interface.ts │ │ │ │ │ │ └── strategies/ │ │ │ │ │ │ ├── abstract.info.strategy.spec.ts │ │ │ │ │ │ ├── abstract.info.strategy.ts │ │ │ │ │ │ ├── default-info.strategy.spec.ts │ │ │ │ │ │ ├── default-info.strategy.ts │ │ │ │ │ │ ├── graph-info.strategy.spec.ts │ │ │ │ │ │ ├── graph-info.strategy.ts │ │ │ │ │ │ ├── hash-info.strategy.spec.ts │ │ │ │ │ │ ├── hash-info.strategy.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── json-info.strategy.spec.ts │ │ │ │ │ │ ├── json-info.strategy.ts │ │ │ │ │ │ ├── list-info.strategy.spec.ts │ │ │ │ │ │ ├── list-info.strategy.ts │ │ │ │ │ │ ├── set-info.strategy.spec.ts │ │ │ │ │ │ ├── set-info.strategy.ts │ │ │ │ │ │ ├── stream-info.strategy.spec.ts │ │ │ │ │ │ ├── stream-info.strategy.ts │ │ │ │ │ │ ├── string-info.strategy.spec.ts │ │ │ │ │ │ ├── string-info.strategy.ts │ │ │ │ │ │ ├── ts-info.strategy.spec.ts │ │ │ │ │ │ ├── ts-info.strategy.ts │ │ │ │ │ │ ├── z-set-info.strategy.spec.ts │ │ │ │ │ │ └── z-set-info.strategy.ts │ │ │ │ │ ├── keys-scanner.spec.ts │ │ │ │ │ └── keys-scanner.ts │ │ │ │ ├── database-discovery/ │ │ │ │ │ ├── auto.database-discovery.service.spec.ts │ │ │ │ │ ├── auto.database-discovery.service.ts │ │ │ │ │ ├── database-discovery.module.ts │ │ │ │ │ ├── database-discovery.service.ts │ │ │ │ │ ├── local.database-discovery.service.spec.ts │ │ │ │ │ ├── local.database-discovery.service.ts │ │ │ │ │ ├── pre-setup.database-discovery.service.spec.ts │ │ │ │ │ ├── pre-setup.database-discovery.service.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── autodiscovery.util.spec.ts │ │ │ │ │ ├── autodiscovery.util.ts │ │ │ │ │ ├── pre-setup.discovery.util.spec.ts │ │ │ │ │ └── pre-setup.discovery.util.ts │ │ │ │ ├── database-import/ │ │ │ │ │ ├── certificate-import.service.spec.ts │ │ │ │ │ ├── certificate-import.service.ts │ │ │ │ │ ├── database-import.analytics.spec.ts │ │ │ │ │ ├── database-import.analytics.ts │ │ │ │ │ ├── database-import.controller.spec.ts │ │ │ │ │ ├── database-import.controller.ts │ │ │ │ │ ├── database-import.module.ts │ │ │ │ │ ├── database-import.service.spec.ts │ │ │ │ │ ├── database-import.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── database-import.response.ts │ │ │ │ │ │ └── import.database.dto.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── invalid-ca-certificate-body.exception.ts │ │ │ │ │ │ ├── invalid-certificate-name.exception.ts │ │ │ │ │ │ ├── invalid-client-certificate-body.exception.ts │ │ │ │ │ │ ├── invalid-client-private-key.exception.ts │ │ │ │ │ │ ├── invalid-compressor.exception.ts │ │ │ │ │ │ ├── invalid-ssh-body.exception.ts │ │ │ │ │ │ ├── invalid-ssh-private-key-body.exception.ts │ │ │ │ │ │ ├── no-database-import-file-provided.exception.ts │ │ │ │ │ │ ├── size-limit-exceeded-database-import-file.exception.ts │ │ │ │ │ │ ├── ssh-agents-are-not-supported.exception.ts │ │ │ │ │ │ └── unable-to-parse-database-import-file.exception.ts │ │ │ │ │ ├── ssh-import.service.spec.ts │ │ │ │ │ └── ssh-import.service.ts │ │ │ │ ├── database-recommendation/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── database-recommendation.analytics.spec.ts │ │ │ │ │ ├── database-recommendation.analytics.ts │ │ │ │ │ ├── database-recommendation.controller.ts │ │ │ │ │ ├── database-recommendation.gateway.ts │ │ │ │ │ ├── database-recommendation.module.ts │ │ │ │ │ ├── database-recommendation.service.spec.ts │ │ │ │ │ ├── database-recommendation.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create.database-recommendation.dto.ts │ │ │ │ │ │ ├── database-recommendations.response.ts │ │ │ │ │ │ ├── delete.database-recommendation.dto.ts │ │ │ │ │ │ ├── delete.database-recommendation.response.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── modify.database-recommendation.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── database-recommendation.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── database-recommendation-params.ts │ │ │ │ │ │ ├── database-recommendation.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── integersInSet.ts │ │ │ │ │ │ └── searchJSON.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── database-recommendation.emitter.spec.ts │ │ │ │ │ │ └── database-recommendation.emitter.ts │ │ │ │ │ ├── repositories/ │ │ │ │ │ │ ├── database-recommendation.repository.ts │ │ │ │ │ │ ├── local.database.recommendation.repository.spec.ts │ │ │ │ │ │ └── local.database.recommendation.repository.ts │ │ │ │ │ └── scanner/ │ │ │ │ │ ├── recommendation.provider.spec.ts │ │ │ │ │ ├── recommendation.provider.ts │ │ │ │ │ ├── recommendation.strategy.interface.ts │ │ │ │ │ ├── recommendations.scanner.spec.ts │ │ │ │ │ ├── recommendations.scanner.ts │ │ │ │ │ └── strategies/ │ │ │ │ │ ├── abstract.recommendation.strategy.spec.ts │ │ │ │ │ ├── abstract.recommendation.strategy.ts │ │ │ │ │ ├── avoid-logical-databases.strategy.spec.ts │ │ │ │ │ ├── avoid-logical-databases.strategy.ts │ │ │ │ │ ├── avoid-lua-scripts.strategy.spec.ts │ │ │ │ │ ├── avoid-lua-scripts.strategy.ts │ │ │ │ │ ├── big-amount-connected-clients.strategy.spec.ts │ │ │ │ │ ├── big-amount-connected-clients.strategy.ts │ │ │ │ │ ├── big-set.strategy.spec.ts │ │ │ │ │ ├── big-set.strategy.ts │ │ │ │ │ ├── big-string.strategy.spec.ts │ │ │ │ │ ├── big-string.strategy.ts │ │ │ │ │ ├── compression-for-list.strategy.spec.ts │ │ │ │ │ ├── compression-for-list.strategy.ts │ │ │ │ │ ├── default.recommendation.strategy.spec.ts │ │ │ │ │ ├── default.recommendation.strategy.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── redis-version.strategy.spec.ts │ │ │ │ │ ├── redis-version.strategy.ts │ │ │ │ │ ├── rts.strategy.spec.ts │ │ │ │ │ ├── rts.strategy.ts │ │ │ │ │ ├── search-JSON.strategy.spec.ts │ │ │ │ │ ├── search-JSON.strategy.ts │ │ │ │ │ ├── search-visualization.strategy.spec.ts │ │ │ │ │ ├── search-visualization.strategy.ts │ │ │ │ │ ├── shard-hash.strategy.spec.ts │ │ │ │ │ ├── shard-hash.strategy.ts │ │ │ │ │ ├── string-to-json.strategy.spec.ts │ │ │ │ │ ├── string-to-json.strategy.ts │ │ │ │ │ ├── try-rdi.strategy.spec.ts │ │ │ │ │ ├── try-rdi.strategy.ts │ │ │ │ │ ├── use-smaller-keys.strategy.spec.ts │ │ │ │ │ └── use-smaller-keys.strategy.ts │ │ │ │ ├── database-settings/ │ │ │ │ │ ├── database-settings.controller.ts │ │ │ │ │ ├── database-settings.module.ts │ │ │ │ │ ├── database-settings.service.spec.ts │ │ │ │ │ ├── database-settings.service.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ └── database-setting.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── database-setting.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ └── database-settings.ts │ │ │ │ │ └── repositories/ │ │ │ │ │ ├── database-settings.repository.ts │ │ │ │ │ ├── local-database-settings.repository.spec.ts │ │ │ │ │ └── local-database-settings.repository.ts │ │ │ │ ├── encryption/ │ │ │ │ │ ├── encryption.module.ts │ │ │ │ │ ├── encryption.service.spec.ts │ │ │ │ │ ├── encryption.service.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── encryption-service-error.exception.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── key-decryption-error.exception.ts │ │ │ │ │ │ ├── key-encryption-error.exception.ts │ │ │ │ │ │ ├── key-unavailable.exception.ts │ │ │ │ │ │ ├── keytar-decryption-error.exception.ts │ │ │ │ │ │ ├── keytar-encryption-error.exception.ts │ │ │ │ │ │ ├── keytar-unavailable.exception.ts │ │ │ │ │ │ └── unsupported-encryption-strategy.exception.ts │ │ │ │ │ ├── model.encryptor.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── encryption-result.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── strategies/ │ │ │ │ │ ├── encryption-strategy.interface.ts │ │ │ │ │ ├── key-encryption.strategy.spec.ts │ │ │ │ │ ├── key-encryption.strategy.ts │ │ │ │ │ ├── keytar-encryption.strategy.spec.ts │ │ │ │ │ ├── keytar-encryption.strategy.ts │ │ │ │ │ ├── plain-encryption.strategy.spec.ts │ │ │ │ │ └── plain-encryption.strategy.ts │ │ │ │ ├── feature/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── known-features.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ ├── feature.entity.ts │ │ │ │ │ │ └── features-config.entity.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── unable-to-fetch-remote-config.exception.ts │ │ │ │ │ ├── feature.analytics.spec.ts │ │ │ │ │ ├── feature.analytics.ts │ │ │ │ │ ├── feature.controller.ts │ │ │ │ │ ├── feature.gateway.ts │ │ │ │ │ ├── feature.module.ts │ │ │ │ │ ├── feature.service.ts │ │ │ │ │ ├── features-config.service.ts │ │ │ │ │ ├── local.feature.service.spec.ts │ │ │ │ │ ├── local.feature.service.ts │ │ │ │ │ ├── local.features-config.service.spec.ts │ │ │ │ │ ├── local.features-config.service.ts │ │ │ │ │ ├── model/ │ │ │ │ │ │ ├── feature.ts │ │ │ │ │ │ ├── features-config.spec.ts │ │ │ │ │ │ └── features-config.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ └── feature-flag/ │ │ │ │ │ │ ├── feature-flag.provider.spec.ts │ │ │ │ │ │ ├── feature-flag.provider.ts │ │ │ │ │ │ └── strategies/ │ │ │ │ │ │ ├── cloud-sso.flag.strategy.ts │ │ │ │ │ │ ├── common.flag.strategy.ts │ │ │ │ │ │ ├── default.flag.strategy.ts │ │ │ │ │ │ ├── feature.flag.strategy.spec.ts │ │ │ │ │ │ ├── feature.flag.strategy.ts │ │ │ │ │ │ ├── switchable.flag.strategy.spec.ts │ │ │ │ │ │ ├── switchable.flag.strategy.ts │ │ │ │ │ │ └── with-data.flag.strategy.ts │ │ │ │ │ ├── repositories/ │ │ │ │ │ │ ├── feature.repository.ts │ │ │ │ │ │ ├── features-config.repository.ts │ │ │ │ │ │ ├── local.feature.repository.spec.ts │ │ │ │ │ │ ├── local.feature.repository.ts │ │ │ │ │ │ ├── local.features-config.repository.spec.ts │ │ │ │ │ │ └── local.features-config.repository.ts │ │ │ │ │ └── transformers/ │ │ │ │ │ ├── feature-config-filter.transformer.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── init/ │ │ │ │ │ ├── init.module.ts │ │ │ │ │ ├── init.service.ts │ │ │ │ │ └── local.init.service.ts │ │ │ │ ├── notification/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create-notification.dto.ts │ │ │ │ │ │ ├── create-notifications.dto.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── notifications.dto.ts │ │ │ │ │ │ └── read-notifications.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── notification.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ └── notification.ts │ │ │ │ │ ├── notification.controller.ts │ │ │ │ │ ├── notification.gateway.ts │ │ │ │ │ ├── notification.module.ts │ │ │ │ │ ├── notification.service.spec.ts │ │ │ │ │ ├── notification.service.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── global-notification.provider.spec.ts │ │ │ │ │ │ ├── global-notification.provider.ts │ │ │ │ │ │ ├── notification.emitter.spec.ts │ │ │ │ │ │ └── notification.emitter.ts │ │ │ │ │ └── repositories/ │ │ │ │ │ ├── local.notification.repository.spec.ts │ │ │ │ │ ├── local.notification.repository.ts │ │ │ │ │ └── notification.repository.ts │ │ │ │ ├── plugin/ │ │ │ │ │ ├── plugin.controller.ts │ │ │ │ │ ├── plugin.module.ts │ │ │ │ │ ├── plugin.response.ts │ │ │ │ │ └── plugin.service.ts │ │ │ │ ├── profiler/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── emitters/ │ │ │ │ │ │ ├── client.logs-emiter.spec.ts │ │ │ │ │ │ ├── client.logs-emitter.ts │ │ │ │ │ │ ├── file.logs-emiter.spec.ts │ │ │ │ │ │ └── file.logs-emitter.ts │ │ │ │ │ ├── interfaces/ │ │ │ │ │ │ ├── logs-emitter.interface.ts │ │ │ │ │ │ ├── monitor-data.interface.ts │ │ │ │ │ │ └── shard-observer.interface.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── log-file.spec.ts │ │ │ │ │ │ ├── log-file.ts │ │ │ │ │ │ ├── monitor-settings.ts │ │ │ │ │ │ ├── profiler.client.spec.ts │ │ │ │ │ │ ├── profiler.client.ts │ │ │ │ │ │ ├── redis.observer.spec.ts │ │ │ │ │ │ └── redis.observer.ts │ │ │ │ │ ├── monitor.service.spec.ts │ │ │ │ │ ├── profiler-analytics.service.ts │ │ │ │ │ ├── profiler.controller.ts │ │ │ │ │ ├── profiler.gateway.ts │ │ │ │ │ ├── profiler.module.ts │ │ │ │ │ ├── profiler.service.ts │ │ │ │ │ └── providers/ │ │ │ │ │ ├── log-file.provider.spec.ts │ │ │ │ │ ├── log-file.provider.ts │ │ │ │ │ ├── profiler-client.provider.spec.ts │ │ │ │ │ ├── profiler-client.provider.ts │ │ │ │ │ ├── redis-observer.provider.spec.ts │ │ │ │ │ └── redis-observer.provider.ts │ │ │ │ ├── pub-sub/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── decorators/ │ │ │ │ │ │ └── client.decorator.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── messages.response.ts │ │ │ │ │ │ ├── publish.dto.ts │ │ │ │ │ │ ├── publish.response.ts │ │ │ │ │ │ ├── subscribe.dto.ts │ │ │ │ │ │ └── subscription.dto.ts │ │ │ │ │ ├── errors/ │ │ │ │ │ │ └── pub-sub-ws.exception.ts │ │ │ │ │ ├── filters/ │ │ │ │ │ │ └── ack-ws-exception.filter.ts │ │ │ │ │ ├── interfaces/ │ │ │ │ │ │ ├── message.interface.ts │ │ │ │ │ │ └── subscription.interface.ts │ │ │ │ │ ├── model/ │ │ │ │ │ │ ├── abstract.subscription.ts │ │ │ │ │ │ ├── pattern.subscription.ts │ │ │ │ │ │ ├── redis-client-subscriber.spec.ts │ │ │ │ │ │ ├── redis-client-subscriber.ts │ │ │ │ │ │ ├── simple.subscription.ts │ │ │ │ │ │ ├── user-client.ts │ │ │ │ │ │ ├── user-session.spec.ts │ │ │ │ │ │ └── user-session.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── redis-client.provider.spec.ts │ │ │ │ │ │ ├── redis-client.provider.ts │ │ │ │ │ │ ├── subscription.provider.spec.ts │ │ │ │ │ │ ├── subscription.provider.ts │ │ │ │ │ │ ├── user-session.provider.spec.ts │ │ │ │ │ │ └── user-session.provider.ts │ │ │ │ │ ├── pub-sub.analytics.service.spec.ts │ │ │ │ │ ├── pub-sub.analytics.service.ts │ │ │ │ │ ├── pub-sub.controller.ts │ │ │ │ │ ├── pub-sub.gateway.ts │ │ │ │ │ ├── pub-sub.module.ts │ │ │ │ │ ├── pub-sub.service.spec.ts │ │ │ │ │ └── pub-sub.service.ts │ │ │ │ ├── query-library/ │ │ │ │ │ ├── __tests__/ │ │ │ │ │ │ └── query-library.factory.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create-query-library-item.dto.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── query-library-filter.dto.ts │ │ │ │ │ │ ├── seed-query-library-item.dto.ts │ │ │ │ │ │ ├── seed-query-library.dto.ts │ │ │ │ │ │ └── update-query-library-item.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── query-library.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── query-library-type.enum.ts │ │ │ │ │ │ └── query-library.ts │ │ │ │ │ ├── query-library.controller.spec.ts │ │ │ │ │ ├── query-library.controller.ts │ │ │ │ │ ├── query-library.module.ts │ │ │ │ │ ├── query-library.service.spec.ts │ │ │ │ │ ├── query-library.service.ts │ │ │ │ │ └── repositories/ │ │ │ │ │ ├── local-query-library.repository.spec.ts │ │ │ │ │ ├── local-query-library.repository.ts │ │ │ │ │ └── query-library.repository.ts │ │ │ │ ├── rdi/ │ │ │ │ │ ├── client/ │ │ │ │ │ │ ├── api/ │ │ │ │ │ │ │ ├── v1/ │ │ │ │ │ │ │ │ ├── api.rdi.client.spec.ts │ │ │ │ │ │ │ │ ├── api.rdi.client.ts │ │ │ │ │ │ │ │ ├── responses/ │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ ├── statistics.responses.ts │ │ │ │ │ │ │ │ │ └── status.responses.ts │ │ │ │ │ │ │ │ └── transformers/ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── statistics.transformers.spec.ts │ │ │ │ │ │ │ │ ├── statistics.transformers.ts │ │ │ │ │ │ │ │ ├── status.transformers.spec.ts │ │ │ │ │ │ │ │ └── status.transformers.ts │ │ │ │ │ │ │ └── v2/ │ │ │ │ │ │ │ ├── api.v2.rdi.client.spec.ts │ │ │ │ │ │ │ ├── api.v2.rdi.client.ts │ │ │ │ │ │ │ ├── responses/ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── info.responses.ts │ │ │ │ │ │ │ │ ├── metrics-collections.response.ts │ │ │ │ │ │ │ │ ├── pipeline.responses.ts │ │ │ │ │ │ │ │ └── status.responses.ts │ │ │ │ │ │ │ └── transformers/ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── metrics-collections.transformer.spec.ts │ │ │ │ │ │ │ └── metrics-collections.transformer.ts │ │ │ │ │ │ └── rdi.client.ts │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── decorators/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── request.rdi.client.metadata.decorator.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create.rdi.dto.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── rdi-template.response.dto.ts │ │ │ │ │ │ ├── rdi-test-connections.response.dto.ts │ │ │ │ │ │ ├── rdi.dry-run.job.dto.ts │ │ │ │ │ │ ├── rdi.dry-run.job.response.dto.ts │ │ │ │ │ │ └── update.rdi.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── rdi.entity.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── rdi-deploy-failed.exception.spec.ts │ │ │ │ │ │ ├── rdi-deploy-failed.exception.ts │ │ │ │ │ │ ├── rdi-pipeline.bad-request.exception.ts │ │ │ │ │ │ ├── rdi-pipeline.error.handler.spec.ts │ │ │ │ │ │ ├── rdi-pipeline.error.handler.ts │ │ │ │ │ │ ├── rdi-pipeline.forbidden.exception.spec.ts │ │ │ │ │ │ ├── rdi-pipeline.forbidden.exception.ts │ │ │ │ │ │ ├── rdi-pipeline.internal-server-error.exception.ts │ │ │ │ │ │ ├── rdi-pipeline.not-found.exception.ts │ │ │ │ │ │ ├── rdi-pipeline.timeout-error.exception.spec.ts │ │ │ │ │ │ ├── rdi-pipeline.timeout-error.exception.ts │ │ │ │ │ │ ├── rdi-pipeline.unauthorized.exception.ts │ │ │ │ │ │ ├── rdi-pipeline.validation.exception.ts │ │ │ │ │ │ ├── rdi-reset-pipeline-failed.exception.spec.ts │ │ │ │ │ │ ├── rdi-reset-pipeline-failed.exception.ts │ │ │ │ │ │ ├── rdi-start-pipeline-failed.exception.spec.ts │ │ │ │ │ │ ├── rdi-start-pipeline-failed.exception.ts │ │ │ │ │ │ ├── rdi-stop-pipeline-failed.exception.spec.ts │ │ │ │ │ │ └── rdi-stop-pipeline-failed.exception.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── rdi-dry-run.ts │ │ │ │ │ │ ├── rdi-info.ts │ │ │ │ │ │ ├── rdi-pipeline.ts │ │ │ │ │ │ ├── rdi-statistics.ts │ │ │ │ │ │ ├── rdi.client.metadata.ts │ │ │ │ │ │ ├── rdi.pipeline.status.ts │ │ │ │ │ │ └── rdi.ts │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── rdi.client.factory.spec.ts │ │ │ │ │ │ ├── rdi.client.factory.ts │ │ │ │ │ │ ├── rdi.client.provider.spec.ts │ │ │ │ │ │ ├── rdi.client.provider.ts │ │ │ │ │ │ ├── rdi.client.storage.spec.ts │ │ │ │ │ │ └── rdi.client.storage.ts │ │ │ │ │ ├── rdi-pipeline.analytics.spec.ts │ │ │ │ │ ├── rdi-pipeline.analytics.ts │ │ │ │ │ ├── rdi-pipeline.controller.ts │ │ │ │ │ ├── rdi-pipeline.service.spec.ts │ │ │ │ │ ├── rdi-pipeline.service.ts │ │ │ │ │ ├── rdi-statistics.controller.ts │ │ │ │ │ ├── rdi-statistics.service.spec.ts │ │ │ │ │ ├── rdi-statistics.service.ts │ │ │ │ │ ├── rdi.analytics.spec.ts │ │ │ │ │ ├── rdi.analytics.ts │ │ │ │ │ ├── rdi.controller.ts │ │ │ │ │ ├── rdi.module.ts │ │ │ │ │ ├── rdi.service.spec.ts │ │ │ │ │ ├── rdi.service.ts │ │ │ │ │ ├── repository/ │ │ │ │ │ │ ├── local.rdi.repository.spec.ts │ │ │ │ │ │ ├── local.rdi.repository.ts │ │ │ │ │ │ └── rdi.repository.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── pipeline.util.spec.ts │ │ │ │ │ ├── pipeline.util.ts │ │ │ │ │ ├── transformer.util.spec.ts │ │ │ │ │ └── transformer.util.ts │ │ │ │ ├── recommendation/ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── recommendation.provider.spec.ts │ │ │ │ │ │ └── recommendation.provider.ts │ │ │ │ │ ├── recommendation.module.ts │ │ │ │ │ └── recommendation.service.ts │ │ │ │ ├── redis/ │ │ │ │ │ ├── client/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── ioredis/ │ │ │ │ │ │ │ ├── cluster.ioredis.client.ts │ │ │ │ │ │ │ ├── ioredis.client.ts │ │ │ │ │ │ │ ├── sentinel.ioredis.client.ts │ │ │ │ │ │ │ └── standalone.ioredis.client.ts │ │ │ │ │ │ ├── node-redis/ │ │ │ │ │ │ │ ├── cluster.node-redis.client.ts │ │ │ │ │ │ │ ├── node-redis.client.ts │ │ │ │ │ │ │ └── standalone.node-redis.client.ts │ │ │ │ │ │ └── redis.client.ts │ │ │ │ │ ├── connection/ │ │ │ │ │ │ ├── ioredis.redis.connection.strategy.spec.ts │ │ │ │ │ │ ├── ioredis.redis.connection.strategy.ts │ │ │ │ │ │ ├── node.redis.connection.strategy.spec.ts │ │ │ │ │ │ ├── node.redis.connection.strategy.ts │ │ │ │ │ │ ├── redis.connection.strategy.spec.ts │ │ │ │ │ │ └── redis.connection.strategy.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── client-not-found-error.exception.ts │ │ │ │ │ │ └── connection/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── redis-connection-auth-unsupported.exception.ts │ │ │ │ │ │ ├── redis-connection-cluster-nodes-unavailable.exception.ts │ │ │ │ │ │ ├── redis-connection-default-user-disabled.exception.ts │ │ │ │ │ │ ├── redis-connection-failed.exception.ts │ │ │ │ │ │ ├── redis-connection-incorrect-certificate.exception.ts │ │ │ │ │ │ ├── redis-connection-sentinel-master-required.exception.ts │ │ │ │ │ │ ├── redis-connection-timeout.exception.ts │ │ │ │ │ │ ├── redis-connection-unauthorized.exception.ts │ │ │ │ │ │ └── redis-connection-unavailable.exception.ts │ │ │ │ │ ├── local.redis.client.factory.spec.ts │ │ │ │ │ ├── local.redis.client.factory.ts │ │ │ │ │ ├── redis.client.factory.ts │ │ │ │ │ ├── redis.client.storage.spec.ts │ │ │ │ │ ├── redis.client.storage.ts │ │ │ │ │ ├── redis.module.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── cluster.util.spec.ts │ │ │ │ │ ├── cluster.util.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── keys.util.spec.ts │ │ │ │ │ ├── keys.util.ts │ │ │ │ │ ├── reply.util.spec.ts │ │ │ │ │ ├── reply.util.ts │ │ │ │ │ ├── sentinel.util.spec.ts │ │ │ │ │ └── sentinel.util.ts │ │ │ │ ├── redis-enterprise/ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── cluster.dto.ts │ │ │ │ │ │ └── redis-enterprise-cluster.dto.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ └── redis-enterprise-database.ts │ │ │ │ │ ├── redis-enterprise.analytics.spec.ts │ │ │ │ │ ├── redis-enterprise.analytics.ts │ │ │ │ │ ├── redis-enterprise.controller.spec.ts │ │ │ │ │ ├── redis-enterprise.controller.ts │ │ │ │ │ ├── redis-enterprise.module.ts │ │ │ │ │ ├── redis-enterprise.service.spec.ts │ │ │ │ │ ├── redis-enterprise.service.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── redis-enterprise-converter.spec.ts │ │ │ │ │ └── redis-enterprise-converter.ts │ │ │ │ ├── redis-sentinel/ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create.sentinel.database.dto.ts │ │ │ │ │ │ ├── create.sentinel.database.response.ts │ │ │ │ │ │ ├── create.sentinel.databases.dto.ts │ │ │ │ │ │ ├── discover.sentinel-masters.dto.ts │ │ │ │ │ │ ├── sentinel.master.response.dto.ts │ │ │ │ │ │ └── update.sentinel.master.dto.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── sentinel-master.ts │ │ │ │ │ │ └── sentinel.ts │ │ │ │ │ ├── redis-sentinel.analytics.spec.ts │ │ │ │ │ ├── redis-sentinel.analytics.ts │ │ │ │ │ ├── redis-sentinel.controller.spec.ts │ │ │ │ │ ├── redis-sentinel.controller.ts │ │ │ │ │ ├── redis-sentinel.module.ts │ │ │ │ │ ├── redis-sentinel.service.spec.ts │ │ │ │ │ └── redis-sentinel.service.ts │ │ │ │ ├── server/ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ └── server.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── server.entity.ts │ │ │ │ │ ├── health.controller.ts │ │ │ │ │ ├── local.server.service.spec.ts │ │ │ │ │ ├── local.server.service.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ └── server.ts │ │ │ │ │ ├── repositories/ │ │ │ │ │ │ ├── local.server.repository.spec.ts │ │ │ │ │ │ ├── local.server.repository.ts │ │ │ │ │ │ └── server.repository.ts │ │ │ │ │ ├── server.controller.ts │ │ │ │ │ ├── server.module.ts │ │ │ │ │ └── server.service.ts │ │ │ │ ├── session/ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── session.provider.ts │ │ │ │ │ │ ├── single-user.session.provider.spec.ts │ │ │ │ │ │ ├── single-user.session.provider.ts │ │ │ │ │ │ └── storage/ │ │ │ │ │ │ ├── in-memory.session.storage.spec.ts │ │ │ │ │ │ ├── in-memory.session.storage.ts │ │ │ │ │ │ └── session.storage.ts │ │ │ │ │ ├── session.module.ts │ │ │ │ │ ├── session.service.spec.ts │ │ │ │ │ └── session.service.ts │ │ │ │ ├── settings/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── settings.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ └── settings.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ ├── agreements.entity.ts │ │ │ │ │ │ └── settings.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── agreements.interface.ts │ │ │ │ │ │ ├── agreements.ts │ │ │ │ │ │ └── settings.ts │ │ │ │ │ ├── repositories/ │ │ │ │ │ │ ├── agreements.repository.ts │ │ │ │ │ │ ├── local.agreements.repository.spec.ts │ │ │ │ │ │ ├── local.agreements.repository.ts │ │ │ │ │ │ ├── local.settings.repository.spec.ts │ │ │ │ │ │ ├── local.settings.repository.ts │ │ │ │ │ │ └── settings.repository.ts │ │ │ │ │ ├── settings.analytics.spec.ts │ │ │ │ │ ├── settings.analytics.ts │ │ │ │ │ ├── settings.controller.ts │ │ │ │ │ ├── settings.module.ts │ │ │ │ │ ├── settings.service.spec.ts │ │ │ │ │ └── settings.service.ts │ │ │ │ ├── slow-log/ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ └── commands.ts │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── get-slow-logs.dto.ts │ │ │ │ │ │ └── update-slow-log-config.dto.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── slow-log-config.ts │ │ │ │ │ │ └── slow-log.ts │ │ │ │ │ ├── slow-log.analytics.ts │ │ │ │ │ ├── slow-log.controller.ts │ │ │ │ │ ├── slow-log.module.ts │ │ │ │ │ ├── slow-log.service.spec.ts │ │ │ │ │ └── slow-log.service.ts │ │ │ │ ├── ssh/ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create.basic-ssh-options.dto.ts │ │ │ │ │ │ ├── create.cert-ssh-options.dto.ts │ │ │ │ │ │ ├── ssh-options.response.ts │ │ │ │ │ │ └── update.ssh-options.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── ssh-options.entity.ts │ │ │ │ │ ├── exceptions/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── tunnel-connection-lost.exception.ts │ │ │ │ │ │ ├── unable-to-create-local-server.exception.ts │ │ │ │ │ │ ├── unable-to-create-ssh-connection.exception.ts │ │ │ │ │ │ └── unable-to-create-tunnel.exception.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ ├── ssh-options.ts │ │ │ │ │ │ └── ssh-tunnel.ts │ │ │ │ │ ├── ssh-tunnel.provider.spec.ts │ │ │ │ │ ├── ssh-tunnel.provider.ts │ │ │ │ │ ├── ssh.module.ts │ │ │ │ │ ├── transformers/ │ │ │ │ │ │ ├── ssh-options.transformer.spec.ts │ │ │ │ │ │ └── ssh-options.transformer.ts │ │ │ │ │ └── utils/ │ │ │ │ │ ├── error-message.spec.ts │ │ │ │ │ ├── error-message.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── statics-management/ │ │ │ │ │ ├── providers/ │ │ │ │ │ │ ├── auto-updated-statics.interface.ts │ │ │ │ │ │ ├── auto-updated-statics.provider.spec.ts │ │ │ │ │ │ └── auto-updated-statics.provider.ts │ │ │ │ │ └── statics-management.module.ts │ │ │ │ ├── tag/ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ ├── create-tag.dto.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── update-tag.dto.ts │ │ │ │ │ ├── entities/ │ │ │ │ │ │ └── tag.entity.ts │ │ │ │ │ ├── models/ │ │ │ │ │ │ └── tag.ts │ │ │ │ │ ├── repository/ │ │ │ │ │ │ ├── local.tag.repository.spec.ts │ │ │ │ │ │ ├── local.tag.repository.ts │ │ │ │ │ │ └── tag.repository.ts │ │ │ │ │ ├── tag.controller.ts │ │ │ │ │ ├── tag.module.ts │ │ │ │ │ ├── tag.service.spec.ts │ │ │ │ │ └── tag.service.ts │ │ │ │ └── workbench/ │ │ │ │ ├── decorators/ │ │ │ │ │ └── workbench-client-metadata.decorator.ts │ │ │ │ ├── dto/ │ │ │ │ │ ├── create-command-execution.dto.ts │ │ │ │ │ ├── create-command-executions.dto.ts │ │ │ │ │ └── create-plugin-state.dto.ts │ │ │ │ ├── entities/ │ │ │ │ │ ├── command-execution.entity.ts │ │ │ │ │ └── plugin-state.entity.ts │ │ │ │ ├── models/ │ │ │ │ │ ├── command-execution-result.ts │ │ │ │ │ ├── command-execution.ts │ │ │ │ │ ├── command-executions.filter.ts │ │ │ │ │ ├── plugin-command-execution.ts │ │ │ │ │ ├── plugin-state.ts │ │ │ │ │ └── short-command-execution.ts │ │ │ │ ├── plugins.controller.ts │ │ │ │ ├── plugins.service.spec.ts │ │ │ │ ├── plugins.service.ts │ │ │ │ ├── providers/ │ │ │ │ │ ├── plugin-commands-whitelist.provider.spec.ts │ │ │ │ │ ├── plugin-commands-whitelist.provider.ts │ │ │ │ │ ├── workbench-commands.executor.spec.ts │ │ │ │ │ └── workbench-commands.executor.ts │ │ │ │ ├── repositories/ │ │ │ │ │ ├── command-execution.repository.ts │ │ │ │ │ ├── local-command-execution.repository.spec.ts │ │ │ │ │ ├── local-command-execution.repository.ts │ │ │ │ │ ├── local-plugin-state.repository.spec.ts │ │ │ │ │ ├── local-plugin-state.repository.ts │ │ │ │ │ └── plugin-state.repository.ts │ │ │ │ ├── utils/ │ │ │ │ │ ├── getUnsupportedCommands.spec.ts │ │ │ │ │ └── getUnsupportedCommands.ts │ │ │ │ ├── workbench.analytics.spec.ts │ │ │ │ ├── workbench.analytics.ts │ │ │ │ ├── workbench.controller.ts │ │ │ │ ├── workbench.module.ts │ │ │ │ ├── workbench.service.spec.ts │ │ │ │ └── workbench.service.ts │ │ │ ├── utils/ │ │ │ │ ├── analytics-helper.spec.ts │ │ │ │ ├── analytics-helper.ts │ │ │ │ ├── base.helper.spec.ts │ │ │ │ ├── base.helper.ts │ │ │ │ ├── big-string.spec.ts │ │ │ │ ├── big-string.ts │ │ │ │ ├── catch-redis-errors.spec.ts │ │ │ │ ├── catch-redis-errors.ts │ │ │ │ ├── class-transformer.ts │ │ │ │ ├── cli-helper.spec.ts │ │ │ │ ├── cli-helper.ts │ │ │ │ ├── config.spec.ts │ │ │ │ ├── config.ts │ │ │ │ ├── converter.spec.ts │ │ │ │ ├── converter.ts │ │ │ │ ├── createHttpOptions.ts │ │ │ │ ├── feature-version-filter.helper.spec.ts │ │ │ │ ├── feature-version-filter.helper.ts │ │ │ │ ├── file-helper.ts │ │ │ │ ├── glob-pattern-helper.spec.ts │ │ │ │ ├── glob-pattern-helper.ts │ │ │ │ ├── hosting-provider-helper.spec.ts │ │ │ │ ├── hosting-provider-helper.ts │ │ │ │ ├── index.ts │ │ │ │ ├── logsFormatter.spec.ts │ │ │ │ ├── logsFormatter.ts │ │ │ │ ├── path.spec.ts │ │ │ │ ├── path.ts │ │ │ │ ├── promise-with-timeout.spec.ts │ │ │ │ ├── promise-with-timeout.ts │ │ │ │ ├── recommendation-helper.spec.ts │ │ │ │ ├── recommendation-helper.ts │ │ │ │ ├── redis-modules-summary.spec.ts │ │ │ │ ├── redis-modules-summary.ts │ │ │ │ ├── redis-reply-converter.spec.ts │ │ │ │ └── redis-reply-converter.ts │ │ │ └── validators/ │ │ │ ├── index.ts │ │ │ ├── isObjectWithValues.validator.ts │ │ │ ├── serializedJson.validator.spec.ts │ │ │ └── serializedJson.validator.ts │ │ ├── stubs/ │ │ │ └── cpu-features/ │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── test/ │ │ │ ├── README.md │ │ │ ├── api/ │ │ │ │ ├── .mocharc.yml │ │ │ │ ├── _init/ │ │ │ │ │ └── WS-notifications-global-sync.test.ts │ │ │ │ ├── ai/ │ │ │ │ │ └── assistant/ │ │ │ │ │ ├── DELETE-ai-assistant-chats-id.test.ts │ │ │ │ │ ├── GET-ai-assistant-chats-id.test.ts │ │ │ │ │ ├── POST-ai-assistant-chats-id-messages.test.ts │ │ │ │ │ └── POST-ai-assistant-chats.test.ts │ │ │ │ ├── analytics/ │ │ │ │ │ ├── POST-analytics-send-event.test.ts │ │ │ │ │ ├── POST-analytics-send-page.test.ts │ │ │ │ │ └── analytics.test.ts │ │ │ │ ├── api.deps.init.ts │ │ │ │ ├── api.tsconfig.json │ │ │ │ ├── browser-history/ │ │ │ │ │ ├── DELETE-browser-histories.test.ts │ │ │ │ │ ├── DELETE-browser-history-id.test.ts │ │ │ │ │ └── GET-browser-histories.test.ts │ │ │ │ ├── bulk-actions/ │ │ │ │ │ ├── POST-databases-id-bulk_actions-import-default_data.test.ts │ │ │ │ │ ├── POST-databases-id-bulk_actions-import-tutorial_data.test.ts │ │ │ │ │ └── POST-databases-id-bulk_actions-import.test.ts │ │ │ │ ├── certificate/ │ │ │ │ │ └── constants.ts │ │ │ │ ├── cli/ │ │ │ │ │ ├── POST-databases-id-cli-uuid-send_cluster_command.test.ts │ │ │ │ │ ├── POST-databases-id-cli-uuid-send_command.test.ts │ │ │ │ │ └── POST-databases-id-cli.test.ts │ │ │ │ ├── cloud/ │ │ │ │ │ ├── autodiscovery/ │ │ │ │ │ │ ├── GET-cloud-autodiscovery-account.test.ts │ │ │ │ │ │ ├── GET-cloud-autodiscovery-subscriptions.test.ts │ │ │ │ │ │ ├── GET-cloud-me-autodiscovery-account.test.ts │ │ │ │ │ │ ├── POST-cloud-autodiscovery-databases.test.ts │ │ │ │ │ │ └── POST-cloud-autodiscovery-get_databases.test.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ └── user/ │ │ │ │ │ ├── GET-cloud-me.test.ts │ │ │ │ │ └── PUT-cloud-me-accounts-id-current.test.ts │ │ │ │ ├── cluster-monitor/ │ │ │ │ │ └── GET-databases-id-cluster_details.test.ts │ │ │ │ ├── commands/ │ │ │ │ │ └── GET-commands.test.ts │ │ │ │ ├── custom-tutorials/ │ │ │ │ │ └── POST-custom-tutorials.test.ts │ │ │ │ ├── database/ │ │ │ │ │ ├── DELETE-databases-id.test.ts │ │ │ │ │ ├── DELETE-databases.test.ts │ │ │ │ │ ├── GET-databases-id-connect.test.ts │ │ │ │ │ ├── GET-databases-id-info.test.ts │ │ │ │ │ ├── GET-databases-id-overview.test.ts │ │ │ │ │ ├── GET-databases.test.ts │ │ │ │ │ ├── PATCH-databases-id.test.ts │ │ │ │ │ ├── POST-databases-clone-id.test.ts │ │ │ │ │ ├── POST-databases-export.test.ts │ │ │ │ │ ├── POST-databases-test-id.test.ts │ │ │ │ │ ├── POST-databases-test.test.ts │ │ │ │ │ ├── POST-databases.test.ts │ │ │ │ │ └── constants.ts │ │ │ │ ├── database-analysis/ │ │ │ │ │ ├── GET-databases-id-analysis-id.test.ts │ │ │ │ │ ├── GET-databases-id-analysis.test.ts │ │ │ │ │ ├── PATCH-databases-id-analysis.test.ts │ │ │ │ │ ├── POST-databases-id-analysis.test.ts │ │ │ │ │ └── constants.ts │ │ │ │ ├── database-discovery/ │ │ │ │ │ └── pre-setup-databases.tests.ts │ │ │ │ ├── database-import/ │ │ │ │ │ └── POST-databases-import.test.ts │ │ │ │ ├── database-recommendations/ │ │ │ │ │ ├── DELETE-databases-id-recommendations.test.ts │ │ │ │ │ ├── GET-databases-id-recommendations.test.ts │ │ │ │ │ ├── PATCH-databases-id-recommendations-id.test.ts │ │ │ │ │ ├── PATCH-databases-id-recommendations-read.test.ts │ │ │ │ │ ├── WS-new-recommendations.test.ts │ │ │ │ │ └── constants.ts │ │ │ │ ├── deps.ts │ │ │ │ ├── enterprise/ │ │ │ │ │ └── POST-redis-enterprise-cluster-get_dbs.test.ts │ │ │ │ ├── feature/ │ │ │ │ │ ├── GET-features.test.ts │ │ │ │ │ └── POST-features-sync.test.ts │ │ │ │ ├── hash/ │ │ │ │ │ ├── DELETE-databases-id-hash-fields.test.ts │ │ │ │ │ ├── POST-databases-id-hash-get_fields.test.ts │ │ │ │ │ ├── POST-databases-id-hash.test.ts │ │ │ │ │ └── PUT-databases-id-hash.test.ts │ │ │ │ ├── info/ │ │ │ │ │ ├── GET-health.test.ts │ │ │ │ │ ├── GET-info-cli-blocking-commands.test.ts │ │ │ │ │ ├── GET-info-cli-unsupported-commands.test.ts │ │ │ │ │ └── GET-info.test.ts │ │ │ │ ├── keys/ │ │ │ │ │ ├── DELETE-databases-id-keys.test.ts │ │ │ │ │ ├── PATCH-databases-id-keys-name.test.ts │ │ │ │ │ ├── PATCH-databases-id-keys-ttl.test.ts │ │ │ │ │ ├── POST-databases-id-keys-get_info.test.ts │ │ │ │ │ ├── POST-databases-id-keys-get_infos.test.ts │ │ │ │ │ └── POST-databases-id-keys.test.ts │ │ │ │ ├── list/ │ │ │ │ │ ├── DELETE-databases-id-list-elements.test.ts │ │ │ │ │ ├── PATCH-databases-id-list.test.ts │ │ │ │ │ ├── POST-databases-id-list-get_elements-index.test.ts │ │ │ │ │ ├── POST-databases-id-list-get_elements.test.ts │ │ │ │ │ ├── POST-databases-id-list.test.ts │ │ │ │ │ └── PUT-databases-id-list.test.ts │ │ │ │ ├── notifications/ │ │ │ │ │ ├── GET-notifications.test.ts │ │ │ │ │ ├── PATCH-notifications.test.ts │ │ │ │ │ └── notifications.json │ │ │ │ ├── plugins/ │ │ │ │ │ ├── GET-databases-id-plugins-commands.test.ts │ │ │ │ │ ├── GET-databases-id-plugins-id-command_executions-id-state.test.ts │ │ │ │ │ ├── GET-plugins.test.ts │ │ │ │ │ ├── POST-databases-id-plugins-command_executions.test.ts │ │ │ │ │ └── POST-databases-id-plugins-id-command_executions-id-state.test.ts │ │ │ │ ├── pub-sub/ │ │ │ │ │ └── POST-databases-id-pub-sub-messages.test.ts │ │ │ │ ├── query-library/ │ │ │ │ │ ├── DELETE-databases-id-query_library-id.test.ts │ │ │ │ │ ├── GET-databases-id-query_library-id.test.ts │ │ │ │ │ ├── GET-databases-id-query_library.test.ts │ │ │ │ │ ├── PATCH-databases-id-query_library-id.test.ts │ │ │ │ │ ├── POST-databases-id-query_library-seed.test.ts │ │ │ │ │ └── POST-databases-id-query_library.test.ts │ │ │ │ ├── rdi/ │ │ │ │ │ ├── DELETE-rdi.test.ts │ │ │ │ │ ├── GET-rdi-id-connect.test.ts │ │ │ │ │ ├── GET-rdi-id.test.ts │ │ │ │ │ ├── GET-rdi.test.ts │ │ │ │ │ ├── PATCH-rdi-id.test.ts │ │ │ │ │ ├── POST-rdi.test.ts │ │ │ │ │ ├── pipeline/ │ │ │ │ │ │ ├── GET-rdi-id-pipeline-config-template-pipelineType-dbType.test.ts │ │ │ │ │ │ ├── GET-rdi-id-pipeline-job-functions.test.ts │ │ │ │ │ │ ├── GET-rdi-id-pipeline-job-template-pipelineType.test.ts │ │ │ │ │ │ ├── GET-rdi-id-pipeline-schema.test.ts │ │ │ │ │ │ ├── GET-rdi-id-pipeline-status.test.ts │ │ │ │ │ │ ├── GET-rdi-id-pipeline-strategies.test.ts │ │ │ │ │ │ ├── GET-rdi-id-pipeline.test.ts │ │ │ │ │ │ ├── POST-rdi-id-pipeline-deploy.test.ts │ │ │ │ │ │ ├── POST-rdi-id-pipeline-dry-run-job.test.ts │ │ │ │ │ │ ├── POST-rdi-id-pipeline-reset.test.ts │ │ │ │ │ │ ├── POST-rdi-id-pipeline-start.test.ts │ │ │ │ │ │ ├── POST-rdi-id-pipeline-stop.test.ts │ │ │ │ │ │ └── POST-rdi-id-pipeline-test-connections.test.ts │ │ │ │ │ └── statistics/ │ │ │ │ │ └── GET-rdi-id-statistics.test.ts │ │ │ │ ├── redisearch/ │ │ │ │ │ ├── DELETE-databases-id-redisearch.test.ts │ │ │ │ │ ├── GET-databases-id-redisearch.test.ts │ │ │ │ │ ├── POST-databases-id-redisearch-info.test.ts │ │ │ │ │ ├── POST-databases-id-redisearch-key-indexes.test.ts │ │ │ │ │ ├── POST-databases-id-redisearch-search.test.ts │ │ │ │ │ └── POST-databases-id-redisearch.test.ts │ │ │ │ ├── rejson-rl/ │ │ │ │ │ ├── DELETE-databases-id-rejson_rl.test.ts │ │ │ │ │ ├── PATCH-databases-id-rejson_rl-arrappend.test.ts │ │ │ │ │ ├── PATCH-databases-id-rejson_rl-set.test.ts │ │ │ │ │ ├── POST-databases-id-rejson_rl-get.test.ts │ │ │ │ │ └── POST-databases-id-rejson_rl.test.ts │ │ │ │ ├── reporters.json │ │ │ │ ├── sentinel/ │ │ │ │ │ ├── POST-redis_sentinel-databases.test.ts │ │ │ │ │ └── POST-redis_sentinel-get_databases.test.ts │ │ │ │ ├── set/ │ │ │ │ │ ├── DELETE-databases-id-set-members.test.ts │ │ │ │ │ ├── POST-databases-id-set-get_members.test.ts │ │ │ │ │ ├── POST-databases-id-set.test.ts │ │ │ │ │ └── PUT-databases-id-set.test.ts │ │ │ │ ├── settings/ │ │ │ │ │ ├── GET-settings-agreements-spec.test.ts │ │ │ │ │ ├── GET-settings.test.ts │ │ │ │ │ └── PATCH-settings.test.ts │ │ │ │ ├── slowlog/ │ │ │ │ │ ├── DELETE-databases-id-slow_logs.test.ts │ │ │ │ │ ├── GET-databases-id-slow_logs-config.test.ts │ │ │ │ │ ├── GET-databases-id-slow_logs.test.ts │ │ │ │ │ └── PATCH-databases-id-slow_logs-config.test.ts │ │ │ │ ├── stream/ │ │ │ │ │ ├── DELETE-databases-id-streams-consumer_groups-consumers.test.ts │ │ │ │ │ ├── DELETE-databases-id-streams-consumer_groups.test.ts │ │ │ │ │ ├── PATCH-databases-id-streams-consumer_groups.test.ts │ │ │ │ │ ├── POST-databases-id-streams-consumer_groups-consumers-get.test.ts │ │ │ │ │ ├── POST-databases-id-streams-consumer_groups-consumers-pending_messages-ack.test.ts │ │ │ │ │ ├── POST-databases-id-streams-consumer_groups-consumers-pending_messages-claim.test.ts │ │ │ │ │ ├── POST-databases-id-streams-consumer_groups-consumers-pending_messages-get.test.ts │ │ │ │ │ ├── POST-databases-id-streams-consumer_groups-get.test.ts │ │ │ │ │ ├── POST-databases-id-streams-consumer_groups.test.ts │ │ │ │ │ ├── POST-databases-id-streams-entries-get.test.ts │ │ │ │ │ ├── POST-databases-id-streams-entries.test.ts │ │ │ │ │ └── POST-databases-id-streams.test.ts │ │ │ │ ├── string/ │ │ │ │ │ ├── POST-databases-id-string-download_value.test.ts │ │ │ │ │ ├── POST-databases-id-string-get_value.test.ts │ │ │ │ │ ├── POST-databases-id-string.test.ts │ │ │ │ │ └── PUT-databases-id-string.test.ts │ │ │ │ ├── triggered-functions/ │ │ │ │ │ ├── DELETE-databases-id-library.test.ts │ │ │ │ │ ├── GET-databases-id-functions.test.ts │ │ │ │ │ ├── GET-databases-id-libraries.test.ts │ │ │ │ │ └── POST-databases-id-library.test.ts │ │ │ │ ├── workbench/ │ │ │ │ │ ├── DELETE-databases-id-workbench-command_executions-id.test.ts │ │ │ │ │ ├── DELETE-databases-id-workbench-command_executions.test.ts │ │ │ │ │ ├── GET-databases-id-workbench-command_executions-id.test.ts │ │ │ │ │ ├── GET-databases-id-workbench-command_executions.test.ts │ │ │ │ │ └── POST-databases-id-workbench-command_executions.test.ts │ │ │ │ ├── ws/ │ │ │ │ │ ├── bulk-actions/ │ │ │ │ │ │ └── bulk-actions-create.test.ts │ │ │ │ │ ├── monitor/ │ │ │ │ │ │ └── monitor.test.ts │ │ │ │ │ └── pub-sub/ │ │ │ │ │ └── pub-sub.test.ts │ │ │ │ └── z-set/ │ │ │ │ ├── DELETE-databases-id-zSet-members.test.ts │ │ │ │ ├── PATCH-databases-id-zSet.test.ts │ │ │ │ ├── POST-databases-id-zSet-get_members.test.ts │ │ │ │ ├── POST-databases-id-zSet-search.test.ts │ │ │ │ ├── POST-databases-id-zSet.test.ts │ │ │ │ └── PUT-databases-id-zSet.test.ts │ │ │ ├── helpers/ │ │ │ │ ├── analytics.ts │ │ │ │ ├── cloud.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── data/ │ │ │ │ │ └── redis.ts │ │ │ │ ├── local-db.ts │ │ │ │ ├── redis.ts │ │ │ │ ├── remote-server.ts │ │ │ │ ├── server.ts │ │ │ │ ├── test/ │ │ │ │ │ ├── conditionalIgnore.ts │ │ │ │ │ └── dataGenerator.ts │ │ │ │ ├── test.ts │ │ │ │ └── utils.ts │ │ │ └── test-runs/ │ │ │ ├── cloud-st/ │ │ │ │ └── docker-compose.yml │ │ │ ├── docker.build.env │ │ │ ├── docker.build.yml │ │ │ ├── gears-clu/ │ │ │ │ └── docker-compose.yml │ │ │ ├── local.build.env │ │ │ ├── local.build.yml │ │ │ ├── mods-preview/ │ │ │ │ └── docker-compose.yml │ │ │ ├── oss-clu/ │ │ │ │ ├── Dockerfile │ │ │ │ └── docker-compose.yml │ │ │ ├── oss-clu-tls/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── certs/ │ │ │ │ │ ├── redis.crt │ │ │ │ │ ├── redis.key │ │ │ │ │ └── redisCA.crt │ │ │ │ └── docker-compose.yml │ │ │ ├── oss-sent/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── docker-compose.yml │ │ │ │ ├── redis.conf │ │ │ │ ├── sentinel.Dockerfile │ │ │ │ ├── sentinel.conf │ │ │ │ ├── sentinel.users.acl │ │ │ │ └── users.acl │ │ │ ├── oss-sent-tls-auth/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── certs/ │ │ │ │ │ ├── ca.crt │ │ │ │ │ ├── redis.crt │ │ │ │ │ └── redis.key │ │ │ │ ├── docker-compose.yml │ │ │ │ ├── redis.conf │ │ │ │ ├── sentinel.Dockerfile │ │ │ │ ├── sentinel.conf │ │ │ │ └── users.acl │ │ │ ├── oss-st-5/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── docker-compose.yml │ │ │ │ └── redis.conf │ │ │ ├── oss-st-5-pass/ │ │ │ │ └── docker-compose.yml │ │ │ ├── oss-st-6/ │ │ │ │ └── docker-compose.yml │ │ │ ├── oss-st-6-tls/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── certs/ │ │ │ │ │ ├── redis.crt │ │ │ │ │ ├── redis.key │ │ │ │ │ └── redisCA.crt │ │ │ │ └── docker-compose.yml │ │ │ ├── oss-st-6-tls-auth/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── certs/ │ │ │ │ │ ├── redis.crt │ │ │ │ │ ├── redis.key │ │ │ │ │ ├── redisCA.crt │ │ │ │ │ ├── user.crt │ │ │ │ │ └── user.key │ │ │ │ └── docker-compose.yml │ │ │ ├── oss-st-6-tls-auth-ssh/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── certs/ │ │ │ │ │ ├── redis.crt │ │ │ │ │ ├── redis.key │ │ │ │ │ ├── redisCA.crt │ │ │ │ │ ├── user.crt │ │ │ │ │ └── user.key │ │ │ │ ├── docker-compose.yml │ │ │ │ └── ssh/ │ │ │ │ └── keys/ │ │ │ │ ├── pub/ │ │ │ │ │ ├── test.pub │ │ │ │ │ └── testp.pub │ │ │ │ ├── test │ │ │ │ └── testp │ │ │ ├── oss-st-big/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── docker-compose.yml │ │ │ │ └── entrypoint.sh │ │ │ ├── re-clu/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── db.json │ │ │ │ ├── docker-compose.yml │ │ │ │ └── entrypoint.sh │ │ │ ├── re-crdt/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── docker-compose.yml │ │ │ │ └── entrypoint.sh │ │ │ ├── re-st/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── db.json │ │ │ │ ├── docker-compose.yml │ │ │ │ └── entrypoint.sh │ │ │ ├── run-all.sh │ │ │ ├── start-test-run.sh │ │ │ ├── test-docker-entry.sh │ │ │ ├── test.Dockerfile │ │ │ └── wait-for-it.sh │ │ ├── tsconfig.build.json │ │ ├── tsconfig.build.prod.json │ │ └── tsconfig.json │ ├── desktop/ │ │ ├── app.ts │ │ ├── config.json │ │ ├── index.ts │ │ ├── package.json │ │ ├── preload.ts │ │ ├── splash.html │ │ ├── src/ │ │ │ ├── config/ │ │ │ │ ├── configMain.ts │ │ │ │ ├── configRenderer.ts │ │ │ │ └── index.ts │ │ │ ├── index.html │ │ │ ├── lib/ │ │ │ │ ├── aboutPanel/ │ │ │ │ │ └── aboutPanel.ts │ │ │ │ ├── app/ │ │ │ │ │ ├── app.handlers.ts │ │ │ │ │ ├── deep-link.handlers.ts │ │ │ │ │ ├── dialog.handlers.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── ipc.handlers.ts │ │ │ │ ├── auth/ │ │ │ │ │ ├── auth.factory.ts │ │ │ │ │ ├── auth.interface.ts │ │ │ │ │ ├── service.auth.strategy.ts │ │ │ │ │ └── tcp.auth.strategy.ts │ │ │ │ ├── azure/ │ │ │ │ │ ├── azure-auth.service.provider.ts │ │ │ │ │ ├── azure-oauth-errors.spec.ts │ │ │ │ │ ├── azure-oauth-errors.ts │ │ │ │ │ ├── deep-link.handlers.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── cloud/ │ │ │ │ │ ├── cloud-oauth.handlers.ts │ │ │ │ │ ├── deep-link.handlers.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── extensions/ │ │ │ │ │ └── extensions.ts │ │ │ │ ├── index.ts │ │ │ │ ├── logging/ │ │ │ │ │ └── logging.ts │ │ │ │ ├── menu/ │ │ │ │ │ └── menu.ts │ │ │ │ ├── server/ │ │ │ │ │ └── server.ts │ │ │ │ ├── store/ │ │ │ │ │ └── store.ts │ │ │ │ ├── tray/ │ │ │ │ │ ├── tray.ts │ │ │ │ │ └── trayManager.ts │ │ │ │ ├── updater/ │ │ │ │ │ ├── updater.handlers.ts │ │ │ │ │ └── updater.ts │ │ │ │ └── window/ │ │ │ │ ├── browserWindow.ts │ │ │ │ ├── index.ts │ │ │ │ └── window.handlers.ts │ │ │ └── utils/ │ │ │ ├── getAssetPath.ts │ │ │ ├── index.ts │ │ │ ├── resolveHtmlPath.ts │ │ │ ├── showOrCreateWindow.ts │ │ │ ├── window-size.ts │ │ │ └── wrapErrorSensitiveData.ts │ │ ├── views/ │ │ │ └── cloud_outh_callback/ │ │ │ ├── callback.html │ │ │ ├── index.js │ │ │ └── styles.css │ │ ├── vite.main.config.ts │ │ ├── vite.preload.config.ts │ │ └── vite.renderer.config.ts │ ├── package.json │ ├── patches/ │ │ └── sqlite3+5.1.7.patch │ └── ui/ │ ├── .eslintignore │ ├── README.md │ ├── index.html │ ├── index.tsx │ ├── indexElectron.tsx │ ├── package.json │ ├── src/ │ │ ├── App.scss │ │ ├── App.spec.tsx │ │ ├── App.tsx │ │ ├── Router.spec.tsx │ │ ├── Router.tsx │ │ ├── RouterElectron.tsx │ │ ├── assets/ │ │ │ └── assets.d.ts │ │ ├── components/ │ │ │ ├── ContentEditable.tsx │ │ │ ├── MonacoEnvironmentInitializer/ │ │ │ │ ├── MonacoEnvironmentInitializer.spec.tsx │ │ │ │ ├── MonacoEnvironmentInitializer.tsx │ │ │ │ └── yaml.worker.js │ │ │ ├── analytics-tabs/ │ │ │ │ ├── AnalyticsTabs.spec.tsx │ │ │ │ ├── AnalyticsTabs.stories.tsx │ │ │ │ ├── AnalyticsTabs.tsx │ │ │ │ └── index.ts │ │ │ ├── auto-discover/ │ │ │ │ ├── EmptyState.tsx │ │ │ │ ├── EmptyState.types.ts │ │ │ │ ├── Header.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.ts │ │ │ ├── auto-refresh/ │ │ │ │ ├── AutoRefresh.spec.tsx │ │ │ │ ├── AutoRefresh.stories.tsx │ │ │ │ ├── AutoRefresh.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── styles.module.scss │ │ │ │ └── utils.ts │ │ │ ├── base/ │ │ │ │ ├── code-editor/ │ │ │ │ │ ├── CodeEditor.styles.ts │ │ │ │ │ ├── CodeEditor.tsx │ │ │ │ │ ├── CodeEditor.types.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── display/ │ │ │ │ │ ├── accordion/ │ │ │ │ │ │ ├── RiAccordion.spec.tsx │ │ │ │ │ │ ├── RiAccordion.tsx │ │ │ │ │ │ └── RiAccordion.types.ts │ │ │ │ │ ├── badge/ │ │ │ │ │ │ └── RiBadge.tsx │ │ │ │ │ ├── banner/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── call-out/ │ │ │ │ │ │ └── CallOut.tsx │ │ │ │ │ ├── collapsible-nav-group/ │ │ │ │ │ │ └── RICollapsibleNavGroup.tsx │ │ │ │ │ ├── image/ │ │ │ │ │ │ ├── RiImage.tsx │ │ │ │ │ │ └── image.styles.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── loader/ │ │ │ │ │ │ └── Loader.tsx │ │ │ │ │ ├── loading-logo/ │ │ │ │ │ │ └── RiLoadingLogo.tsx │ │ │ │ │ ├── modal/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── progress-bar/ │ │ │ │ │ │ ├── ProgressBarLoader.tsx │ │ │ │ │ │ └── progress-bar-loader.styles.ts │ │ │ │ │ ├── section/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── toast/ │ │ │ │ │ │ ├── RiToast.tsx │ │ │ │ │ │ ├── RiToaster.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── tour/ │ │ │ │ │ ├── TourStep.tsx │ │ │ │ │ └── types.ts │ │ │ │ ├── forms/ │ │ │ │ │ ├── FormField.tsx │ │ │ │ │ ├── button-group/ │ │ │ │ │ │ └── ButtonGroup.tsx │ │ │ │ │ ├── buttons/ │ │ │ │ │ │ ├── ActionIconButton.stories.tsx │ │ │ │ │ │ ├── ActionIconButton.tsx │ │ │ │ │ │ ├── Button.stories.tsx │ │ │ │ │ │ ├── Button.tsx │ │ │ │ │ │ ├── DestructiveButton.stories.tsx │ │ │ │ │ │ ├── DestructiveButton.tsx │ │ │ │ │ │ ├── EmptyButton.stories.tsx │ │ │ │ │ │ ├── EmptyButton.tsx │ │ │ │ │ │ ├── EmptyButton.types.ts │ │ │ │ │ │ ├── IconButton.stories.tsx │ │ │ │ │ │ ├── IconButton.tsx │ │ │ │ │ │ ├── PrimaryButton.stories.tsx │ │ │ │ │ │ ├── PrimaryButton.tsx │ │ │ │ │ │ ├── SecondaryButton.stories.tsx │ │ │ │ │ │ ├── SecondaryButton.tsx │ │ │ │ │ │ ├── ToggleButton.stories.tsx │ │ │ │ │ │ ├── ToggleButton.tsx │ │ │ │ │ │ ├── button.styles.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── checkbox/ │ │ │ │ │ │ ├── Checkbox.test.tsx │ │ │ │ │ │ └── Checkbox.tsx │ │ │ │ │ ├── combo-box/ │ │ │ │ │ │ ├── AutoTag.spec.tsx │ │ │ │ │ │ └── AutoTag.tsx │ │ │ │ │ ├── fieldset/ │ │ │ │ │ │ ├── FormFieldset.spec.tsx │ │ │ │ │ │ ├── FormFieldset.styles.ts │ │ │ │ │ │ ├── FormFieldset.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── file-picker/ │ │ │ │ │ │ ├── RiFilePicker.tsx │ │ │ │ │ │ └── styles.tsx │ │ │ │ │ ├── radio-group/ │ │ │ │ │ │ └── RadioGroup.tsx │ │ │ │ │ └── select/ │ │ │ │ │ ├── RISelectWithActions.spec.tsx │ │ │ │ │ ├── RISelectWithActions.tsx │ │ │ │ │ └── RiSelect.tsx │ │ │ │ ├── icons/ │ │ │ │ │ ├── Icon.tsx │ │ │ │ │ ├── RiIcon.tsx │ │ │ │ │ ├── iconRegistry.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── inputs/ │ │ │ │ │ ├── ComposedInput.tsx │ │ │ │ │ ├── NumericInput.tsx │ │ │ │ │ ├── PasswordInput.tsx │ │ │ │ │ ├── SearchInput.tsx │ │ │ │ │ ├── SwitchInput.spec.tsx │ │ │ │ │ ├── SwitchInput.tsx │ │ │ │ │ ├── TextArea.ts │ │ │ │ │ ├── TextInput.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── layout/ │ │ │ │ │ ├── card/ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── drawer/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── empty-prompt/ │ │ │ │ │ │ └── RiEmptyPrompt.tsx │ │ │ │ │ ├── flex/ │ │ │ │ │ │ ├── flex.spec.tsx │ │ │ │ │ │ ├── flex.styles.ts │ │ │ │ │ │ ├── flex.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── flex.module.scss │ │ │ │ │ ├── horizontal-rule/ │ │ │ │ │ │ ├── HorizontalRule.spec.tsx │ │ │ │ │ │ ├── HorizontalRule.tsx │ │ │ │ │ │ └── horizontal-rule.styles.ts │ │ │ │ │ ├── horizontal-spacer/ │ │ │ │ │ │ ├── HorizontalSpacer.spec.tsx │ │ │ │ │ │ ├── horizontal-spacer.styles.ts │ │ │ │ │ │ ├── horizontal-spacer.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── list/ │ │ │ │ │ │ ├── Group.tsx │ │ │ │ │ │ ├── Item.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── list.styles.ts │ │ │ │ │ ├── loading-content/ │ │ │ │ │ │ ├── LoadingContent.spec.tsx │ │ │ │ │ │ ├── LoadingContent.tsx │ │ │ │ │ │ └── loading-content.styles.ts │ │ │ │ │ ├── menu/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── page/ │ │ │ │ │ │ ├── Page.tsx │ │ │ │ │ │ ├── PageBody.tsx │ │ │ │ │ │ ├── PageContentBody.tsx │ │ │ │ │ │ ├── PageHeader.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── page-body.spec.tsx │ │ │ │ │ │ ├── page-body.styles.ts │ │ │ │ │ │ ├── page-heading.styles.ts │ │ │ │ │ │ ├── page.spec.tsx │ │ │ │ │ │ └── page.styles.ts │ │ │ │ │ ├── profile-icon/ │ │ │ │ │ │ └── ProfileIcon.tsx │ │ │ │ │ ├── resize/ │ │ │ │ │ │ ├── container/ │ │ │ │ │ │ │ └── ResizableContainer.tsx │ │ │ │ │ │ ├── handle/ │ │ │ │ │ │ │ ├── ResizablePanelHandle.tsx │ │ │ │ │ │ │ └── resizable-panel-handle.styles.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── panel/ │ │ │ │ │ │ └── ResizablePanel.tsx │ │ │ │ │ ├── sidebar/ │ │ │ │ │ │ ├── SideBarItemIcon.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── sidebar-item-icon.styles.ts │ │ │ │ │ ├── spacer/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── spacer.spec.tsx │ │ │ │ │ │ ├── spacer.styles.ts │ │ │ │ │ │ └── spacer.tsx │ │ │ │ │ ├── stepper/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── table/ │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── tabs/ │ │ │ │ │ └── index.ts │ │ │ │ ├── link/ │ │ │ │ │ ├── Link.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── link.styles.ts │ │ │ │ │ └── link.types.ts │ │ │ │ ├── navigation/ │ │ │ │ │ └── breadcrumbs/ │ │ │ │ │ ├── RiBreadcrumbs.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── popover/ │ │ │ │ │ ├── RiPopover.constants.ts │ │ │ │ │ ├── RiPopover.spec.tsx │ │ │ │ │ ├── RiPopover.tsx │ │ │ │ │ ├── RiPopover.types.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── shared/ │ │ │ │ │ └── WindowControlGroup.tsx │ │ │ │ ├── text/ │ │ │ │ │ ├── ColorText.tsx │ │ │ │ │ ├── HealthText.tsx │ │ │ │ │ ├── MultilineEllipsisText.tsx │ │ │ │ │ ├── Text.tsx │ │ │ │ │ ├── Title.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── text.styles.ts │ │ │ │ ├── theme/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── tooltip/ │ │ │ │ │ ├── HoverContent.tsx │ │ │ │ │ ├── RITooltip.tsx │ │ │ │ │ ├── RiTooltip.spec.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── utils/ │ │ │ │ ├── FocusTrap.tsx │ │ │ │ ├── OutsideClickDetector.tsx │ │ │ │ ├── ShowHide.spec.tsx │ │ │ │ ├── ShowHide.tsx │ │ │ │ ├── WindowEvent.spec.tsx │ │ │ │ ├── WindowEvent.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ ├── generate-id.ts │ │ │ │ │ └── inner-text.ts │ │ │ │ ├── index.ts │ │ │ │ ├── outsideClickDetector.spec.tsx │ │ │ │ ├── pluginsThemeContext.tsx │ │ │ │ └── resize-observer/ │ │ │ │ └── ResizeObserver.tsx │ │ │ ├── bottom-group-components/ │ │ │ │ ├── BottomGroupComponents.spec.tsx │ │ │ │ ├── BottomGroupComponents.stories.tsx │ │ │ │ ├── BottomGroupComponents.tsx │ │ │ │ ├── components/ │ │ │ │ │ └── bottom-group-minimized/ │ │ │ │ │ ├── BottomGroupMinimized.spec.tsx │ │ │ │ │ ├── BottomGroupMinimized.stories.tsx │ │ │ │ │ ├── BottomGroupMinimized.tsx │ │ │ │ │ ├── ButtonGroupMinimized.styles.ts │ │ │ │ │ └── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── browser/ │ │ │ │ ├── KeysBrowser.spec.tsx │ │ │ │ ├── KeysBrowser.styles.ts │ │ │ │ ├── KeysBrowser.tsx │ │ │ │ ├── KeysBrowser.types.ts │ │ │ │ ├── columns-menu/ │ │ │ │ │ ├── ColumnsMenu.styles.ts │ │ │ │ │ ├── ColumnsMenu.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── hooks/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── useResponsiveColumns.ts │ │ │ │ ├── index.ts │ │ │ │ └── view-switch/ │ │ │ │ ├── ViewSwitch.styles.ts │ │ │ │ ├── ViewSwitch.tsx │ │ │ │ ├── ViewSwitch.types.ts │ │ │ │ └── index.ts │ │ │ ├── bulk-actions-config/ │ │ │ │ ├── BulkActionsConfig.spec.tsx │ │ │ │ ├── BulkActionsConfig.tsx │ │ │ │ └── index.ts │ │ │ ├── charts/ │ │ │ │ ├── bar-chart/ │ │ │ │ │ ├── BarChart.spec.tsx │ │ │ │ │ ├── BarChart.stories.tsx │ │ │ │ │ ├── BarChart.styles.ts │ │ │ │ │ ├── BarChart.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── donut-chart/ │ │ │ │ │ ├── DonutChart.spec.tsx │ │ │ │ │ ├── DonutChart.stories.tsx │ │ │ │ │ ├── DonutChart.styles.ts │ │ │ │ │ ├── DonutChart.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── cli/ │ │ │ │ ├── Cli/ │ │ │ │ │ ├── Cli.spec.tsx │ │ │ │ │ ├── Cli.stories.tsx │ │ │ │ │ ├── Cli.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── CliWrapper.spec.tsx │ │ │ │ ├── CliWrapper.stories.tsx │ │ │ │ ├── CliWrapper.tsx │ │ │ │ └── components/ │ │ │ │ ├── cli-body/ │ │ │ │ │ ├── CliBody/ │ │ │ │ │ │ ├── CliBody.spec.tsx │ │ │ │ │ │ ├── CliBody.stories.tsx │ │ │ │ │ │ ├── CliBody.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── CliBodyWrapper.spec.tsx │ │ │ │ │ ├── CliBodyWrapper.stories.tsx │ │ │ │ │ ├── CliBodyWrapper.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── cli-header/ │ │ │ │ │ ├── CliHeader.spec.tsx │ │ │ │ │ ├── CliHeader.stories.tsx │ │ │ │ │ ├── CliHeader.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── cli-input/ │ │ │ │ ├── CliAutocomplete/ │ │ │ │ │ ├── CliAutocomplete.spec.tsx │ │ │ │ │ ├── CliAutocomplete.stories.tsx │ │ │ │ │ ├── CliAutocomplete.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── CliInput/ │ │ │ │ │ ├── CliInput.spec.tsx │ │ │ │ │ ├── CliInput.stories.tsx │ │ │ │ │ ├── CliInput.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── CliInputWrapper.spec.tsx │ │ │ │ ├── CliInputWrapper.stories.tsx │ │ │ │ ├── CliInputWrapper.tsx │ │ │ │ └── index.ts │ │ │ ├── code-block/ │ │ │ │ ├── CodeBlock.spec.tsx │ │ │ │ ├── CodeBlock.stories.tsx │ │ │ │ ├── CodeBlock.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── column-header/ │ │ │ │ ├── ColumnHeader.spec.tsx │ │ │ │ ├── ColumnHeader.tsx │ │ │ │ └── index.ts │ │ │ ├── columns-config/ │ │ │ │ ├── ColumnsConfigPopover.spec.tsx │ │ │ │ └── ColumnsConfigPopover.tsx │ │ │ ├── command-helper/ │ │ │ │ ├── CommandHelper/ │ │ │ │ │ ├── CommandHelper.spec.tsx │ │ │ │ │ ├── CommandHelper.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── CommandHelperHeader/ │ │ │ │ │ ├── CommandHelperHeader.spec.tsx │ │ │ │ │ ├── CommandHelperHeader.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── CommandHelperWrapper.spec.tsx │ │ │ │ ├── CommandHelperWrapper.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── command-helper-info/ │ │ │ │ │ │ ├── CHCommandInfo.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── command-helper-search/ │ │ │ │ │ │ ├── CHSearchFilter/ │ │ │ │ │ │ │ ├── CHSearchFilter.spec.tsx │ │ │ │ │ │ │ ├── CHSearchFilter.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── CHSearchInput/ │ │ │ │ │ │ │ ├── CHSearchInput.spec.tsx │ │ │ │ │ │ │ ├── CHSearchInput.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── CHSearchWrapper.spec.tsx │ │ │ │ │ │ ├── CHSearchWrapper.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ └── command-helper-search-output/ │ │ │ │ │ ├── CHSearchOutput.tsx │ │ │ │ │ ├── CliSearchOutput.spec.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── index.ts │ │ │ ├── config/ │ │ │ │ ├── Config.spec.tsx │ │ │ │ ├── Config.tsx │ │ │ │ └── index.ts │ │ │ ├── confirmation-popover/ │ │ │ │ ├── ConfirmationPopover.spec.tsx │ │ │ │ ├── ConfirmationPopover.tsx │ │ │ │ └── index.ts │ │ │ ├── connectivity-error/ │ │ │ │ ├── ConnectivityError.spec.tsx │ │ │ │ └── ConnectivityError.tsx │ │ │ ├── consents-settings/ │ │ │ │ ├── ConsentOption/ │ │ │ │ │ ├── ConsentOption.spec.tsx │ │ │ │ │ ├── ConsentOption.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── ItemDescription.tsx │ │ │ │ │ │ └── index.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── ConsentsNotifications/ │ │ │ │ │ ├── ConsentsNotifications.spec.tsx │ │ │ │ │ ├── ConsentsNotifications.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── ConsentsPrivacy/ │ │ │ │ │ ├── ConsentsPrivacy.spec.tsx │ │ │ │ │ ├── ConsentsPrivacy.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── ConsentsSettings.spec.tsx │ │ │ │ ├── ConsentsSettings.tsx │ │ │ │ ├── ConsentsSettingsPopup/ │ │ │ │ │ ├── ConsentsSettingsPopup.spec.tsx │ │ │ │ │ └── ConsentsSettingsPopup.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── styles.module.scss │ │ │ │ └── styles.ts │ │ │ ├── copy-button/ │ │ │ │ ├── CopyButton.spec.tsx │ │ │ │ ├── CopyButton.styles.ts │ │ │ │ ├── CopyButton.tsx │ │ │ │ ├── CopyButton.types.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── ButtonWithTooltip/ │ │ │ │ │ │ ├── ButtonWithTooltip.tsx │ │ │ │ │ │ ├── ButtonWithTooltip.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── css.d.ts │ │ │ ├── database-list-modules/ │ │ │ │ ├── DatabaseListModules.spec.tsx │ │ │ │ ├── DatabaseListModules.stories.tsx │ │ │ │ ├── DatabaseListModules.styles.ts │ │ │ │ ├── DatabaseListModules.tsx │ │ │ │ ├── DatabaseListModules.types.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── DatabaseModuleContent/ │ │ │ │ │ │ ├── DatabaseModuleContent.tsx │ │ │ │ │ │ └── DatabaseModuleContent.types.ts │ │ │ │ │ ├── DatabaseModuleContentItem/ │ │ │ │ │ │ ├── DatabaseModuleContentItem.styles.ts │ │ │ │ │ │ ├── DatabaseModuleContentItem.tsx │ │ │ │ │ │ └── DatabaseModuleContentItem.types.ts │ │ │ │ │ ├── DatabaseModuleItem/ │ │ │ │ │ │ ├── DatabaseModuleItem.styles.ts │ │ │ │ │ │ ├── DatabaseModuleItem.tsx │ │ │ │ │ │ └── DatabaseModuleItem.types.ts │ │ │ │ │ ├── DatabaseModulesList/ │ │ │ │ │ │ ├── DatabaseModulesList.tsx │ │ │ │ │ │ └── DatabaseModulesList.types.ts │ │ │ │ │ └── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── database-list-options/ │ │ │ │ ├── DatabaseListOptions.spec.tsx │ │ │ │ ├── DatabaseListOptions.stories.tsx │ │ │ │ ├── DatabaseListOptions.styles.ts │ │ │ │ ├── DatabaseListOptions.tsx │ │ │ │ ├── components/ │ │ │ │ │ └── Tooltip.tsx │ │ │ │ └── constants.ts │ │ │ ├── database-overview/ │ │ │ │ ├── DatabaseOverview.spec.tsx │ │ │ │ ├── DatabaseOverview.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── OverviewMetrics/ │ │ │ │ │ │ ├── MetricItem.tsx │ │ │ │ │ │ ├── OverviewMetrics.spec.tsx │ │ │ │ │ │ ├── OverviewMetrics.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ └── icons.ts │ │ │ │ ├── hooks/ │ │ │ │ │ ├── useDatabaseOverview.spec.ts │ │ │ │ │ └── useDatabaseOverview.ts │ │ │ │ └── styles.module.scss │ │ │ ├── divider/ │ │ │ │ ├── Divider.spec.tsx │ │ │ │ ├── Divider.styles.ts │ │ │ │ ├── Divider.tsx │ │ │ │ └── Divider.types.ts │ │ │ ├── explore-guides/ │ │ │ │ ├── ExploreGuides.spec.tsx │ │ │ │ ├── ExploreGuides.styles.ts │ │ │ │ ├── ExploreGuides.tsx │ │ │ │ ├── icons.ts │ │ │ │ └── index.ts │ │ │ ├── feature-flag-component/ │ │ │ │ ├── FeatureFlagComponent.spec.tsx │ │ │ │ ├── FeatureFlagComponent.tsx │ │ │ │ └── index.ts │ │ │ ├── field-message/ │ │ │ │ ├── FieldMessage.spec.tsx │ │ │ │ ├── FieldMessage.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── form-dialog/ │ │ │ │ ├── FooterDatabaseForm.ts │ │ │ │ ├── FormDialog.spec.tsx │ │ │ │ ├── FormDialog.styles.ts │ │ │ │ ├── FormDialog.tsx │ │ │ │ └── index.ts │ │ │ ├── formated-date/ │ │ │ │ ├── FormatedDate.spec.tsx │ │ │ │ ├── FormatedDate.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── full-screen/ │ │ │ │ ├── FullScreen.spec.tsx │ │ │ │ ├── FullScreen.tsx │ │ │ │ └── index.ts │ │ │ ├── global-azure-auth/ │ │ │ │ ├── AzureAuthCallbackPage.spec.tsx │ │ │ │ ├── AzureAuthCallbackPage.styles.ts │ │ │ │ ├── AzureAuthCallbackPage.tsx │ │ │ │ ├── GlobalAzureAuth.spec.tsx │ │ │ │ ├── GlobalAzureAuth.tsx │ │ │ │ └── index.ts │ │ │ ├── global-dialogs/ │ │ │ │ ├── GlobalDialogs.tsx │ │ │ │ └── index.ts │ │ │ ├── global-subscriptions/ │ │ │ │ ├── CommonAppSubscription/ │ │ │ │ │ ├── CommonAppSubscription.spec.tsx │ │ │ │ │ ├── CommonAppSubscription.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── GlobalSubscriptions.tsx │ │ │ │ └── index.ts │ │ │ ├── global-url-handler/ │ │ │ │ ├── GlobalUrlHandler.spec.tsx │ │ │ │ ├── GlobalUrlHandler.tsx │ │ │ │ └── index.ts │ │ │ ├── group-badge/ │ │ │ │ ├── GroupBadge.stories.tsx │ │ │ │ ├── GroupBadge.styles.ts │ │ │ │ ├── GroupBadge.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── hightlighted-feature/ │ │ │ │ ├── HighlightedFeature.spec.tsx │ │ │ │ ├── HighlightedFeature.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── home-tabs/ │ │ │ │ ├── HomeTabs.spec.tsx │ │ │ │ ├── HomeTabs.tsx │ │ │ │ ├── constants.ts │ │ │ │ └── index.ts │ │ │ ├── hooks/ │ │ │ │ ├── useAzureAuth.spec.ts │ │ │ │ ├── useAzureAuth.ts │ │ │ │ ├── useConnectionType.spec.ts │ │ │ │ └── useConnectionType.ts │ │ │ ├── import-file-modal/ │ │ │ │ ├── ImportFileModal.spec.tsx │ │ │ │ ├── ImportFileModal.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── index.ts │ │ │ ├── init/ │ │ │ │ ├── AppInit.spec.tsx │ │ │ │ └── AppInit.tsx │ │ │ ├── inline-item-editor/ │ │ │ │ ├── InlineItemEditor.spec.tsx │ │ │ │ ├── InlineItemEditor.styles.tsx │ │ │ │ ├── InlineItemEditor.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── input-field-sentinel/ │ │ │ │ ├── InputFieldSentinel.spec.tsx │ │ │ │ ├── InputFieldSentinel.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── instance-header/ │ │ │ │ ├── InstanceHeader.spec.tsx │ │ │ │ ├── InstanceHeader.stories.tsx │ │ │ │ ├── InstanceHeader.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── ShortInstanceInfo.spec.tsx │ │ │ │ │ ├── ShortInstanceInfo.styles.ts │ │ │ │ │ ├── ShortInstanceInfo.tsx │ │ │ │ │ ├── instances-navigation-popover/ │ │ │ │ │ │ ├── InstancesNavigationPopover.spec.tsx │ │ │ │ │ │ ├── InstancesNavigationPopover.styles.ts │ │ │ │ │ │ ├── InstancesNavigationPopover.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── instances-list/ │ │ │ │ │ │ │ ├── InstancesList.spec.tsx │ │ │ │ │ │ │ ├── InstancesList.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ └── user-profile/ │ │ │ │ │ ├── CloudUserProfile.tsx │ │ │ │ │ ├── UserProfile.spec.tsx │ │ │ │ │ ├── UserProfile.tsx │ │ │ │ │ ├── UserProfileBadge.spec.tsx │ │ │ │ │ └── UserProfileBadge.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── item-list/ │ │ │ │ └── components/ │ │ │ │ ├── action-bar/ │ │ │ │ │ ├── ActionBar.spec.tsx │ │ │ │ │ ├── ActionBar.styles.ts │ │ │ │ │ └── ActionBar.tsx │ │ │ │ ├── delete-action/ │ │ │ │ │ ├── DeleteAction.spec.tsx │ │ │ │ │ └── DeleteAction.tsx │ │ │ │ ├── export-action/ │ │ │ │ │ ├── ExportAction.spec.tsx │ │ │ │ │ └── ExportAction.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── json-viewer/ │ │ │ │ ├── JSONViewer.spec.tsx │ │ │ │ ├── JSONViewer.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── json-array/ │ │ │ │ │ │ ├── JsonArray.spec.tsx │ │ │ │ │ │ ├── JsonArray.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── json-object/ │ │ │ │ │ │ ├── JsonObject.spec.tsx │ │ │ │ │ │ ├── JsonObject.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── json-pretty/ │ │ │ │ │ │ ├── JsonPretty.spec.tsx │ │ │ │ │ │ ├── JsonPretty.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── json-primitive/ │ │ │ │ │ ├── JsonPrimitive.spec.tsx │ │ │ │ │ ├── JsonPrimitive.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── interfaces.ts │ │ │ │ ├── utils.spec.ts │ │ │ │ └── utils.ts │ │ │ ├── keyboard-shortcut/ │ │ │ │ ├── KeyboardShortcut.spec.tsx │ │ │ │ ├── KeyboardShortcut.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── keys-summary/ │ │ │ │ ├── KeysSummary.spec.tsx │ │ │ │ ├── KeysSummary.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── main/ │ │ │ │ └── MainComponent.tsx │ │ │ ├── main-router/ │ │ │ │ ├── MainRouter.spec.tsx │ │ │ │ ├── MainRouter.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── RedisStackRoutes.spec.tsx │ │ │ │ │ ├── RedisStackRoutes.tsx │ │ │ │ │ ├── SuspenseLoader.tsx │ │ │ │ │ └── loader.module.scss │ │ │ │ ├── config.ts │ │ │ │ ├── constants/ │ │ │ │ │ ├── commonRoutes.ts │ │ │ │ │ ├── defaultRoutes.ts │ │ │ │ │ ├── redisStackRoutes.ts │ │ │ │ │ └── sub-routes/ │ │ │ │ │ ├── analyticsRoutes.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── rdiPipelineManagementRoutes.ts │ │ │ │ │ └── vectorSearchRoutes.ts │ │ │ │ ├── hooks/ │ │ │ │ │ ├── useActivityMonitor.spec.ts │ │ │ │ │ └── useActivityMonitor.ts │ │ │ │ └── interfaces.ts │ │ │ ├── markdown/ │ │ │ │ ├── CloudLink/ │ │ │ │ │ ├── CloudLink.spec.tsx │ │ │ │ │ ├── CloudLink.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── CodeButtonBlock/ │ │ │ │ │ ├── CodeButtonBlock.spec.tsx │ │ │ │ │ ├── CodeButtonBlock.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── RunConfirmationPopover.spec.tsx │ │ │ │ │ │ ├── RunConfirmationPopover.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── Image/ │ │ │ │ │ ├── Image.spec.tsx │ │ │ │ │ ├── Image.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── RedisInsightLink/ │ │ │ │ │ ├── RedisInsightLink.spec.tsx │ │ │ │ │ ├── RedisInsightLink.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── RedisUploadButton/ │ │ │ │ │ ├── RedisUploadButton.spec.tsx │ │ │ │ │ ├── RedisUploadButton.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── index.ts │ │ │ ├── message-bar/ │ │ │ │ ├── MessageBar.spec.tsx │ │ │ │ ├── MessageBar.styles.ts │ │ │ │ ├── MessageBar.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── messages/ │ │ │ │ ├── cli-output/ │ │ │ │ │ ├── cliOutput.spec.tsx │ │ │ │ │ └── cliOutput.tsx │ │ │ │ ├── database-not-opened/ │ │ │ │ │ ├── DatabaseNotOpened.spec.tsx │ │ │ │ │ ├── DatabaseNotOpened.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── feature-not-available/ │ │ │ │ │ ├── FeatureNotAvailable.spec.tsx │ │ │ │ │ ├── FeatureNotAvailable.styles.ts │ │ │ │ │ ├── FeatureNotAvailable.tsx │ │ │ │ │ ├── FeatureNotAvailable.types.ts │ │ │ │ │ ├── constants.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── module-not-loaded/ │ │ │ │ │ ├── ModuleNotLoaded.spec.tsx │ │ │ │ │ ├── ModuleNotLoaded.tsx │ │ │ │ │ ├── ModuleNotLoadedButton.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── module-not-loaded-minimalized/ │ │ │ │ ├── ModuleNotLoadedMinimalized.spec.tsx │ │ │ │ ├── ModuleNotLoadedMinimalized.tsx │ │ │ │ ├── constants.ts │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── monaco-editor/ │ │ │ │ ├── MonacoEditor.spec.tsx │ │ │ │ ├── MonacoEditor.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── dedicated-editor/ │ │ │ │ │ │ ├── DedicatedEditor.spec.tsx │ │ │ │ │ │ ├── DedicatedEditor.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── monaco-json/ │ │ │ │ │ │ ├── MonacoJson.spec.tsx │ │ │ │ │ │ ├── MonacoJson.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── monaco-yaml/ │ │ │ │ │ ├── MonacoYaml.spec.tsx │ │ │ │ │ ├── MonacoYaml.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── monacoYamlModel.ts │ │ │ │ ├── index.ts │ │ │ │ ├── styles.module.scss │ │ │ │ ├── useMonacoValidation.spec.tsx │ │ │ │ └── useMonacoValidation.ts │ │ │ ├── monaco-laguages/ │ │ │ │ ├── MonacoLanguages.spec.tsx │ │ │ │ ├── MonacoLanguages.tsx │ │ │ │ └── index.ts │ │ │ ├── monitor/ │ │ │ │ ├── Monitor/ │ │ │ │ │ ├── Monitor.spec.tsx │ │ │ │ │ ├── Monitor.styles.tsx │ │ │ │ │ ├── Monitor.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── MonitorHeader/ │ │ │ │ │ ├── MonitorHeader.spec.tsx │ │ │ │ │ ├── MonitorHeader.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── MonitorLog/ │ │ │ │ │ ├── MonitorLog.spec.tsx │ │ │ │ │ ├── MonitorLog.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── MonitorOutputList/ │ │ │ │ │ ├── MonitorOutputList.spec.tsx │ │ │ │ │ ├── MonitorOutputList.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── MonitorWrapper.spec.tsx │ │ │ │ ├── MonitorWrapper.tsx │ │ │ │ └── index.ts │ │ │ ├── monitor-config/ │ │ │ │ ├── MonitorConfig.spec.tsx │ │ │ │ ├── MonitorConfig.tsx │ │ │ │ └── index.ts │ │ │ ├── multi-search/ │ │ │ │ ├── MultiSearch.spec.tsx │ │ │ │ ├── MultiSearch.styles.ts │ │ │ │ └── MultiSearch.tsx │ │ │ ├── navigation-menu/ │ │ │ │ ├── NavigationMenu.spec.tsx │ │ │ │ ├── NavigationMenu.tsx │ │ │ │ ├── app-navigation/ │ │ │ │ │ ├── AppNavigation.styles.ts │ │ │ │ │ ├── AppNavigation.tsx │ │ │ │ │ └── AppNavigationTabTrigger.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── create-cloud/ │ │ │ │ │ │ ├── CreateCloud.spec.tsx │ │ │ │ │ │ ├── CreateCloud.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── help-menu/ │ │ │ │ │ │ ├── HelpMenu.spec.tsx │ │ │ │ │ │ ├── HelpMenu.tsx │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── notifications-center/ │ │ │ │ │ │ ├── Notification/ │ │ │ │ │ │ │ ├── Notification.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── NotificationCenter.spec.tsx │ │ │ │ │ │ ├── NotificationCenter.tsx │ │ │ │ │ │ ├── NotificationMenu.spec.tsx │ │ │ │ │ │ ├── NotificationMenu.tsx │ │ │ │ │ │ ├── PopoverNotification/ │ │ │ │ │ │ │ ├── PopoverNotification.spec.tsx │ │ │ │ │ │ │ ├── PopoverNotification.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ └── redis-logo/ │ │ │ │ │ ├── RedisLogo.spec.tsx │ │ │ │ │ └── RedisLogo.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ └── useNavigation.ts │ │ │ │ ├── navigation.types.ts │ │ │ │ └── styles.module.scss │ │ │ ├── notifications/ │ │ │ │ ├── Notifications.spec.tsx │ │ │ │ ├── Notifications.stories.tsx │ │ │ │ ├── Notifications.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── azure-token-expired/ │ │ │ │ │ │ ├── AzureTokenExpiredErrorContent.spec.tsx │ │ │ │ │ │ ├── AzureTokenExpiredErrorContent.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── cloud-capi-unauthorized/ │ │ │ │ │ │ ├── CloudCapiUnAuthorizedErrorContent.spec.tsx │ │ │ │ │ │ ├── CloudCapiUnAuthorizedErrorContent.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── default-error-content/ │ │ │ │ │ │ ├── DefaultErrorContent.spec.tsx │ │ │ │ │ │ ├── DefaultErrorContent.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── encryption-error-content/ │ │ │ │ │ │ ├── EncryptionErrorContent.spec.tsx │ │ │ │ │ │ ├── EncryptionErrorContent.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── infinite-messages/ │ │ │ │ │ │ ├── InfiniteMessages.spec.tsx │ │ │ │ │ │ ├── InfiniteMessages.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── persistent-error-content/ │ │ │ │ │ │ ├── PersistentErrorContent.spec.tsx │ │ │ │ │ │ ├── PersistentErrorContent.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── rdi-deploy-error-content/ │ │ │ │ │ ├── RdiDeployErrorContent.spec.tsx │ │ │ │ │ ├── RdiDeployErrorContent.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── error-messages.spec.tsx │ │ │ │ ├── error-messages.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useErrorNotifications.spec.tsx │ │ │ │ │ ├── useErrorNotifications.ts │ │ │ │ │ ├── useInfiniteNotifications.ts │ │ │ │ │ └── useMessageNotifications.tsx │ │ │ │ ├── index.ts │ │ │ │ └── success-messages.tsx │ │ │ ├── oauth/ │ │ │ │ ├── index.ts │ │ │ │ ├── oauth-connect-free-db/ │ │ │ │ │ ├── OAuthConnectFreeDb.spec.tsx │ │ │ │ │ ├── OAuthConnectFreeDb.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── oauth-jobs/ │ │ │ │ │ ├── OAuthJobs.spec.tsx │ │ │ │ │ ├── OAuthJobs.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── oauth-select-account-dialog/ │ │ │ │ │ ├── OAuthSelectAccountDialog.spec.tsx │ │ │ │ │ ├── OAuthSelectAccountDialog.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── oauth-select-plan/ │ │ │ │ │ ├── OAuthSelectPlan.spec.tsx │ │ │ │ │ ├── OAuthSelectPlan.styles.ts │ │ │ │ │ ├── OAuthSelectPlan.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── oauth-sign-in-button/ │ │ │ │ │ ├── OAuthSignInButton.spec.tsx │ │ │ │ │ ├── OAuthSignInButton.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── oauth-sso/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── oauth-autodiscovery/ │ │ │ │ │ │ ├── OAuthAutodiscovery.spec.tsx │ │ │ │ │ │ ├── OAuthAutodiscovery.styles.ts │ │ │ │ │ │ ├── OAuthAutodiscovery.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── oauth-create-db/ │ │ │ │ │ │ ├── OAuthCreateDb.spec.tsx │ │ │ │ │ │ ├── OAuthCreateDb.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ └── oauth-sign-in/ │ │ │ │ │ ├── OAuthSignIn.spec.tsx │ │ │ │ │ ├── OAuthSignIn.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── oauth-sso-dialog/ │ │ │ │ │ ├── OAuthSsoDialog.spec.tsx │ │ │ │ │ ├── OAuthSsoDialog.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── oauth-sso-handler-dialog/ │ │ │ │ │ ├── OAuthSsoHandlerDialog.spec.tsx │ │ │ │ │ ├── OAuthSsoHandlerDialog.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── oauth-user-profile/ │ │ │ │ │ ├── OAuthUserProfile.spec.tsx │ │ │ │ │ ├── OAuthUserProfile.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── shared/ │ │ │ │ ├── index.ts │ │ │ │ ├── oauth-advantages/ │ │ │ │ │ ├── OAuthAdvantages.spec.tsx │ │ │ │ │ ├── OAuthAdvantages.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── oauth-agreement/ │ │ │ │ │ ├── OAuthAgreement.spec.tsx │ │ │ │ │ ├── OAuthAgreement.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── oauth-form/ │ │ │ │ │ ├── OAuthForm.spec.tsx │ │ │ │ │ ├── OAuthForm.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ └── oauth-sso-form/ │ │ │ │ │ │ ├── OAuthSsoForm.styles.ts │ │ │ │ │ │ ├── OAuthSsoForm.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── oauth-recommended-settings/ │ │ │ │ │ ├── OAuthRecommendedSettings.spec.tsx │ │ │ │ │ ├── OAuthRecommendedSettings.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── oauth-social-buttons/ │ │ │ │ │ ├── OAuthSocialButtons.spec.tsx │ │ │ │ │ ├── OAuthSocialButtons.styles.ts │ │ │ │ │ ├── OAuthSocialButtons.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── styles.ts │ │ │ ├── onboarding-features/ │ │ │ │ ├── OnboardingFeatures.spec.tsx │ │ │ │ ├── OnboardingFeatures.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── onboarding-tour/ │ │ │ │ ├── OnboardingTour.spec.tsx │ │ │ │ ├── OnboardingTour.tsx │ │ │ │ ├── OnboardingTourWrapper.spec.tsx │ │ │ │ ├── OnboardingTourWrapper.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces.ts │ │ │ │ └── styles.module.scss │ │ │ ├── page-header/ │ │ │ │ ├── PageHeader.module.scss │ │ │ │ ├── PageHeader.spec.tsx │ │ │ │ ├── PageHeader.tsx │ │ │ │ └── components/ │ │ │ │ └── index.ts │ │ │ ├── page-placeholder/ │ │ │ │ ├── PagePlaceholder.spec.tsx │ │ │ │ ├── PagePlaceholder.tsx │ │ │ │ └── index.ts │ │ │ ├── panel/ │ │ │ │ └── index.ts │ │ │ ├── promo-link/ │ │ │ │ ├── PromoLink.spec.tsx │ │ │ │ ├── PromoLink.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── pub-sub-config/ │ │ │ │ ├── PubSubConfig.spec.tsx │ │ │ │ ├── PubSubConfig.tsx │ │ │ │ └── index.ts │ │ │ ├── query/ │ │ │ │ ├── components/ │ │ │ │ │ └── RunButton.tsx │ │ │ │ ├── context/ │ │ │ │ │ ├── query-editor-context.spec.tsx │ │ │ │ │ ├── query-editor.context.tsx │ │ │ │ │ ├── query-editor.context.types.ts │ │ │ │ │ ├── query-results-context.spec.tsx │ │ │ │ │ ├── query-results.context.tsx │ │ │ │ │ ├── view-mode-context.spec.tsx │ │ │ │ │ └── view-mode.context.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useCommandHistory.ts │ │ │ │ │ ├── useCommandHistory.types.ts │ │ │ │ │ ├── useDslSyntax.ts │ │ │ │ │ ├── useDslSyntax.types.ts │ │ │ │ │ ├── useMonacoRedisEditor.ts │ │ │ │ │ ├── useMonacoRedisEditor.types.ts │ │ │ │ │ ├── useQueryDecorations.ts │ │ │ │ │ ├── useQueryDecorations.types.ts │ │ │ │ │ ├── useQueryEditor.ts │ │ │ │ │ ├── useQueryEditor.types.ts │ │ │ │ │ ├── useRedisCompletions.ts │ │ │ │ │ └── useRedisCompletions.types.ts │ │ │ │ ├── index.ts │ │ │ │ ├── query-actions/ │ │ │ │ │ ├── QueryActions.spec.tsx │ │ │ │ │ ├── QueryActions.styles.ts │ │ │ │ │ ├── QueryActions.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── query-card/ │ │ │ │ │ ├── QueryCard.spec.tsx │ │ │ │ │ ├── QueryCard.tsx │ │ │ │ │ ├── QueryCardCliDefaultResult/ │ │ │ │ │ │ ├── QueryCardCliDefaultResult.spec.tsx │ │ │ │ │ │ ├── QueryCardCliDefaultResult.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── QueryCardCliGroupResult/ │ │ │ │ │ │ ├── QueryCardCliGroupResult.spec.tsx │ │ │ │ │ │ ├── QueryCardCliGroupResult.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── QueryCardCliPlugin/ │ │ │ │ │ │ ├── QueryCardCliPlugin.spec.tsx │ │ │ │ │ │ ├── QueryCardCliPlugin.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── QueryCardCliResultWrapper/ │ │ │ │ │ │ ├── QueryCardCliResultWrapper.spec.tsx │ │ │ │ │ │ ├── QueryCardCliResultWrapper.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── QueryCardCommonResult/ │ │ │ │ │ │ ├── QueryCardCommonResult.spec.tsx │ │ │ │ │ │ ├── QueryCardCommonResult.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── CommonErrorResponse/ │ │ │ │ │ │ │ ├── CommonErrorResponse.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── QueryCardHeader/ │ │ │ │ │ │ ├── QueryCardHeader.spec.tsx │ │ │ │ │ │ ├── QueryCardHeader.styles.ts │ │ │ │ │ │ ├── QueryCardHeader.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── QueryCardTooltip/ │ │ │ │ │ │ ├── QueryCardTooltip.spec.tsx │ │ │ │ │ │ ├── QueryCardTooltip.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── query-lite-actions/ │ │ │ │ │ ├── QueryActions.spec.tsx │ │ │ │ │ ├── QueryLiteActions.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── query-results/ │ │ │ │ │ ├── QueryResults.spec.tsx │ │ │ │ │ ├── QueryResults.styles.ts │ │ │ │ │ ├── QueryResults.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── query-tutorials/ │ │ │ │ │ ├── QueryTutorials.spec.tsx │ │ │ │ │ ├── QueryTutorials.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── query.styles.ts │ │ │ ├── range-filter/ │ │ │ │ ├── RangeFilter.spec.tsx │ │ │ │ ├── RangeFilter.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── rdi-instance-header/ │ │ │ │ ├── RdiInstanceHeader.spec.tsx │ │ │ │ ├── RdiInstanceHeader.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── recommendation/ │ │ │ │ ├── badge-icon/ │ │ │ │ │ ├── BadgeIcon.spec.tsx │ │ │ │ │ ├── BadgeIcon.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── constants.tsx │ │ │ │ ├── content-element/ │ │ │ │ │ ├── ContentElement.spec.tsx │ │ │ │ │ ├── ContentElement.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── internal-link/ │ │ │ │ │ ├── InternalLink.spec.tsx │ │ │ │ │ ├── InternalLink.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── recommendation-badges/ │ │ │ │ │ ├── RecommendationBadges.spec.tsx │ │ │ │ │ ├── RecommendationBadges.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── recommendation-badges-legend/ │ │ │ │ │ ├── RecommendationBadgesLegend.spec.tsx │ │ │ │ │ ├── RecommendationBadgesLegend.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── recommendation-body/ │ │ │ │ │ ├── RecommendationBody.spec.tsx │ │ │ │ │ ├── RecommendationBody.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── recommendation-copy-component/ │ │ │ │ │ ├── RecommendationCopyComponent.spec.tsx │ │ │ │ │ ├── RecommendationCopyComponent.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── recommendation-voting/ │ │ │ │ │ ├── RecommendationVoting.spec.tsx │ │ │ │ │ ├── RecommendationVoting.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ └── vote-option/ │ │ │ │ │ │ ├── VoteOption.spec.tsx │ │ │ │ │ │ ├── VoteOption.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ │ └── utils.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── styles.module.scss │ │ │ ├── scan-more/ │ │ │ │ ├── ScanMore.spec.tsx │ │ │ │ ├── ScanMore.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── settings-item/ │ │ │ │ ├── SettingItem.spec.tsx │ │ │ │ ├── SettingItem.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── shortcuts-flyout/ │ │ │ │ ├── ShortcutsFlyout.spec.tsx │ │ │ │ ├── ShortcutsFlyout.tsx │ │ │ │ └── schema.tsx │ │ │ ├── side-panels/ │ │ │ │ ├── SidePanels.styles.ts │ │ │ │ ├── SidePanels.test.tsx │ │ │ │ ├── SidePanels.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── copilot-panel/ │ │ │ │ │ │ ├── CopilotPanel.spec.tsx │ │ │ │ │ │ ├── CopilotPanel.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── header/ │ │ │ │ │ │ ├── Header.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── index.ts │ │ │ │ │ └── insights-panel/ │ │ │ │ │ ├── InsightsPanel.spec.tsx │ │ │ │ │ ├── InsightsPanel.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── panels/ │ │ │ │ │ ├── ai-assistant/ │ │ │ │ │ │ ├── AiAssistant.spec.tsx │ │ │ │ │ │ ├── AiAssistant.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── assistance-chat/ │ │ │ │ │ │ │ │ ├── AssistanceChat.spec.tsx │ │ │ │ │ │ │ │ ├── AssistanceChat.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── chats-wrapper/ │ │ │ │ │ │ │ │ ├── ChatsWrapper.spec.tsx │ │ │ │ │ │ │ │ ├── ChatsWrapper.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── expert-chat/ │ │ │ │ │ │ │ │ ├── ExpertChat.spec.tsx │ │ │ │ │ │ │ │ ├── ExpertChat.tsx │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── expert-chat-header/ │ │ │ │ │ │ │ │ │ │ ├── ExpertChatHeader.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── ExpertChatHeader.tsx │ │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ │ └── no-indexes-initial-message/ │ │ │ │ │ │ │ │ │ ├── NoIndexesInitialMessage.spec.tsx │ │ │ │ │ │ │ │ │ ├── NoIndexesInitialMessage.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ │ │ ├── chat-form/ │ │ │ │ │ │ │ │ │ ├── ChatForm.spec.tsx │ │ │ │ │ │ │ │ │ ├── ChatForm.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── chat-history/ │ │ │ │ │ │ │ │ │ ├── ChatHistory.spec.tsx │ │ │ │ │ │ │ │ │ ├── ChatHistory.styles.ts │ │ │ │ │ │ │ │ │ ├── ChatHistory.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── texts.tsx │ │ │ │ │ │ │ │ ├── error-message/ │ │ │ │ │ │ │ │ │ ├── ErrorMessage.spec.tsx │ │ │ │ │ │ │ │ │ ├── ErrorMessage.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── loading-message/ │ │ │ │ │ │ │ │ │ ├── LoadingMessage.spec.tsx │ │ │ │ │ │ │ │ │ ├── LoadingMessage.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── markdown-message/ │ │ │ │ │ │ │ │ │ ├── MarkdownMessage.spec.tsx │ │ │ │ │ │ │ │ │ ├── MarkdownMessage.tsx │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── chat-external-link/ │ │ │ │ │ │ │ │ │ │ │ ├── ChatExternalLink.spec.tsx │ │ │ │ │ │ │ │ │ │ │ ├── ChatExternalLink.tsx │ │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ │ ├── code-block/ │ │ │ │ │ │ │ │ │ │ │ ├── CodeBlock.spec.tsx │ │ │ │ │ │ │ │ │ │ │ ├── CodeBlock.tsx │ │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ └── restart-chat/ │ │ │ │ │ │ │ │ ├── RestartChat.spec.tsx │ │ │ │ │ │ │ │ ├── RestartChat.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── texts.tsx │ │ │ │ │ │ │ └── welcome-ai-assistant/ │ │ │ │ │ │ │ ├── WelcomeAiAssistant.spec.tsx │ │ │ │ │ │ │ ├── WelcomeAiAssistant.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── enablement-area/ │ │ │ │ │ │ ├── EnablementArea/ │ │ │ │ │ │ │ ├── EnablementArea.spec.tsx │ │ │ │ │ │ │ ├── EnablementArea.tsx │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── Code/ │ │ │ │ │ │ │ │ │ ├── Code.spec.tsx │ │ │ │ │ │ │ │ │ ├── Code.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── CreateTutorialLink/ │ │ │ │ │ │ │ │ │ ├── CreateTutorialLink.spec.tsx │ │ │ │ │ │ │ │ │ ├── CreateTutorialLink.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── DeleteTutorialButton/ │ │ │ │ │ │ │ │ │ ├── DeleteTutorialButton.spec.tsx │ │ │ │ │ │ │ │ │ ├── DeleteTutorialButton.styles.ts │ │ │ │ │ │ │ │ │ ├── DeleteTutorialButton.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── EmptyPrompt/ │ │ │ │ │ │ │ │ │ ├── EmptyPrompt.spec.tsx │ │ │ │ │ │ │ │ │ ├── EmptyPrompt.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── Group/ │ │ │ │ │ │ │ │ │ ├── Group.spec.tsx │ │ │ │ │ │ │ │ │ ├── Group.styles.ts │ │ │ │ │ │ │ │ │ ├── Group.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.scss │ │ │ │ │ │ │ │ ├── InternalLink/ │ │ │ │ │ │ │ │ │ ├── InternalLink.spec.tsx │ │ │ │ │ │ │ │ │ ├── InternalLink.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ │ │ │ │ └── styles.scss │ │ │ │ │ │ │ │ ├── InternalPage/ │ │ │ │ │ │ │ │ │ ├── InternalPage.spec.tsx │ │ │ │ │ │ │ │ │ ├── InternalPage.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── LazyInternalPage/ │ │ │ │ │ │ │ │ │ ├── LazyInternalPage.spec.tsx │ │ │ │ │ │ │ │ │ ├── LazyInternalPage.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── Navigation/ │ │ │ │ │ │ │ │ │ ├── Navigation.spec.tsx │ │ │ │ │ │ │ │ │ ├── Navigation.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── Pagination/ │ │ │ │ │ │ │ │ │ ├── Pagination.spec.tsx │ │ │ │ │ │ │ │ │ ├── Pagination.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── PlainText/ │ │ │ │ │ │ │ │ │ ├── PlainText.spec.tsx │ │ │ │ │ │ │ │ │ ├── PlainText.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── UploadTutorialForm/ │ │ │ │ │ │ │ │ │ ├── UploadTutorialForm.spec.tsx │ │ │ │ │ │ │ │ │ ├── UploadTutorialForm.styles.ts │ │ │ │ │ │ │ │ │ ├── UploadTutorialForm.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ │ ├── getFileInfo.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── tests/ │ │ │ │ │ │ │ └── getFileInfo.spec.ts │ │ │ │ │ │ ├── EnablementAreaWrapper.spec.tsx │ │ │ │ │ │ ├── EnablementAreaWrapper.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ └── live-time-recommendations/ │ │ │ │ │ ├── LiveTimeRecommendations.spec.tsx │ │ │ │ │ ├── LiveTimeRecommendations.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── popover-run-analyze/ │ │ │ │ │ │ │ ├── PopoverRunAnalyze.spec.tsx │ │ │ │ │ │ │ ├── PopoverRunAnalyze.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── recommendation/ │ │ │ │ │ │ │ ├── Recommendation.spec.tsx │ │ │ │ │ │ │ ├── Recommendation.styles.ts │ │ │ │ │ │ │ ├── Recommendation.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ └── welcome-screen/ │ │ │ │ │ │ ├── WelcomeScreen.spec.tsx │ │ │ │ │ │ ├── WelcomeScreen.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── styles.module.scss │ │ │ ├── table-column-search/ │ │ │ │ ├── TableColumnSearch.spec.tsx │ │ │ │ ├── TableColumnSearch.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── table-column-search-trigger/ │ │ │ │ ├── TableColumnSearchTrigger.spec.tsx │ │ │ │ ├── TableColumnSearchTrigger.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── triggers/ │ │ │ │ ├── copilot-trigger/ │ │ │ │ │ ├── CopilotTrigger.styles.ts │ │ │ │ │ ├── CopilotTrigger.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── insights-trigger/ │ │ │ │ ├── InsightsTrigger.spec.tsx │ │ │ │ ├── InsightsTrigger.styles.ts │ │ │ │ ├── InsightsTrigger.tsx │ │ │ │ └── index.ts │ │ │ ├── upload-file/ │ │ │ │ ├── UploadFile.spec.tsx │ │ │ │ ├── UploadFile.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── upload-warning/ │ │ │ │ ├── UploadWarning.spec.tsx │ │ │ │ ├── UploadWarning.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── styles.ts │ │ │ ├── virtual-grid/ │ │ │ │ ├── VirtualGrid.spec.tsx │ │ │ │ ├── VirtualGrid.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces.ts │ │ │ │ ├── styles.module.scss │ │ │ │ ├── tests/ │ │ │ │ │ └── utils.spec.ts │ │ │ │ └── utils.tsx │ │ │ ├── virtual-list/ │ │ │ │ ├── VirtualList.spec.tsx │ │ │ │ ├── VirtualList.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── virtual-table/ │ │ │ │ ├── VirtualTable.spec.tsx │ │ │ │ ├── VirtualTable.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces.ts │ │ │ │ ├── styles.module.scss │ │ │ │ └── utils.tsx │ │ │ └── yaml-validator/ │ │ │ ├── index.ts │ │ │ ├── validatePipeline.test.ts │ │ │ ├── validatePipeline.ts │ │ │ ├── validateYamlSchema.test.ts │ │ │ └── validateYamlSchema.ts │ │ ├── config/ │ │ │ ├── default.ts │ │ │ ├── domain.ts │ │ │ └── index.ts │ │ ├── constants/ │ │ │ ├── allRedisModules.json │ │ │ ├── api.ts │ │ │ ├── apiErrors.ts │ │ │ ├── apiStatusCode.ts │ │ │ ├── breadcrumbs.ts │ │ │ ├── browser/ │ │ │ │ └── keyDetailsHeader.ts │ │ │ ├── browser.ts │ │ │ ├── bulkActions.ts │ │ │ ├── cliOutput.ts │ │ │ ├── commands.ts │ │ │ ├── commandsVersions.ts │ │ │ ├── customErrorCodes.ts │ │ │ ├── databaseList.ts │ │ │ ├── datetime.ts │ │ │ ├── durationUnits.tsx │ │ │ ├── env.ts │ │ │ ├── featureFlags.ts │ │ │ ├── featuresHighlighting.tsx │ │ │ ├── help-texts.tsx │ │ │ ├── importDatabasesTableResult.ts │ │ │ ├── index.ts │ │ │ ├── keyboardShortcuts.tsx │ │ │ ├── keys.ts │ │ │ ├── links.ts │ │ │ ├── mocks/ │ │ │ │ ├── mock-custom-tutorials.ts │ │ │ │ ├── mock-explore-guides.ts │ │ │ │ ├── mock-recommendations.ts │ │ │ │ ├── mock-redis-commands.ts │ │ │ │ ├── mock-sso.ts │ │ │ │ └── mock-tutorials.ts │ │ │ ├── modules.ts │ │ │ ├── monaco/ │ │ │ │ ├── cypher/ │ │ │ │ │ ├── functions.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── monacoCypher.ts │ │ │ │ ├── index.ts │ │ │ │ ├── jmespath/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── monacoJmespath.ts │ │ │ │ ├── monaco.ts │ │ │ │ ├── monacoRedis.ts │ │ │ │ ├── monitorEvents.ts │ │ │ │ ├── sqliteFunctions/ │ │ │ │ │ ├── functions.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── monacoSQLiteFunctions.ts │ │ │ │ └── theme.ts │ │ │ ├── notifications.ts │ │ │ ├── onboarding.ts │ │ │ ├── pages.ts │ │ │ ├── prop-types/ │ │ │ │ ├── keys.ts │ │ │ │ └── zset.ts │ │ │ ├── pubSub.ts │ │ │ ├── rdiList.ts │ │ │ ├── recommendations.ts │ │ │ ├── redisearch.ts │ │ │ ├── redisinsight.ts │ │ │ ├── regex.ts │ │ │ ├── securityField.ts │ │ │ ├── serverVersions.ts │ │ │ ├── socketErrors.ts │ │ │ ├── socketEvents.ts │ │ │ ├── sorting.ts │ │ │ ├── storage.ts │ │ │ ├── streamViews.ts │ │ │ ├── string.ts │ │ │ ├── table.ts │ │ │ ├── telemetry.ts │ │ │ ├── texts.tsx │ │ │ ├── themes.tsx │ │ │ ├── tutorials.ts │ │ │ ├── validationErrors.ts │ │ │ ├── workbench.ts │ │ │ └── workbenchResults.ts │ │ ├── contexts/ │ │ │ ├── AppNavigationActionsProvider.tsx │ │ │ ├── ModalTitleProvider.tsx │ │ │ └── themeContext.tsx │ │ ├── electron/ │ │ │ ├── AppElectron.spec.tsx │ │ │ ├── AppElectron.tsx │ │ │ ├── components/ │ │ │ │ ├── ConfigAzureAuth/ │ │ │ │ │ ├── ConfigAzureAuth.spec.tsx │ │ │ │ │ ├── ConfigAzureAuth.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── ConfigElectron/ │ │ │ │ │ ├── ConfigElectron.spec.tsx │ │ │ │ │ ├── ConfigElectron.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── ConfigOAuth/ │ │ │ │ │ ├── ConfigOAuth.spec.tsx │ │ │ │ │ ├── ConfigOAuth.tsx │ │ │ │ │ └── index.tsx │ │ │ │ └── index.ts │ │ │ ├── constants/ │ │ │ │ ├── cloudAuth.ts │ │ │ │ ├── index.ts │ │ │ │ ├── ipcEvent.ts │ │ │ │ └── storageElectron.ts │ │ │ └── utils/ │ │ │ ├── index.ts │ │ │ ├── ipcAppRestart.ts │ │ │ ├── ipcAuth.ts │ │ │ ├── ipcCheckUpdates.ts │ │ │ ├── ipcDeleteStoreValues.ts │ │ │ ├── ipcThemeChange.ts │ │ │ └── tests/ │ │ │ └── ipcCheckUpdates.spec.ts │ │ ├── helpers/ │ │ │ ├── constructKeysToTree.ts │ │ │ ├── index.ts │ │ │ └── tests/ │ │ │ ├── constructKeysToTree.spec.ts │ │ │ └── constructKeysToTreeMockResult.ts │ │ ├── hoc/ │ │ │ └── extractRouter.hoc.tsx │ │ ├── mocks/ │ │ │ ├── content/ │ │ │ │ └── content.ts │ │ │ ├── data/ │ │ │ │ ├── analysis.ts │ │ │ │ ├── bigString.ts │ │ │ │ ├── dateNow.ts │ │ │ │ ├── instances.ts │ │ │ │ ├── mocked_redis_commands.ts │ │ │ │ ├── oauth.ts │ │ │ │ └── rdi.ts │ │ │ ├── factories/ │ │ │ │ ├── browser/ │ │ │ │ │ └── bulkActions/ │ │ │ │ │ └── bulkActionOverview.factory.ts │ │ │ │ ├── cloud/ │ │ │ │ │ ├── AzureAccount.factory.ts │ │ │ │ │ ├── RedisCloudAccount.factory.ts │ │ │ │ │ ├── RedisCloudInstance.factory.ts │ │ │ │ │ └── RedisCloudSubscription.factory.ts │ │ │ │ ├── cluster/ │ │ │ │ │ ├── ClusterNodeDetails.factory.ts │ │ │ │ │ └── RedisClusterInstance.factory.ts │ │ │ │ ├── database/ │ │ │ │ │ ├── DBInstance.factory.ts │ │ │ │ │ └── DbConnectionInfo.factory.ts │ │ │ │ ├── database-analysis/ │ │ │ │ │ └── DatabaseAnalysis.factory.ts │ │ │ │ ├── pubsub/ │ │ │ │ │ └── PubSubMessage.factory.ts │ │ │ │ ├── query-library/ │ │ │ │ │ └── queryLibraryItem.factory.ts │ │ │ │ ├── rdi/ │ │ │ │ │ └── RdiStatistics.factory.ts │ │ │ │ ├── redisearch/ │ │ │ │ │ ├── IndexField.factory.ts │ │ │ │ │ └── IndexInfo.factory.ts │ │ │ │ ├── sentinel/ │ │ │ │ │ └── SentinelMaster.factory.ts │ │ │ │ ├── vector-search/ │ │ │ │ │ ├── indexInfo.factory.ts │ │ │ │ │ └── indexList.factory.ts │ │ │ │ └── workbench/ │ │ │ │ └── commandExectution.factory.ts │ │ │ ├── handlers/ │ │ │ │ ├── ai/ │ │ │ │ │ ├── assistantHandlers.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── analytics/ │ │ │ │ │ ├── clusterDetailsHandlers.ts │ │ │ │ │ ├── dbAnalysisHistoryHandlers.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── app/ │ │ │ │ │ ├── featureHandlers.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── infoHandlers.ts │ │ │ │ │ └── telemetryHandlers.ts │ │ │ │ ├── browser/ │ │ │ │ │ ├── bulkActionsHandlers.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── queryLibraryHandlers.ts │ │ │ │ │ └── redisearchHandlers.ts │ │ │ │ ├── content/ │ │ │ │ │ ├── createRedisButtonsHandlers.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── instances/ │ │ │ │ │ ├── caCertsHandlers.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── instancesHandlers.ts │ │ │ │ ├── misc/ │ │ │ │ │ └── index.ts │ │ │ │ ├── oauth/ │ │ │ │ │ ├── cloud.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── rdi/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── rdiHandler.ts │ │ │ │ │ └── rdiPipelineStrategiesHandlers.ts │ │ │ │ ├── recommendations/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── recommendationsHandler.ts │ │ │ │ │ └── recommendationsReadHandler.ts │ │ │ │ ├── tutorials/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── tutorialsHandlers.ts │ │ │ │ ├── user/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── userSettingsHandlers.ts │ │ │ │ └── workbench/ │ │ │ │ ├── commands.ts │ │ │ │ └── index.ts │ │ │ ├── rdi/ │ │ │ │ └── RdiInstance.factory.ts │ │ │ ├── res/ │ │ │ │ └── responseComposition.ts │ │ │ └── server.ts │ │ ├── packages/ │ │ │ ├── clients-list/ │ │ │ │ ├── README.md │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── json-view/ │ │ │ │ │ │ ├── JSONView.spec.tsx │ │ │ │ │ │ ├── JSONView.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── json-array/ │ │ │ │ │ │ │ │ ├── JsonArray.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── json-object/ │ │ │ │ │ │ │ │ ├── JsonObject.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── json-pretty/ │ │ │ │ │ │ │ │ ├── JsonPretty.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── json-primitive/ │ │ │ │ │ │ │ ├── JsonPrimitive.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── interfaces.ts │ │ │ │ │ │ └── utils.ts │ │ │ │ │ └── table-view/ │ │ │ │ │ ├── TableView.spec.tsx │ │ │ │ │ ├── TableView.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── global.d.ts │ │ │ │ ├── icons/ │ │ │ │ │ ├── arrow_down.jsx │ │ │ │ │ ├── arrow_left.jsx │ │ │ │ │ ├── arrow_right.jsx │ │ │ │ │ ├── check.js │ │ │ │ │ ├── copy.js │ │ │ │ │ ├── cross.js │ │ │ │ │ └── empty.js │ │ │ │ ├── main.tsx │ │ │ │ ├── result.json │ │ │ │ ├── styles/ │ │ │ │ │ └── styles.scss │ │ │ │ └── utils/ │ │ │ │ ├── cachedIcons.ts │ │ │ │ ├── index.ts │ │ │ │ └── parseResponse.ts │ │ │ ├── common/ │ │ │ │ └── package.json │ │ │ ├── package.json │ │ │ ├── redisearch/ │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── GroupBadge/ │ │ │ │ │ │ ├── GroupBadge.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── TableInfoResult/ │ │ │ │ │ │ ├── TableInfoResult.spec.tsx │ │ │ │ │ │ ├── TableInfoResult.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── TableResult/ │ │ │ │ │ │ ├── TableResult.spec.tsx │ │ │ │ │ │ ├── TableResult.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── constants/ │ │ │ │ │ ├── constants.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── global.d.ts │ │ │ │ ├── main.tsx │ │ │ │ ├── result.json │ │ │ │ ├── result2.json │ │ │ │ ├── result3.json │ │ │ │ ├── resultInfo.json │ │ │ │ ├── result_aggregate_array.json │ │ │ │ ├── styles/ │ │ │ │ │ └── styles.scss │ │ │ │ └── utils/ │ │ │ │ ├── formatLongName.ts │ │ │ │ ├── index.ts │ │ │ │ ├── parseResponse.ts │ │ │ │ ├── replaceSpaces.ts │ │ │ │ └── tests/ │ │ │ │ ├── formatLongName.spec.ts │ │ │ │ └── parseResponse.spec.ts │ │ │ ├── redisgraph/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ ├── src/ │ │ │ │ │ ├── App.tsx │ │ │ │ │ ├── Graph.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── global.d.ts │ │ │ │ │ ├── graphd3.ts │ │ │ │ │ ├── main.tsx │ │ │ │ │ ├── mockData/ │ │ │ │ │ │ └── resultGraph.json │ │ │ │ │ ├── parser.ts │ │ │ │ │ ├── result.ts │ │ │ │ │ ├── styles/ │ │ │ │ │ │ └── styles.scss │ │ │ │ │ └── utils.ts │ │ │ │ └── types/ │ │ │ │ └── @elastic/ │ │ │ │ └── index.d.ts │ │ │ ├── redisinsight-plugin-sdk/ │ │ │ │ ├── .gitignore │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── events.js │ │ │ │ ├── helpers.js │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ │ ├── redistimeseries-app/ │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── global.d.ts │ │ │ │ ├── index.html │ │ │ │ ├── jest.config.js │ │ │ │ ├── mockData/ │ │ │ │ │ └── resultTimeSeries.json │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── App.tsx │ │ │ │ ├── components/ │ │ │ │ │ └── Chart/ │ │ │ │ │ ├── Chart.tsx │ │ │ │ │ ├── ChartConfigForm.tsx │ │ │ │ │ ├── ChartResultView.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── interfaces.ts │ │ │ │ │ ├── utils.test.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── main.tsx │ │ │ │ ├── response.ts │ │ │ │ └── styles/ │ │ │ │ └── styles.scss │ │ │ ├── ri-explain/ │ │ │ │ ├── README.md │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ ├── src/ │ │ │ │ │ ├── App.tsx │ │ │ │ │ ├── Explain.tsx │ │ │ │ │ ├── Node.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── global.d.ts │ │ │ │ │ ├── main.tsx │ │ │ │ │ ├── parser.ts │ │ │ │ │ └── styles/ │ │ │ │ │ ├── _dark_theme.less │ │ │ │ │ ├── _light_theme.less │ │ │ │ │ └── styles.scss │ │ │ │ └── test-data/ │ │ │ │ ├── result-explain-pd.json │ │ │ │ ├── result-explain.json │ │ │ │ ├── result-profile_r7--aggregate.json │ │ │ │ ├── result-profile_r7.json │ │ │ │ └── result-profile_r8.json │ │ │ └── vite.config.mjs │ │ ├── pages/ │ │ │ ├── analytics/ │ │ │ │ ├── AnalyticsPage.spec.tsx │ │ │ │ ├── AnalyticsPage.tsx │ │ │ │ ├── AnalyticsPageRouter.spec.tsx │ │ │ │ ├── AnalyticsPageRouter.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── autodiscover-azure/ │ │ │ │ ├── azure/ │ │ │ │ │ ├── AzurePage.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── azure-databases/ │ │ │ │ │ ├── AzureDatabases/ │ │ │ │ │ │ ├── AzureDatabases.constants.tsx │ │ │ │ │ │ ├── AzureDatabases.spec.tsx │ │ │ │ │ │ ├── AzureDatabases.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── AzureDatabasesPage.spec.tsx │ │ │ │ │ ├── AzureDatabasesPage.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── azure-subscriptions/ │ │ │ │ │ ├── AzureSubscriptions/ │ │ │ │ │ │ ├── AzureSubscriptions.constants.tsx │ │ │ │ │ │ ├── AzureSubscriptions.spec.tsx │ │ │ │ │ │ ├── AzureSubscriptions.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── AzureSubscriptionsPage.spec.tsx │ │ │ │ │ ├── AzureSubscriptionsPage.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── DescriptionsTooltip.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── constants.ts │ │ │ │ └── index.ts │ │ │ ├── autodiscover-cloud/ │ │ │ │ ├── column-definitions/ │ │ │ │ │ ├── columns/ │ │ │ │ │ │ ├── alert.tsx │ │ │ │ │ │ ├── database.tsx │ │ │ │ │ │ ├── databaseResult.tsx │ │ │ │ │ │ ├── endpoint.tsx │ │ │ │ │ │ ├── endpointResult.tsx │ │ │ │ │ │ ├── id.tsx │ │ │ │ │ │ ├── messageResult.tsx │ │ │ │ │ │ ├── modules.tsx │ │ │ │ │ │ ├── modulesResult.tsx │ │ │ │ │ │ ├── numberOfDbs.tsx │ │ │ │ │ │ ├── options.tsx │ │ │ │ │ │ ├── optionsResult.tsx │ │ │ │ │ │ ├── provider.tsx │ │ │ │ │ │ ├── region.tsx │ │ │ │ │ │ ├── selection.ts │ │ │ │ │ │ ├── status.tsx │ │ │ │ │ │ ├── statusDb.tsx │ │ │ │ │ │ ├── statusDbResult.tsx │ │ │ │ │ │ ├── subscription.tsx │ │ │ │ │ │ ├── subscriptionDb.tsx │ │ │ │ │ │ ├── subscriptionDbResult.tsx │ │ │ │ │ │ ├── subscriptionId.tsx │ │ │ │ │ │ ├── subscriptionIdResult.tsx │ │ │ │ │ │ ├── subscriptionType.tsx │ │ │ │ │ │ ├── subscriptionTypeResult.tsx │ │ │ │ │ │ └── type.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── AlertCell/ │ │ │ │ │ │ │ ├── AlertCell.spec.tsx │ │ │ │ │ │ │ ├── AlertCell.tsx │ │ │ │ │ │ │ └── AlertCell.types.ts │ │ │ │ │ │ ├── DatabaseCell/ │ │ │ │ │ │ │ ├── DatabaseCell.spec.tsx │ │ │ │ │ │ │ ├── DatabaseCell.tsx │ │ │ │ │ │ │ └── DatabaseCell.types.ts │ │ │ │ │ │ ├── EndpointCell/ │ │ │ │ │ │ │ ├── EndpointCell.spec.tsx │ │ │ │ │ │ │ ├── EndpointCell.tsx │ │ │ │ │ │ │ └── EndpointCell.types.ts │ │ │ │ │ │ ├── MessageResultCell/ │ │ │ │ │ │ │ ├── MessageResultCell.spec.tsx │ │ │ │ │ │ │ ├── MessageResultCell.tsx │ │ │ │ │ │ │ └── MessageResultCell.types.ts │ │ │ │ │ │ ├── SubscriptionCell/ │ │ │ │ │ │ │ ├── SubscriptionCell.spec.tsx │ │ │ │ │ │ │ ├── SubscriptionCell.tsx │ │ │ │ │ │ │ └── SubscriptionCell.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── components/ │ │ │ │ │ └── AlertStatusContent.tsx │ │ │ │ ├── constants/ │ │ │ │ │ └── constants.ts │ │ │ │ ├── index.ts │ │ │ │ ├── redis-cloud/ │ │ │ │ │ ├── RedisCloudPage.spec.tsx │ │ │ │ │ ├── RedisCloudPage.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── redis-cloud-databases/ │ │ │ │ │ ├── RedisCloudDatabases/ │ │ │ │ │ │ ├── RedisCloudDatabases.spec.tsx │ │ │ │ │ │ ├── RedisCloudDatabases.stories.tsx │ │ │ │ │ │ ├── RedisCloudDatabases.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── RedisCloudDatabasesPage.spec.tsx │ │ │ │ │ ├── RedisCloudDatabasesPage.tsx │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ ├── useCloudDatabasesConfig.test.ts │ │ │ │ │ │ ├── useCloudDatabasesConfig.ts │ │ │ │ │ │ └── useCloudDatabasesConfig.types.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ └── utils/ │ │ │ │ │ ├── colFactory.spec.ts │ │ │ │ │ └── colFactory.ts │ │ │ │ ├── redis-cloud-databases-result/ │ │ │ │ │ ├── RedisCloudDatabasesResult.spec.tsx │ │ │ │ │ ├── RedisCloudDatabasesResult.stories.tsx │ │ │ │ │ ├── RedisCloudDatabasesResult.tsx │ │ │ │ │ ├── RedisCloudDatabasesResultPage.spec.tsx │ │ │ │ │ ├── RedisCloudDatabasesResultPage.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── SummaryText/ │ │ │ │ │ │ │ ├── SummaryText.tsx │ │ │ │ │ │ │ └── SummaryText.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ ├── useCloudDatabasesResultConfig.ts │ │ │ │ │ │ └── useCloudDatabasesResultConfig.types.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ └── utils/ │ │ │ │ │ ├── colFactory.spec.ts │ │ │ │ │ └── colFactory.ts │ │ │ │ ├── redis-cloud-subscriptions/ │ │ │ │ │ ├── RedisCloudSubscriptions/ │ │ │ │ │ │ ├── RedisCloudSubscriptions.spec.tsx │ │ │ │ │ │ ├── RedisCloudSubscriptions.stories.tsx │ │ │ │ │ │ ├── RedisCloudSubscriptions.styles.ts │ │ │ │ │ │ └── RedisCloudSubscriptions.tsx │ │ │ │ │ ├── RedisCloudSubscriptionsPage.spec.tsx │ │ │ │ │ ├── RedisCloudSubscriptionsPage.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── Account/ │ │ │ │ │ │ │ ├── Account.style.ts │ │ │ │ │ │ │ ├── Account.tsx │ │ │ │ │ │ │ └── Account.types.ts │ │ │ │ │ │ ├── CancelButton/ │ │ │ │ │ │ │ ├── CancelButton.tsx │ │ │ │ │ │ │ └── CancelButton.types.ts │ │ │ │ │ │ ├── SubmitButton/ │ │ │ │ │ │ │ ├── SubmitButton.tsx │ │ │ │ │ │ │ └── SubmitButton.types.ts │ │ │ │ │ │ ├── SummaryText/ │ │ │ │ │ │ │ ├── SummaryText.tsx │ │ │ │ │ │ │ └── SummaryText.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ ├── useCloudSubscriptionConfig.test.ts │ │ │ │ │ │ ├── useCloudSubscriptionConfig.ts │ │ │ │ │ │ └── useCloudSubscriptionConfig.types.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ └── utils/ │ │ │ │ │ ├── canSelectRow.test.ts │ │ │ │ │ ├── canSelectRow.ts │ │ │ │ │ ├── colFactory.spec.ts │ │ │ │ │ └── colFactory.ts │ │ │ │ └── utils.tsx │ │ │ ├── autodiscover-sentinel/ │ │ │ │ ├── constants/ │ │ │ │ │ └── constants.ts │ │ │ │ ├── index.ts │ │ │ │ ├── sentinel/ │ │ │ │ │ ├── SentinelPage.spec.tsx │ │ │ │ │ ├── SentinelPage.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── sentinel-databases/ │ │ │ │ │ ├── SentinelDatabasesPage.spec.tsx │ │ │ │ │ ├── SentinelDatabasesPage.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── SentinelDatabases/ │ │ │ │ │ │ │ ├── SentinelDatabases.spec.tsx │ │ │ │ │ │ │ ├── SentinelDatabases.stories.tsx │ │ │ │ │ │ │ ├── SentinelDatabases.tsx │ │ │ │ │ │ │ └── components/ │ │ │ │ │ │ │ ├── CancelButton/ │ │ │ │ │ │ │ │ ├── CancelButton.tsx │ │ │ │ │ │ │ │ ├── CancelButton.types.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── NoMastersMessage/ │ │ │ │ │ │ │ │ ├── NoMastersMessage.tsx │ │ │ │ │ │ │ │ └── NoMastersMessage.types.ts │ │ │ │ │ │ │ ├── SubmitButton/ │ │ │ │ │ │ │ │ ├── SubmitButton.tsx │ │ │ │ │ │ │ │ └── SubmitButton.types.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── column-definitions/ │ │ │ │ │ │ │ ├── columns/ │ │ │ │ │ │ │ │ ├── address.tsx │ │ │ │ │ │ │ │ ├── alias.tsx │ │ │ │ │ │ │ │ ├── dbIndex.tsx │ │ │ │ │ │ │ │ ├── numberOfReplicas.ts │ │ │ │ │ │ │ │ ├── password.tsx │ │ │ │ │ │ │ │ ├── primaryGroup.tsx │ │ │ │ │ │ │ │ ├── selection.ts │ │ │ │ │ │ │ │ └── username.tsx │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── AddressCell/ │ │ │ │ │ │ │ │ │ ├── AddressCell.tsx │ │ │ │ │ │ │ │ │ └── AddressCell.types.ts │ │ │ │ │ │ │ │ ├── AliasCell/ │ │ │ │ │ │ │ │ │ ├── AliasCell.tsx │ │ │ │ │ │ │ │ │ └── AliasCell.types.ts │ │ │ │ │ │ │ │ ├── DbIndexCell/ │ │ │ │ │ │ │ │ │ ├── DbIndexCell.tsx │ │ │ │ │ │ │ │ │ └── DbIndexCell.types.ts │ │ │ │ │ │ │ │ ├── PasswordCell/ │ │ │ │ │ │ │ │ │ ├── PasswordCell.tsx │ │ │ │ │ │ │ │ │ └── PasswordCell.types.ts │ │ │ │ │ │ │ │ ├── PrimaryGroupCell/ │ │ │ │ │ │ │ │ │ ├── PrimaryGroupCell.tsx │ │ │ │ │ │ │ │ │ └── PrimaryGroupCell.types.ts │ │ │ │ │ │ │ │ ├── UsernameCell/ │ │ │ │ │ │ │ │ │ ├── UsernameCell.tsx │ │ │ │ │ │ │ │ │ └── UsernameCell.types.ts │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── useSentinelDatabasesConfig.tsx │ │ │ │ ├── sentinel-databases-result/ │ │ │ │ │ ├── SentinelDatabasesResultPage.spec.tsx │ │ │ │ │ ├── SentinelDatabasesResultPage.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── SentinelDatabasesResult/ │ │ │ │ │ │ │ ├── SentinelDatabasesResult.spec.tsx │ │ │ │ │ │ │ ├── SentinelDatabasesResult.stories.tsx │ │ │ │ │ │ │ ├── SentinelDatabasesResult.tsx │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── Summary.tsx │ │ │ │ │ │ │ │ └── SummaryTextProps.types.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── column-definitions/ │ │ │ │ │ │ │ ├── columns/ │ │ │ │ │ │ │ │ ├── address.tsx │ │ │ │ │ │ │ │ ├── alias.tsx │ │ │ │ │ │ │ │ ├── db.tsx │ │ │ │ │ │ │ │ ├── numberOfReplicas.ts │ │ │ │ │ │ │ │ ├── password.tsx │ │ │ │ │ │ │ │ ├── primaryGroup.tsx │ │ │ │ │ │ │ │ ├── result.tsx │ │ │ │ │ │ │ │ └── username.tsx │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── AddErrorButton/ │ │ │ │ │ │ │ │ │ ├── AddErrorButton.tsx │ │ │ │ │ │ │ │ │ └── AddErrorButton.types.ts │ │ │ │ │ │ │ │ ├── AddressCell/ │ │ │ │ │ │ │ │ │ ├── AddressCell.tsx │ │ │ │ │ │ │ │ │ └── AddressCell.types.ts │ │ │ │ │ │ │ │ ├── AliasCell/ │ │ │ │ │ │ │ │ │ ├── AliasCell.tsx │ │ │ │ │ │ │ │ │ └── AliasCell.types.ts │ │ │ │ │ │ │ │ ├── DbCell/ │ │ │ │ │ │ │ │ │ ├── DbCell.tsx │ │ │ │ │ │ │ │ │ └── DbCell.types.ts │ │ │ │ │ │ │ │ ├── PasswordCell/ │ │ │ │ │ │ │ │ │ ├── PasswordCell.tsx │ │ │ │ │ │ │ │ │ └── PasswordCell.types.ts │ │ │ │ │ │ │ │ ├── PrimaryGroupCell/ │ │ │ │ │ │ │ │ │ ├── PrimaryGroupCell.tsx │ │ │ │ │ │ │ │ │ └── PrimaryGroupCell.types.ts │ │ │ │ │ │ │ │ ├── ResultCell/ │ │ │ │ │ │ │ │ │ ├── ResultCell.tsx │ │ │ │ │ │ │ │ │ └── ResultCell.types.ts │ │ │ │ │ │ │ │ ├── UsernameCell/ │ │ │ │ │ │ │ │ │ ├── UsernameCell.tsx │ │ │ │ │ │ │ │ │ └── UsernameCell.types.ts │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── useSentinelDatabasesResultConfig.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── browser/ │ │ │ │ ├── BrowserPage.spec.tsx │ │ │ │ ├── BrowserPage.styles.ts │ │ │ │ ├── BrowserPage.test.tsx │ │ │ │ ├── BrowserPage.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── action-footer/ │ │ │ │ │ │ ├── ActionFooter.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── actions/ │ │ │ │ │ │ ├── Actions.spec.tsx │ │ │ │ │ │ └── Actions.tsx │ │ │ │ │ ├── add-key/ │ │ │ │ │ │ ├── AddKey.spec.tsx │ │ │ │ │ │ ├── AddKey.styles.ts │ │ │ │ │ │ ├── AddKey.tsx │ │ │ │ │ │ ├── AddKeyCommonFields/ │ │ │ │ │ │ │ ├── AddKeyCommonFields.spec.tsx │ │ │ │ │ │ │ ├── AddKeyCommonFields.tsx │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── AddKeyFooter/ │ │ │ │ │ │ │ ├── AddKeyFooter.spec.tsx │ │ │ │ │ │ │ └── AddKeyFooter.tsx │ │ │ │ │ │ ├── AddKeyHash/ │ │ │ │ │ │ │ ├── AddKeyHash.spec.tsx │ │ │ │ │ │ │ ├── AddKeyHash.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── interfaces.ts │ │ │ │ │ │ ├── AddKeyList/ │ │ │ │ │ │ │ ├── AddKeyList.spec.tsx │ │ │ │ │ │ │ ├── AddKeyList.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── AddKeyReJSON/ │ │ │ │ │ │ │ ├── AddKeyReJSON.spec.tsx │ │ │ │ │ │ │ ├── AddKeyReJSON.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── AddKeySet/ │ │ │ │ │ │ │ ├── AddKeySet.spec.tsx │ │ │ │ │ │ │ ├── AddKeySet.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── interfaces.ts │ │ │ │ │ │ ├── AddKeyStream/ │ │ │ │ │ │ │ ├── AddKeyStream.spec.tsx │ │ │ │ │ │ │ ├── AddKeyStream.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── AddKeyString/ │ │ │ │ │ │ │ ├── AddKeyString.spec.tsx │ │ │ │ │ │ │ ├── AddKeyString.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── AddKeyZset/ │ │ │ │ │ │ │ ├── AddKeyZset.spec.tsx │ │ │ │ │ │ │ ├── AddKeyZset.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── interfaces.ts │ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ │ ├── fields-config.ts │ │ │ │ │ │ │ └── key-type-options.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── add-multiple-fields/ │ │ │ │ │ │ ├── AddMultipleFields.spec.tsx │ │ │ │ │ │ ├── AddMultipleFields.styles.ts │ │ │ │ │ │ ├── AddMultipleFields.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── browser-left-panel/ │ │ │ │ │ │ ├── BrowserLeftPanel.tsx │ │ │ │ │ │ ├── BrowserLeftPanelLegacy.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── browser-right-panel/ │ │ │ │ │ │ ├── BrowserRightPanel.spec.tsx │ │ │ │ │ │ ├── BrowserRightPanel.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── browser-search-panel/ │ │ │ │ │ │ ├── BrowserSearchPanel.spec.tsx │ │ │ │ │ │ ├── BrowserSearchPanel.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── bulk-actions/ │ │ │ │ │ │ ├── BulkActionSummary/ │ │ │ │ │ │ │ ├── BulkActionSummary.spec.tsx │ │ │ │ │ │ │ ├── BulkActionSummary.styles.ts │ │ │ │ │ │ │ ├── BulkActionSummary.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── BulkActions.spec.tsx │ │ │ │ │ │ ├── BulkActions.styles.ts │ │ │ │ │ │ ├── BulkActions.tsx │ │ │ │ │ │ ├── BulkActionsInfo/ │ │ │ │ │ │ │ ├── BulkActionsInfo.spec.tsx │ │ │ │ │ │ │ ├── BulkActionsInfo.styles.tsx │ │ │ │ │ │ │ ├── BulkActionsInfo.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── BulkActionsStatusDisplay/ │ │ │ │ │ │ │ ├── BulkActionsStatusDisplay.spec.tsx │ │ │ │ │ │ │ ├── BulkActionsStatusDisplay.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── BulkActionsTabs/ │ │ │ │ │ │ │ ├── BulkActionsTabs.spec.tsx │ │ │ │ │ │ │ ├── BulkActionsTabs.styles.ts │ │ │ │ │ │ │ ├── BulkActionsTabs.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── BulkDelete/ │ │ │ │ │ │ │ ├── BulkDelete.tsx │ │ │ │ │ │ │ ├── BulkDeleteContent/ │ │ │ │ │ │ │ │ ├── BulkDeleteContent.spec.tsx │ │ │ │ │ │ │ │ ├── BulkDeleteContent.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── BulkDeleteFooter/ │ │ │ │ │ │ │ │ ├── BulkDeleteFooter.spec.tsx │ │ │ │ │ │ │ │ ├── BulkDeleteFooter.styles.ts │ │ │ │ │ │ │ │ ├── BulkDeleteFooter.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── BulkDeleteSummary/ │ │ │ │ │ │ │ │ ├── BulkDeleteSummary.spec.tsx │ │ │ │ │ │ │ │ ├── BulkDeleteSummary.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── BulkUpload/ │ │ │ │ │ │ │ ├── BulkUpload.spec.tsx │ │ │ │ │ │ │ ├── BulkUpload.styles.ts │ │ │ │ │ │ │ ├── BulkUpload.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── constants/ │ │ │ │ │ │ │ └── bulk-type-options.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ │ └── utils.ts │ │ │ │ │ ├── create-redisearch-index/ │ │ │ │ │ │ └── constants.ts │ │ │ │ │ ├── delete-key-popover/ │ │ │ │ │ │ ├── DeleteKeyPopover.spec.tsx │ │ │ │ │ │ └── DeleteKeyPopover.tsx │ │ │ │ │ ├── filter-key-type/ │ │ │ │ │ │ ├── FilterKeyType.spec.tsx │ │ │ │ │ │ ├── FilterKeyType.tsx │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── key-list/ │ │ │ │ │ │ ├── KeyList.spec.tsx │ │ │ │ │ │ ├── KeyList.styles.ts │ │ │ │ │ │ ├── KeyList.tsx │ │ │ │ │ │ ├── KeyList.types.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── key-row-name/ │ │ │ │ │ │ ├── KeyRowName.spec.tsx │ │ │ │ │ │ ├── KeyRowName.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── key-row-size/ │ │ │ │ │ │ ├── KeyRowSize.spec.tsx │ │ │ │ │ │ ├── KeyRowSize.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── key-row-ttl/ │ │ │ │ │ │ ├── KeyRowTTL.spec.tsx │ │ │ │ │ │ ├── KeyRowTTL.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── key-row-type/ │ │ │ │ │ │ ├── KeyRowType.spec.tsx │ │ │ │ │ │ ├── KeyRowType.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── key-tree/ │ │ │ │ │ │ ├── KeyTree.spec.tsx │ │ │ │ │ │ ├── KeyTree.tsx │ │ │ │ │ │ ├── KeyTree.types.ts │ │ │ │ │ │ ├── KeyTreeSettings/ │ │ │ │ │ │ │ ├── KeyTreeSettings.spec.tsx │ │ │ │ │ │ │ ├── KeyTreeSettings.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── keys-browser-panel/ │ │ │ │ │ │ ├── KeysBrowserPanel.styles.ts │ │ │ │ │ │ ├── KeysBrowserPanel.tsx │ │ │ │ │ │ ├── KeysBrowserPanel.types.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── Content.tsx │ │ │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ │ │ └── Header.tsx │ │ │ │ │ │ ├── contexts/ │ │ │ │ │ │ │ └── Context.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── keys-header/ │ │ │ │ │ │ ├── KeysHeader.spec.tsx │ │ │ │ │ │ ├── KeysHeader.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── load-sample-data/ │ │ │ │ │ │ ├── LoadSampleData.spec.tsx │ │ │ │ │ │ ├── LoadSampleData.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── make-searchable-button/ │ │ │ │ │ │ ├── MakeSearchableButton.spec.tsx │ │ │ │ │ │ ├── MakeSearchableButton.tsx │ │ │ │ │ │ ├── MakeSearchableButton.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── make-searchable-modal/ │ │ │ │ │ │ ├── MakeSearchableModal.spec.tsx │ │ │ │ │ │ ├── MakeSearchableModal.stories.tsx │ │ │ │ │ │ ├── MakeSearchableModal.styles.ts │ │ │ │ │ │ ├── MakeSearchableModal.tsx │ │ │ │ │ │ ├── MakeSearchableModal.types.ts │ │ │ │ │ │ ├── MakeSearchableModalProvider.spec.tsx │ │ │ │ │ │ ├── MakeSearchableModalProvider.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── no-keys-found/ │ │ │ │ │ │ ├── NoKeysFound.spec.tsx │ │ │ │ │ │ ├── NoKeysFound.styles.ts │ │ │ │ │ │ ├── NoKeysFound.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── no-keys-message/ │ │ │ │ │ │ ├── NoKeysMessage.spec.tsx │ │ │ │ │ │ ├── NoKeysMessage.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── onboarding-start-popover/ │ │ │ │ │ │ ├── OnboardingStartPopover.spec.tsx │ │ │ │ │ │ ├── OnboardingStartPopover.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── popover-delete/ │ │ │ │ │ │ ├── PopoverDelete.spec.tsx │ │ │ │ │ │ ├── PopoverDelete.tsx │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── redisearch-key-list/ │ │ │ │ │ │ ├── RediSearchIndexesList.spec.tsx │ │ │ │ │ │ ├── RediSearchIndexesList.styles.ts │ │ │ │ │ │ ├── RediSearchIndexesList.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── search-key-list/ │ │ │ │ │ │ ├── SearchKeyList.spec.tsx │ │ │ │ │ │ ├── SearchKeyList.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── use-key-format/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useKeyFormat.spec.tsx │ │ │ │ │ │ └── useKeyFormat.ts │ │ │ │ │ ├── view-index-data-button/ │ │ │ │ │ │ ├── ViewIndexDataButton.spec.tsx │ │ │ │ │ │ ├── ViewIndexDataButton.stories.tsx │ │ │ │ │ │ ├── ViewIndexDataButton.styles.ts │ │ │ │ │ │ ├── ViewIndexDataButton.tsx │ │ │ │ │ │ ├── ViewIndexDataButton.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── virtual-tree/ │ │ │ │ │ ├── VirtualTree.spec.tsx │ │ │ │ │ ├── VirtualTree.tsx │ │ │ │ │ ├── VirtualTree.types.ts │ │ │ │ │ ├── components/ │ │ │ │ │ │ └── Node/ │ │ │ │ │ │ ├── Node.spec.tsx │ │ │ │ │ │ ├── Node.styles.ts │ │ │ │ │ │ ├── Node.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── index.ts │ │ │ │ ├── modules/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── key-details/ │ │ │ │ │ │ ├── KeyDetails.spec.tsx │ │ │ │ │ │ ├── KeyDetails.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── change-editor-type-button/ │ │ │ │ │ │ │ │ ├── ChangeEditorTypeButton.spec.tsx │ │ │ │ │ │ │ │ ├── ChangeEditorTypeButton.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── useChangeEditorType.spec.ts │ │ │ │ │ │ │ │ └── useChangeEditorType.tsx │ │ │ │ │ │ │ ├── common/ │ │ │ │ │ │ │ │ └── AddKeysContainer.styled.ts │ │ │ │ │ │ │ ├── dynamic-type-details/ │ │ │ │ │ │ │ │ ├── DynamicTypeDetails.spec.tsx │ │ │ │ │ │ │ │ ├── DynamicTypeDetails.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── hash-details/ │ │ │ │ │ │ │ │ ├── HashDetails.spec.tsx │ │ │ │ │ │ │ │ ├── HashDetails.tsx │ │ │ │ │ │ │ │ ├── add-hash-fields/ │ │ │ │ │ │ │ │ │ ├── AddHashFields.spec.tsx │ │ │ │ │ │ │ │ │ └── AddHashFields.tsx │ │ │ │ │ │ │ │ ├── hash-details-table/ │ │ │ │ │ │ │ │ │ ├── HashDetailsTable.spec.tsx │ │ │ │ │ │ │ │ │ ├── HashDetailsTable.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── key-details-actions/ │ │ │ │ │ │ │ │ ├── add-items-action/ │ │ │ │ │ │ │ │ │ ├── AddItemsAction.spec.tsx │ │ │ │ │ │ │ │ │ └── AddItemsAction.tsx │ │ │ │ │ │ │ │ ├── edit-item-action/ │ │ │ │ │ │ │ │ │ ├── EditItemAction.spec.tsx │ │ │ │ │ │ │ │ │ └── EditItemAction.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── remove-items-action/ │ │ │ │ │ │ │ │ │ ├── RemoveItemsAction.spec.tsx │ │ │ │ │ │ │ │ │ └── RemoveItemsAction.tsx │ │ │ │ │ │ │ │ ├── stream-items-action/ │ │ │ │ │ │ │ │ │ ├── StreamItemsAction.spec.tsx │ │ │ │ │ │ │ │ │ └── StreamItemsAction.tsx │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── key-details-subheader/ │ │ │ │ │ │ │ │ ├── KeyDetailsSubheader.spec.tsx │ │ │ │ │ │ │ │ ├── KeyDetailsSubheader.tsx │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── list-details/ │ │ │ │ │ │ │ │ ├── ListDetails.spec.tsx │ │ │ │ │ │ │ │ ├── ListDetails.tsx │ │ │ │ │ │ │ │ ├── add-list-elements/ │ │ │ │ │ │ │ │ │ ├── AddListElements.spec.tsx │ │ │ │ │ │ │ │ │ └── AddListElements.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── list-details-table/ │ │ │ │ │ │ │ │ │ ├── ListDetailsTable.spec.tsx │ │ │ │ │ │ │ │ │ ├── ListDetailsTable.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── remove-list-elements/ │ │ │ │ │ │ │ │ │ ├── RemoveListElements.spec.tsx │ │ │ │ │ │ │ │ │ ├── RemoveListElements.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── modules-type-details/ │ │ │ │ │ │ │ │ ├── ModulesTypeDetails.spec.tsx │ │ │ │ │ │ │ │ ├── ModulesTypeDetails.tsx │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── no-key-selected/ │ │ │ │ │ │ │ │ ├── NoKeySelected.spec.tsx │ │ │ │ │ │ │ │ ├── NoKeySelected.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── rejson-details/ │ │ │ │ │ │ │ │ ├── RejsonDetailsWrapper.spec.tsx │ │ │ │ │ │ │ │ ├── RejsonDetailsWrapper.tsx │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── add-item/ │ │ │ │ │ │ │ │ │ │ ├── AddItem.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── AddItem.tsx │ │ │ │ │ │ │ │ │ │ ├── ConfirmOverwrite.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ ├── add-item-field-action/ │ │ │ │ │ │ │ │ │ │ ├── AddItemFieldAction.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── AddItemFieldAction.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ ├── edit-entire-item-action/ │ │ │ │ │ │ │ │ │ │ ├── EditEntireItemAction.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── EditEntireItemAction.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ ├── edit-item-field-action/ │ │ │ │ │ │ │ │ │ │ ├── EditItemFieldAction.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── EditItemFieldAction.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── interfaces.ts │ │ │ │ │ │ │ │ ├── monaco-editor/ │ │ │ │ │ │ │ │ │ ├── MonacoEditor.spec.tsx │ │ │ │ │ │ │ │ │ ├── MonacoEditor.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── rejson-details/ │ │ │ │ │ │ │ │ │ ├── RejsonDetails.spec.tsx │ │ │ │ │ │ │ │ │ ├── RejsonDetails.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── rejson-dynamic-types/ │ │ │ │ │ │ │ │ │ ├── RejsonDynamicTypes.spec.tsx │ │ │ │ │ │ │ │ │ ├── RejsonDynamicTypes.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── rejson-object/ │ │ │ │ │ │ │ │ │ ├── RejsonObject.spec.tsx │ │ │ │ │ │ │ │ │ ├── RejsonObject.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── rejson-scalar/ │ │ │ │ │ │ │ │ │ ├── RejsonScalar.spec.tsx │ │ │ │ │ │ │ │ │ ├── RejsonScalar.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ │ │ │ ├── styles.scss │ │ │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── utils.spec.ts │ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ │ ├── set-details/ │ │ │ │ │ │ │ │ ├── SetDetails.spec.tsx │ │ │ │ │ │ │ │ ├── SetDetails.tsx │ │ │ │ │ │ │ │ ├── add-set-members/ │ │ │ │ │ │ │ │ │ ├── AddSetMembers.spec.tsx │ │ │ │ │ │ │ │ │ ├── AddSetMembers.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── set-details-table/ │ │ │ │ │ │ │ │ ├── SetDetailsTable.spec.tsx │ │ │ │ │ │ │ │ ├── SetDetailsTable.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── stream-details/ │ │ │ │ │ │ │ │ ├── StreamDetails.spec.tsx │ │ │ │ │ │ │ │ ├── StreamDetails.tsx │ │ │ │ │ │ │ │ ├── add-stream-entity/ │ │ │ │ │ │ │ │ │ ├── AddStreamEntries.spec.tsx │ │ │ │ │ │ │ │ │ ├── AddStreamEntries.styles.ts │ │ │ │ │ │ │ │ │ ├── AddStreamEntries.tsx │ │ │ │ │ │ │ │ │ ├── StreamEntryFields/ │ │ │ │ │ │ │ │ │ │ ├── StreamEntryFields.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── StreamEntryFields.styles.ts │ │ │ │ │ │ │ │ │ │ └── StreamEntryFields.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── add-stream-group/ │ │ │ │ │ │ │ │ │ ├── AddStreamGroup.spec.tsx │ │ │ │ │ │ │ │ │ ├── AddStreamGroup.styles.ts │ │ │ │ │ │ │ │ │ ├── AddStreamGroup.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ │ │ ├── consumers-view/ │ │ │ │ │ │ │ │ │ ├── ConsumersView/ │ │ │ │ │ │ │ │ │ │ ├── ConsumersView.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── ConsumersView.tsx │ │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ │ ├── ConsumersViewWrapper.spec.tsx │ │ │ │ │ │ │ │ │ ├── ConsumersViewWrapper.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── groups-view/ │ │ │ │ │ │ │ │ │ ├── GroupsView/ │ │ │ │ │ │ │ │ │ │ ├── GroupsView.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── GroupsView.tsx │ │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ │ ├── GroupsViewWrapper.spec.tsx │ │ │ │ │ │ │ │ │ ├── GroupsViewWrapper.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── messages-view/ │ │ │ │ │ │ │ │ │ ├── MessageAckPopover/ │ │ │ │ │ │ │ │ │ │ ├── MessageAckPopover.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── MessageAckPopover.tsx │ │ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ │ │ ├── MessageClaimPopover/ │ │ │ │ │ │ │ │ │ │ ├── MessageClaimPopover.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── MessageClaimPopover.tsx │ │ │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ │ ├── MessagesView/ │ │ │ │ │ │ │ │ │ │ ├── MessagesView.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── MessagesView.tsx │ │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ │ ├── MessagesViewWrapper.spec.tsx │ │ │ │ │ │ │ │ │ ├── MessagesViewWrapper.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── stream-data-view/ │ │ │ │ │ │ │ │ │ ├── StreamDataView/ │ │ │ │ │ │ │ │ │ │ ├── StreamDataView.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── StreamDataView.tsx │ │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ │ ├── StreamDataViewWrapper.spec.tsx │ │ │ │ │ │ │ │ │ ├── StreamDataViewWrapper.tsx │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ ├── stream-details-body/ │ │ │ │ │ │ │ │ │ ├── StreamDetailsBody.spec.tsx │ │ │ │ │ │ │ │ │ ├── StreamDetailsBody.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ └── stream-tabs/ │ │ │ │ │ │ │ │ ├── StreamTabs.spec.tsx │ │ │ │ │ │ │ │ ├── StreamTabs.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── string-details/ │ │ │ │ │ │ │ │ ├── StringDetails.spec.tsx │ │ │ │ │ │ │ │ ├── StringDetails.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── string-details-value/ │ │ │ │ │ │ │ │ ├── StringDetailsValue.spec.tsx │ │ │ │ │ │ │ │ ├── StringDetailsValue.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── text-details-wrapper/ │ │ │ │ │ │ │ │ ├── TextDetailsWrapper.spec.tsx │ │ │ │ │ │ │ │ ├── TextDetailsWrapper.tsx │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── too-long-key-name-details/ │ │ │ │ │ │ │ │ ├── TooLongKeyNameDetails.spec.tsx │ │ │ │ │ │ │ │ └── TooLongKeyNameDetails.tsx │ │ │ │ │ │ │ ├── unsupported-type-details/ │ │ │ │ │ │ │ │ ├── UnsupportedTypeDetails.spec.tsx │ │ │ │ │ │ │ │ ├── UnsupportedTypeDetails.tsx │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ └── zset-details/ │ │ │ │ │ │ │ ├── ZSetDetails.spec.tsx │ │ │ │ │ │ │ ├── ZSetDetails.tsx │ │ │ │ │ │ │ ├── add-zset-members/ │ │ │ │ │ │ │ │ ├── AddZsetMembers.spec.tsx │ │ │ │ │ │ │ │ └── AddZsetMembers.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── zset-details-table/ │ │ │ │ │ │ │ ├── ZSetDetailsTable.spec.tsx │ │ │ │ │ │ │ ├── ZSetDetailsTable.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ │ ├── editable-input/ │ │ │ │ │ │ │ │ ├── EditableInput.spec.tsx │ │ │ │ │ │ │ │ ├── EditableInput.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── editable-popover/ │ │ │ │ │ │ │ │ ├── EditablePopover.spec.tsx │ │ │ │ │ │ │ │ ├── EditablePopover.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── editable-textarea/ │ │ │ │ │ │ │ │ ├── EditableTextArea.spec.tsx │ │ │ │ │ │ │ │ ├── EditableTextArea.tsx │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ ├── formatted-value/ │ │ │ │ │ │ │ │ ├── FormattedValue.spec.tsx │ │ │ │ │ │ │ │ ├── FormattedValue.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ └── key-details-header/ │ │ │ │ │ ├── KeyDetailsHeader.spec.tsx │ │ │ │ │ ├── KeyDetailsHeader.styles.ts │ │ │ │ │ ├── KeyDetailsHeader.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── key-details-header-delete/ │ │ │ │ │ │ │ ├── KeyDetailsHeaderDelete.spec.tsx │ │ │ │ │ │ │ ├── KeyDetailsHeaderDelete.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── key-details-header-formatter/ │ │ │ │ │ │ │ ├── KeyDetailsHeaderFormatter.spec.tsx │ │ │ │ │ │ │ ├── KeyDetailsHeaderFormatter.styles.tsx │ │ │ │ │ │ │ ├── KeyDetailsHeaderFormatter.tsx │ │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── key-details-header-name/ │ │ │ │ │ │ │ ├── KeyDetailsHeaderName.spec.tsx │ │ │ │ │ │ │ ├── KeyDetailsHeaderName.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── key-details-header-size-length/ │ │ │ │ │ │ │ ├── KeyDetailsHeaderSizeLength.spec.tsx │ │ │ │ │ │ │ ├── KeyDetailsHeaderSizeLength.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ └── key-details-header-ttl/ │ │ │ │ │ │ ├── KeyDetailsHeaderTTL.spec.tsx │ │ │ │ │ │ ├── KeyDetailsHeaderTTL.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── styles.module.scss │ │ │ ├── cluster-details/ │ │ │ │ ├── ClusterDetailsPage.spec.tsx │ │ │ │ ├── ClusterDetailsPage.styles.ts │ │ │ │ ├── ClusterDetailsPage.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── ClusterNodesTable/ │ │ │ │ │ │ ├── ClusterNodesTable.constants.ts │ │ │ │ │ │ ├── ClusterNodesTable.spec.tsx │ │ │ │ │ │ ├── ClusterNodesTable.tsx │ │ │ │ │ │ ├── ClusterNodesTable.types.ts │ │ │ │ │ │ └── components/ │ │ │ │ │ │ ├── ClusterNodesEmptyState/ │ │ │ │ │ │ │ ├── ClusterNodesEmptyState.styles.ts │ │ │ │ │ │ │ └── ClusterNodesEmptyState.tsx │ │ │ │ │ │ ├── ClusterNodesHostCell/ │ │ │ │ │ │ │ ├── ClusterNodesHostCell.styles.ts │ │ │ │ │ │ │ └── ClusterNodesHostCell.tsx │ │ │ │ │ │ └── ClusterNodesNumericCell/ │ │ │ │ │ │ ├── ClusterNodesNumericCell.spec.tsx │ │ │ │ │ │ ├── ClusterNodesNumericCell.tsx │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ ├── formatters.ts │ │ │ │ │ │ ├── isMaxColumnFieldValue.spec.ts │ │ │ │ │ │ └── isMaxColumnFieldValue.ts │ │ │ │ │ ├── cluster-details-graphics/ │ │ │ │ │ │ ├── ClusterDetailsGraphics.spec.tsx │ │ │ │ │ │ ├── ClusterDetailsGraphics.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── cluster-details-header/ │ │ │ │ │ │ ├── ClusterDetailsHeader.spec.tsx │ │ │ │ │ │ ├── ClusterDetailsHeader.styles.ts │ │ │ │ │ │ ├── ClusterDetailsHeader.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── database-analysis/ │ │ │ │ ├── DatabaseAnalysisPage.spec.tsx │ │ │ │ ├── DatabaseAnalysisPage.tsx │ │ │ │ ├── DatabaseAnalysisPageView.stories.tsx │ │ │ │ ├── DatabaseAnalysisPageView.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── analysis-data-view/ │ │ │ │ │ │ ├── AnalysisDataView.spec.tsx │ │ │ │ │ │ ├── AnalysisDataView.styles.ts │ │ │ │ │ │ ├── AnalysisDataView.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── analysis-page-container/ │ │ │ │ │ │ ├── AnalysisPageContainer.styles.ts │ │ │ │ │ │ ├── AnalysisPageContainer.tsx │ │ │ │ │ │ ├── AnalysisPageContainer.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── analysis-ttl-view/ │ │ │ │ │ │ ├── ExpirationGroupsView.spec.tsx │ │ │ │ │ │ ├── ExpirationGroupsView.stories.tsx │ │ │ │ │ │ ├── ExpirationGroupsView.styles.ts │ │ │ │ │ │ ├── ExpirationGroupsView.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── analytics-page-header/ │ │ │ │ │ │ ├── AnalyticsPageHeader.styles.ts │ │ │ │ │ │ ├── AnalyticsPageHeader.tsx │ │ │ │ │ │ ├── AnalyticsPageHeader.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── base/ │ │ │ │ │ │ ├── TableTextBtn.tsx │ │ │ │ │ │ └── TextBtn.tsx │ │ │ │ │ ├── data-nav-tabs/ │ │ │ │ │ │ ├── DatabaseAnalysisTabs.spec.tsx │ │ │ │ │ │ ├── DatabaseAnalysisTabs.styles.ts │ │ │ │ │ │ ├── DatabaseAnalysisTabs.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── empty-analysis-message/ │ │ │ │ │ │ ├── EmptyAnalysisMessage.spec.tsx │ │ │ │ │ │ ├── EmptyAnalysisMessage.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── header/ │ │ │ │ │ │ ├── Header.spec.tsx │ │ │ │ │ │ ├── Header.styles.ts │ │ │ │ │ │ ├── Header.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── recommendations-view/ │ │ │ │ │ │ ├── Recommendations.spec.tsx │ │ │ │ │ │ ├── Recommendations.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── styles.ts │ │ │ │ │ ├── summary-per-data/ │ │ │ │ │ │ ├── SummaryPerData.spec.tsx │ │ │ │ │ │ ├── SummaryPerData.styles.ts │ │ │ │ │ │ ├── SummaryPerData.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── table-loader/ │ │ │ │ │ │ ├── TableLoader.spec.tsx │ │ │ │ │ │ ├── TableLoader.styles.ts │ │ │ │ │ │ ├── TableLoader.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── top-keys/ │ │ │ │ │ │ ├── TopKeys.spec.tsx │ │ │ │ │ │ ├── TopKeys.stories.tsx │ │ │ │ │ │ ├── TopKeys.tsx │ │ │ │ │ │ ├── TopKeysTable.spec.tsx │ │ │ │ │ │ └── TopKeysTable.tsx │ │ │ │ │ └── top-namespace/ │ │ │ │ │ ├── TopNamespace.spec.tsx │ │ │ │ │ ├── TopNamespace.stories.tsx │ │ │ │ │ ├── TopNamespace.styles.ts │ │ │ │ │ ├── TopNamespace.tsx │ │ │ │ │ ├── TopNamespacesTable.spec.tsx │ │ │ │ │ ├── TopNamespacesTable.tsx │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── constants.ts │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── home/ │ │ │ │ ├── HomePage.spec.tsx │ │ │ │ ├── HomePage.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── ManualConnection.styles.ts │ │ │ │ │ ├── add-database-screen/ │ │ │ │ │ │ ├── AddDatabaseScreen.spec.tsx │ │ │ │ │ │ ├── AddDatabaseScreen.styles.ts │ │ │ │ │ │ ├── AddDatabaseScreen.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── connection-url/ │ │ │ │ │ │ │ │ ├── ConnectionUrl.spec.tsx │ │ │ │ │ │ │ │ ├── ConnectionUrl.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── connectivity-options/ │ │ │ │ │ │ │ ├── ConnectivityOptions.spec.tsx │ │ │ │ │ │ │ ├── ConnectivityOptions.styles.ts │ │ │ │ │ │ │ ├── ConnectivityOptions.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── constants.tsx │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ ├── useConnectivityOptions.spec.ts │ │ │ │ │ │ │ └── useConnectivityOptions.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── cloud-connection/ │ │ │ │ │ │ ├── CloudConnectionFormWrapper.spec.tsx │ │ │ │ │ │ ├── CloudConnectionFormWrapper.tsx │ │ │ │ │ │ ├── cloud-connection-form/ │ │ │ │ │ │ │ ├── CloudConnectionForm.spec.tsx │ │ │ │ │ │ │ ├── CloudConnectionForm.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── cluster-connection/ │ │ │ │ │ │ ├── ClusterConnectionFormWrapper.spec.tsx │ │ │ │ │ │ ├── ClusterConnectionFormWrapper.tsx │ │ │ │ │ │ ├── cluster-connection-form/ │ │ │ │ │ │ │ ├── ClusterConnectionForm.spec.tsx │ │ │ │ │ │ │ ├── ClusterConnectionForm.stories.tsx │ │ │ │ │ │ │ ├── ClusterConnectionForm.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ │ └── types.ts │ │ │ │ │ ├── database-list-header/ │ │ │ │ │ │ ├── DatabaseListHeader.spec.tsx │ │ │ │ │ │ ├── DatabaseListHeader.tsx │ │ │ │ │ │ ├── handleClickFreeCloudDb.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── database-manage-tags-modal/ │ │ │ │ │ │ ├── ManageTagsModal.spec.tsx │ │ │ │ │ │ ├── ManageTagsModal.styles.ts │ │ │ │ │ │ ├── ManageTagsModal.tsx │ │ │ │ │ │ ├── TagInputField.spec.tsx │ │ │ │ │ │ ├── TagInputField.tsx │ │ │ │ │ │ ├── TagInputField.types.ts │ │ │ │ │ │ ├── TagSuggestions.spec.tsx │ │ │ │ │ │ ├── TagSuggestions.styles.ts │ │ │ │ │ │ ├── TagSuggestions.tsx │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ └── utils.ts │ │ │ │ │ ├── database-panel-dialog/ │ │ │ │ │ │ ├── DatabasePanelDialog.spec.tsx │ │ │ │ │ │ ├── DatabasePanelDialog.stories.tsx │ │ │ │ │ │ ├── DatabasePanelDialog.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── databases-list/ │ │ │ │ │ │ ├── DatabasesList.config.tsx │ │ │ │ │ │ ├── DatabasesList.tsx │ │ │ │ │ │ ├── DatabasesList.types.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── BulkItemsActions/ │ │ │ │ │ │ │ │ ├── BulkItemsActions.tsx │ │ │ │ │ │ │ │ └── methods/ │ │ │ │ │ │ │ │ ├── handlers.spec.ts │ │ │ │ │ │ │ │ └── handlers.ts │ │ │ │ │ │ │ ├── DatabasesListCellConnectionType/ │ │ │ │ │ │ │ │ └── DatabasesListCellConnectionType.tsx │ │ │ │ │ │ │ ├── DatabasesListCellControls/ │ │ │ │ │ │ │ │ ├── DatabasesListCellControls.spec.tsx │ │ │ │ │ │ │ │ ├── DatabasesListCellControls.styles.ts │ │ │ │ │ │ │ │ ├── DatabasesListCellControls.tsx │ │ │ │ │ │ │ │ └── methods/ │ │ │ │ │ │ │ │ ├── handlers.spec.ts │ │ │ │ │ │ │ │ └── handlers.ts │ │ │ │ │ │ │ ├── DatabasesListCellHost/ │ │ │ │ │ │ │ │ ├── DatabasesListCellHost.styles.ts │ │ │ │ │ │ │ │ ├── DatabasesListCellHost.tsx │ │ │ │ │ │ │ │ └── methods/ │ │ │ │ │ │ │ │ ├── handlers.spec.ts │ │ │ │ │ │ │ │ └── handlers.ts │ │ │ │ │ │ │ ├── DatabasesListCellLastConnection/ │ │ │ │ │ │ │ │ └── DatabasesListCellLastConnection.tsx │ │ │ │ │ │ │ ├── DatabasesListCellModules/ │ │ │ │ │ │ │ │ └── DatabasesListCellModules.tsx │ │ │ │ │ │ │ ├── DatabasesListCellName/ │ │ │ │ │ │ │ │ ├── DatabasesListCellName.styles.ts │ │ │ │ │ │ │ │ └── DatabasesListCellName.tsx │ │ │ │ │ │ │ └── DatabasesListCellTags/ │ │ │ │ │ │ │ └── DatabasesListCellTags.tsx │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ ├── useDatabaseListData.spec.ts │ │ │ │ │ │ │ └── useDatabaseListData.ts │ │ │ │ │ │ └── methods/ │ │ │ │ │ │ ├── handlers.spec.ts │ │ │ │ │ │ └── handlers.ts │ │ │ │ │ ├── db-status/ │ │ │ │ │ │ ├── DbStatus.spec.tsx │ │ │ │ │ │ ├── DbStatus.styles.ts │ │ │ │ │ │ ├── DbStatus.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── texts.tsx │ │ │ │ │ ├── empty-message/ │ │ │ │ │ │ ├── EmptyMessage.spec.tsx │ │ │ │ │ │ ├── EmptyMessage.styles.ts │ │ │ │ │ │ └── EmptyMessage.tsx │ │ │ │ │ ├── form/ │ │ │ │ │ │ ├── DatabaseForm.spec.tsx │ │ │ │ │ │ ├── DatabaseForm.tsx │ │ │ │ │ │ ├── DbCompressor.tsx │ │ │ │ │ │ ├── DbIndex.tsx │ │ │ │ │ │ ├── DbInfo.styles.ts │ │ │ │ │ │ ├── DbInfo.tsx │ │ │ │ │ │ ├── ForceStandalone.tsx │ │ │ │ │ │ ├── KeyFormatSelector.tsx │ │ │ │ │ │ ├── Messages.tsx │ │ │ │ │ │ ├── SSHDetails.tsx │ │ │ │ │ │ ├── TlsDetails.spec.tsx │ │ │ │ │ │ ├── TlsDetails.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── sentinel/ │ │ │ │ │ │ │ ├── DbInfoSentinel.styles.ts │ │ │ │ │ │ │ ├── DbInfoSentinel.tsx │ │ │ │ │ │ │ ├── PrimaryGroupSentinel.tsx │ │ │ │ │ │ │ ├── SentinelMasterDatabase.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── types.ts │ │ │ │ │ ├── host-info-tooltip-content/ │ │ │ │ │ │ ├── HostInfoTooltipContent.styles.ts │ │ │ │ │ │ └── HostInfoTooltipContent.tsx │ │ │ │ │ ├── import-database/ │ │ │ │ │ │ ├── ImportDatabase.spec.tsx │ │ │ │ │ │ ├── ImportDatabase.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── ResultsLog/ │ │ │ │ │ │ │ │ ├── ResultLog.styles.ts │ │ │ │ │ │ │ │ ├── ResultsLog.config.tsx │ │ │ │ │ │ │ │ ├── ResultsLog.spec.tsx │ │ │ │ │ │ │ │ ├── ResultsLog.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── TableResult/ │ │ │ │ │ │ │ ├── TableResult.spec.tsx │ │ │ │ │ │ │ ├── TableResult.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── manual-connection/ │ │ │ │ │ │ ├── ManualConnectionWrapper.spec.tsx │ │ │ │ │ │ ├── ManualConnectionWrapper.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── manual-connection-form/ │ │ │ │ │ │ ├── ManualConnectionForm.stories.tsx │ │ │ │ │ │ ├── ManualConnectionForm.tsx │ │ │ │ │ │ ├── ManualConnectionFrom.spec.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── CloneConnection.tsx │ │ │ │ │ │ │ └── FooterActions.tsx │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ ├── forms/ │ │ │ │ │ │ │ ├── AddConnection.tsx │ │ │ │ │ │ │ ├── DecompressionAndFormatters.tsx │ │ │ │ │ │ │ ├── EditConnection.tsx │ │ │ │ │ │ │ ├── EditSentinelConnection.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── search-databases-list/ │ │ │ │ │ │ ├── SearchDatabasesList.spec.tsx │ │ │ │ │ │ ├── SearchDatabasesList.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── sentinel-connection/ │ │ │ │ │ │ ├── SentinelConnectionWrapper.spec.tsx │ │ │ │ │ │ ├── SentinelConnectionWrapper.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── sentinel-connection-form/ │ │ │ │ │ │ ├── SentinelConnectionForm.spec.tsx │ │ │ │ │ │ ├── SentinelConnectionForm.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ └── tags-cell/ │ │ │ │ │ ├── TagsCell.spec.tsx │ │ │ │ │ ├── TagsCell.tsx │ │ │ │ │ ├── TagsCellHeader.spec.tsx │ │ │ │ │ ├── TagsCellHeader.tsx │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ ├── useFilterTags.spec.ts │ │ │ │ │ └── useFilterTags.ts │ │ │ │ ├── constants/ │ │ │ │ │ ├── database.ts │ │ │ │ │ ├── form.ts │ │ │ │ │ ├── help-links.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── contexts/ │ │ │ │ │ └── HomePageDataProvider.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── interfaces/ │ │ │ │ │ ├── form.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── styles.module.scss │ │ │ │ ├── styles.scss │ │ │ │ └── utils/ │ │ │ │ ├── form.tsx │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── instance/ │ │ │ │ ├── InstancePage.spec.tsx │ │ │ │ ├── InstancePage.tsx │ │ │ │ ├── InstancePageRouter.spec.tsx │ │ │ │ ├── InstancePageRouter.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── instanceConnectionLost.spec.tsx │ │ │ │ ├── instanceConnectionLost.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── not-found-error/ │ │ │ │ ├── NotFoundErrorPage.spec.tsx │ │ │ │ ├── NotFoundErrorPage.tsx │ │ │ │ └── styles.module.scss │ │ │ ├── pub-sub/ │ │ │ │ ├── PubSubPage.spec.tsx │ │ │ │ ├── PubSubPage.styles.tsx │ │ │ │ ├── PubSubPage.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── messages-list/ │ │ │ │ │ │ ├── EmptyMessagesList/ │ │ │ │ │ │ │ ├── EmptyMessagesList.spec.tsx │ │ │ │ │ │ │ ├── EmptyMessagesList.styles.tsx │ │ │ │ │ │ │ ├── EmptyMessagesList.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── MessagesListTable/ │ │ │ │ │ │ │ ├── MessagesListTable.config.tsx │ │ │ │ │ │ │ ├── MessagesListTable.constants.ts │ │ │ │ │ │ │ ├── MessagesListTable.spec.tsx │ │ │ │ │ │ │ ├── MessagesListTable.stories.tsx │ │ │ │ │ │ │ ├── MessagesListTable.styles.tsx │ │ │ │ │ │ │ ├── MessagesListTable.tsx │ │ │ │ │ │ │ ├── MessagesListTable.types.ts │ │ │ │ │ │ │ └── components/ │ │ │ │ │ │ │ ├── MessagesListTableCellMessage.tsx │ │ │ │ │ │ │ └── MessagesListTableCellTimestamp.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── patternsInfo/ │ │ │ │ │ │ ├── PatternsInfo.spec.tsx │ │ │ │ │ │ ├── PatternsInfo.styles.tsx │ │ │ │ │ │ ├── PatternsInfo.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── publish-message/ │ │ │ │ │ │ ├── PublishMessage.spec.tsx │ │ │ │ │ │ ├── PublishMessage.styles.tsx │ │ │ │ │ │ ├── PublishMessage.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── subscribe-form/ │ │ │ │ │ │ ├── SubscribeForm.spec.tsx │ │ │ │ │ │ ├── SubscribeForm.styles.tsx │ │ │ │ │ │ ├── SubscribeForm.tsx │ │ │ │ │ │ ├── SubscribeForm.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── subscribe-information/ │ │ │ │ │ ├── SubscribeInformation.spec.tsx │ │ │ │ │ ├── SubscribeInformation.styles.tsx │ │ │ │ │ ├── SubscribeInformation.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── rdi/ │ │ │ │ ├── components/ │ │ │ │ │ └── confirmation-popover/ │ │ │ │ │ ├── ConfirmationPopover.spec.tsx │ │ │ │ │ ├── ConfirmationPopover.tsx │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── constants/ │ │ │ │ │ ├── errors.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── home/ │ │ │ │ │ ├── RdiPage.spec.tsx │ │ │ │ │ ├── RdiPage.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ └── rdi-instances-list/ │ │ │ │ │ │ ├── RdiInstancesList.config.ts │ │ │ │ │ │ ├── RdiInstancesList.tsx │ │ │ │ │ │ ├── RdiInstancesList.types.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── BulkItemsActions/ │ │ │ │ │ │ │ │ ├── BulkItemsActions.spec.tsx │ │ │ │ │ │ │ │ ├── BulkItemsActions.tsx │ │ │ │ │ │ │ │ └── methods/ │ │ │ │ │ │ │ │ └── handlers.ts │ │ │ │ │ │ │ ├── RdiInstancesListCell/ │ │ │ │ │ │ │ │ ├── RdiInstancesListCell.spec.tsx │ │ │ │ │ │ │ │ ├── RdiInstancesListCell.styles.ts │ │ │ │ │ │ │ │ └── RdiInstancesListCell.tsx │ │ │ │ │ │ │ ├── RdiInstancesListCellControls/ │ │ │ │ │ │ │ │ └── RdiInstancesListCellControls.tsx │ │ │ │ │ │ │ └── RdiInstancesListCellSelect/ │ │ │ │ │ │ │ └── RdiInstancesListCellSelect.tsx │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ ├── useRdiInstancesListData.spec.ts │ │ │ │ │ │ │ └── useRdiInstancesListData.ts │ │ │ │ │ │ └── methods/ │ │ │ │ │ │ ├── handlers.ts │ │ │ │ │ │ ├── sortingAdapters.spec.ts │ │ │ │ │ │ └── sortingAdapters.ts │ │ │ │ │ ├── connection-form/ │ │ │ │ │ │ ├── ConnectionForm.spec.tsx │ │ │ │ │ │ ├── ConnectionForm.tsx │ │ │ │ │ │ ├── ConnectionFormWrapper.spec.tsx │ │ │ │ │ │ ├── ConnectionFormWrapper.tsx │ │ │ │ │ │ └── components/ │ │ │ │ │ │ ├── ValidationTooltip.spec.tsx │ │ │ │ │ │ └── ValidationTooltip.tsx │ │ │ │ │ ├── contexts/ │ │ │ │ │ │ └── RdiPageDataProvider.tsx │ │ │ │ │ ├── empty-message/ │ │ │ │ │ │ ├── EmptyMessage.spec.tsx │ │ │ │ │ │ ├── EmptyMessage.tsx │ │ │ │ │ │ └── styles.ts │ │ │ │ │ ├── header/ │ │ │ │ │ │ ├── RdiHeader.spec.tsx │ │ │ │ │ │ └── RdiHeader.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── search/ │ │ │ │ │ │ ├── SearchRdiList.spec.tsx │ │ │ │ │ │ └── SearchRdiList.tsx │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── instance/ │ │ │ │ │ ├── InstancePage.spec.tsx │ │ │ │ │ ├── InstancePage.tsx │ │ │ │ │ ├── InstancePageRouter.spec.tsx │ │ │ │ │ ├── InstancePageRouter.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── download/ │ │ │ │ │ │ │ ├── Download.spec.tsx │ │ │ │ │ │ │ ├── Download.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── header/ │ │ │ │ │ │ │ ├── RdiPipelineHeader.spec.tsx │ │ │ │ │ │ │ ├── RdiPipelineHeader.tsx │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── buttons/ │ │ │ │ │ │ │ │ │ ├── deploy-pipeline-button/ │ │ │ │ │ │ │ │ │ │ ├── DeployPipelineButton.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── DeployPipelineButton.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ ├── reset-pipeline-button/ │ │ │ │ │ │ │ │ │ │ ├── ResetPipelineButton.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── ResetPipelineButton.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ ├── start-pipeline-button/ │ │ │ │ │ │ │ │ │ │ ├── StartPipelineButton.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── StartPipelineButton.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ ├── stop-pipeline-button/ │ │ │ │ │ │ │ │ │ │ ├── StopPipelineButton.spec.tsx │ │ │ │ │ │ │ │ │ │ ├── StopPipelineButton.tsx │ │ │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ │ │ ├── current-pipeline-status/ │ │ │ │ │ │ │ │ │ ├── CurrentPipelineStatus.spec.tsx │ │ │ │ │ │ │ │ │ ├── CurrentPipelineStatus.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ ├── utils.spec.ts │ │ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ ├── pipeline-actions/ │ │ │ │ │ │ │ │ │ ├── PipelineActions.spec.tsx │ │ │ │ │ │ │ │ │ ├── PipelineActions.tsx │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ ├── utils.spec.ts │ │ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ │ │ └── rdi-config-file-action-menu/ │ │ │ │ │ │ │ │ ├── RdiConfigFileActionMenu.spec.tsx │ │ │ │ │ │ │ │ ├── RdiConfigFileActionMenu.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── pipeline-management/ │ │ │ │ │ ├── PipelineManagementPage.spec.tsx │ │ │ │ │ ├── PipelineManagementPage.styles.tsx │ │ │ │ │ ├── PipelineManagementPage.tsx │ │ │ │ │ ├── PipelineManagementPageRouter.spec.tsx │ │ │ │ │ ├── PipelineManagementPageRouter.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── download-from-server-modal/ │ │ │ │ │ │ │ ├── DownloadFromServerModal.spec.tsx │ │ │ │ │ │ │ └── DownloadFromServerModal.tsx │ │ │ │ │ │ ├── dry-run-job-commands/ │ │ │ │ │ │ │ ├── DryRunJobCommands.spec.tsx │ │ │ │ │ │ │ ├── DryRunJobCommands.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── dry-run-job-transformations/ │ │ │ │ │ │ │ ├── DryRunJobTransformations.spec.tsx │ │ │ │ │ │ │ ├── DryRunJobTransformations.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── jobs-panel/ │ │ │ │ │ │ │ ├── Panel.spec.tsx │ │ │ │ │ │ │ ├── Panel.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.ts │ │ │ │ │ │ ├── navigation/ │ │ │ │ │ │ │ ├── Navigation.spec.tsx │ │ │ │ │ │ │ ├── Navigation.tsx │ │ │ │ │ │ │ ├── cards/ │ │ │ │ │ │ │ │ ├── BaseCard.styles.ts │ │ │ │ │ │ │ │ ├── BaseCard.tsx │ │ │ │ │ │ │ │ ├── ConfigurationCard.spec.tsx │ │ │ │ │ │ │ │ ├── ConfigurationCard.tsx │ │ │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ │ ├── useConfigurationState.spec.ts │ │ │ │ │ │ │ │ │ └── useConfigurationState.ts │ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ │ └── jobs/ │ │ │ │ │ │ │ │ ├── JobNameForm.tsx │ │ │ │ │ │ │ │ ├── JobsCard.spec.tsx │ │ │ │ │ │ │ │ ├── JobsCard.tsx │ │ │ │ │ │ │ │ └── JobsItem.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── source-pipeline-dialog/ │ │ │ │ │ │ │ ├── SourcePipelineModal.spec.tsx │ │ │ │ │ │ │ ├── SourcePipelineModal.styles.ts │ │ │ │ │ │ │ ├── SourcePipelineModal.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── template-button/ │ │ │ │ │ │ │ ├── TemplateButton.spec.tsx │ │ │ │ │ │ │ ├── TemplateButton.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── template-form/ │ │ │ │ │ │ │ ├── TemplateForm.spec.tsx │ │ │ │ │ │ │ ├── TemplateForm.tsx │ │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── template-popover/ │ │ │ │ │ │ │ ├── TemplatePopover.spec.tsx │ │ │ │ │ │ │ ├── TemplatePopover.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── test-connections-log/ │ │ │ │ │ │ │ ├── TestConnectionsLog.spec.tsx │ │ │ │ │ │ │ ├── TestConnectionsLog.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── test-connections-panel/ │ │ │ │ │ │ │ ├── TestConnectionsPanel.spec.tsx │ │ │ │ │ │ │ ├── TestConnectionsPanel.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.ts │ │ │ │ │ │ ├── upload-modal/ │ │ │ │ │ │ │ ├── UploadModal.spec.tsx │ │ │ │ │ │ │ ├── UploadModal.tsx │ │ │ │ │ │ │ └── components/ │ │ │ │ │ │ │ └── upload-dialog/ │ │ │ │ │ │ │ ├── UploadDialog.spec.tsx │ │ │ │ │ │ │ └── UploadDialog.tsx │ │ │ │ │ │ └── validation-errors-list/ │ │ │ │ │ │ ├── ValidationErrorsList.spec.tsx │ │ │ │ │ │ └── ValidationErrorsList.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── pages/ │ │ │ │ │ ├── config/ │ │ │ │ │ │ ├── Config.spec.tsx │ │ │ │ │ │ ├── Config.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.ts │ │ │ │ │ └── job/ │ │ │ │ │ ├── Job.spec.tsx │ │ │ │ │ ├── Job.tsx │ │ │ │ │ ├── JobWrapper.tsx │ │ │ │ │ ├── JobsWrapper.spec.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.ts │ │ │ │ └── statistics/ │ │ │ │ ├── StatisticsPage.spec.tsx │ │ │ │ ├── StatisticsPage.styles.ts │ │ │ │ ├── StatisticsPage.tsx │ │ │ │ ├── clients/ │ │ │ │ │ └── Clients.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── accordion/ │ │ │ │ │ │ ├── Accordion.spec.tsx │ │ │ │ │ │ ├── Accordion.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── panel/ │ │ │ │ │ │ ├── Panel.spec.tsx │ │ │ │ │ │ ├── Panel.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── statistics-blocks/ │ │ │ │ │ │ ├── StatisticsBlocks.spec.tsx │ │ │ │ │ │ ├── StatisticsBlocks.styles.ts │ │ │ │ │ │ ├── StatisticsBlocks.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── statistics-info/ │ │ │ │ │ │ ├── StatisticsInfo.spec.tsx │ │ │ │ │ │ ├── StatisticsInfo.styles.ts │ │ │ │ │ │ ├── StatisticsInfo.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── statistics-table/ │ │ │ │ │ │ ├── StatisticsTable.spec.tsx │ │ │ │ │ │ ├── StatisticsTable.styles.ts │ │ │ │ │ │ ├── StatisticsTable.tsx │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ └── useStatisticsTableColumns.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── vertical-divider/ │ │ │ │ │ ├── VerticalDivider.spec.tsx │ │ │ │ │ ├── VerticalDivider.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── empty/ │ │ │ │ │ ├── Empty.spec.tsx │ │ │ │ │ ├── Empty.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── index.ts │ │ │ │ ├── status/ │ │ │ │ │ └── styles.ts │ │ │ │ └── styles.ts │ │ │ ├── redis-cluster/ │ │ │ │ ├── RedisClusterDatabases.stories.tsx │ │ │ │ ├── RedisClusterDatabases.tsx │ │ │ │ ├── RedisClusterDatabasesPage.spec.tsx │ │ │ │ ├── RedisClusterDatabasesPage.tsx │ │ │ │ ├── RedisClusterDatabasesResult.spec.tsx │ │ │ │ ├── RedisClusterDatabasesResult.stories.tsx │ │ │ │ ├── RedisClusterDatabasesResult.tsx │ │ │ │ ├── column-definitions/ │ │ │ │ │ ├── columns/ │ │ │ │ │ │ ├── capabilities.tsx │ │ │ │ │ │ ├── database.tsx │ │ │ │ │ │ ├── endpoint.tsx │ │ │ │ │ │ ├── options.tsx │ │ │ │ │ │ ├── result.tsx │ │ │ │ │ │ ├── selection.ts │ │ │ │ │ │ └── status.ts │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── DatabaseCell.tsx │ │ │ │ │ │ ├── EndpointCell.tsx │ │ │ │ │ │ ├── ResultCell.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── CancelButton/ │ │ │ │ │ │ ├── CancelButton.style.ts │ │ │ │ │ │ ├── CancelButton.tsx │ │ │ │ │ │ └── CancelButton.types.ts │ │ │ │ │ ├── SummaryText/ │ │ │ │ │ │ ├── SummaryText.tsx │ │ │ │ │ │ └── SummaryText.types.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── constants/ │ │ │ │ │ └── constants.ts │ │ │ │ ├── index.ts │ │ │ │ ├── styles.module.scss │ │ │ │ └── useClusterDatabasesConfig.tsx │ │ │ ├── redis-stack/ │ │ │ │ └── components/ │ │ │ │ ├── edit-connection/ │ │ │ │ │ ├── EditConnection.spec.tsx │ │ │ │ │ ├── EditConnection.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── styles.module.scss │ │ │ │ │ └── styles.scss │ │ │ │ └── protected-route/ │ │ │ │ ├── ProtectedRoute.spec.tsx │ │ │ │ ├── ProtectedRoute.tsx │ │ │ │ └── index.ts │ │ │ ├── settings/ │ │ │ │ ├── SettingsPage.spec.tsx │ │ │ │ ├── SettingsPage.stories.tsx │ │ │ │ ├── SettingsPage.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── advanced-settings/ │ │ │ │ │ │ ├── AdvancedSettings.spec.tsx │ │ │ │ │ │ ├── AdvancedSettings.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── app-version/ │ │ │ │ │ │ ├── AppVersion.spec.tsx │ │ │ │ │ │ ├── AppVersion.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── cloud-settings/ │ │ │ │ │ │ ├── CloudSettings.spec.tsx │ │ │ │ │ │ ├── CloudSettings.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── user-api-keys-table/ │ │ │ │ │ │ │ ├── UserApiKeysTable.spec.tsx │ │ │ │ │ │ │ ├── UserApiKeysTable.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── general-settings/ │ │ │ │ │ │ ├── datetime-formatter/ │ │ │ │ │ │ │ ├── DateTimeFormatter.spec.tsx │ │ │ │ │ │ │ ├── DateTimeFormatter.stories.tsx │ │ │ │ │ │ │ ├── DateTimeFormatter.tsx │ │ │ │ │ │ │ └── components/ │ │ │ │ │ │ │ ├── datetime-form/ │ │ │ │ │ │ │ │ ├── DatetimeForm.spec.tsx │ │ │ │ │ │ │ │ └── DatetimeForm.tsx │ │ │ │ │ │ │ └── timezone-form/ │ │ │ │ │ │ │ ├── TimezoneForm.spec.tsx │ │ │ │ │ │ │ └── TimezoneForm.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── theme-settings/ │ │ │ │ │ │ ├── ThemeSettings.spec.tsx │ │ │ │ │ │ ├── ThemeSettings.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── workbench-settings/ │ │ │ │ │ ├── WorkbenchSettings.spec.tsx │ │ │ │ │ ├── WorkbenchSettings.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── slow-log/ │ │ │ │ ├── SlowLogPage.spec.tsx │ │ │ │ ├── SlowLogPage.styles.ts │ │ │ │ ├── SlowLogPage.tsx │ │ │ │ ├── components/ │ │ │ │ │ ├── Actions/ │ │ │ │ │ │ ├── Actions.spec.tsx │ │ │ │ │ │ ├── Actions.styles.ts │ │ │ │ │ │ ├── Actions.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── ClearSlowLogModal/ │ │ │ │ │ │ ├── ClearSlowLogModal.spec.tsx │ │ │ │ │ │ ├── ClearSlowLogModal.styles.ts │ │ │ │ │ │ └── ClearSlowLogModal.tsx │ │ │ │ │ ├── EmptySlowLog/ │ │ │ │ │ │ ├── EmptySlowLog.spec.tsx │ │ │ │ │ │ ├── EmptySlowLog.styles.ts │ │ │ │ │ │ ├── EmptySlowLog.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── SlowLogConfig/ │ │ │ │ │ │ ├── SlowLogConfig.spec.tsx │ │ │ │ │ │ ├── SlowLogConfig.styles.ts │ │ │ │ │ │ ├── SlowLogConfig.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── SlowLogTable/ │ │ │ │ │ │ ├── SlowLogTable.spec.tsx │ │ │ │ │ │ ├── SlowLogTable.styles.ts │ │ │ │ │ │ ├── SlowLogTable.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ │ ├── vector-search/ │ │ │ │ ├── VectorSearchPageRouter.spec.tsx │ │ │ │ ├── VectorSearchPageRouter.tsx │ │ │ │ ├── VectorSearchPageRouter.types.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── .gitkeep │ │ │ │ │ ├── command-view/ │ │ │ │ │ │ ├── CommandView.constants.ts │ │ │ │ │ │ ├── CommandView.spec.tsx │ │ │ │ │ │ ├── CommandView.stories.tsx │ │ │ │ │ │ ├── CommandView.styles.ts │ │ │ │ │ │ ├── CommandView.tsx │ │ │ │ │ │ ├── CommandView.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── create-index-onboarding/ │ │ │ │ │ │ ├── CreateIndexOnboarding.constants.tsx │ │ │ │ │ │ ├── CreateIndexOnboardingPopover.spec.tsx │ │ │ │ │ │ ├── CreateIndexOnboardingPopover.styles.ts │ │ │ │ │ │ ├── CreateIndexOnboardingPopover.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── delete-confirmation-modal/ │ │ │ │ │ │ ├── DeleteConfirmationModal.spec.tsx │ │ │ │ │ │ ├── DeleteConfirmationModal.stories.tsx │ │ │ │ │ │ ├── DeleteConfirmationModal.styles.ts │ │ │ │ │ │ ├── DeleteConfirmationModal.tsx │ │ │ │ │ │ ├── DeleteConfirmationModal.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── field-tag/ │ │ │ │ │ │ ├── FieldTag.tsx │ │ │ │ │ │ ├── FieldTag.types.ts │ │ │ │ │ │ └── constants.ts │ │ │ │ │ ├── field-type-list/ │ │ │ │ │ │ ├── FieldTypeList.styles.ts │ │ │ │ │ │ ├── FieldTypeList.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── field-type-modal/ │ │ │ │ │ │ ├── FieldTypeModal.constants.ts │ │ │ │ │ │ ├── FieldTypeModal.spec.tsx │ │ │ │ │ │ ├── FieldTypeModal.stories.tsx │ │ │ │ │ │ ├── FieldTypeModal.styles.ts │ │ │ │ │ │ ├── FieldTypeModal.tsx │ │ │ │ │ │ ├── FieldTypeModal.types.ts │ │ │ │ │ │ ├── FieldTypeModal.utils.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── FieldTypeForm/ │ │ │ │ │ │ │ │ ├── FieldTypeForm.tsx │ │ │ │ │ │ │ │ └── FieldTypeForm.types.ts │ │ │ │ │ │ │ ├── FieldTypeSelect/ │ │ │ │ │ │ │ │ ├── FieldTypeSelect.styles.ts │ │ │ │ │ │ │ │ └── FieldTypeSelect.tsx │ │ │ │ │ │ │ ├── TextFieldOptions/ │ │ │ │ │ │ │ │ └── TextFieldOptions.tsx │ │ │ │ │ │ │ └── VectorFieldOptions/ │ │ │ │ │ │ │ └── VectorFieldOptions.tsx │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ ├── useFieldTypeValidation.ts │ │ │ │ │ │ │ └── useVectorDataTypeOptions.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index-details/ │ │ │ │ │ │ ├── IndexDetails.columns.tsx │ │ │ │ │ │ ├── IndexDetails.config.tsx │ │ │ │ │ │ ├── IndexDetails.spec.tsx │ │ │ │ │ │ ├── IndexDetails.stories.tsx │ │ │ │ │ │ ├── IndexDetails.styles.tsx │ │ │ │ │ │ ├── IndexDetails.tsx │ │ │ │ │ │ ├── IndexDetails.types.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── ColumnHeader/ │ │ │ │ │ │ │ │ ├── ColumnHeader.spec.tsx │ │ │ │ │ │ │ │ ├── ColumnHeader.tsx │ │ │ │ │ │ │ │ └── ColumnHeader.types.ts │ │ │ │ │ │ │ ├── FieldActionsCell/ │ │ │ │ │ │ │ │ ├── FieldActionsCell.spec.tsx │ │ │ │ │ │ │ │ ├── FieldActionsCell.tsx │ │ │ │ │ │ │ │ └── FieldActionsCell.types.ts │ │ │ │ │ │ │ ├── FieldNameCell/ │ │ │ │ │ │ │ │ ├── FieldNameCell.tsx │ │ │ │ │ │ │ │ ├── FieldNameCell.types.ts │ │ │ │ │ │ │ │ └── FieldNameTooltip.tsx │ │ │ │ │ │ │ ├── FieldTypeCell/ │ │ │ │ │ │ │ │ ├── FieldTypeCell.tsx │ │ │ │ │ │ │ │ ├── FieldTypeCell.types.ts │ │ │ │ │ │ │ │ └── FieldTypeTooltip.tsx │ │ │ │ │ │ │ └── FieldValueCell/ │ │ │ │ │ │ │ ├── FieldValueCell.tsx │ │ │ │ │ │ │ ├── FieldValueCell.types.ts │ │ │ │ │ │ │ └── FieldValueTooltip.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index-info/ │ │ │ │ │ │ ├── IndexInfo.constants.tsx │ │ │ │ │ │ ├── IndexInfo.spec.tsx │ │ │ │ │ │ ├── IndexInfo.stories.tsx │ │ │ │ │ │ ├── IndexInfo.styles.ts │ │ │ │ │ │ ├── IndexInfo.tsx │ │ │ │ │ │ ├── IndexInfo.types.ts │ │ │ │ │ │ ├── IndexInfo.utils.spec.ts │ │ │ │ │ │ ├── IndexInfo.utils.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index-info-side-panel/ │ │ │ │ │ │ ├── IndexInfoSidePanel.spec.tsx │ │ │ │ │ │ ├── IndexInfoSidePanel.styles.ts │ │ │ │ │ │ ├── IndexInfoSidePanel.tsx │ │ │ │ │ │ ├── IndexInfoSidePanel.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index-list/ │ │ │ │ │ │ ├── IndexList.config.tsx │ │ │ │ │ │ ├── IndexList.spec.tsx │ │ │ │ │ │ ├── IndexList.stories.tsx │ │ │ │ │ │ ├── IndexList.tsx │ │ │ │ │ │ ├── IndexList.types.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── ActionsCell/ │ │ │ │ │ │ │ │ ├── ActionsCell.spec.tsx │ │ │ │ │ │ │ │ └── ActionsCell.tsx │ │ │ │ │ │ │ ├── ColumnHeader/ │ │ │ │ │ │ │ │ ├── ColumnHeader.spec.tsx │ │ │ │ │ │ │ │ ├── ColumnHeader.tsx │ │ │ │ │ │ │ │ └── ColumnHeader.types.ts │ │ │ │ │ │ │ ├── FieldTypesCell/ │ │ │ │ │ │ │ │ └── FieldTypesCell.tsx │ │ │ │ │ │ │ ├── NameCell/ │ │ │ │ │ │ │ │ └── NameCell.tsx │ │ │ │ │ │ │ ├── NumericCell/ │ │ │ │ │ │ │ │ ├── NumericCell.tsx │ │ │ │ │ │ │ │ └── NumericCell.types.ts │ │ │ │ │ │ │ └── PrefixCell/ │ │ │ │ │ │ │ └── PrefixCell.tsx │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── keys-browser/ │ │ │ │ │ │ ├── KeysBrowser.spec.tsx │ │ │ │ │ │ ├── KeysBrowser.stories.tsx │ │ │ │ │ │ ├── KeysBrowser.styles.ts │ │ │ │ │ │ ├── KeysBrowser.tsx │ │ │ │ │ │ ├── KeysBrowser.types.ts │ │ │ │ │ │ ├── __stories__/ │ │ │ │ │ │ │ ├── StorePopulator.tsx │ │ │ │ │ │ │ └── contextMock.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── Content.spec.tsx │ │ │ │ │ │ │ ├── Content.tsx │ │ │ │ │ │ │ ├── Footer.spec.tsx │ │ │ │ │ │ │ ├── Footer.stories.tsx │ │ │ │ │ │ │ ├── Footer.tsx │ │ │ │ │ │ │ ├── Header.spec.tsx │ │ │ │ │ │ │ ├── Header.tsx │ │ │ │ │ │ │ ├── TypeTabs.spec.tsx │ │ │ │ │ │ │ └── TypeTabs.tsx │ │ │ │ │ │ ├── contexts/ │ │ │ │ │ │ │ └── Context.tsx │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ └── useKeysBrowser.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── no-search-results/ │ │ │ │ │ │ ├── NoSearchResults.spec.tsx │ │ │ │ │ │ ├── NoSearchResults.stories.tsx │ │ │ │ │ │ ├── NoSearchResults.styles.ts │ │ │ │ │ │ ├── NoSearchResults.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── pick-sample-data-modal/ │ │ │ │ │ │ ├── PickSampleDataModal.constants.ts │ │ │ │ │ │ ├── PickSampleDataModal.spec.tsx │ │ │ │ │ │ ├── PickSampleDataModal.stories.tsx │ │ │ │ │ │ ├── PickSampleDataModal.styles.ts │ │ │ │ │ │ ├── PickSampleDataModal.tsx │ │ │ │ │ │ ├── PickSampleDataModal.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── query-editor/ │ │ │ │ │ │ ├── EditorLibraryToggle.spec.tsx │ │ │ │ │ │ ├── EditorLibraryToggle.tsx │ │ │ │ │ │ ├── QueryEditor.constants.ts │ │ │ │ │ │ ├── QueryEditor.styles.ts │ │ │ │ │ │ ├── QueryEditor.types.ts │ │ │ │ │ │ ├── QueryEditor.utils.spec.ts │ │ │ │ │ │ ├── QueryEditor.utils.ts │ │ │ │ │ │ ├── QueryEditorWrapper.spec.tsx │ │ │ │ │ │ ├── QueryEditorWrapper.stories.tsx │ │ │ │ │ │ ├── QueryEditorWrapper.tsx │ │ │ │ │ │ ├── VectorSearchActions.spec.tsx │ │ │ │ │ │ ├── VectorSearchActions.tsx │ │ │ │ │ │ ├── VectorSearchEditor.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── query-onboarding-popover/ │ │ │ │ │ │ │ ├── QueryOnboardingPopover.spec.tsx │ │ │ │ │ │ │ ├── QueryOnboardingPopover.styles.ts │ │ │ │ │ │ │ ├── QueryOnboardingPopover.tsx │ │ │ │ │ │ │ ├── QueryOnboardingPopover.types.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── onboardingSuggestions.spec.ts │ │ │ │ │ │ └── onboardingSuggestions.ts │ │ │ │ │ ├── query-library-item/ │ │ │ │ │ │ ├── QueryLibraryItem.constants.ts │ │ │ │ │ │ ├── QueryLibraryItem.spec.tsx │ │ │ │ │ │ ├── QueryLibraryItem.stories.tsx │ │ │ │ │ │ ├── QueryLibraryItem.styles.ts │ │ │ │ │ │ ├── QueryLibraryItem.tsx │ │ │ │ │ │ ├── QueryLibraryItem.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── query-library-view/ │ │ │ │ │ │ ├── QueryLibraryView.spec.tsx │ │ │ │ │ │ ├── QueryLibraryView.styles.ts │ │ │ │ │ │ ├── QueryLibraryView.tsx │ │ │ │ │ │ ├── QueryLibraryView.types.ts │ │ │ │ │ │ ├── QueryLibraryView.utils.spec.ts │ │ │ │ │ │ ├── QueryLibraryView.utils.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ └── delete-query-modal/ │ │ │ │ │ │ │ ├── DeleteQueryModal.spec.tsx │ │ │ │ │ │ │ ├── DeleteQueryModal.tsx │ │ │ │ │ │ │ ├── DeleteQueryModal.types.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ ├── useQueryLibrary.spec.ts │ │ │ │ │ │ │ └── useQueryLibrary.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── rqe-not-available/ │ │ │ │ │ │ ├── RqeNotAvailable.spec.tsx │ │ │ │ │ │ ├── RqeNotAvailable.stories.tsx │ │ │ │ │ │ ├── RqeNotAvailable.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── save-query-modal/ │ │ │ │ │ │ ├── SaveQueryModal.spec.tsx │ │ │ │ │ │ ├── SaveQueryModal.styles.ts │ │ │ │ │ │ ├── SaveQueryModal.tsx │ │ │ │ │ │ ├── SaveQueryModal.types.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── search-page-fallback/ │ │ │ │ │ │ ├── SearchPageFallback.spec.tsx │ │ │ │ │ │ ├── SearchPageFallback.styles.ts │ │ │ │ │ │ ├── SearchPageFallback.tsx │ │ │ │ │ │ ├── SearchPageFallback.types.ts │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── select-key-onboarding-popover/ │ │ │ │ │ │ ├── SelectKeyOnboardingPopover.spec.tsx │ │ │ │ │ │ ├── SelectKeyOnboardingPopover.styles.ts │ │ │ │ │ │ ├── SelectKeyOnboardingPopover.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── upgrade-redis-banner/ │ │ │ │ │ │ ├── UpgradeRedisBanner.spec.tsx │ │ │ │ │ │ ├── UpgradeRedisBanner.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── version-not-supported/ │ │ │ │ │ │ ├── VersionNotSupported.spec.tsx │ │ │ │ │ │ ├── VersionNotSupported.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── welcome-screen/ │ │ │ │ │ ├── WelcomeScreen.constants.ts │ │ │ │ │ ├── WelcomeScreen.spec.tsx │ │ │ │ │ ├── WelcomeScreen.stories.tsx │ │ │ │ │ ├── WelcomeScreen.styles.ts │ │ │ │ │ ├── WelcomeScreen.tsx │ │ │ │ │ ├── WelcomeScreen.types.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── constants/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── key-type-maps.ts │ │ │ │ │ ├── notifications.ts │ │ │ │ │ └── sample-data/ │ │ │ │ │ ├── bikes.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── movies.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── context/ │ │ │ │ │ ├── create-index-onboarding/ │ │ │ │ │ │ ├── CreateIndexOnboardingContext.tsx │ │ │ │ │ │ ├── CreateIndexOnboardingProvider.spec.tsx │ │ │ │ │ │ ├── CreateIndexOnboardingProvider.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── create-index-page/ │ │ │ │ │ │ ├── CreateIndexPageContext.tsx │ │ │ │ │ │ ├── CreateIndexPageContext.types.ts │ │ │ │ │ │ ├── CreateIndexPageProvider.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── vector-search/ │ │ │ │ │ ├── VectorSearchContext.tsx │ │ │ │ │ ├── VectorSearchContext.types.ts │ │ │ │ │ ├── VectorSearchProvider.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── hooks/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useCreateIndex/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useCreateIndex.spec.ts │ │ │ │ │ │ └── useCreateIndex.ts │ │ │ │ │ ├── useCreateIndexCommand/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useCreateIndexCommand.spec.ts │ │ │ │ │ │ └── useCreateIndexCommand.ts │ │ │ │ │ ├── useCreateIndexFlow/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useCreateIndexFlow.spec.ts │ │ │ │ │ │ └── useCreateIndexFlow.ts │ │ │ │ │ ├── useHasExistingKeys/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useHasExistingKeys.spec.ts │ │ │ │ │ │ └── useHasExistingKeys.ts │ │ │ │ │ ├── useIndexInfo/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useIndexInfo.spec.ts │ │ │ │ │ │ ├── useIndexInfo.ts │ │ │ │ │ │ ├── useIndexInfo.types.ts │ │ │ │ │ │ ├── useIndexInfo.utils.spec.ts │ │ │ │ │ │ └── useIndexInfo.utils.ts │ │ │ │ │ ├── useIndexListData/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useIndexListData.spec.ts │ │ │ │ │ │ ├── useIndexListData.ts │ │ │ │ │ │ ├── useIndexListData.utils.spec.ts │ │ │ │ │ │ └── useIndexListData.utils.ts │ │ │ │ │ ├── useIndexNameValidation/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useIndexNameValidation.spec.ts │ │ │ │ │ │ └── useIndexNameValidation.ts │ │ │ │ │ ├── useIsKeyIndexed/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useIsKeyIndexed.spec.ts │ │ │ │ │ │ ├── useIsKeyIndexed.ts │ │ │ │ │ │ └── useIsKeyIndexed.types.ts │ │ │ │ │ ├── useLastViewedPage/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useLastViewedPage.spec.ts │ │ │ │ │ │ └── useLastViewedPage.ts │ │ │ │ │ ├── useListContent/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useListContent.spec.ts │ │ │ │ │ │ └── useListContent.ts │ │ │ │ │ ├── useLoadKeyData/ │ │ │ │ │ │ ├── helpers.spec.ts │ │ │ │ │ │ ├── helpers.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useLoadKeyData.spec.ts │ │ │ │ │ │ ├── useLoadKeyData.ts │ │ │ │ │ │ └── useLoadKeyData.types.ts │ │ │ │ │ ├── useRedisInstanceCompatibility/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── useRedisInstanceCompatibility.spec.ts │ │ │ │ │ │ ├── useRedisInstanceCompatibility.ts │ │ │ │ │ │ └── useRedisInstanceCompatibility.types.ts │ │ │ │ │ └── useRedisearchListData/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useRedisearchListData.spec.ts │ │ │ │ │ ├── useRedisearchListData.ts │ │ │ │ │ └── useRedisearchListData.types.ts │ │ │ │ ├── index.ts │ │ │ │ ├── pages/ │ │ │ │ │ ├── VectorSearchCreateIndexPage/ │ │ │ │ │ │ ├── VectorSearchCreateIndexPage.spec.tsx │ │ │ │ │ │ ├── VectorSearchCreateIndexPage.styles.ts │ │ │ │ │ │ ├── VectorSearchCreateIndexPage.tsx │ │ │ │ │ │ ├── VectorSearchCreateIndexPage.types.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── ConfirmKeyChangeModal/ │ │ │ │ │ │ │ │ ├── ConfirmKeyChangeModal.spec.tsx │ │ │ │ │ │ │ │ ├── ConfirmKeyChangeModal.styles.ts │ │ │ │ │ │ │ │ ├── ConfirmKeyChangeModal.tsx │ │ │ │ │ │ │ │ ├── ConfirmKeyChangeModal.types.ts │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── CreateIndexBrowser.tsx │ │ │ │ │ │ │ ├── CreateIndexContent.tsx │ │ │ │ │ │ │ ├── CreateIndexFooter.tsx │ │ │ │ │ │ │ ├── CreateIndexHeader.tsx │ │ │ │ │ │ │ ├── CreateIndexToolbar.tsx │ │ │ │ │ │ │ └── IndexNameEditor/ │ │ │ │ │ │ │ ├── IndexNameEditor.spec.tsx │ │ │ │ │ │ │ ├── IndexNameEditor.styles.ts │ │ │ │ │ │ │ ├── IndexNameEditor.tsx │ │ │ │ │ │ │ ├── IndexNameEditor.types.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── VectorSearchListPage/ │ │ │ │ │ │ ├── VectorSearchListPage.spec.tsx │ │ │ │ │ │ ├── VectorSearchListPage.styles.ts │ │ │ │ │ │ ├── VectorSearchListPage.tsx │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── ListHeader.tsx │ │ │ │ │ │ │ ├── create-index-menu/ │ │ │ │ │ │ │ │ ├── CreateIndexMenu.spec.tsx │ │ │ │ │ │ │ │ ├── CreateIndexMenu.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── delete-index-confirmation/ │ │ │ │ │ │ │ │ ├── DeleteIndexConfirmation.spec.tsx │ │ │ │ │ │ │ │ └── DeleteIndexConfirmation.tsx │ │ │ │ │ │ │ ├── header-title/ │ │ │ │ │ │ │ │ ├── HeaderTitle.spec.tsx │ │ │ │ │ │ │ │ ├── HeaderTitle.styles.ts │ │ │ │ │ │ │ │ ├── HeaderTitle.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── list-content/ │ │ │ │ │ │ │ ├── ListContent.spec.tsx │ │ │ │ │ │ │ ├── ListContent.styles.ts │ │ │ │ │ │ │ ├── ListContent.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── VectorSearchPage/ │ │ │ │ │ │ ├── VectorSearchPage.spec.tsx │ │ │ │ │ │ ├── VectorSearchPage.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── VectorSearchQueryPage/ │ │ │ │ │ │ ├── VectorSearchQueryPage.spec.tsx │ │ │ │ │ │ ├── VectorSearchQueryPage.styles.ts │ │ │ │ │ │ ├── VectorSearchQueryPage.tsx │ │ │ │ │ │ ├── VectorSearchQueryPage.types.ts │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ ├── header-title/ │ │ │ │ │ │ │ │ ├── HeaderTitle.spec.tsx │ │ │ │ │ │ │ │ ├── HeaderTitle.styles.ts │ │ │ │ │ │ │ │ ├── HeaderTitle.tsx │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── page-content/ │ │ │ │ │ │ │ │ ├── PageContent.spec.tsx │ │ │ │ │ │ │ │ ├── PageContent.styles.ts │ │ │ │ │ │ │ │ ├── PageContent.tsx │ │ │ │ │ │ │ │ ├── PageContent.types.ts │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ ├── page-header/ │ │ │ │ │ │ │ │ ├── PageHeader.spec.tsx │ │ │ │ │ │ │ │ ├── PageHeader.styles.ts │ │ │ │ │ │ │ │ ├── PageHeader.tsx │ │ │ │ │ │ │ │ ├── PageHeader.types.ts │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── view-index-button/ │ │ │ │ │ │ │ ├── ViewIndexButton.tsx │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ ├── useQuery.spec.ts │ │ │ │ │ │ │ ├── useQuery.ts │ │ │ │ │ │ │ ├── useQuery.utils.spec.ts │ │ │ │ │ │ │ └── useQuery.utils.ts │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── VectorSearchWelcomePage/ │ │ │ │ │ │ ├── VectorSearchWelcomePage.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── styles.ts │ │ │ │ ├── telemetry.constants.ts │ │ │ │ └── utils/ │ │ │ │ ├── generateDynamicFtCreateCommand.spec.ts │ │ │ │ ├── generateDynamicFtCreateCommand.ts │ │ │ │ ├── generateFtCreateCommand.spec.ts │ │ │ │ ├── generateFtCreateCommand.ts │ │ │ │ ├── helpers.spec.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── index.ts │ │ │ │ ├── inferFieldType.spec.ts │ │ │ │ ├── inferFieldType.ts │ │ │ │ ├── sampleData.ts │ │ │ │ ├── telemetry.utils.spec.ts │ │ │ │ └── telemetry.utils.ts │ │ │ └── workbench/ │ │ │ ├── WorkbenchPage.spec.tsx │ │ │ ├── WorkbenchPage.tsx │ │ │ ├── components/ │ │ │ │ ├── query/ │ │ │ │ │ ├── Query/ │ │ │ │ │ │ ├── Query.spec.tsx │ │ │ │ │ │ ├── Query.styles.ts │ │ │ │ │ │ ├── Query.tsx │ │ │ │ │ │ ├── Query.types.ts │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── styles.module.scss │ │ │ │ │ ├── QueryWrapper.spec.tsx │ │ │ │ │ ├── QueryWrapper.stories.tsx │ │ │ │ │ ├── QueryWrapper.styles.ts │ │ │ │ │ ├── QueryWrapper.tsx │ │ │ │ │ ├── QueryWrapper.types.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── wb-no-results-message/ │ │ │ │ │ ├── WbNoResultsMessage.spec.tsx │ │ │ │ │ ├── WbNoResultsMessage.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── wb-results/ │ │ │ │ │ └── WBResults/ │ │ │ │ │ ├── WBResults.spec.tsx │ │ │ │ │ ├── WBResults.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ └── wb-view/ │ │ │ │ ├── WBView/ │ │ │ │ │ ├── WBView.spec.tsx │ │ │ │ │ ├── WBView.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── styles.module.scss │ │ │ │ ├── WBViewWrapper.spec.tsx │ │ │ │ ├── WBViewWrapper.tsx │ │ │ │ └── index.ts │ │ │ ├── constants.ts │ │ │ ├── contexts/ │ │ │ │ └── enablementAreaContext.tsx │ │ │ ├── data/ │ │ │ │ └── supported_commands.json │ │ │ ├── index.ts │ │ │ ├── interfaces.ts │ │ │ ├── telemetry.constants.spec.ts │ │ │ ├── telemetry.constants.ts │ │ │ ├── types.ts │ │ │ └── utils/ │ │ │ ├── helpers.ts │ │ │ ├── monaco.ts │ │ │ ├── profile.ts │ │ │ ├── query.ts │ │ │ ├── query_old.ts │ │ │ ├── searchSuggestions.ts │ │ │ ├── suggestions.ts │ │ │ └── tests/ │ │ │ ├── monaco.spec.ts │ │ │ ├── profile.spec.ts │ │ │ ├── query.spec.ts │ │ │ └── test-cases/ │ │ │ ├── common.ts │ │ │ ├── ft-aggregate.ts │ │ │ ├── ft-search.ts │ │ │ └── index.ts │ │ ├── plugins/ │ │ │ ├── pluginEvents.spec.ts │ │ │ ├── pluginEvents.ts │ │ │ ├── pluginImport.spec.ts │ │ │ └── pluginImport.ts │ │ ├── resourses/ │ │ │ └── en-EN.ts │ │ ├── services/ │ │ │ ├── PluginAPI.ts │ │ │ ├── apiService.ts │ │ │ ├── capability.ts │ │ │ ├── commands-history/ │ │ │ │ ├── commandsHistoryService.spec.ts │ │ │ │ ├── commandsHistoryService.ts │ │ │ │ ├── database/ │ │ │ │ │ ├── CommandsHistoryIndexedDB.spec.ts │ │ │ │ │ ├── CommandsHistoryIndexedDB.ts │ │ │ │ │ ├── CommandsHistorySQLite.spec.ts │ │ │ │ │ ├── CommandsHistorySQLite.ts │ │ │ │ │ └── interface.ts │ │ │ │ └── utils/ │ │ │ │ ├── command-execution.mapper.spec.ts │ │ │ │ └── command-execution.mapper.ts │ │ │ ├── database/ │ │ │ │ └── instancesService.ts │ │ │ ├── databaseSettingsService.ts │ │ │ ├── formatter/ │ │ │ │ ├── FormatSelector.spec.ts │ │ │ │ ├── FormatSelector.ts │ │ │ │ ├── HtmlToJsxString.ts │ │ │ │ ├── MarkdownToJsxString.ts │ │ │ │ └── formatter.interfaces.ts │ │ │ ├── hooks/ │ │ │ │ ├── hooks.ts │ │ │ │ ├── index.ts │ │ │ │ ├── useCabability.ts │ │ │ │ ├── useIoConnection.ts │ │ │ │ ├── useLoadData.spec.ts │ │ │ │ ├── useLoadData.ts │ │ │ │ ├── useStateWithContext.ts │ │ │ │ ├── useSystemThemeListener.ts │ │ │ │ └── useWebworkers.ts │ │ │ ├── index.ts │ │ │ ├── keys.ts │ │ │ ├── migrateStorageData.ts │ │ │ ├── query-library/ │ │ │ │ ├── QueryLibraryService.spec.ts │ │ │ │ ├── QueryLibraryService.ts │ │ │ │ ├── database/ │ │ │ │ │ ├── QueryLibraryIndexedDB.spec.ts │ │ │ │ │ ├── QueryLibraryIndexedDB.ts │ │ │ │ │ ├── QueryLibrarySQLite.spec.ts │ │ │ │ │ ├── QueryLibrarySQLite.ts │ │ │ │ │ ├── QueryLibraryStorage.ts │ │ │ │ │ └── interface.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── resourcesService.ts │ │ │ ├── routing.ts │ │ │ ├── storage.ts │ │ │ ├── tests/ │ │ │ │ ├── PluguinApi.spec.ts │ │ │ │ ├── apiService.spec.ts │ │ │ │ ├── formatter/ │ │ │ │ │ ├── HtmlToJsxString.spec.tsx │ │ │ │ │ └── MarkdownToJsxString.spec.ts │ │ │ │ ├── resourcesService.spec.ts │ │ │ │ └── routing.spec.tsx │ │ │ ├── theme.ts │ │ │ ├── utils/ │ │ │ │ └── index.ts │ │ │ ├── vectorSearchHistoryStorage.ts │ │ │ ├── workbenchStorage.ts │ │ │ └── wsService.ts │ │ ├── setup-env.ts │ │ ├── setup-tests.ts │ │ ├── slices/ │ │ │ ├── analytics/ │ │ │ │ ├── clusterDetails.ts │ │ │ │ ├── dbAnalysis.ts │ │ │ │ ├── settings.ts │ │ │ │ └── slowlog.ts │ │ │ ├── app/ │ │ │ │ ├── connectivity.ts │ │ │ │ ├── context.ts │ │ │ │ ├── csrf.ts │ │ │ │ ├── db-settings.ts │ │ │ │ ├── features.ts │ │ │ │ ├── info.ts │ │ │ │ ├── init.ts │ │ │ │ ├── notifications.ts │ │ │ │ ├── plugins.ts │ │ │ │ ├── redis-commands.ts │ │ │ │ ├── socket-connection.ts │ │ │ │ └── url-handling.ts │ │ │ ├── browser/ │ │ │ │ ├── bulkActions.ts │ │ │ │ ├── hash.ts │ │ │ │ ├── keys.ts │ │ │ │ ├── list.ts │ │ │ │ ├── redisearch.ts │ │ │ │ ├── rejson.ts │ │ │ │ ├── set.ts │ │ │ │ ├── stream.ts │ │ │ │ ├── string.ts │ │ │ │ └── zset.ts │ │ │ ├── cli/ │ │ │ │ ├── cli-output.ts │ │ │ │ ├── cli-settings.ts │ │ │ │ └── monitor.ts │ │ │ ├── content/ │ │ │ │ ├── create-redis-buttons.ts │ │ │ │ └── guide-links.ts │ │ │ ├── instances/ │ │ │ │ ├── azure.ts │ │ │ │ ├── caCerts.ts │ │ │ │ ├── clientCerts.ts │ │ │ │ ├── cloud.ts │ │ │ │ ├── cluster.ts │ │ │ │ ├── instances.ts │ │ │ │ ├── sentinel.ts │ │ │ │ └── tags.ts │ │ │ ├── interfaces/ │ │ │ │ ├── aiAssistant.ts │ │ │ │ ├── analytics.ts │ │ │ │ ├── api.ts │ │ │ │ ├── app.ts │ │ │ │ ├── azure.ts │ │ │ │ ├── bulkActions.ts │ │ │ │ ├── cli.ts │ │ │ │ ├── cloud.ts │ │ │ │ ├── content.ts │ │ │ │ ├── hash.ts │ │ │ │ ├── index.ts │ │ │ │ ├── insights.ts │ │ │ │ ├── instances.ts │ │ │ │ ├── keys.ts │ │ │ │ ├── list.ts │ │ │ │ ├── monitor.ts │ │ │ │ ├── pubsub.ts │ │ │ │ ├── rdi.ts │ │ │ │ ├── recommendations.ts │ │ │ │ ├── redisearch.ts │ │ │ │ ├── searchAndQuery.ts │ │ │ │ ├── stream.ts │ │ │ │ ├── string.ts │ │ │ │ ├── tag.ts │ │ │ │ ├── urlHandling.ts │ │ │ │ ├── user.ts │ │ │ │ ├── workbench.ts │ │ │ │ └── zset.ts │ │ │ ├── oauth/ │ │ │ │ ├── azure.ts │ │ │ │ └── cloud.ts │ │ │ ├── panels/ │ │ │ │ ├── aiAssistant.ts │ │ │ │ └── sidePanels.ts │ │ │ ├── pubsub/ │ │ │ │ └── pubsub.ts │ │ │ ├── rdi/ │ │ │ │ ├── dryRun.ts │ │ │ │ ├── instances.ts │ │ │ │ ├── pipeline.ts │ │ │ │ ├── statistics.ts │ │ │ │ └── testConnections.ts │ │ │ ├── recommendations/ │ │ │ │ └── recommendations.ts │ │ │ ├── search/ │ │ │ │ └── searchAndQuery.ts │ │ │ ├── store.ts │ │ │ ├── tests/ │ │ │ │ ├── analytics/ │ │ │ │ │ ├── clusterDetails.spec.ts │ │ │ │ │ ├── dbAnalysis.spec.ts │ │ │ │ │ ├── settings.spec.ts │ │ │ │ │ └── slowlog.spec.ts │ │ │ │ ├── app/ │ │ │ │ │ ├── connectivity.spec.ts │ │ │ │ │ ├── context.spec.ts │ │ │ │ │ ├── csrf.spec.ts │ │ │ │ │ ├── db-settings.spec.ts │ │ │ │ │ ├── features.spec.ts │ │ │ │ │ ├── info.spec.ts │ │ │ │ │ ├── init.spec.ts │ │ │ │ │ ├── notifications.spec.ts │ │ │ │ │ ├── plugins.spec.ts │ │ │ │ │ ├── redis-commands.spec.ts │ │ │ │ │ └── url-handling.spec.ts │ │ │ │ ├── browser/ │ │ │ │ │ ├── bulkActions.spec.ts │ │ │ │ │ ├── hash.spec.ts │ │ │ │ │ ├── keys.spec.ts │ │ │ │ │ ├── list.spec.ts │ │ │ │ │ ├── redisearch.spec.ts │ │ │ │ │ ├── rejson.setJsonDataAction.spec.ts │ │ │ │ │ ├── rejson.spec.ts │ │ │ │ │ ├── set.spec.ts │ │ │ │ │ ├── stream.spec.ts │ │ │ │ │ ├── string.spec.ts │ │ │ │ │ └── zset.spec.ts │ │ │ │ ├── cli/ │ │ │ │ │ ├── cli-output.spec.ts │ │ │ │ │ ├── cli-settings.spec.ts │ │ │ │ │ └── monitor.spec.ts │ │ │ │ ├── content/ │ │ │ │ │ ├── create-redis-buttons.spec.ts │ │ │ │ │ └── guide-links.spec.ts │ │ │ │ ├── instances/ │ │ │ │ │ ├── azure.spec.ts │ │ │ │ │ ├── caCerts.spec.ts │ │ │ │ │ ├── clientCerts.spec.ts │ │ │ │ │ ├── cloud.spec.ts │ │ │ │ │ ├── cluster.spec.ts │ │ │ │ │ ├── instances.spec.ts │ │ │ │ │ └── sentinel.spec.ts │ │ │ │ ├── oauth/ │ │ │ │ │ ├── azure.spec.ts │ │ │ │ │ └── cloud.spec.ts │ │ │ │ ├── panels/ │ │ │ │ │ ├── aiAssistant.spec.ts │ │ │ │ │ └── sidePanels.spec.ts │ │ │ │ ├── pubsub/ │ │ │ │ │ └── pubsub.spec.ts │ │ │ │ ├── rdi/ │ │ │ │ │ ├── dryRun.spec.tsx │ │ │ │ │ ├── instances.spec.ts │ │ │ │ │ ├── pipeline.spec.ts │ │ │ │ │ └── testConnections.spec.ts │ │ │ │ ├── recommendations/ │ │ │ │ │ └── recommendations.spec.ts │ │ │ │ ├── search/ │ │ │ │ │ └── searchAndQuery.spec.ts │ │ │ │ ├── user/ │ │ │ │ │ └── user-settings.spec.ts │ │ │ │ └── workbench/ │ │ │ │ ├── wb-custom-tutorials.spec.ts │ │ │ │ ├── wb-results.spec.ts │ │ │ │ └── wb-tutorials.spec.ts │ │ │ ├── user/ │ │ │ │ ├── cloud-user-profile.ts │ │ │ │ └── user-settings.ts │ │ │ └── workbench/ │ │ │ ├── wb-custom-tutorials.ts │ │ │ ├── wb-results.ts │ │ │ └── wb-tutorials.ts │ │ ├── styles/ │ │ │ ├── base/ │ │ │ │ ├── _base.scss │ │ │ │ ├── _flex_groups.scss │ │ │ │ ├── _fonts.scss │ │ │ │ ├── _functions.scss │ │ │ │ ├── _functions_electron.scss │ │ │ │ ├── _helpers.scss │ │ │ │ ├── _inputs.scss │ │ │ │ ├── _overrides.scss │ │ │ │ ├── _react_virtualized.scss │ │ │ │ ├── _selects.scss │ │ │ │ └── _typography.scss │ │ │ ├── components/ │ │ │ │ ├── _accordion.scss │ │ │ │ ├── _badge.scss │ │ │ │ ├── _buttons.scss │ │ │ │ ├── _callout.scss │ │ │ │ ├── _cli_output.scss │ │ │ │ ├── _components.scss │ │ │ │ ├── _database.scss │ │ │ │ ├── _forms.scss │ │ │ │ ├── _homePage.scss │ │ │ │ ├── _itemList.scss │ │ │ │ ├── _json_view.scss │ │ │ │ ├── _modal.scss │ │ │ │ ├── _notificationBody.scss │ │ │ │ ├── _popover.scss │ │ │ │ ├── _radio.scss │ │ │ │ ├── _resizable_container.scss │ │ │ │ ├── _table.scss │ │ │ │ ├── _toasts.scss │ │ │ │ └── markdown/ │ │ │ │ ├── _blockquote.scss │ │ │ │ ├── _code.scss │ │ │ │ ├── _list.scss │ │ │ │ ├── _table.scss │ │ │ │ ├── _typography.scss │ │ │ │ ├── _variables.scss │ │ │ │ └── index.scss │ │ │ ├── elastic.css │ │ │ ├── globalStyles.ts │ │ │ ├── main.scss │ │ │ ├── main_plugin.scss │ │ │ ├── mixins/ │ │ │ │ ├── _eui.scss │ │ │ │ ├── _global.scss │ │ │ │ ├── index.ts │ │ │ │ └── styledComponents.ts │ │ │ └── themes/ │ │ │ ├── dark_theme/ │ │ │ │ ├── _theme_color.scss │ │ │ │ └── darkTheme.scss │ │ │ └── light_theme/ │ │ │ ├── _theme_color.scss │ │ │ └── lightTheme.scss │ │ ├── telemetry/ │ │ │ ├── analytics.d.ts │ │ │ ├── checkAnalytics.ts │ │ │ ├── events.ts │ │ │ ├── index.ts │ │ │ ├── interfaces.ts │ │ │ ├── pageViews.ts │ │ │ ├── telemetryUtils.ts │ │ │ ├── tests/ │ │ │ │ ├── telemetryUtils.spec.ts │ │ │ │ └── usePageViewTelemetry.spec.ts │ │ │ └── usePageViewTelemetry.ts │ │ ├── templates/ │ │ │ ├── autodiscovery-page-template/ │ │ │ │ ├── AutoDiscoveryPageTemplate.spec.tsx │ │ │ │ ├── AutodiscoveryPageTemplate.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── explore-panel/ │ │ │ │ ├── ExplorePanelTemplate.spec.tsx │ │ │ │ ├── ExplorePanelTemplate.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styles.module.scss │ │ │ ├── home-page-template/ │ │ │ │ ├── HomePageTemplate.spec.tsx │ │ │ │ ├── HomePageTemplate.styles.ts │ │ │ │ ├── HomePageTemplate.tsx │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── instance-page-template/ │ │ │ │ ├── InstancePageTemplate.spec.tsx │ │ │ │ ├── InstancePageTemplate.tsx │ │ │ │ └── index.ts │ │ │ └── rdi-instance-page-template/ │ │ │ ├── RdiInstancePageTemplate.spec.tsx │ │ │ ├── RdiInstancePageTemplate.tsx │ │ │ ├── index.ts │ │ │ ├── styles.module.scss │ │ │ └── styles.ts │ │ ├── types/ │ │ │ └── index.d.ts │ │ └── utils/ │ │ ├── api/ │ │ │ ├── chatbots.ts │ │ │ └── index.ts │ │ ├── apiResponse.ts │ │ ├── bigString.ts │ │ ├── calculateTextareaLines.ts │ │ ├── capability.ts │ │ ├── cliHelper.tsx │ │ ├── cliOutputActions.ts │ │ ├── colors.ts │ │ ├── commands.ts │ │ ├── common.ts │ │ ├── comparisons/ │ │ │ ├── bigKeys.ts │ │ │ ├── compareConsents.ts │ │ │ ├── compareVersions.ts │ │ │ ├── diff.ts │ │ │ └── index.ts │ │ ├── content.ts │ │ ├── decompressors/ │ │ │ ├── decompressors.ts │ │ │ └── index.ts │ │ ├── dom/ │ │ │ ├── downloadFile.ts │ │ │ ├── handleBrowsers.ts │ │ │ ├── handlePlatforms.ts │ │ │ ├── index.ts │ │ │ ├── pagePlaceholder.ts │ │ │ ├── scrollIntoView.ts │ │ │ ├── setPageTitle.ts │ │ │ └── triggerDownloadFromUrl.ts │ │ ├── errors.tsx │ │ ├── events/ │ │ │ ├── handleDownloadButton.ts │ │ │ ├── handlePasteHostName.ts │ │ │ ├── index.ts │ │ │ └── selectOnFocus.ts │ │ ├── features.ts │ │ ├── formatters/ │ │ │ ├── bufferFormatters.ts │ │ │ ├── index.ts │ │ │ ├── java-date.ts │ │ │ ├── json.ts │ │ │ ├── markdown/ │ │ │ │ ├── index.ts │ │ │ │ ├── rehypeLinks.ts │ │ │ │ ├── remarkCode.ts │ │ │ │ ├── remarkImage.ts │ │ │ │ ├── remarkLink.ts │ │ │ │ ├── remarkRedisUpload.ts │ │ │ │ └── remarkSanitize.ts │ │ │ ├── msgpack/ │ │ │ │ ├── decoder.spec.ts │ │ │ │ ├── decoder.ts │ │ │ │ ├── extensions.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lz4.spec.ts │ │ │ │ └── lz4.ts │ │ │ ├── utils.ts │ │ │ └── valueFormatters.tsx │ │ ├── getLetterByIndex.ts │ │ ├── groupTypes.ts │ │ ├── index.ts │ │ ├── instance/ │ │ │ ├── getUrlInstance.ts │ │ │ ├── index.ts │ │ │ ├── instanceModules.spec.ts │ │ │ ├── instanceModules.ts │ │ │ ├── instanceNavigation.ts │ │ │ ├── instanceOptions.ts │ │ │ └── instanceProvider.ts │ │ ├── links.ts │ │ ├── longNames.tsx │ │ ├── modules.ts │ │ ├── monaco/ │ │ │ ├── completionProvider.ts │ │ │ ├── index.ts │ │ │ ├── monacoActions.ts │ │ │ ├── monacoDecorations.ts │ │ │ ├── monacoInterfaces.ts │ │ │ ├── monacoRedisCompletionProvider.ts │ │ │ ├── monacoRedisMonarchTokensProvider.ts │ │ │ ├── monacoRedisSignatureHelpProvider.ts │ │ │ ├── monacoUtils.ts │ │ │ ├── monarchTokens/ │ │ │ │ ├── cypherTokens.ts │ │ │ │ ├── jmespathTokens.ts │ │ │ │ ├── redisearchTokensSubRedis.ts │ │ │ │ ├── redisearchTokensTemplates.ts │ │ │ │ └── sqliteFunctionsTokens.ts │ │ │ ├── redisearch/ │ │ │ │ └── utils.ts │ │ │ └── regex.ts │ │ ├── monitorUtils.ts │ │ ├── numbers.ts │ │ ├── oauth/ │ │ │ └── cloudSsoUtm.tsx │ │ ├── onboarding.tsx │ │ ├── parseRedisUrl.ts │ │ ├── parseResponse.ts │ │ ├── pathUtil.ts │ │ ├── plugins.ts │ │ ├── polyfills.ts │ │ ├── pubSubUtils.ts │ │ ├── rdi/ │ │ │ ├── getUrlRdiInstance.ts │ │ │ ├── index.ts │ │ │ └── pipeline.ts │ │ ├── recommendation/ │ │ │ ├── helper.ts │ │ │ └── index.ts │ │ ├── redisearch.ts │ │ ├── redistack.ts │ │ ├── rejson.spec.ts │ │ ├── rejson.ts │ │ ├── routerWithSubRoutes.tsx │ │ ├── routing.ts │ │ ├── statuses.ts │ │ ├── streamUtils.ts │ │ ├── telemetry.ts │ │ ├── test-store.ts │ │ ├── test-utils.tsx │ │ ├── tests/ │ │ │ ├── apiResponse.spec.ts │ │ │ ├── bigString.spec.ts │ │ │ ├── capability.spec.ts │ │ │ ├── cliHelper.spec.ts │ │ │ ├── cliOutputActions.spec.ts │ │ │ ├── colors.spec.ts │ │ │ ├── commands.spec.ts │ │ │ ├── common.spec.tsx │ │ │ ├── comparisons/ │ │ │ │ ├── bigKeys.spec.ts │ │ │ │ ├── compareConsents.spec.ts │ │ │ │ ├── compareVersions.spec.ts │ │ │ │ └── diff.spec.ts │ │ │ ├── decompressors/ │ │ │ │ ├── constants.ts │ │ │ │ ├── decompressors.spec.ts │ │ │ │ └── index.ts │ │ │ ├── dom/ │ │ │ │ ├── downloadFile.spec.ts │ │ │ │ ├── handlePlatform.spec.ts │ │ │ │ └── scrollIntoView.spec.ts │ │ │ ├── errors.spec.tsx │ │ │ ├── events/ │ │ │ │ └── handleDownloadButton.spec.ts │ │ │ ├── formatters/ │ │ │ │ ├── bufferFormatters.spec.ts │ │ │ │ ├── markdown/ │ │ │ │ │ ├── remarkImage.spec.ts │ │ │ │ │ ├── remarkLink.spec.ts │ │ │ │ │ ├── remarkRedisCode.spec.ts │ │ │ │ │ ├── remarkRedisUpload.spec.ts │ │ │ │ │ └── remarkSanitize.spec.ts │ │ │ │ └── valueFormatters.spec.ts │ │ │ ├── getLetterByIndex.spec.ts │ │ │ ├── groupTypes.spec.ts │ │ │ ├── highlighting.spec.ts │ │ │ ├── instance/ │ │ │ │ ├── instanceNavigation.spec.ts │ │ │ │ ├── instanceOptions.spec.ts │ │ │ │ └── instanceProvider.spec.ts │ │ │ ├── links.spec.ts │ │ │ ├── longNames.spec.ts │ │ │ ├── modules.spec.ts │ │ │ ├── monaco/ │ │ │ │ ├── cyber/ │ │ │ │ │ ├── completionProvider.spec.ts │ │ │ │ │ └── monarchTokensProvider.spec.ts │ │ │ │ ├── monacoRedisCompletionProvider.spec.ts │ │ │ │ └── monacoUtils.spec.ts │ │ │ ├── monitorUtils.spec.ts │ │ │ ├── nodes.json │ │ │ ├── oauth/ │ │ │ │ └── cloudSsoUtm.spec.tsx │ │ │ ├── onboarding.spec.tsx │ │ │ ├── parseRedisUrl.spec.ts │ │ │ ├── parseResponse.spec.ts │ │ │ ├── pathUtil.spec.ts │ │ │ ├── plugins.spec.ts │ │ │ ├── rdi/ │ │ │ │ ├── getUrlRdiInstance.spec.ts │ │ │ │ └── pipeline.spec.ts │ │ │ ├── recommendation/ │ │ │ │ └── helper.spec.ts │ │ │ ├── redisearch.spec.ts │ │ │ ├── redistack.spec.ts │ │ │ ├── routerWithSubRoutes.spec.tsx │ │ │ ├── routing.spec.ts │ │ │ ├── streamUtils.spec.ts │ │ │ ├── telemetry.spec.ts │ │ │ ├── transformers/ │ │ │ │ ├── browser.spec.ts │ │ │ │ ├── chatbot.spec.ts │ │ │ │ ├── cliTextFormatter.spec.ts │ │ │ │ ├── extrapolation.spec.ts │ │ │ │ ├── formatBytes.spec.ts │ │ │ │ ├── formatDate.spec.ts │ │ │ │ ├── getTruncatedName.spec.ts │ │ │ │ ├── removeEmpty.spec.ts │ │ │ │ ├── replaceSpaces.spec.ts │ │ │ │ ├── transformQueryParams.spec.ts │ │ │ │ ├── transformRdiPipeline.spec.ts │ │ │ │ ├── truncateNumber.spec.ts │ │ │ │ └── truncateTTL.spec.ts │ │ │ ├── tree.spec.ts │ │ │ ├── validations.spec.ts │ │ │ ├── workbench.spec.ts │ │ │ └── сontent.spec.ts │ │ ├── transformers/ │ │ │ ├── browser.ts │ │ │ ├── chatbot.ts │ │ │ ├── cliTextFormatter.ts │ │ │ ├── extrapolation.ts │ │ │ ├── formatBytes.ts │ │ │ ├── formatDate.ts │ │ │ ├── getTruncatedName.ts │ │ │ ├── index.ts │ │ │ ├── parseRedisJsonPath.spec.ts │ │ │ ├── parseRedisJsonPath.ts │ │ │ ├── redisCommands.ts │ │ │ ├── removeEmpty.ts │ │ │ ├── replaceSpaces.ts │ │ │ ├── toRedisCodeBlock.ts │ │ │ ├── transformQueryParams.ts │ │ │ ├── transformRdiPipeline.ts │ │ │ ├── truncateNumber.ts │ │ │ └── truncateTTL.ts │ │ ├── tree.ts │ │ ├── types.ts │ │ ├── validations.ts │ │ └── workbench.ts │ ├── tsconfig.json │ ├── vite-env.d.ts │ └── vite.config.mjs ├── resources/ │ ├── app/ │ │ └── redisinsight.sh │ ├── entitlements.mac.plist │ ├── entitlements.mas.inherit.plist │ ├── entitlements.mas.loginhelper.plist │ ├── entitlements.mas.plist │ └── resources.d.ts ├── scripts/ │ ├── .eslintrc │ ├── DeleteDistWeb.js │ ├── DeleteSourceMaps.js │ ├── build-statics.cmd │ ├── build-statics.sh │ ├── check-port-in-use.js │ ├── deb-after-install.sh │ ├── deb-before-remove.sh │ ├── fetch-jira-tickets.js │ ├── prebuild.js │ └── update-version.js ├── stories/ │ ├── Playground.mdx │ ├── Start.mdx │ └── playground/ │ ├── Colors.tsx │ ├── Gallery.tsx │ ├── Playground.stories.tsx │ ├── PlaygroundPage.tsx │ └── Theme.tsx ├── tests/ │ ├── e2e/ │ │ ├── .desktop.env │ │ ├── .dockerignore │ │ ├── .eslintignore │ │ ├── .eslintrc │ │ ├── .gitignore │ │ ├── .testcafe-electron-rc.js │ │ ├── README.md │ │ ├── REDIS_ENVIRONMENTS.md │ │ ├── common-actions/ │ │ │ ├── browser-actions.ts │ │ │ ├── common-elements-actions.ts │ │ │ ├── databases-actions.ts │ │ │ ├── recommendations-actions.ts │ │ │ └── workbench-actions.ts │ │ ├── desktop.runner.ci.ts │ │ ├── desktop.runner.ts │ │ ├── desktop.runner.win.ts │ │ ├── docker.web.docker-compose.yml │ │ ├── e2e.Dockerfile │ │ ├── helpers/ │ │ │ ├── api/ │ │ │ │ ├── api-common.ts │ │ │ │ ├── api-database.ts │ │ │ │ ├── api-info.ts │ │ │ │ ├── api-keys.ts │ │ │ │ └── api-rdi.ts │ │ │ ├── async-helper.ts │ │ │ ├── common.ts │ │ │ ├── conf.ts │ │ │ ├── constants.ts │ │ │ ├── database-scripts.ts │ │ │ ├── database.ts │ │ │ ├── decompressors/ │ │ │ │ ├── base-decompressors-populator.ts │ │ │ │ ├── brotli-database-populator.ts │ │ │ │ ├── gzip-database-populator.ts │ │ │ │ ├── lz4-database-populator.ts │ │ │ │ └── php-gzcompress-database-populator.ts │ │ │ ├── helpers.ts │ │ │ ├── index.ts │ │ │ ├── insights.ts │ │ │ ├── keys.ts │ │ │ ├── notifications.ts │ │ │ ├── pub-sub.ts │ │ │ ├── scripts/ │ │ │ │ ├── browser-scripts.ts │ │ │ │ ├── close_chrome_tab.applescript │ │ │ │ ├── generate-big-data.ts │ │ │ │ └── get_chrome_tab_url.applescript │ │ │ ├── sso-authorization.ts │ │ │ ├── telemetry.ts │ │ │ └── utils.ts │ │ ├── local.web.docker-compose.yml │ │ ├── package.json │ │ ├── pageObjects/ │ │ │ ├── auto-discover-redis-enterprise-databases.ts │ │ │ ├── base-overview-page.ts │ │ │ ├── base-page.ts │ │ │ ├── browser-page.ts │ │ │ ├── cluster-details-page.ts │ │ │ ├── components/ │ │ │ │ ├── bottom-panel/ │ │ │ │ │ ├── cli.ts │ │ │ │ │ ├── command-helper.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── profiler.ts │ │ │ │ │ └── survey-link.ts │ │ │ │ ├── browser/ │ │ │ │ │ ├── bulk-actions.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── tree-view.ts │ │ │ │ ├── chatbot/ │ │ │ │ │ ├── ai-chatbot-panel.ts │ │ │ │ │ ├── chatbot-base-tab.ts │ │ │ │ │ ├── database-chatbot-tab.ts │ │ │ │ │ └── general-chatbot-tab.ts │ │ │ │ ├── common/ │ │ │ │ │ ├── editorButton.ts │ │ │ │ │ ├── modal.ts │ │ │ │ │ └── toast.ts │ │ │ │ ├── explore-tab.ts │ │ │ │ ├── insights-panel.ts │ │ │ │ ├── monaco-editor.ts │ │ │ │ ├── navigation/ │ │ │ │ │ ├── base-navigation-panel.ts │ │ │ │ │ ├── help-center.ts │ │ │ │ │ ├── navigation-header.ts │ │ │ │ │ ├── notification-panel.ts │ │ │ │ │ └── rdi-navigation-panel.ts │ │ │ │ ├── navigation-panel.ts │ │ │ │ ├── navigation-tabs.ts │ │ │ │ ├── overview-panel.ts │ │ │ │ ├── recommendations-tab.ts │ │ │ │ ├── redis-cloud-sign-in-panel.ts │ │ │ │ ├── shortcuts-panel.ts │ │ │ │ └── top-panel/ │ │ │ │ ├── database-overview.ts │ │ │ │ └── index.ts │ │ │ ├── dialogs/ │ │ │ │ ├── add-rdi-instance-dialog.ts │ │ │ │ ├── add-redis-database-dialog.ts │ │ │ │ ├── authorization-dialog.ts │ │ │ │ ├── filters-dialog.ts │ │ │ │ ├── index.ts │ │ │ │ ├── onboarding-cards-dialog.ts │ │ │ │ └── user-agreement-dialog.ts │ │ │ ├── enhanced-selector.ts │ │ │ ├── index.ts │ │ │ ├── instance-page.ts │ │ │ ├── memory-efficiency-page.ts │ │ │ ├── my-redis-databases-page.ts │ │ │ ├── pub-sub-page.ts │ │ │ ├── rdi-instance-page.ts │ │ │ ├── rdi-instances-list-page.ts │ │ │ ├── rdi-status-page.ts │ │ │ ├── sentinel/ │ │ │ │ ├── adding-master-groups-result-page.ts │ │ │ │ └── discovered-sentinel-master-groups-page.ts │ │ │ ├── settings-page.ts │ │ │ ├── slow-log-page.ts │ │ │ ├── sso-authorization-page.ts │ │ │ └── workbench-page.ts │ │ ├── rte/ │ │ │ ├── RedisInsight_Connections.json │ │ │ ├── openvpn/ │ │ │ │ ├── docker-compose.yml │ │ │ │ ├── openvpn-data/ │ │ │ │ │ └── conf/ │ │ │ │ │ ├── crl.pem │ │ │ │ │ ├── openvpn.conf │ │ │ │ │ ├── openvpn.conf.1636357834.bak │ │ │ │ │ ├── ovpn_env.sh │ │ │ │ │ └── pki/ │ │ │ │ │ ├── ca.crt │ │ │ │ │ ├── certs_by_serial/ │ │ │ │ │ │ ├── 139D258986D24CF7F2000F4365EA7CDE.pem │ │ │ │ │ │ └── 8055804ACAE0109030FB7947F31147A9.pem │ │ │ │ │ ├── crl.pem │ │ │ │ │ ├── dh.pem │ │ │ │ │ ├── index.txt │ │ │ │ │ ├── index.txt.attr │ │ │ │ │ ├── index.txt.attr.old │ │ │ │ │ ├── index.txt.old │ │ │ │ │ ├── issued/ │ │ │ │ │ │ ├── localhost.crt │ │ │ │ │ │ └── test.crt │ │ │ │ │ ├── openssl-easyrsa.cnf │ │ │ │ │ ├── private/ │ │ │ │ │ │ ├── ca.key │ │ │ │ │ │ ├── localhost.key │ │ │ │ │ │ └── test.key │ │ │ │ │ ├── reqs/ │ │ │ │ │ │ ├── localhost.req │ │ │ │ │ │ └── test.req │ │ │ │ │ ├── safessl-easyrsa.cnf │ │ │ │ │ ├── serial │ │ │ │ │ ├── serial.old │ │ │ │ │ └── ta.key │ │ │ │ └── test.ovpn │ │ │ ├── oss-cluster-7/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── cluster-create.sh │ │ │ │ ├── creator.Dockerfile │ │ │ │ └── redis.conf │ │ │ ├── oss-cluster-7-rs/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── cluster-rs-create.sh │ │ │ │ ├── creator.Dockerfile │ │ │ │ └── redis.conf │ │ │ ├── oss-sentinel/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── entrypoint.sh │ │ │ │ └── sentinel.conf │ │ │ ├── oss-standalone-big/ │ │ │ │ ├── Dockerfile │ │ │ │ └── entrypoint.sh │ │ │ ├── oss-standalone-tls/ │ │ │ │ ├── Dockerfile │ │ │ │ └── certs/ │ │ │ │ ├── redis.crt │ │ │ │ ├── redis.key │ │ │ │ ├── redisCA.crt │ │ │ │ ├── user.crt │ │ │ │ └── user.key │ │ │ ├── redis-enterprise/ │ │ │ │ ├── Dockerfile │ │ │ │ ├── db.json │ │ │ │ └── entrypoint.sh │ │ │ └── ssh/ │ │ │ └── keys/ │ │ │ ├── pub/ │ │ │ │ ├── test.pub │ │ │ │ └── testp.pub │ │ │ ├── test │ │ │ └── testp │ │ ├── rte.critical-path.docker-compose.yml │ │ ├── rte.docker-compose.yml │ │ ├── rte.networks.docker-compose.yml │ │ ├── rte.regression.docker-compose.yml │ │ ├── rte.smoke.docker-compose.yml │ │ ├── static-server.Dockerfile │ │ ├── static.ts │ │ ├── test-data/ │ │ │ ├── big-json/ │ │ │ │ ├── big-json.json │ │ │ │ └── json-BigInt.json │ │ │ ├── bulk-upload/ │ │ │ │ ├── bigKeysData.rtf │ │ │ │ └── bulkUplAllKeyTypes.txt │ │ │ ├── certs/ │ │ │ │ ├── ca.crt │ │ │ │ ├── certsByPath/ │ │ │ │ │ ├── caPath.crt │ │ │ │ │ ├── caSameBody.crt │ │ │ │ │ ├── clientPath.crt │ │ │ │ │ ├── clientPath.key │ │ │ │ │ ├── clientSameBody.crt │ │ │ │ │ └── clientSameBody.key │ │ │ │ ├── client.crt │ │ │ │ ├── client.key │ │ │ │ └── sameNameCerts/ │ │ │ │ ├── caPath.crt │ │ │ │ ├── clientPath.crt │ │ │ │ └── clientPath.key │ │ │ ├── decompressors/ │ │ │ │ ├── awesome.proto │ │ │ │ ├── pickleFile1.pickle │ │ │ │ ├── test_annotated_obj.ser │ │ │ │ ├── test_serialised_obj.ser │ │ │ │ └── vector.json │ │ │ ├── features-configs/ │ │ │ │ ├── insights-analytics-filter-off.json │ │ │ │ ├── insights-build-type-filter.json │ │ │ │ ├── insights-default-remote.json │ │ │ │ ├── insights-docker-build.json │ │ │ │ ├── insights-electron-build.json │ │ │ │ ├── insights-flag-off.json │ │ │ │ ├── insights-invalid.json │ │ │ │ ├── insights-valid.json │ │ │ │ ├── sso-docker-build.json │ │ │ │ └── sso-electron-build.json │ │ │ ├── formatters/ │ │ │ │ ├── ASCII.ts │ │ │ │ ├── Binary.ts │ │ │ │ ├── DataTime.ts │ │ │ │ ├── HEX.ts │ │ │ │ ├── JSON.ts │ │ │ │ ├── Java.ts │ │ │ │ ├── Msgpack.ts │ │ │ │ ├── PHP.ts │ │ │ │ ├── Pickle.ts │ │ │ │ ├── Protobuf.ts │ │ │ │ ├── Vector32Bit.ts │ │ │ │ ├── Vector64Bit.ts │ │ │ │ └── index.ts │ │ │ ├── formatters-data.ts │ │ │ ├── import-databases/ │ │ │ │ ├── ardm-valid.ano │ │ │ │ ├── racompFullSSH.json │ │ │ │ ├── racompass-invalid.json │ │ │ │ ├── racompass-valid.json │ │ │ │ ├── rdm-certificates.json │ │ │ │ └── rdm-full.json │ │ │ ├── ssh/ │ │ │ │ ├── sshPrivateKey │ │ │ │ └── sshPrivateKeyPasscode │ │ │ ├── sshPrivateKeys.ts │ │ │ ├── triggers-and-functions/ │ │ │ │ ├── invoke_function.txt │ │ │ │ └── library.txt │ │ │ ├── upload-json/ │ │ │ │ └── sample.json │ │ │ └── upload-tutorials/ │ │ │ └── customTutorials/ │ │ │ ├── _upload/ │ │ │ │ ├── bulkUplAllKeyTypes.txt │ │ │ │ └── bulkUplString.txt │ │ │ ├── folder-1/ │ │ │ │ └── probably-1.md │ │ │ └── folder-2/ │ │ │ └── vector-2.md │ │ ├── tests/ │ │ │ ├── electron/ │ │ │ │ ├── critical-path/ │ │ │ │ │ ├── a-first-start-form/ │ │ │ │ │ │ ├── autodiscovery.e2e.ts │ │ │ │ │ │ └── user-agreements-form.e2e.ts │ │ │ │ │ ├── analysis-tools/ │ │ │ │ │ │ └── recommendations.e2e.ts │ │ │ │ │ ├── browser/ │ │ │ │ │ │ ├── bulk-delete.e2e.ts │ │ │ │ │ │ └── bulk-upload.e2e.ts │ │ │ │ │ ├── database/ │ │ │ │ │ │ ├── add-ssh-db.e2e.ts │ │ │ │ │ │ └── clone-databases.e2e.ts │ │ │ │ │ ├── files-auto-update/ │ │ │ │ │ │ ├── enablement-area-autoupdate.e2e.ts │ │ │ │ │ │ └── promo-button-autoupdate.e2e.ts │ │ │ │ │ ├── monitor/ │ │ │ │ │ │ └── monitor.e2e.ts │ │ │ │ │ ├── pub-sub/ │ │ │ │ │ │ └── subscribe-unsubscribe.e2e.ts │ │ │ │ │ ├── slow-log/ │ │ │ │ │ │ └── slow-log.e2e.ts │ │ │ │ │ ├── tree-view/ │ │ │ │ │ │ └── tree-view-improvements.e2e.ts │ │ │ │ │ └── workbench/ │ │ │ │ │ ├── index-schema.e2e.ts │ │ │ │ │ └── json-workbench.e2e.ts │ │ │ │ ├── regression/ │ │ │ │ │ ├── browser/ │ │ │ │ │ │ └── keys-all-databases.e2e.ts │ │ │ │ │ ├── cli/ │ │ │ │ │ │ └── cli-re-cluster.e2e.ts │ │ │ │ │ ├── database/ │ │ │ │ │ │ ├── cloud-sso.e2e.ts │ │ │ │ │ │ └── edit-db.e2e.ts │ │ │ │ │ ├── insights/ │ │ │ │ │ │ └── feature-flag.e2e.ts │ │ │ │ │ ├── monitor/ │ │ │ │ │ │ └── monitor.e2e.ts │ │ │ │ │ ├── shortcuts/ │ │ │ │ │ │ └── shortcuts.e2e.ts │ │ │ │ │ └── workbench/ │ │ │ │ │ ├── redis-stack-commands.e2e.ts │ │ │ │ │ └── workbench-re-cluster.e2e.ts │ │ │ │ └── smoke/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── add-keys.e2e.ts │ │ │ │ │ └── list-of-keys-verifications.e2e.ts │ │ │ │ ├── cli/ │ │ │ │ │ └── cli.e2e.ts │ │ │ │ └── database/ │ │ │ │ ├── autodiscover-db.e2e.ts │ │ │ │ └── edit-db.e2e.ts │ │ │ └── web/ │ │ │ ├── critical-path/ │ │ │ │ ├── a-first-start-form/ │ │ │ │ │ └── user-agreements-form.e2e.ts │ │ │ │ ├── browser/ │ │ │ │ │ ├── bulk-delete.e2e.ts │ │ │ │ │ ├── bulk-upload.e2e.ts │ │ │ │ │ ├── consumer-group.e2e.ts │ │ │ │ │ ├── context.e2e.ts │ │ │ │ │ ├── filtering-history.e2e.ts │ │ │ │ │ ├── filtering.e2e.ts │ │ │ │ │ ├── formatters.e2e.ts │ │ │ │ │ ├── hash-field.e2e.ts │ │ │ │ │ ├── json-key.e2e.ts │ │ │ │ │ ├── key-details.e2e.ts │ │ │ │ │ ├── keylist-actions.e2e.ts │ │ │ │ │ ├── large-data.e2e.ts │ │ │ │ │ ├── list-key.e2e.ts │ │ │ │ │ ├── scan-keys.e2e.ts │ │ │ │ │ ├── search-capabilities.e2e.ts │ │ │ │ │ ├── set-key.e2e.ts │ │ │ │ │ ├── stream-key-entry-deletion.e2e.ts │ │ │ │ │ ├── stream-key.e2e.ts │ │ │ │ │ ├── stream-pending-messages.e2e.ts │ │ │ │ │ └── zset-key.e2e.ts │ │ │ │ ├── cli/ │ │ │ │ │ ├── cli-command-helper.e2e.ts │ │ │ │ │ └── cli-critical.e2e.ts │ │ │ │ ├── cluster-details/ │ │ │ │ │ └── cluster-details.e2e.ts │ │ │ │ ├── database/ │ │ │ │ │ ├── clone-databases.e2e.ts │ │ │ │ │ ├── connecting-to-the-db.e2e.ts │ │ │ │ │ ├── encryption.e2e.ts │ │ │ │ │ ├── export-databases.e2e.ts │ │ │ │ │ ├── import-databases.e2e.ts │ │ │ │ │ ├── logical-databases.e2e.ts │ │ │ │ │ └── modules.e2e.ts │ │ │ │ ├── database-overview/ │ │ │ │ │ ├── database-index.e2e.ts │ │ │ │ │ └── database-overview.e2e.ts │ │ │ │ ├── memory-efficiency/ │ │ │ │ │ ├── memory-efficiency.e2e.ts │ │ │ │ │ ├── recommendations.e2e.ts │ │ │ │ │ └── top-keys-table.e2e.ts │ │ │ │ ├── monitor/ │ │ │ │ │ ├── monitor.e2e.ts │ │ │ │ │ └── save-commands.e2e.ts │ │ │ │ ├── notifications/ │ │ │ │ │ ├── notification-center.e2e.ts │ │ │ │ │ └── notifications.json │ │ │ │ ├── pub-sub/ │ │ │ │ │ └── subscribe-unsubscribe.e2e.ts │ │ │ │ ├── settings/ │ │ │ │ │ └── settings.e2e.ts │ │ │ │ ├── slow-log/ │ │ │ │ │ └── slow-log.e2e.ts │ │ │ │ ├── tree-view/ │ │ │ │ │ ├── delimiter.e2e.ts │ │ │ │ │ ├── tree-view-improvements.e2e.ts │ │ │ │ │ └── tree-view.e2e.ts │ │ │ │ ├── url-handling/ │ │ │ │ │ └── url-handling.e2e.ts │ │ │ │ └── workbench/ │ │ │ │ ├── autocomplete.e2e.ts │ │ │ │ ├── command-results.e2e.ts │ │ │ │ ├── context.e2e.ts │ │ │ │ ├── cypher.e2e.ts │ │ │ │ ├── default-scripts-area.e2e.ts │ │ │ │ ├── no-indexes-suggestions.e2e.ts │ │ │ │ ├── scripting-area.e2e.ts │ │ │ │ └── search-and-query-autocomplete.e2e.ts │ │ │ ├── regression/ │ │ │ │ ├── browser/ │ │ │ │ │ ├── add-keys.e2e.ts │ │ │ │ │ ├── consumer-group.e2e.ts │ │ │ │ │ ├── context.e2e.ts │ │ │ │ │ ├── filtering-iteratively.e2e.ts │ │ │ │ │ ├── filtering.e2e.ts │ │ │ │ │ ├── format-switcher.e2e.ts │ │ │ │ │ ├── formatter-warning.e2e.ts │ │ │ │ │ ├── formatters.e2e.ts │ │ │ │ │ ├── full-screen.e2e.ts │ │ │ │ │ ├── handle-dbsize-permissions.e2e.ts │ │ │ │ │ ├── hash-field.e2e.ts │ │ │ │ │ ├── key-messages.e2e.ts │ │ │ │ │ ├── keys-all-databases.e2e.ts │ │ │ │ │ ├── large-key-details-values.e2e.ts │ │ │ │ │ ├── last-refresh.e2e.ts │ │ │ │ │ ├── list-key.e2e.ts │ │ │ │ │ ├── onboarding.e2e.ts │ │ │ │ │ ├── resize-columns.e2e.ts │ │ │ │ │ ├── scan-keys.e2e.ts │ │ │ │ │ ├── set-key.e2e.ts │ │ │ │ │ ├── stream-key.e2e.ts │ │ │ │ │ ├── stream-pending-messages.e2e.ts │ │ │ │ │ ├── survey-link.e2e.ts │ │ │ │ │ ├── ttl-format.e2e.ts │ │ │ │ │ └── upload-json-key.e2e.ts │ │ │ │ ├── cli/ │ │ │ │ │ ├── cli-all-db-types.e2e.ts │ │ │ │ │ ├── cli-command-helper.e2e.ts │ │ │ │ │ ├── cli-logical-db.e2e.ts │ │ │ │ │ ├── cli-promote-workbench.e2e.ts │ │ │ │ │ └── cli.e2e.ts │ │ │ │ ├── database/ │ │ │ │ │ ├── add-sentinel-db.e2e.ts │ │ │ │ │ ├── add-standalone-db.e2e.ts │ │ │ │ │ ├── autodiscover-db.e2e.ts │ │ │ │ │ ├── cloud-sso.e2e.ts │ │ │ │ │ ├── connecting-to-the-db.e2e.ts │ │ │ │ │ ├── database-list-search.e2e.ts │ │ │ │ │ ├── database-sorting.e2e.ts │ │ │ │ │ ├── edit-db.e2e.ts │ │ │ │ │ ├── github.e2e.ts │ │ │ │ │ ├── logical-databases.e2e.ts │ │ │ │ │ ├── navigation.e2e.ts │ │ │ │ │ ├── notification.e2e.ts │ │ │ │ │ └── redisstack.e2e.ts │ │ │ │ ├── database-overview/ │ │ │ │ │ ├── database-info.e2e.ts │ │ │ │ │ ├── database-overview-keys.e2e.ts │ │ │ │ │ ├── database-overview.e2e.ts │ │ │ │ │ ├── database-tls-certificates.e2e.ts │ │ │ │ │ └── overview.e2e.ts │ │ │ │ ├── insights/ │ │ │ │ │ ├── feature-flag.e2e.ts │ │ │ │ │ ├── import-tutorials.e2e.ts │ │ │ │ │ ├── live-recommendations.e2e.ts │ │ │ │ │ └── open-insights-panel.e2e.ts │ │ │ │ ├── monitor/ │ │ │ │ │ ├── monitor.e2e.ts │ │ │ │ │ └── save-commands.e2e.ts │ │ │ │ ├── pub-sub/ │ │ │ │ │ ├── debug-mode.e2e.ts │ │ │ │ │ └── pub-sub-oss-cluster-7.e2e.ts │ │ │ │ ├── settings/ │ │ │ │ │ └── settings.e2e.ts │ │ │ │ ├── shortcuts/ │ │ │ │ │ └── shortcuts.e2e.ts │ │ │ │ ├── tree-view/ │ │ │ │ │ └── tree-view.e2e.ts │ │ │ │ ├── triggers-and-functions/ │ │ │ │ │ └── libraries.e2e.ts │ │ │ │ ├── url-handling/ │ │ │ │ │ └── url-handling.e2e.ts │ │ │ │ └── workbench/ │ │ │ │ ├── autocomplete.e2e.ts │ │ │ │ ├── autoexecute-button.e2e.ts │ │ │ │ ├── command-results.e2e.ts │ │ │ │ ├── context.e2e.ts │ │ │ │ ├── cypher.e2e.ts │ │ │ │ ├── default-scripts-area.e2e.ts │ │ │ │ ├── editor-cleanup.e2e.ts │ │ │ │ ├── empty-command-history.e2e.ts │ │ │ │ ├── group-mode.e2e.ts │ │ │ │ ├── history-of-results.e2e.ts │ │ │ │ ├── raw-mode.e2e.ts │ │ │ │ ├── redis-stack-commands.e2e.ts │ │ │ │ ├── redisearch-module-not-available.e2e.ts │ │ │ │ ├── scripting-area.e2e.ts │ │ │ │ ├── workbench-all-db-types.e2e.ts │ │ │ │ ├── workbench-non-auto-guides.e2e.ts │ │ │ │ └── workbench-pipeline.e2e.ts │ │ │ └── smoke/ │ │ │ ├── browser/ │ │ │ │ ├── add-keys.e2e.ts │ │ │ │ ├── edit-key-name.e2e.ts │ │ │ │ ├── edit-key-value.e2e.ts │ │ │ │ ├── filtering.e2e.ts │ │ │ │ ├── hash-field.e2e.ts │ │ │ │ ├── json-key.e2e.ts │ │ │ │ ├── list-key.e2e.ts │ │ │ │ ├── list-of-keys-verifications.e2e.ts │ │ │ │ ├── set-key.e2e.ts │ │ │ │ ├── set-ttl-for-key.e2e.ts │ │ │ │ ├── verify-key-details.e2e.ts │ │ │ │ ├── verify-keys-refresh.e2e.ts │ │ │ │ └── zset-key.e2e.ts │ │ │ ├── cli/ │ │ │ │ ├── cli-command-helper.e2e.ts │ │ │ │ └── cli.e2e.ts │ │ │ ├── database/ │ │ │ │ ├── delete-the-db.e2e.ts │ │ │ │ └── edit-db.e2e.ts │ │ │ └── workbench/ │ │ │ ├── json-workbench.e2e.ts │ │ │ └── scripting-area.e2e.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.testcafe.json │ │ ├── upload-custom-plugins.sh │ │ ├── vpn.docker-compose.yml │ │ ├── wait-for-it.sh │ │ ├── wait-for-redis.sh │ │ ├── web.runner.ci.ts │ │ └── web.runner.ts │ ├── e2e-playwright/ │ │ ├── .eslintrc.json │ │ ├── .gitignore │ │ ├── .husky/ │ │ │ └── pre-commit │ │ ├── .prettierrc │ │ ├── README.md │ │ ├── TEST_PLAN.md │ │ ├── config/ │ │ │ ├── app.ts │ │ │ ├── databases/ │ │ │ │ ├── cluster.ts │ │ │ │ ├── index.ts │ │ │ │ ├── sentinel.ts │ │ │ │ ├── ssh.ts │ │ │ │ ├── standalone.ts │ │ │ │ └── tls.ts │ │ │ ├── env.ts │ │ │ └── index.ts │ │ ├── example.env │ │ ├── fixtures/ │ │ │ └── base.ts │ │ ├── helpers/ │ │ │ ├── api.ts │ │ │ ├── index.ts │ │ │ └── retry.ts │ │ ├── package.json │ │ ├── pages/ │ │ │ ├── BasePage.ts │ │ │ ├── InstancePage.ts │ │ │ ├── analytics/ │ │ │ │ ├── AnalyticsPage.ts │ │ │ │ └── index.ts │ │ │ ├── browser/ │ │ │ │ ├── BrowserPage.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── AddKeyDialog.ts │ │ │ │ │ ├── BulkActionsPanel.ts │ │ │ │ │ ├── KeyDetails.ts │ │ │ │ │ ├── KeyList.ts │ │ │ │ │ ├── MakeSearchableModal.ts │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── cli/ │ │ │ │ ├── CliPanel.ts │ │ │ │ └── index.ts │ │ │ ├── command-helper/ │ │ │ │ ├── CommandHelperPanel.ts │ │ │ │ └── index.ts │ │ │ ├── components/ │ │ │ │ ├── BottomPanel.ts │ │ │ │ ├── InstanceHeader.ts │ │ │ │ ├── NavigationTabs.ts │ │ │ │ └── index.ts │ │ │ ├── databases/ │ │ │ │ ├── DatabasesPage.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── AddDatabaseDialog.ts │ │ │ │ │ ├── CloneDatabaseDialog.ts │ │ │ │ │ ├── DatabaseList.ts │ │ │ │ │ ├── ImportDatabaseDialog.ts │ │ │ │ │ ├── TagsDialog.ts │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── eula/ │ │ │ │ ├── EulaPage.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── insights/ │ │ │ │ ├── InsightsPanel.ts │ │ │ │ └── index.ts │ │ │ ├── navigation/ │ │ │ │ ├── SidebarPanel.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── HelpMenu.ts │ │ │ │ │ └── NotificationCenter.ts │ │ │ │ └── index.ts │ │ │ ├── pubsub/ │ │ │ │ ├── PubSubPage.ts │ │ │ │ └── index.ts │ │ │ ├── settings/ │ │ │ │ ├── SettingsPage.ts │ │ │ │ └── index.ts │ │ │ ├── vector-search/ │ │ │ │ ├── VectorSearchPage.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── CreateIndexForm.ts │ │ │ │ │ ├── CreateIndexOnboarding.ts │ │ │ │ │ ├── DeleteConfirmationModal.ts │ │ │ │ │ ├── FieldTypeModal.ts │ │ │ │ │ ├── IndexInfoPanel.ts │ │ │ │ │ ├── IndexList.ts │ │ │ │ │ ├── PickSampleDataModal.ts │ │ │ │ │ ├── QueryEditor.ts │ │ │ │ │ ├── QueryLibrary.ts │ │ │ │ │ ├── QueryResults.ts │ │ │ │ │ ├── RqeNotAvailable.ts │ │ │ │ │ ├── SaveQueryModal.ts │ │ │ │ │ ├── WelcomeScreen.ts │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ └── workbench/ │ │ │ ├── WorkbenchPage.ts │ │ │ ├── components/ │ │ │ │ ├── Editor.ts │ │ │ │ ├── ResultsPanel.ts │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── playwright.config.ts │ │ ├── setup/ │ │ │ ├── browser.setup.ts │ │ │ ├── browser.teardown.ts │ │ │ ├── electron.setup.ts │ │ │ └── electron.teardown.ts │ │ ├── test-data/ │ │ │ ├── browser/ │ │ │ │ └── index.ts │ │ │ ├── databases/ │ │ │ │ ├── import-fixtures/ │ │ │ │ │ ├── generate.ts │ │ │ │ │ └── invalid-format.txt │ │ │ │ └── index.ts │ │ │ └── vector-search/ │ │ │ └── index.ts │ │ ├── tests/ │ │ │ └── main/ │ │ │ ├── analytics/ │ │ │ │ └── database-analysis/ │ │ │ │ └── database-analysis.spec.ts │ │ │ ├── browser/ │ │ │ │ ├── add-key/ │ │ │ │ │ └── add-key.spec.ts │ │ │ │ └── key-filtering/ │ │ │ │ └── key-filtering.spec.ts │ │ │ ├── cli/ │ │ │ │ └── cli-panel.spec.ts │ │ │ ├── command-helper/ │ │ │ │ └── command-helper-panel.spec.ts │ │ │ ├── databases/ │ │ │ │ ├── add/ │ │ │ │ │ └── add-database.spec.ts │ │ │ │ ├── clone/ │ │ │ │ │ └── clone-database.spec.ts │ │ │ │ ├── decompression/ │ │ │ │ │ └── decompression.spec.ts │ │ │ │ ├── encryption/ │ │ │ │ │ └── encryption.spec.ts │ │ │ │ ├── import-export/ │ │ │ │ │ └── import-export.spec.ts │ │ │ │ ├── list/ │ │ │ │ │ └── database-list.spec.ts │ │ │ │ ├── pagination/ │ │ │ │ │ └── pagination.spec.ts │ │ │ │ ├── security/ │ │ │ │ │ └── connection-security.spec.ts │ │ │ │ └── tags/ │ │ │ │ └── tags.spec.ts │ │ │ ├── insights/ │ │ │ │ └── insights-panel.spec.ts │ │ │ ├── navigation/ │ │ │ │ ├── help-menu/ │ │ │ │ │ └── help-menu.spec.ts │ │ │ │ ├── main-navigation/ │ │ │ │ │ └── main-navigation.spec.ts │ │ │ │ └── notification-center/ │ │ │ │ └── notification-center.spec.ts │ │ │ ├── settings/ │ │ │ │ ├── advanced-settings/ │ │ │ │ │ └── advanced-settings.spec.ts │ │ │ │ ├── general-settings/ │ │ │ │ │ └── general-settings.spec.ts │ │ │ │ ├── redis-cloud-settings/ │ │ │ │ │ └── redis-cloud-settings.spec.ts │ │ │ │ └── workbench-settings/ │ │ │ │ └── workbench-settings.spec.ts │ │ │ └── vector-search/ │ │ │ ├── browser-integration/ │ │ │ │ └── browser-integration.spec.ts │ │ │ ├── create-index/ │ │ │ │ ├── existing-data.spec.ts │ │ │ │ ├── onboarding.spec.ts │ │ │ │ └── sample-data.spec.ts │ │ │ ├── list-indexes/ │ │ │ │ ├── create-index.spec.ts │ │ │ │ └── list-indexes.spec.ts │ │ │ ├── navigation/ │ │ │ │ └── navigation.spec.ts │ │ │ └── query/ │ │ │ ├── query-editor.spec.ts │ │ │ ├── query-library.spec.ts │ │ │ ├── query-onboarding.spec.ts │ │ │ └── save-query.spec.ts │ │ ├── tsconfig.json │ │ └── types/ │ │ ├── database.ts │ │ ├── index.ts │ │ ├── key.ts │ │ └── vector-search.ts │ └── playwright/ │ ├── .gitignore │ ├── .nycrc.json │ ├── README.md │ ├── env/ │ │ ├── .desktop.env │ │ ├── .docker.env │ │ └── .local-web.env │ ├── factories/ │ │ └── redisearch-index.factory.ts │ ├── fixtures/ │ │ └── test.ts │ ├── helpers/ │ │ ├── api/ │ │ │ ├── api-databases.ts │ │ │ ├── api-indexes.ts │ │ │ ├── api-keys.ts │ │ │ └── http-client.ts │ │ ├── conf.ts │ │ ├── constants.ts │ │ └── utils.ts │ ├── package.json │ ├── pageObjects/ │ │ ├── auto-discover-redis-enterprise-databases.ts │ │ ├── base-overview-page.ts │ │ ├── base-page.ts │ │ ├── browser-page.ts │ │ ├── components/ │ │ │ ├── common/ │ │ │ │ └── toast.ts │ │ │ └── redis-cloud-sign-in-panel.ts │ │ ├── dialogs/ │ │ │ ├── add-rdi-instance-dialog.ts │ │ │ ├── add-redis-database-dialog.ts │ │ │ └── user-agreement-dialog.ts │ │ ├── index.ts │ │ └── rdi-instances-list-page.ts │ ├── playwright.config.ts │ ├── selectors/ │ │ ├── index.ts │ │ ├── toast-selectors.ts │ │ └── user-agreement-selectors.ts │ ├── setup/ │ │ └── module-mocks.ts │ ├── tests/ │ │ ├── basic-navigation.spec.ts │ │ ├── browser/ │ │ │ ├── keys-delete.spec.ts │ │ │ ├── keys-edit/ │ │ │ │ ├── edit-hash-key.spec.ts │ │ │ │ ├── edit-json-key.spec.ts │ │ │ │ ├── edit-list-key.spec.ts │ │ │ │ ├── edit-set-key.spec.ts │ │ │ │ ├── edit-string-key.spec.ts │ │ │ │ └── edit-zset-key.spec.ts │ │ │ ├── keys-edit.spec.ts │ │ │ └── keys-read.spec.ts │ │ └── keys.spec.ts │ └── types/ │ ├── connections.ts │ ├── databases.ts │ ├── index.ts │ ├── indexes.ts │ ├── keys.ts │ └── rdi.ts └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .ai/README.md ================================================ # RedisInsight AI Development Rules This directory contains the **single source of truth** for AI-assisted development rules and workflows in RedisInsight. ## Overview This repository uses a centralized approach to AI development rules: - **`AGENTS.md`** (at repository root) - Entry point for AI agents with essential commands, testing instructions, and quick reference - **`.ai/rules/`** - Detailed development standards organized by topic - **`.ai/commands/`** - AI workflow commands and templates These rules are used by multiple AI coding assistants: - **Cursor** (via symlinks: `.cursor/rules/` and `.cursor/commands/`) - **Augment** (via symlink: `.augment/`) - **Windsurf** (via symlink: `.windsurfrules`) - **GitHub Copilot** (via file: `.github/copilot-instructions.md`) ## Structure ``` AGENTS.md # 🎯 AI agent entry point .ai/ # Single source of truth ├── README.md # This file (human-readable overview) ├── rules/ # Development standards (modular) │ ├── code-quality.md # Linting, TypeScript standards │ ├── frontend.md # React, Redux, UI patterns │ ├── backend.md # NestJS, API patterns │ ├── testing.md # Testing standards │ ├── branches.md # Branch naming conventions │ ├── commits.md # Commit message guidelines │ └── pull-requests.md # Pull request process └── commands/ # AI workflow commands ├── pr-plan.md # JIRA ticket implementation planning ├── commit-message.md # Commit message generation └── pull-request-review.md # PR review workflow # Symlinks (all AI tools read from .ai/) .cursor/ ├── rules/ -> ../.ai/rules/ # Cursor AI (rules) └── commands/ -> ../.ai/commands/ # Cursor AI (commands) .augment/ -> .ai/ # Augment AI .windsurfrules -> .ai/ # Windsurf AI .github/copilot-instructions.md # GitHub Copilot ``` ## For AI Agents **Start here**: Read `AGENTS.md` at the repository root for: - Setup and build commands - Code quality standards - Testing instructions - Git workflow guidelines - Boundaries and best practices **Then refer to**: `.ai/rules/` for detailed guidelines on specific topics. ## For Human Developers This directory contains comprehensive development standards that are automatically used by AI coding assistants. The rules are organized into modular files for easy maintenance: - **Code Quality Standards**: `.ai/rules/code-quality.md` - TypeScript standards, import organization, best practices - **Frontend Patterns**: `.ai/rules/frontend.md` - React, Redux, styled-components, UI component usage - **Backend Patterns**: `.ai/rules/backend.md` - NestJS, dependency injection, API patterns - **Testing Standards**: `.ai/rules/testing.md` - Testing patterns, faker usage, test helpers - **Branch Naming**: `.ai/rules/branches.md` - Branch naming conventions - **Commit Messages**: `.ai/rules/commits.md` - Commit message guidelines (Conventional Commits) - **Pull Request Process**: `.ai/rules/pull-requests.md` - PR creation and review guidelines ## MCP (Model Context Protocol) Setup AI tools can access external services (JIRA, Confluence, GitHub, Figma) via MCP configuration. ### Initial Setup 1. **Copy the example configuration:** ```bash cp env.mcp.example .env.mcp ``` 2. **Get your Atlassian API token:** - Go to: https://id.atlassian.com/manage-profile/security/api-tokens - Create a classic token by pressing the first "Create Token" button - Copy the token 3. **Edit `.env.mcp` with your credentials:** - Add your JIRA and Confluence API tokens - Note: Figma MCP server uses OAuth authentication and doesn't require API keys 4. **Verify your setup:** **For Cursor users:** - Restart Cursor to load the new MCP configuration - Ask the AI: "Can you list all available MCP tools and test them?" - The AI should be able to access JIRA, Confluence, GitHub, Figma, and other configured services - **For Figma**: On first use, you'll be prompted to authenticate via OAuth flow in your browser **For Augment users:** ```bash npx @augmentcode/auggie --mcp-config mcp.json "go over all my mcp tools and make sure they work as expected" ``` **For GitHub Copilot users:** - Note: GitHub Copilot does not currently support MCP integration - MCP services (JIRA, Confluence, etc.) will not be available in Copilot ### Available MCP Services The `mcp.json` file configures these services: - **github** - GitHub integration (issues, PRs, repository operations) - **memory** - Persistent context storage across sessions - **sequential-thinking** - Enhanced reasoning for complex tasks - **context-7** - Advanced context management - **atlassian** - JIRA (RI-XXX tickets) and Confluence integration (requires API tokens in `.env.mcp`) - **figma** - Figma design files, frames, and layers (uses OAuth authentication - no API key needed) ## Updating These Rules To update AI rules: 1. **Edit files in `.ai/` only** (never edit symlinked files directly) 2. **Update `AGENTS.md`** if you change commands, testing instructions, or boundaries 3. Changes automatically propagate to all AI tools via symlinks 4. Commit changes to version control **Remember**: These rules exist to maintain code quality and consistency. Follow them, but also use good judgment. ================================================ FILE: .ai/commands/commit-message.md ================================================ # Commit Message Generation Generate concise, meaningful commit messages following RedisInsight conventions. ## Format ``` (): [optional body] References: #RI-XXX ``` ## Types & Scopes **Types**: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `ci` **Scopes**: `api`, `ui`, `e2e`, `deps` ## Rules **DO:** - ✅ Always include scope: `feat(api):`, `fix(ui):` - ✅ Use imperative mood: "add feature" not "added feature" - ✅ Start with lowercase after scope - ✅ Keep subject under 250 characters - ✅ Inspect all uncommitted files before generating **DON'T:** - ❌ Omit scope - ❌ Use past tense - ❌ Add period at end - ❌ Use multiple scopes (split into separate commits) ## Examples ```bash feat(ui): add user profile editing fix(api): resolve memory leak in connection pool refactor(api): extract validation logic test(e2e): add authentication tests chore(deps): upgrade React to 18.2 ``` ## Issue References **JIRA**: `References: #RI-123` or `Fixes #RI-123` **GitHub**: `Fixes #123` or `Closes #123` ## Process 1. Run `git status && git diff` 2. Identify scope: API → `api`, UI → `ui`, Both → separate commits 3. Identify type: New → `feat`, Bug → `fix`, Improvement → `refactor` 4. Write description (what changed and why) 5. Add issue reference in body ## Multiple Scopes Split into separate commits: ```bash # ✅ Good git commit -m "feat(api): add user endpoint References: #RI-123" git commit -m "feat(ui): add user interface References: #RI-123" # ❌ Bad git commit -m "feat(api,ui): add user feature" ``` ## Output Format Present in copyable format: ```markdown Based on the changes, here's your commit message: \`\`\` feat(api): add OAuth 2.0 authentication Implements OAuth flow with token management and refresh token support. References: #RI-123 \`\`\` ``` If multiple scopes: ```markdown Changes span multiple scopes. I recommend two commits: **Commit 1:** \`\`\` feat(api): add OAuth endpoints References: #RI-123 \`\`\` **Commit 2:** \`\`\` feat(ui): add OAuth login interface References: #RI-123 \`\`\` ``` ================================================ FILE: .ai/commands/e2e-fix.md ================================================ --- description: Run E2E tests and fix any failures argument-hint: --- # Fix E2E Tests Run E2E tests matching a pattern, analyze failures, and fix them. **Follow all standards in `.ai/rules/e2e-testing.md`** ## Input **Test pattern** (required) - Test name or describe block pattern - Examples: `"Analytics > Slow Log"`, `"should add string key"`, `"@smoke"` ## Process ### Step 1: Run the Tests ```bash cd tests/e2e-playwright npx playwright test --grep "" --reporter=list 2>&1 | tail -50 ``` ### Step 2: Analyze Failures If tests fail, check the error context file: ```bash cat test-results//error-context.md | head -150 ``` The error context contains: - **Page snapshot** - Current UI state (element tree with refs) - **Error message** - What assertion failed - **Call log** - Playwright's action log ### Step 3: Diagnose the Issue Common failure patterns: | Error | Likely Cause | Solution | |-------|--------------|----------| | `element(s) not found` | Wrong selector or element not rendered | Check snapshot for correct testid/role | | `Timeout waiting for` | Element takes too long to appear | Add proper wait or check if element exists | | `expected visible` | Element hidden or removed | Verify UI flow, check if dialog closed | | `not.toBeVisible failed` | Element still visible | Wait for element to be removed | ### Step 4: Explore UI if Needed If the error context doesn't reveal the issue, use Playwright MCP to explore: ``` browser_navigate_Playwright → http://localhost:8080 browser_snapshot_Playwright browser_click_Playwright → element, ref ``` ### Step 5: Fix the Test Apply fixes following these priorities: 1. **Fix selectors** - Use correct `data-testid` or role from snapshot 2. **Fix waits** - Replace `waitForTimeout` with proper element waits 3. **Fix test data** - Ensure unique prefixes to avoid conflicts with other tests 4. **Fix assertions** - Match actual UI behavior ### Step 6: Verify the Fix ```bash cd tests/e2e-playwright npx playwright test --grep "" --reporter=list 2>&1 | tail -30 ``` ### Step 7: Run Linter and Type Check **REQUIRED before completing:** ```bash cd tests/e2e-playwright npm run lint && npx tsc --noEmit ``` Both must pass. ## Debugging Tips ### Check Page Snapshot for Correct Selectors ```yaml # Look for data-testid in the snapshot - button "Add" [ref=e123] [cursor=pointer] # Use getByRole('button', { name: 'Add' }) - generic "my-testid" [ref=e456] # Use getByTestId('my-testid') - treeitem "String keyname..." [ref=e789] # Use getByRole('treeitem', { name: /keyname/ }) ``` ### Handle View Mode Differences Browser page has List view and Tree view with different element structures: ```typescript // List view uses gridcell page.getByRole('gridcell', { name: keyName }) // Tree view uses treeitem page.getByRole('treeitem', { name: new RegExp(keyName) }) // KeyList.getKeyRow() handles both ``` ### Test Isolation Issues If test fails inconsistently, check for: - Missing unique suffix in test data (conflicts with parallel runs) - Missing cleanup in `afterEach` - Shared state between tests (use `test.describe.serial` if needed) ### Dropdown/Dialog Issues If clicking fails after interacting with dropdown: ```typescript // Close dropdown before next action await page.keyboard.press('Escape'); ``` ## Example Usage ``` @e2e-fix "Analytics > Slow Log" @e2e-fix "should add string key" @e2e-fix "Browser > Key Details > String" @e2e-fix "@smoke" ``` ## Quick Reference | Command | Purpose | |---------|---------| | `npx playwright test --grep "pattern"` | Run matching tests | | `npx playwright test --grep "pattern" --debug` | Run with inspector | | `npx playwright show-trace ` | View test trace | | `npm run lint` | Check for lint errors | | `npx tsc --noEmit` | Check for type errors | ================================================ FILE: .ai/commands/e2e-generate.md ================================================ --- description: Explore a page using Playwright MCP and generate E2E tests for a Jira ticket argument-hint: --- # Generate E2E Tests Use Playwright MCP to explore a page, discover testable functionality, and generate E2E tests based on a Jira ticket. **Follow all standards in `.ai/rules/e2e-testing.md`** **Reference:** @tests/e2e-playwright/TEST_PLAN.md ## Prerequisites - App must be running at `http://localhost:8080` for Playwright exploration ## Input 1. **Ticket ID or URL** (required) ## Process ### Step 1: Fetch Jira Ticket Details Use the Jira API to get ticket information: - Summary and description - Acceptance criteria - Related components/features ### Step 2: Check Test Plan Review `tests/e2e-playwright/TEST_PLAN.md` to find related tests: - ✅ = Already implemented (skip or verify) - 🔲 = Not implemented (create new) ### Step 3: Explore the Page with Playwright MCP Navigate to the relevant page based on the ticket's feature area: ``` browser_navigate_Playwright → url (e.g., http://localhost:8080) browser_snapshot_Playwright browser_click_Playwright → element, ref browser_snapshot_Playwright (after each action) ``` Look for: - `data-testid` attributes → use with `page.getByTestId()` - Element roles (button, combobox, grid) → use with `page.getByRole()` - Form field placeholders → use with `page.getByPlaceholder()` ### Step 4: Check Existing Infrastructure ```bash ls tests/e2e-playwright/tests/ ls tests/e2e-playwright/pages/ ls tests/e2e-playwright/test-data/ ``` ### Step 5: Generate Test Artifacts Based on exploration and ticket requirements, create/update: 1. **Page Object** - `tests/e2e-playwright/pages/{feature}/{Feature}Page.ts` 2. **Test Data Factory** - `tests/e2e-playwright/test-data/{feature}/index.ts` 3. **Fixture** (if new page) - Update `tests/e2e-playwright/fixtures/base.ts` 4. **Test File** - `tests/e2e-playwright/tests/{feature}/{action}/*.spec.ts` ### Step 6: Verify Run only the new tests using list reporter (no HTML report): ```bash cd tests/e2e-playwright npx playwright test tests/main/{feature}/{action}/ --project=chromium --reporter=list npm run lint && npx tsc --noEmit ``` **Note:** Use `--reporter=list` to avoid Playwright generating and hosting an HTML report. Use `--project=chromium` to run only browser tests (faster feedback). ### Step 7: Update Test Plan Update `tests/e2e-playwright/TEST_PLAN.md` to match actual tests: - **Rename** test case names to match the actual test titles in spec files - **Add** new test cases that were created - **Delete** test cases that were removed or consolidated - Mark implemented tests as ✅ Test case names in TEST_PLAN.md should exactly match the test titles in spec files (e.g., `should open Help Center and display all menu options`). ## Exploration Checklist - [ ] Main page purpose and entry points - [ ] Forms and their fields - [ ] Buttons and their actions - [ ] Lists/tables and CRUD operations - [ ] Dialogs/modals triggered by actions - [ ] Loading states and spinners - [ ] Success/error toasts - [ ] Empty states - [ ] Validation messages - [ ] `data-testid` attributes ## Feature-to-URL Mapping | Feature | URL Pattern | |---------|-------------| | Database Management | `http://localhost:8080` | | Browser | `http://localhost:8080/{dbId}/browser` | | Workbench | `http://localhost:8080/{dbId}/workbench` | | CLI | (Panel on any database page) | | Pub/Sub | `http://localhost:8080/{dbId}/pub-sub` | | Slow Log | `http://localhost:8080/{dbId}/analytics/slowlog` | | Database Analysis | `http://localhost:8080/{dbId}/analytics/database-analysis` | | Settings | `http://localhost:8080/settings` | **Note:** Replace `{dbId}` with an actual database UUID. ## Example Usage ``` @e2e-generate RI-7992 @e2e-generate https://redislabs.atlassian.net/browse/RI-7992 ``` The command will: 1. Fetch ticket details from Jira 2. Determine the relevant page/feature to test 3. Explore the UI at http://localhost:8080 4. Generate appropriate E2E tests based on ticket requirements ================================================ FILE: .ai/commands/generate-release-notes.md ================================================ *** description: Generate release notes from JIRA tickets for a specific version argument-hint: \[jira-filter-link-or-jql-or-csv-file] --------------------------------------------------------------- Generate release notes for RedisInsight releases based on JIRA tickets. ## Examples ```bash # Generate from JIRA filter link (PREFERRED) generate-release-notes 3.0.3 "https:///jira/software/c/projects//issues?jql=project%20%3D%20..." # Generate from JIRA query (JQL) generate-release-notes 3.0.2 "project = AND parent = " # Generate from CSV export generate-release-notes 3.0.2 /path/to/jira-export.csv # Generate from ticket keys generate-release-notes 3.0.2 ,, ``` **Always reference the GitHub releases page as the source of truth for format and style:** https://github.com/redis/RedisInsight/releases Use existing releases (especially recent ones like 3.0.2, 3.0.0) as examples for: * Format and structure * Tone and language * Section organization * Ticket reference format ## 1. Get Version and Ticket Data **If version is not provided as an argument, prompt the user for it.** The version should be in semantic versioning format (e.g., `3.0.2`). **Ticket data can be provided in one of these ways:** 1. **JIRA Filter Link** (PREFERRED): If a JIRA filter link is provided: * **Detection**: Check if the input starts with `http://` or `https://` and contains `atlassian.net` and `jql=` * **Example**: `https:///jira/software/c/projects//issues?jql=project%20%3D%20...` * Extract the JQL query from the URL (decode URL-encoded parameters) * **Use the JavaScript script `scripts/fetch-jira-tickets.js` to fetch all tickets matching the filter** (or JIRA MCP tools if available) * For each ticket, fetch complete details including: * Issue key, summary, type, status, priority * Labels (check for "Github-Issue" label) * Description * All custom fields and metadata needed for categorization * Process the tickets the same way as CSV data 2. **JIRA Query (JQL)**: If a raw JQL query is provided (e.g., `project = AND parent = `), use the JIRA MCP tools to fetch tickets with full details 3. **CSV File**: If a CSV file path is provided, parse it to extract ticket information * To export from JIRA: Go to JIRA → Search for issues → Run your JQL query → Export → CSV * The CSV will contain all ticket information needed for generation 4. **Ticket Keys**: If specific ticket keys are provided (e.g., `,`), fetch each ticket individually with full details ## 2. Fetch and Categorize Tickets For each ticket, analyze its essence to categorize it: ### Exclusion Rules **Exclude entirely (do not include in any section):** * **Spike tickets**: If issue type is "Spike", exclude from release notes * **POC tickets**: If "POC" appears in the title or description (indicating proof-of-concept that is not implemented), exclude from release notes * These tickets are not ready for release and should not be mentioned ### Categorization Logic **Bug indicators:** * Issue type contains "bug" or "defect" * Summary contains: "fix", "bug", "error", "issue", "broken", "crash", "fail" * Labels contain "bug" or "defect" **IMPORTANT: Bugs/Bug fixes section filter:** * **Only tickets with the "Github-Issue" label should be included in the Bugs/Bug fixes section** * When processing tickets from JIRA query or CSV, filter bugs to only include those with the "Github-Issue" label * **Include all bugs that have the "Github-Issue" label**—every such ticket must appear in the Bugs section with no limit or additional filtering * Other bug tickets (without this label) should be excluded from the Bugs/Bug fixes section * **Bugs with Github-Issue label should ONLY appear in the Bugs section, NOT in Headlines or Details sections** * **Always list each of these bugs with the GitHub issue link**: For every ticket in the Bugs section (tickets with "Github-Issue" label), output the line in the form `[#ISSUE-NUMBER](https://github.com/redis/RedisInsight/issues/ISSUE-NUMBER) [Short description]`. Resolve the GitHub issue number from: (1) JIRA labels such as `Github-4658` (use the number part), (2) JIRA description or linked PR body (e.g. "References #5381", "Closes #5382"), or (3) search on GitHub (repo: redis/RedisInsight) for the issue or PR that matches the bug (e.g. by JIRA key like RI-7894 or by summary). If the number cannot be determined, still include the short description but add a note to look up the link. **Feature indicators:** * Issue type contains: "story", "feature", "epic", "enhancement" * Summary contains: "add", "implement", "new", "introduce", "support", "enable" * Labels contain "feature" or "enhancement" **Improvement indicators:** * Issue type contains: "task", "improvement" * Summary contains: "improve", "enhance", "update", "optimize", "refactor" * Labels contain "improvement" ## 3. Generate Release Notes Use the template from `docs/release-notes/RELEASE_NOTES_TEMPLATE.md` as a reference. ### Format Selection * **If only bugs (with "Github-Issue" label)**: Use simple "Bug fixes" section only; include every ticket that has the "Github-Issue" label * **If features/improvements exist**: Use full format with "Headlines", "Details", and "Bugs" sections * Note: The "Bugs" section must include all tickets with the "Github-Issue" label (include every one) ### Section Organization Rules **IMPORTANT: Avoid duplication between sections:** * **Tickets with "Github-Issue" label**: These should **ONLY** appear in the "Bugs" section, never in "Headlines" or "Details" sections * **No duplication**: Items in the Bugs section must not appear in Headlines or Details sections * **Headlines and Details relationship**: * Headlines should contain short summaries of the most important user-facing features and improvements * Details can expand on Headlines items with more information, or include additional features/improvements not mentioned in Headlines * The same item can appear in both Headlines (short summary) and Details (full description), but items from Bugs section must not appear in either ### Release Notes Structure **Reference format from GitHub releases:** https://github.com/redis/RedisInsight/releases ```markdown # [VERSION] ([MONTH] [YEAR]) [Release description based on content] ### Headlines (if features exist - see 3.0.0 example) * [Top 3-5 most important items - user-facing features or critical improvements] ### Details (if features/improvements exist - see 3.0.0 example) * [Short description of what was added/improved] (for JIRA tickets, don't include ticket ID) * [#ISSUE-NUMBER](https://github.com/redis/RedisInsight/issues/ISSUE-NUMBER) [Summary] (for GitHub issues, use link format) ### Bugs (if features exist) OR Bug fixes (if only bugs - see 3.0.2 example) * **IMPORTANT: Include all tickets with the "Github-Issue" label in this section (every one, no limit). Always list each bug with its GitHub issue link.** * Each line must be: `[#ISSUE-NUMBER](https://github.com/redis/RedisInsight/issues/ISSUE-NUMBER) [Short description of problem and fix]` * Resolve ISSUE-NUMBER from JIRA labels (e.g. Github-4658 → 4658), ticket/PR references, or GitHub search if needed. **SHA-512 Checksums** https://redis.io/docs/latest/develop/tools/insight/release-notes/v.[VERSION]/ **Full Changelog**: https://github.com/redis/RedisInsight/compare/[LAST_RELEASED]...[VERSION] ``` **Important formatting notes from GitHub releases:** * **For the Bugs section (tickets with "Github-Issue" label)**: Always list each bug with its GitHub issue link: `[#](https://github.com/redis/RedisInsight/issues/) [Short description]`. Resolve the issue number from JIRA labels (e.g. `Github-4658`), from "References #NNNN" / "Closes #NNNN" in linked PRs or descriptions, or by searching GitHub (repo: redis/RedisInsight) for the matching issue. * **For other JIRA tickets** (Headlines/Details): Do NOT include ticket IDs. Provide a very short description of what was added or fixed. * **For GitHub issues** (when referenced elsewhere): Use actual links in format `[#](https://github.com/redis/RedisInsight/issues/)` (not just `#` or `#`). * Use "SHA-512 Checksums" for all releases * Keep descriptions concise and user-focused * Headlines should highlight the most impactful user-facing changes ### Release Description **Examples from GitHub releases:** * **Major releases** (x.0.0): "This is the General Availability (GA) release of Redis Insight \[version], a major version upgrade that introduces \[key themes]." * See 3.0.0 example: mentions "new UI experience, new navigation architecture, and foundational improvements" * **Patch releases with only bugs**: * Check ticket priorities to determine description: * If only high/critical priority bugs: "This maintenance patch release includes critical bug fixes for Redis Insight \[major.minor].0." * If only medium/low priority bugs: "This maintenance patch release includes non-critical bug fixes for Redis Insight \[major.minor].0." * If both critical and non-critical: "This maintenance patch release includes critical and non-critical bug fixes for Redis Insight \[major.minor].0." * See 3.0.2 example * **Patch releases with features**: "This release includes new features, improvements, and bug fixes for Redis Insight." * See 2.64, 2.62, 2.60 examples for format with "Highlights" and "Details" sections ## 4. Generate All Release Note Formats After generating the main release notes, create **two different formats** for different platforms: ### 4.1 GitHub/Redis Docs Format Save the generated release notes to `RELEASE_NOTES_[VERSION].md` in the repository root. **Important: Links** * **Checksums link**: Use format `https://redis.io/docs/latest/develop/tools/insight/release-notes/v.[VERSION]/` * Example for 3.0.3: `https://redis.io/docs/latest/develop/tools/insight/release-notes/v.3.0.3/` * **Full Changelog link**: Use format `https://github.com/redis/RedisInsight/compare/[LAST_RELEASED]...[VERSION]` * Example for 3.0.3 (if last release was 3.0.2): `https://github.com/redis/RedisInsight/compare/3.0.2...3.0.3` * Determine the last released version by checking GitHub releases or repository tags ### 4.2 Store Format (App Store & Microsoft Store) Save to `RELEASE_NOTES_STORE_[VERSION].md` in the repository root. **IMPORTANT:** Reuse the same content from the GitHub/Redis Docs format (`RELEASE_NOTES_[VERSION].md`), but apply different formatting. Only the formatting changes - the content (sections, descriptions, items) should remain the same. **Note:** This single file is used for both App Store and Microsoft Store as they have identical format requirements. **Format requirements (formatting changes only):** * Plain text only (no markdown formatting) * Section header: "Bug fixes" (if only bugs) or appropriate section name (if features exist) - keep the same section names from GitHub format * Use bullet points with `•` character (not `*`) * No version number or date header * No links (remove SHA-512 Checksums and Full Changelog sections) * No markdown headers (`#`, `###`) * No bold formatting (`**`) * Just the section headers and bullet points - same content, different formatting **Example format:** ``` Bug fixes • Fixed default database sorting order to display most recently used databases at the top • Restored missing Pub/Sub functionality including message clear option, full message display with line wrapping, and descending chronological order (most recent messages first) ``` **If features/improvements exist, use appropriate section headers:** ``` Features • [Feature description] Improvements • [Improvement description] Bug fixes • [Bug fix description] ``` ## 5. Display Summary Show a summary of: * Total tickets processed * Number of bugs, features, and improvements * Which format was used (simple vs. full) * File locations for all formats: * GitHub/Redis Docs: `RELEASE_NOTES_[VERSION].md` * App Store & Microsoft Store: `RELEASE_NOTES_STORE_[VERSION].md` ## JIRA Filter Link Processing When a JIRA filter link is provided: 1. **Parse the URL and fetch tickets**: Extract the JQL query from the `jql` parameter in the URL and use the JavaScript script `scripts/fetch-jira-tickets.js` to fetch all tickets matching the query * Example URL: `https:///jira/software/c/projects//issues?jql=project%20%3D%20%20AND%20status%20%3D%20Closed` * Extract and decode: `project = AND status = Closed` * **Use `node scripts/fetch-jira-tickets.js ` to fetch tickets** (the script uses JIRA REST API with credentials from `.env.mcp`) * Alternatively, if JIRA MCP tools are available, use them (check with `list_mcp_resources`) such as `jira_search` or `jira_get_project_issues` 2. **Fetch full details**: For each ticket returned, fetch complete information: * **Basic fields**: key, summary, type, status, priority, description * **Labels**: Extract all labels and check for "Github-Issue" label (critical for filtering) * **Custom fields**: Any additional fields needed for categorization * **Links**: Check for linked GitHub pull requests or issues * **Metadata**: Created date, updated date, resolved date, assignee, reporter 3. **Transform to CSV-like structure**: Convert the fetched ticket data into a structure similar to CSV format: ```javascript { 'Issue key': '', 'Summary': 'Fix default database sorting...', 'Issue Type': 'Bug', 'Status': 'Closed', 'Priority': 'Medium', 'Labels': ['Github-Issue', 'Github-Issue-Notification'], 'Description': 'Full description text...', // ... other fields } ``` 4. **Process**: Use the same categorization and filtering logic as CSV processing ## Notes * Keep summaries concise, user-focused, and descriptive * For Headlines section, prioritize the most impactful user-facing changes (see 3.0.0 example) * Ensure all closed tickets are included if they match the criteria * **Always check GitHub releases page** before generating to ensure consistency with published format: https://github.com/redis/RedisInsight/releases * Match the tone and style of existing releases (professional, clear, user-focused) ================================================ FILE: .ai/commands/pr-plan.md ================================================ --- description: Analyze a JIRA ticket and create a detailed implementation plan argument-hint: --- Create a comprehensive implementation plan for a JIRA ticket. ## 1. Fetch JIRA Ticket **If ticket ID is not provided as an argument, prompt the user for it.** Fetch all the information from the ticket, its comments, linked documents, and parent ticket. Use the `jira` tool to fetch the ticket details. ## 4. Create Implementation Plan Use `sequential-thinking` tool for complex analysis. Break down into thoughts: ### Thought 1-5: Requirements Analysis - Parse acceptance criteria into specific tasks - Identify functional requirements - Identify non-functional requirements (performance, security, cost) - Map requirements to system components - Identify dependencies and blockers ### Thought 6-10: Architecture Planning - Determine which services are affected - Identify new components needed - Identify existing components to modify - Plan data flow and interactions - Consider error handling and edge cases ### Thought 16-20: Implementation Breakdown - Break work into logical phases - Identify dependencies between phases - Consider testing strategy for each phase - Plan for incremental delivery ### Thought 21-25: Testing Strategy - Identify test scenarios from acceptance criteria - Plan unit tests (behavior-based, not implementation) - Plan integration tests - Consider edge cases and error scenarios - Plan test data needs ### Thought 26-30: Risk Assessment - Identify technical risks - Identify integration risks - Identify timeline risks - Identify knowledge gaps - Plan mitigation strategies ## 5. Generate Implementation Plan Document **CRITICAL: You MUST create and save a plan document. This is NOT optional.** Create a comprehensive Markdown document and save it to `docs/pr-plan-{ticket-id}-{brief-description}.md` using the `write` tool. **IMPORTANT: Planner Detection** - Detect which AI tool is being used (Cursor, Augment, or other) - Set the **Planner** field to: - "Cursor Agent" if running in Cursor - "Augment Agent" if running in Augment - "[Tool Name] Agent" for other tools - You can infer the tool from context, user messages, or environment **The document structure MUST include all sections below:** ```markdown # Implementation Plan: [Ticket Title] **JIRA Ticket:** [MOD-XXXXX](https://redislabs.atlassian.net/browse/MOD-XXXXX) **Epic:** [EPIC-XXX](link) (if applicable) **Parent:** [PARENT-XXX](link) (if applicable) **Plan Date:** [Date] **Planner:** [Detect and set: Cursor Agent / Augment Agent / [Tool Name] Agent] --- ## Executive Summary **Components Affected:** - [component name] **Key Risks:** 1. [Risk with mitigation] 2. [Risk with mitigation] 3. [Risk with mitigation] --- ## 1. Requirements Summary **Story (Why):** [Quote or summarize the story from the ticket] **Acceptance Criteria (What):** 1. [AC1] 2. [AC2] 3. [AC3] **Functional Requirements:** - [Requirement 1] - [Requirement 2] **Non-Functional Requirements:** - [NFR 1 - e.g., Performance: <100ms response time] - [NFR 2 - e.g., Security: Requires authentication] **Resources Provided:** - [Link 1: Description] - [Link 2: Description] ## 2. Current State Analysis ### Frontend Changes **Components to Modify:** - [Component 1]: [What changes are needed] - [Component 2]: [What changes are needed] **Components to Create:** - [Component 1]: [Why it's needed] - [Component 2]: [Why it's needed] **Components to Reuse:** - [Component 1]: [How it will be used] - [Component 2]: [How it will be used] ### Backend Changes **Services to Modify:** - [Service 1]: [What changes are needed] - [Service 2]: [What changes are needed] **Services to Create:** - [Service 1]: [Why it's needed] - [Service 2]: [Why it's needed] **APIs to Modify:** - [API 1]: [What's changing] - [API 2]: [What's changing] **APIs to Create:** - [API 1]: [Why it's needed] - [API 2]: [Why it's needed] **Data Models:** - [Model 1]: [Description and whether it needs extension] - [Model 2]: [Description and whether it needs extension] **Repositories:** - [Repo 1]: [Description and whether it can be reused] --- ## 3. Implementation Plan ### Phase 1: [Phase Name] **Goal:** [What this phase achieves] **Tasks:** 1. [ ] [Task 1 - specific, actionable] - Files: [List of files to create/modify] - Acceptance: [How to verify this task is done] 2. [ ] [Task 2] - Files: [List of files] - Acceptance: [Verification criteria] **Deliverables:** - [Deliverable 1] - [Deliverable 2] **Testing:** - [Test scenario 1] - [Test scenario 2] ### Phase 2: [Phase Name] [Same structure as Phase 1] ### Phase 3: [Phase Name] [Same structure as Phase 1] --- ## 5. Testing Strategy ### Test Scenarios (from Acceptance Criteria) **AC1: [Acceptance Criterion]** - Test Scenario: [Given-When-Then] - Test Type: Unit/Integration - Test Location: [File path] **AC2: [Acceptance Criterion]** - Test Scenario: [Given-When-Then] - Test Type: Unit/Integration - Test Location: [File path] ### Edge Cases and Error Scenarios 1. **[Edge Case 1]** - Scenario: [Description] - Expected Behavior: [What should happen] - Test: [How to test] 2. **[Error Scenario 1]** - Scenario: [Description] - Expected Error: [Error type/code] - Test: [How to test] ### Test Data Needs - [Test data 1]: [Description] - [Test data 2]: [Description] --- ## 6. Risk Assessment and Mitigation ### Technical Risks | Risk | Likelihood | Impact | Mitigation | | -------- | --------------- | --------------- | --------------------- | | [Risk 1] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | | [Risk 2] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | ### Integration Risks | Risk | Likelihood | Impact | Mitigation | | -------- | --------------- | --------------- | --------------------- | | [Risk 1] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | ### Timeline Risks | Risk | Likelihood | Impact | Mitigation | | -------- | --------------- | --------------- | --------------------- | | [Risk 1] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | ### Knowledge Gaps - [Gap 1]: [What we don't know and how to find out] - [Gap 2]: [What we don't know and how to find out] ``` --- ## 6. Save the Plan Document **CRITICAL: You MUST save the plan document using the `write` tool.** 1. **Generate the complete plan document** following the structure in section 5 2. **Save it** to `docs/pr-plan-{ticket-id}-{brief-description}.md` using `write` tool 3. **Verify the file was created** by confirming the write tool succeeded **Example filename:** `docs/pr-plan-MOD-11280-dp-services-clean-architecture.md` --- ## 7. Follow-up Actions After saving the plan document: 1. **Confirm document was saved** - Show the file path to the user 2. **Summarize key findings** for the user: - Key risks - Recommended approach - **Confirm plan document was saved** (file path) 3. **Ask if user wants to:** - Review the plan document - Proceed with implementation --- ## Important Notes - **ALWAYS save the plan document** - use `write` tool to save to `docs/pr-plan-{ticket-id}-{brief-description}.md` - **Use main branch as baseline** - all analysis should be against current main - **Be specific and actionable** - every task should be clear and verifiable - **Consider PR stacking** - plan for small, reviewable PRs (see `.ai/rules/pull-requests.md`). plan breaking the implementation in a stack of PRs. - **Follow all project standards** - reference rules in `.ai/rules/` - **Document assumptions** - if anything is unclear, document the assumption made - **Identify blockers early** - surface dependencies and knowledge gaps upfront ## Execution Order Summary **The correct order of operations is:** 1. ✅ Fetch JIRA ticket 2. ✅ Analyze current codebase state 3. ✅ Create implementation plan using sequential-thinking 4. ✅ Generate implementation plan document content 5. ✅ **Save plan document to `docs/pr-plan-{ticket-id}-{brief-description}.md`** (CRITICAL - use write tool) 6. ✅ Present results to user and confirm document location **Do NOT skip step 5 - it is mandatory and must be done during command execution.** **Step 5 is MANDATORY:** You MUST use the `write` tool to save the plan document. Do NOT just present the plan to the user without saving it. ================================================ FILE: .ai/commands/pull-request-review.md ================================================ # PR Review Command ## Purpose Reviews code changes in the current branch against requirements, best practices, and project standards. ## Usage ```bash /pr:review ``` **Examples**: - JIRA ticket: `/pr:review RI-1234` - GitHub issue: `/pr:review 456` ## Prerequisites 1. Checkout the branch to review locally 2. Ensure the ticket ID is valid and accessible 3. Have JIRA MCP tool configured (if using JIRA integration) ## Process ### 1. Gather Context - Fetch JIRA ticket details (if available) - Read requirements and acceptance criteria - Identify affected files in the PR - Review recent commits ### 2. Code Analysis Analyze the changes against: - **Code Quality**: Linting rules, TypeScript types, complexity - **Testing**: Test coverage, test quality, edge cases - **Performance**: Rendering optimizations - **Security**: Input validation, XSS prevention, credential handling - **Accessibility**: ARIA labels, keyboard navigation, semantic HTML - **Best Practices**: React patterns, Redux usage, NestJS conventions ### 3. Requirements Check - Verify all acceptance criteria are met - Check for missing functionality - Validate edge case handling - Ensure proper error messages ### 4. Testing Validation - Unit test coverage (80% minimum) - Integration tests for API endpoints - Component tests for React components - E2E tests for critical flows - No fixed timeouts or magic numbers - Use of faker for test data ### 5. Generate Report Create a markdown report in `docs/reviews/pr--.md` with: **Note**: Use appropriate ticket reference format: - JIRA tickets: `pr-RI-1234-2024-11-20.md` - GitHub issues: `pr-456-2024-11-20.md` Report should include: - **Summary**: Overview of changes - **Strengths**: What was done well - **Issues**: Categorized by severity (Critical, High, Medium, Low) - **Suggestions**: Improvements and optimizations - **Requirements Coverage**: Acceptance criteria checklist - **Testing Assessment**: Coverage and quality analysis - **Risk Assessment**: Potential issues or impacts ## Review Checklist ### Code Quality - [ ] No linting errors - [ ] TypeScript types are proper (no `any` without justification) - [ ] Code follows project conventions - [ ] No console.log statements - [ ] Import order is correct - [ ] Cognitive complexity within limits - [ ] No duplicate code ### Testing - [ ] Unit tests added/updated - [ ] Test coverage meets thresholds - [ ] Tests use faker for data generation - [ ] No fixed timeouts in tests - [ ] Edge cases are tested - [ ] Mocks are properly configured ### React/Frontend (if applicable) - [ ] Functional components with hooks - [ ] Proper state management (Redux vs local) - [ ] Effects cleanup properly - [ ] No unnecessary re-renders - [ ] Accessibility considerations - [ ] Styled-components for styling (no new SCSS modules) - [ ] Proper error boundaries - [ ] Component folder structure follows guidelines ### NestJS/Backend (if applicable) - [ ] Dependency injection used properly - [ ] DTOs for validation - [ ] Proper error handling - [ ] Swagger documentation - [ ] Service layer separation - [ ] Database transactions where needed ### Performance - [ ] No performance regressions - [ ] Large lists virtualized - [ ] Routes lazy loaded - [ ] Expensive operations memoized - [ ] Bundle size impact acceptable ### Security - [ ] Input validation - [ ] Output sanitization - [ ] No sensitive data in logs - [ ] Proper authentication/authorization - [ ] SQL injection prevention (if applicable) ### Documentation - [ ] README updated if needed - [ ] Complex logic documented - [ ] API documentation updated - [ ] Breaking changes noted ## Example Output **Note**: Use appropriate ticket format (RI-1234 for JIRA or #456 for GitHub issues) ```markdown # PR Review: RI-1234 - Add User Profile Editing **Date**: 2024-11-20 **Reviewer**: AI Assistant **Branch**: feature/RI-1234/user-profile-editing ## Summary This PR implements user profile editing functionality including UI components, API endpoints, and data persistence. The implementation follows project standards with good test coverage. ## High Priority Issues 1. **Missing Input Validation** (Security) - File: `redisinsight/api/src/user/user.service.ts:45` - Issue: Email validation missing on backend - Recommendation: Add class-validator decorator to DTO ## Medium Priority Issues 1. **Performance Concern** (Performance) - File: `redisinsight/ui/src/components/UserProfile.tsx:78` - Issue: Inline function in render - Recommendation: Extract to useCallback 2. **Test Flakiness Risk** (Testing) - File: `redisinsight/ui/src/components/UserProfile.spec.tsx:45` - Issue: Direct state check without waitFor - Recommendation: Wrap assertion in waitFor ## Low Priority Issues 1. **Code Style** (Style) - File: Multiple files - Issue: Inconsistent import ordering - Recommendation: Run `yarn prettier:fix` ## Risk Assessment **Low Risk** - Well-tested implementation with minor issues that can be addressed before merge. No breaking changes or security vulnerabilities. ## Recommendation **Approve with comments** - Address high priority issues before merging. Consider suggestions for future improvements. ``` ## Notes - Focus on constructive feedback - Prioritize issues by severity - Be specific with file locations and line numbers - Provide actionable recommendations - Balance criticism with recognition of good practices - Consider the broader impact of changes ================================================ FILE: .ai/rules/backend.md ================================================ --- description: NestJS backend development patterns, module structure, services, controllers, DTOs, and error handling globs: redisinsight/api/**/*.ts alwaysApply: false --- # Backend Development (NestJS/API) ## Module Structure ### NestJS Architecture - Follow **modular architecture** (feature-based modules) - Use **dependency injection** throughout - **Separate concerns**: Controllers, Services, Repositories - Use **DTOs** for validation and data transfer - Apply **proper error handling** with NestJS exceptions ### Module Folder Structure Each feature module in its own directory under `api/src/`: ``` feature/ ├── feature.module.ts # Module definition ├── feature.controller.ts # REST endpoints ├── feature.service.ts # Business logic ├── feature.service.spec.ts # Service tests ├── feature.controller.spec.ts # Controller tests ├── feature.types.ts # Interfaces and types related to the feature ├── dto/ # Data transfer objects │ ├── create-feature.dto.ts │ ├── update-feature.dto.ts │ └── feature.dto.ts ├── entities/ # TypeORM entities ├── repositories/ # Custom repositories ├── exceptions/ # Custom exceptions ├── guards/ # Feature-specific guards ├── decorators/ # Custom decorators └── constants/ # Feature constants ``` ### File Naming - **Modules**: `feature.module.ts` - **Controllers**: `feature.controller.ts` - **Services**: `feature.service.ts` - **DTOs**: `create-feature.dto.ts`, `update-feature.dto.ts` - **Entities**: `feature.entity.ts` - **Interfaces and types**: `feature.types.ts` - **Tests**: `feature.service.spec.ts` - **Constants**: `feature.constants.ts` - **Exceptions**: `feature-not-found.exception.ts` ### Constants Organization Store feature-specific constants in dedicated constants file: ```typescript export const FEATURE_CONSTANTS = { MAX_NAME_LENGTH: 100, DEFAULT_PAGE_SIZE: 20, } as const; export const FEATURE_ERROR_MESSAGES = { NOT_FOUND: 'Feature not found', INVALID_INPUT: 'Invalid feature data', } as const; ``` ### Imports Order 1. Node.js built-in modules 2. External dependencies (`@nestjs/*`, etc.) 3. Internal modules (using `apiSrc/*` alias) 4. Local relative imports ## Service Layer ### Service Pattern - Inject dependencies via constructor - Use TypeORM repositories - Handle errors with NestJS exceptions - Use Logger for important operations - Keep business logic in services (not controllers) ### Dependency Injection Always inject dependencies via constructor with proper decorators: ```typescript @Injectable() export class UserService { constructor( @InjectRepository(User) private readonly userRepository: Repository, private readonly emailService: EmailService, ) {} } ``` ## Controller Layer ### Controller Pattern - Keep controllers thin (delegate to services) - Use proper HTTP decorators (`@Get`, `@Post`, etc.) - Use `@Body`, `@Param`, `@Query` for inputs - Apply guards with `@UseGuards()` - Document with Swagger decorators ### HTTP Status Codes - Use `@HttpCode()` decorator for non-standard codes - Return appropriate status codes (200, 201, 204, 400, 404, etc.) ## Data Transfer Objects (DTOs) ### Validation Use `class-validator` decorators for validation: - `@IsString()`, `@IsNumber()`, `@IsEmail()` - `@IsNotEmpty()`, `@IsOptional()` - `@MinLength()`, `@MaxLength()` - `@Min()`, `@Max()` ### Swagger Documentation Use `@ApiProperty()` and `@ApiPropertyOptional()` for Swagger docs. ## Error Handling ### NestJS Exceptions Use appropriate exception types: - `NotFoundException` - 404 - `BadRequestException` - 400 - `UnauthorizedException` - 401 - `ForbiddenException` - 403 - `ConflictException` - 409 - `InternalServerErrorException` - 500 ### Custom Exceptions **Prefer custom exceptions over generic ones** when you need: - Consistent error codes for frontend handling - Specific error messages from constants - Consistent error structure across the codebase Create custom exceptions following existing patterns: ```typescript // src/modules/feature/exceptions/feature-invalid.exception.ts import { HttpException, HttpExceptionOptions, HttpStatus, } from '@nestjs/common'; import ERROR_MESSAGES from 'src/constants/error-messages'; import { CustomErrorCodes } from 'src/constants'; export class FeatureInvalidException extends HttpException { constructor( message = ERROR_MESSAGES.FEATURE_INVALID, options?: HttpExceptionOptions, ) { const response = { message, statusCode: HttpStatus.BAD_REQUEST, error: 'FeatureInvalid', errorCode: CustomErrorCodes.FeatureInvalid, }; super(response, response.statusCode, options); } } ``` ### Error Logging ```typescript private readonly logger = new Logger(ServiceName.name) this.logger.error('Error message', error.stack, { context }) ``` ## Redis Integration ### Redis Service Pattern - Use RedisClient from `apiSrc/modules/redis` - Handle errors gracefully - Log Redis operations - Use try-catch for error handling ## Code Quality ### Cognitive Complexity (≤ 15) - Use early returns to reduce nesting - Extract complex logic to separate functions - Avoid deeply nested conditions ### No Duplicate Strings Extract repeated strings to constants in constants file. ## API Documentation (Swagger) ### Required Decorators - `@ApiTags()` - Group endpoints - `@ApiOperation()` - Describe operation - `@ApiResponse()` - Document responses - `@ApiParam()` - Document params - `@ApiQuery()` - Document query params - `@ApiBearerAuth()` - Auth requirement ## Checklist - [ ] Services use dependency injection - [ ] DTOs have validation decorators - [ ] Controllers have Swagger documentation - [ ] Proper HTTP status codes used - [ ] Error handling with appropriate exceptions - [ ] Logging for important operations - [ ] Transactions for related DB operations - [ ] Configuration via ConfigService - [ ] Guards for authentication/authorization - [ ] Cognitive complexity ≤ 15 ================================================ FILE: .ai/rules/code-quality.md ================================================ --- alwaysApply: true --- # Code Quality Standards ## Critical Rules - **ALWAYS run linter** after code changes: `yarn lint` - Linter must pass before committing - No console.log in production code (use console.warn/error only) ## TypeScript Standards ### Essential Rules - Use TypeScript for all new code - **Avoid `any`** - use proper types or `unknown` - **Prefer interfaces** for object shapes - Use **type** for unions, intersections, primitives - Add explicit return types for non-obvious functions - Leverage type inference where clear ## Import Organization ### Required Order (enforced by ESLint) 1. External libraries (`react`, `lodash`, etc.) 2. Built-in Node modules (`path`, `fs` - backend only) 3. Internal modules with aliases (`uiSrc/*`, `apiSrc/*`) 4. Sibling/parent relative imports 5. Style imports (ALWAYS LAST) ### Module Aliases - `uiSrc/*` → `redisinsight/ui/src/*` - `apiSrc/*` → `redisinsight/api/src/*` - `desktopSrc/*` → `redisinsight/desktop/src/*` ✅ **Use aliases**: `import { Button } from 'uiSrc/components/Button'` ❌ **Avoid relative**: `import { Button } from '../../../ui/src/components/Button'` ## Naming Conventions - **Components**: `PascalCase` - `UserProfile` - **Functions/Variables**: `camelCase` - `fetchUserProfile` - **Constants**: `UPPER_SNAKE_CASE` - `MAX_RETRY_ATTEMPTS` - **Booleans**: Use `is/has/should` prefix - `isLoading`, `hasError` ## SonarJS Rules - Keep cognitive complexity low (refactor complex functions) - Extract duplicate strings to constants - Follow DRY principle - no duplicate code - Use immediate return (avoid unnecessary intermediate variables) ## Best Practices - Use destructuring for objects and arrays - Use template literals over string concatenation - Use `const` by default, `let` only when reassignment needed - Use descriptive variable names - Handle errors properly - Clean up subscriptions and timers - Use constants instead of magic numbers ## Vite Cache Management When updating npm packages (especially `@redis-ui/*` packages): 1. **Clear Vite cache** after `yarn install`: ```bash rm -rf node_modules/.vite rm -rf redisinsight/ui/node_modules/.vite ``` 2. **Restart dev server** to rebuild dependencies 3. This ensures new package versions are properly loaded ## Pre-Commit Checklist - [ ] `yarn lint` passes - [ ] No TypeScript errors - [ ] Import order is correct - [ ] No `any` types without reason - [ ] No console.log statements - [ ] No magic numbers - [ ] Descriptive variable names - [ ] Low cognitive complexity - [ ] No duplicate code - [ ] Vite cache cleared (if updated dependencies) ================================================ FILE: .ai/rules/e2e-testing.md ================================================ --- description: Playwright E2E testing standards, page object models, test structure, fixtures, and navigation patterns globs: tests/e2e-playwright/**/*.ts alwaysApply: false --- # E2E Testing Standards (Playwright) ## Location All E2E tests are in `tests/e2e-playwright/`. This is a **standalone package** - no imports from `redisinsight/ui/` or `redisinsight/api/`. ## Test Plan **Always refer to `tests/e2e-playwright/TEST_PLAN.md`** for: - Test coverage status (✅ implemented, 🔲 not implemented) - Feature implementation order - Test data requirements **After implementing tests, update TEST_PLAN.md** to mark tests as ✅. ## Project Structure ``` tests/e2e-playwright/ ├── TEST_PLAN.md # Master test plan with coverage status ├── config/ # Configuration (env, databases) │ └── databases/ # Database configs by type ├── fixtures/ # Playwright fixtures ├── helpers/ # API helpers for setup/teardown ├── pages/ # Page Object Models │ ├── BasePage.ts # Base class for all pages │ ├── InstancePage.ts # Base class for database instance pages │ ├── components/ # Shared components (InstanceHeader, NavigationTabs, BottomPanel) │ └── {feature}/ # Feature-specific pages (browser/, cli/, etc.) ├── test-data/ # Test data factories ├── tests/ # Test specs organized by project │ ├── main/ # Default parallel tests │ │ └── {feature}/ │ │ └── {action}/ │ ├── auto-update/ # Serial tests with special setup │ └── electron/ # Electron-specific tests └── types/ # TypeScript types ``` ## Playwright Projects Tests are organized into **projects** based on execution requirements. Each project can have different parallelism, timeouts, and setup. | Project | Folder | Parallelism | Use Case | |---------|--------|-------------|----------| | `main` | `tests/main/` | Parallel | Standard tests that can run concurrently | | `auto-update` | `tests/auto-update/` | Serial | Tests requiring special setup or causing flakiness | | `electron` | `tests/electron/` | Serial | Electron-specific features (deep links, etc.) | ### Running Projects ```bash npx playwright test --project=main # Only main parallel tests npx playwright test --project=auto-update # Only auto-update tests npx playwright test # All projects ``` ### When to Create a New Project Create a new project folder when tests: - Require different parallelism settings (serial vs parallel) - Need different global setup/teardown - Would cause flakiness when run with other tests - Require special environment configuration ### Adding a New Project 1. Create folder under `tests/` (e.g., `tests/my-feature/`) 2. Add project configuration in `playwright.config.ts`: ```typescript { name: 'my-feature', testDir: './tests/my-feature', fullyParallel: false, // or true workers: 1, timeout: 120000, // Optional: different setup // globalSetup: './my-feature-setup.ts', } ``` ## Page Objects ### Page Object Hierarchy ``` BasePage (abstract) ├── DatabasesPage # Databases list page ├── SettingsPage # Settings page └── InstancePage (abstract) # Base for all database instance pages ├── instanceHeader # Database name, stats, breadcrumb ├── navigationTabs # Browse, Workbench, Analyze, Pub/Sub ├── bottomPanel # CLI, Command Helper, Profiler └── BrowserPage # Browser-specific (extends InstancePage) └── WorkbenchPage (future) └── AnalyzePage (future) └── PubSubPage (future) ``` ### Extend the Appropriate Base Class - **BasePage** - For standalone pages (DatabasesPage, SettingsPage) - **InstancePage** - For pages within a connected database (BrowserPage, WorkbenchPage, etc.) Page objects are **stateless** - they don't store database objects. Pass `databaseId` to navigation methods. ```typescript // For database instance pages - extend InstancePage import { Page, Locator } from '@playwright/test'; import { InstancePage } from '../InstancePage'; export class WorkbenchPage extends InstancePage { readonly editor: Locator; constructor(page: Page) { super(page); this.editor = page.getByTestId('workbench-editor'); } // InstancePage provides: instanceHeader, navigationTabs, bottomPanel // Plus navigation methods: navigateToBrowser(), openCli(), etc. async goto(databaseId: string): Promise { await this.gotoDatabase(databaseId); await this.navigationTabs.gotoWorkbench(); await this.waitForLoad(); } } ``` ### Component-Based Structure Break large pages into components: ```typescript // pages/feature/FeaturePage.ts export class FeaturePage extends InstancePage { readonly dialog: FeatureDialog; readonly list: FeatureList; constructor(page: Page) { super(page); this.dialog = new FeatureDialog(page); this.list = new FeatureList(page); } } ``` ## Test Structure ### File Organization ``` tests/ ├── main/ # Default parallel tests (most tests go here) │ └── {feature}/ # e.g., databases, browser, workbench │ └── {action}/ # e.g., add, edit, delete │ ├── standalone.spec.ts │ └── cluster.spec.ts ├── auto-update/ # Serial tests with special setup └── electron/ # Electron-specific tests ``` ### Test Setup Pattern Use simple, explicit setup with clear separation of concerns. **Page objects are fixtures** - they don't store database state. Pass `databaseId` to `goto()` methods. ```typescript import { test, expect } from '../../../fixtures/base'; import { standaloneConfig } from '../../../config/databases/standalone'; import { DatabaseInstance } from '../../../types'; test.describe('Feature > Action', () => { let database: DatabaseInstance; // Setup: Create database once for all tests test.beforeAll(async ({ apiHelper }) => { database = await apiHelper.createDatabase({ name: 'test-feature-db', host: standaloneConfig.host, port: standaloneConfig.port, }); }); // Teardown: Clean up database after all tests test.afterAll(async ({ apiHelper }) => { await apiHelper.deleteDatabase(database.id); }); test.describe('Sub-feature', () => { // Navigation: Pass databaseId to goto() - page is a fixture test.beforeEach(async ({ featurePage }) => { await featurePage.goto(database.id); }); // Tests receive page fixtures they need test('should do something', async ({ featurePage }) => { await featurePage.doAction(); await expect(featurePage.result).toBeVisible(); }); // Tests that need both page and apiHelper test('should create and verify', async ({ featurePage, apiHelper }) => { await apiHelper.createKey(database.id, 'test-key', 'value'); await featurePage.refresh(); await expect(featurePage.keyList).toContainText('test-key'); }); }); }); ``` ### Key Principles 1. **`beforeAll`** - Create database/test data via API (runs once) 2. **`afterAll`** - Clean up database/test data via API (runs once) 3. **`beforeEach`** - Navigate to page via UI using `goto(databaseId)` (runs before each test) 4. **Individual tests** - Receive page fixtures they need in the signature 5. **Page objects are stateless** - Don't store database objects in pages, pass IDs to methods ### Avoid These Anti-Patterns ```typescript // ❌ BAD: Storing database in page object const browserPage = createBrowserPage(database); // OLD pattern - don't use // ✅ GOOD: Pass databaseId to goto() await browserPage.goto(database.id); // ❌ BAD: Using page fixture without declaring it in test signature test('should work', async () => { await browserPage.doSomething(); // browserPage is undefined! }); // ✅ GOOD: Declare fixtures in test signature test('should work', async ({ browserPage }) => { await browserPage.doSomething(); }); // ❌ BAD: Navigation inside each test test('should work', async ({ browserPage }) => { await browserPage.goto(database.id); // Should be in beforeEach // ... }); // ❌ BAD: Using test.describe.serial when not needed test.describe.serial('Feature', () => { // Use regular describe unless tests truly depend on each other // ... }); ``` ## Test Data ### Use Fishery Factories with Faker Use the [fishery](https://github.com/thoughtbot/fishery) library for test data factories: ```typescript import { Factory } from 'fishery'; import { faker } from '@faker-js/faker'; export const TEST_PREFIX = 'test-'; export const ConfigFactory = Factory.define(() => ({ name: `${TEST_PREFIX}${faker.string.alphanumeric(8)}`, host: '127.0.0.1', port: 6379, })); // Usage in tests const config = ConfigFactory.build(); const config = ConfigFactory.build({ name: 'custom-name' }); ``` ### Cleanup Pattern Always prefix test data with `test-` for easy cleanup: ```typescript // In apiHelper async deleteTestData(): Promise { return this.deleteByPattern(new RegExp(`^${TEST_PREFIX}`)); } ``` ## Fixtures ### Add New Fixtures to base.ts ```typescript // fixtures/base.ts type Fixtures = { myPage: MyPage; apiHelper: ApiHelper; }; export const test = base.extend({ myPage: async ({ page }, use) => { await use(new MyPage(page)); }, apiHelper: async ({}, use) => { const helper = new ApiHelper(); await use(helper); await helper.dispose(); }, }); ``` ## UI Exploration with Playwright MCP **Before writing tests, ALWAYS use Playwright MCP to explore the UI:** ### Why Explore First? - Discover actual `data-testid` attributes used in the application - Understand element roles and accessible names for `getByRole()` - See page structure and component hierarchy - Avoid trial-and-error test writing ### Exploration Workflow 1. **Navigate to the page**: `browser_navigate_Playwright` to target URL 2. **Take snapshot**: `browser_snapshot_Playwright` to see element tree 3. **Interact with elements**: `browser_click_Playwright` to trigger dialogs, dropdowns, etc. 4. **Wait for async content**: `browser_wait_for_Playwright` for dynamic content 5. **Document findings**: Add discovered UI patterns to `TEST_PLAN.md` under the feature section ### What to Look For - `data-testid` attributes → use with `page.getByTestId()` - Element roles (button, combobox, grid, treeitem) → use with `page.getByRole()` - Accessible names → use with `{ name: 'text' }` option - Form field placeholders → use with `page.getByPlaceholder()` - Text content patterns → use with `page.getByText()` ### Use Discovered Patterns in Page Objects After exploring, use discovered patterns directly in Page Object locators: ```typescript // Use data-testid when available this.addButton = page.getByTestId('btn-add-key'); // Use role + name for accessible elements this.submitButton = page.getByRole('button', { name: 'Submit' }); // Use placeholder for form fields this.searchInput = page.getByPlaceholder('Search...'); ``` **Note**: Keep TEST_PLAN.md as a simple visual list of test cases. Document UI patterns in Page Object comments if needed. ## Best Practices ### ✅ DO - **Explore UI with Playwright MCP before writing tests** - **Use Page Object navigation methods** (e.g., `browserPage.goto()`, `workbenchPage.goto()`) - Use `data-testid` attributes for stable selectors - Use `getByRole`, `getByLabel` for accessible elements - Wait for elements with `waitFor({ state: 'visible' })` - Clean up test data in `afterEach` - Use API for setup, UI for assertions - Handle both List view and Tree view in key assertions ### ❌ DON'T - **NEVER use `page.goto()` directly** - tests must work in both browser and Electron - Write tests without exploring the actual UI first - Use fixed timeouts (`waitForTimeout`) - Use CSS selectors for dynamic content - Leave test data after tests - Import from `redisinsight/ui/` or `redisinsight/api/` - Hardcode test data (use faker) - Assume element structure without verification ## Navigation (IMPORTANT) **All navigation must use UI-based methods, NOT URL navigation.** Tests must work in both browser mode (http://localhost:8080) and Electron mode (no baseURL). Direct `page.goto()` calls fail in Electron because there's no baseURL. ### Navigation Architecture **BasePage** provides only fundamental navigation: ```typescript await this.gotoHome(); // Click Redis logo → databases list await this.gotoDatabase(dbId); // Click database → Browser page (default) ``` **Each page owns its navigation** via its `goto()` method: ```typescript await settingsPage.goto(); // Settings page await browserPage.goto(dbId); // Browser page for database await workbenchPage.goto(dbId); // Workbench page for database await analyticsPage.goto(dbId); // Analytics page for database await pubSubPage.goto(dbId); // Pub/Sub page for database ``` **NavigationTabs component** handles tab switching within a connected database: ```typescript await browserPage.navigationTabs.gotoBrowser(); await browserPage.navigationTabs.gotoWorkbench(); await browserPage.navigationTabs.gotoAnalyze(); await browserPage.navigationTabs.gotoPubSub(); ``` ### ✅ Correct Navigation Pattern ```typescript // Use Page Object's goto() method in beforeEach test.beforeEach(async ({ browserPage }) => { await browserPage.goto(database.id); // Navigates and waits for page load }); // Switch tabs when already connected await browserPage.navigationTabs.gotoWorkbench(); ``` ### ❌ Incorrect Navigation Pattern ```typescript // NEVER do this - fails in Electron await page.goto(`/${database.id}/browser`); await page.goto('/settings'); await page.goto('/'); ``` ## Running Tests ```bash npm test # Main project tests (default) npm run test:main # Main project tests only npm run test:electron # Electron tests (auto-detects platform) npm run test:all # All projects ENV=ci npm test # CI environment ENV=staging npm test # Staging environment ``` ## Code Quality (IMPORTANT) **Always run linter and type checker after making changes:** ```bash npm run lint # ESLint check npx tsc --noEmit # TypeScript type check ``` Both must pass before committing. Common issues: - Unused variables/imports - Missing return types - `any` types (avoid when possible) - Null/undefined handling (use proper types like `Promise`) ## Test Isolation (IMPORTANT) Tests should be isolated and not depend on execution order: ### 1. Shared Database with beforeAll/afterAll ```typescript test.describe('Feature Name', () => { let database: DatabaseInstance; test.beforeAll(async ({ apiHelper }) => { database = await apiHelper.createDatabase({ name: 'test-feature-db', ... }); }); test.afterAll(async ({ apiHelper }) => { await apiHelper.deleteDatabase(database.id); }); // Tests can run in parallel - they share the database but don't modify shared state }); ``` ### 2. Use Serial Only When Tests Truly Depend on Each Other ```typescript // Only use .serial when tests modify state that subsequent tests depend on test.describe.serial('Workflow that modifies state', () => { test('step 1: create item', ...); test('step 2: modify item created in step 1', ...); test('step 3: delete item', ...); }); ``` ### 3. Unique Test Data Per Test (when needed) ```typescript test('should create unique item', async ({ apiHelper }) => { const uniqueName = `test-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`; // Use uniqueName for this test's data }); ``` ## Feature-to-Path Mapping Follow this naming convention for test and page object paths: | Feature | Test Path | Page Object Path | |---------|-----------|------------------| | Database List | `tests/main/databases/list/` | `pages/databases/` | | Add Database | `tests/main/databases/add/` | `pages/databases/` | | Import Database | `tests/main/databases/import/` | `pages/databases/` | | Browser - Key List | `tests/main/browser/key-list/` | `pages/browser/` | | Browser - Add Key | `tests/main/browser/add-key/` | `pages/browser/` | | Browser - Key Details | `tests/main/browser/key-details/` | `pages/browser/` | | Workbench | `tests/main/workbench/` | `pages/workbench/` | | CLI | `tests/main/cli/` | `pages/cli/` | | Pub/Sub | `tests/main/pubsub/` | `pages/pubsub/` | | Slow Log | `tests/main/analytics/slow-log/` | `pages/analytics/` | | DB Analysis | `tests/main/analytics/analysis/` | `pages/analytics/` | | Settings | `tests/main/settings/` | `pages/settings/` | | Navigation | `tests/main/navigation/` | `pages/navigation/` | | Auto-Update | `tests/auto-update/` | `pages/` (shared) | | Deep Links | `tests/electron/deep-links/` | `pages/` (shared) | **Note**: Most tests go in `tests/main/`. Only use other project folders for tests with special requirements (serial execution, different setup, etc.). ================================================ FILE: .ai/rules/frontend.md ================================================ --- description: React frontend development patterns, Redux, styled-components, UI components, and hooks globs: redisinsight/ui/**/*.{ts,tsx} alwaysApply: false --- # Frontend Development (React/Redux) ## Component Structure ### Functional Components - Use **functional components with hooks** (no class components) - **Prefer named exports** over default exports - Keep components focused and single-responsibility - Extract complex logic into custom hooks ### Component Folder Structure Each component in its own directory under `**/ComponentName`: ``` ComponentName/ ComponentName.tsx # Main component ComponentName.styles.ts # Styled-components styles (PascalCase) ComponentName.types.ts # TypeScript interfaces ComponentName.spec.tsx # Tests ComponentName.constants.ts # Constants ComponentName.story.tsx # Storybook examples hooks/ # Custom hooks components/ # Sub-components utils/ # Utility functions ``` ### Props Interface - Name as `ComponentNameProps` - Use separate interfaces for complex prop objects - Always use proper TypeScript types, never `any` ### Imports Order in Components 1. External dependencies (`react`, `redux`, etc.) 2. Internal modules (aliases) 3. Local imports (types, constants, hooks) 4. Styles (always last: `import { Container } from './Component.styles'`) ### Barrel Files Use barrel files (`index.ts`) only when exporting **3 or more** items. Make sure exports appear in only one barrel file, not propagated up the chain. ## Styled Components **We are migrating to styled-components** (deprecating SCSS modules). ### Encapsulate Styles in .styles.ts Keep all component styles in dedicated `.styles.ts` files using styled-components. Use PascalCase for the filename to match the component name: ``` ComponentName/ ComponentName.tsx ComponentName.styles.ts # ✅ PascalCase # Not component-name.styles.ts ❌ ``` ### Import Pattern Keep all component styles in dedicated .style.ts files and import them with a namespace. **CRITICAL: `import * as S` is reserved for local styles only** (e.g., from `ComponentName.styles.ts`). When you need to use styled components from external components, create a local styles file that re-exports them. #### ✅ Good ```typescript // ComponentName.tsx import * as S from './ComponentName.styles' return ( Title Content ) // ComponentName.styles.ts (when re-exporting from external component) export { ExternalStyledComponent } from '../ExternalComponent/ExternalComponent.styles' ``` #### ❌ Bad ```typescript // ❌ BAD: Importing styled components directly from external component import * as S from '../ExternalComponent/ExternalComponent.styles' // ❌ BAD: Named imports instead of namespace import { Container, Title, Content } from './Component.styles' ``` ### Use Layout Components Instead of div **Prefer `FlexGroup` over `div`** when creating flex containers: ```typescript // ✅ GOOD: Use FlexGroup import { FlexGroup } from 'uiSrc/components/base/layout/flex' export const Wrapper = styled(FlexGroup)` user-select: none; ` // Usage: Pass layout props as component props {children} // ❌ BAD: Using div with hardcoded flex properties export const Wrapper = styled.div` display: flex; align-items: center; justify-content: flex-end; ` ``` ### Pass Layout Props as Component Props **Don't hardcode layout properties** in styled components when using layout components like `FlexGroup`. Pass them as props instead: ```typescript // ✅ GOOD: Pass props in JSX export const Wrapper = styled(FlexGroup)` user-select: none; ` {children} // ❌ BAD: Hardcoding in styled component export const Wrapper = styled(FlexGroup)` align-items: center; justify-content: flex-end; user-select: none; ` ``` ### Use Gap Prop Instead of Custom Margins **Prefer `gap` prop on layout components** instead of custom margins for spacing between elements: ```typescript // ✅ GOOD: Use gap prop Item 1 Item 2 ``` ### Use Theme Spacing Instead of Magic Numbers **Always use theme spacing values** instead of hardcoded pixel values: ```typescript // ✅ GOOD: Use theme spacing export const Container = styled(Row)` height: ${({ theme }) => theme.core.space.space500}; padding: 0 ${({ theme }) => theme.core.space.space200}; margin-bottom: ${({ theme }) => theme.core.space.space200}; `; // ❌ BAD: Using magic numbers export const Container = styled(Row)` height: 64px; padding: 0 16px; margin-bottom: 16px; `; ``` ### Use Semantic Colors from Theme **Always use semantic colors** from the theme instead of CSS variables or hardcoded colors: ```typescript // ✅ GOOD: Use semantic colors export const Header = styled(Row)` background-color: ${({ theme }) => theme.semantic.color.background.neutral100}; border-bottom: 1px solid ${({ theme }) => theme.semantic.color.border.neutral500}; `; // ❌ BAD: Using deprecated EUI CSS variables export const Header = styled(Row)` background-color: var(--euiColorEmptyShade); border-bottom: 1px solid var(--separatorColor); `; ``` ### Use Layout Components (Row/Col/FlexGroup) Instead of div **Prefer layout components** from the layout system instead of regular `div` elements: ```typescript // ✅ GOOD: Use Row component import { Row } from 'uiSrc/components/base/layout/flex' export const PageHeader = styled(Row)` height: ${({ theme }) => theme.core.space.space500}; background-color: ${({ theme }) => theme.semantic.color.background.neutral100}; ` {children} // ❌ BAD: Using div with flex properties export const PageHeader = styled.div` display: flex; align-items: center; justify-content: space-between; height: 64px; ` ``` ### Conditional Styling Use `$` prefix for transient props that shouldn't pass to DOM: ```typescript export const Button = styled.button<{ $isActive?: boolean }>` background-color: ${({ $isActive }) => ($isActive ? '#007bff' : '#6c757d')}; `; ``` ### Avoid !important **Never use `!important` in styled-components**. Styled-components handles CSS specificity through component hierarchy. If you need to override styles, use more specific selectors or adjust the component structure: ```typescript // ✅ GOOD: Rely on CSS specificity export const IconButton = styled(IconButton)<{ isOpen: boolean }>` ${({ isOpen }) => isOpen && css` background-color: ${({ theme }) => theme.semantic.color.background.primary200}; `} `; // ❌ BAD: Using !important export const IconButton = styled(IconButton)` background-color: ${({ theme }) => theme.semantic.color.background.primary200} !important; `; ``` ### Verify Type System Compatibility When using layout components or other typed components, verify your prop values match the type system: ```typescript // Check the component's type definitions // FlexGroup accepts: align?: 'center' | 'stretch' | 'baseline' | 'start' | 'end' // Use valid values from the type system ``` ## State Management (Redux) ### When to Use What - **Global State (Redux)**: - Data shared across multiple components - Data persisting across routes - Server state (API data) - User preferences/settings - **Local State (useState)**: - UI state (modals, dropdowns, tabs) - Form inputs before submission - Component-specific temporary data - **Derived State (Selectors)**: - Computed values from Redux state - Filtered/sorted lists - Aggregated data ### Redux Toolkit Patterns #### Slice Structure - Use `createSlice` from Redux Toolkit - Define proper TypeScript types for state - Use `PayloadAction` for action typing - Handle async with `extraReducers` and thunks #### Thunks - Use `createAsyncThunk` for async operations - Handle pending, fulfilled, and rejected states - Use `rejectWithValue` for error handling #### Selectors - Create basic selectors for direct state access - Use `createSelector` from `reselect` for memoized/computed values - Keep selectors in separate `selectors.ts` file ## React Best Practices ### Performance - Use `useCallback` for functions passed as props - Use `useMemo` for expensive computations - Use `React.memo` for expensive components - Avoid inline arrow functions in JSX props ### Effect Cleanup Always clean up subscriptions, timers, and event listeners in `useEffect` return function. ### Keys in Lists - Use unique, stable IDs (not array indices) - Only use indices if list never reorders and items have no IDs ### Conditional Rendering - Use early returns for loading/error states - Avoid deeply nested ternaries - extract to functions ## Custom Hooks ### Extract Reusable Logic Create custom hooks for reusable stateful logic. Store component-specific hooks in the component's `/hooks` directory. ## Form Handling Use Formik with Yup for validation. Keep form logic in custom hooks when complex. ## UI Components **⚠️ IMPORTANT**: - We are **deprecating Elastic UI** components - Migrating to **Redis UI** (`@redis-ui/*`) - **Use internal wrappers** from `uiSrc/components/ui` - **DO NOT import directly** from `@redis-ui/*` ### Component Usage ```typescript // ✅ GOOD: Import from internal wrappers import { Button, Input, FlexGroup } from 'uiSrc/components/ui'; // ❌ BAD: Don't import directly from @redis-ui import { Button } from '@redis-ui/components'; // ❌ DEPRECATED: Don't use Elastic UI for new code import { EuiButton } from '@elastic/eui'; ``` ### Migration Guidelines - ✅ Use internal wrappers from `uiSrc/components/ui` for all new features - ✅ Create internal wrappers for Redis UI components as needed - ✅ Replace Elastic UI when touching existing code - ❌ Do not import directly from `@redis-ui/*` - ❌ Do not add new Elastic UI imports ## Icons **⚠️ IMPORTANT**: Always use icons from Redis UI library instead of custom SVGs. ### Icon Usage - **Use Redis UI icons** from `@redis-ui/icons` via `iconRegistry.tsx` - Icons are automatically exported via `export * from '@redis-ui/icons'` in `iconRegistry.tsx` - Use `RiIcon` component with icon type: `` - **DO NOT create custom SVG icons** - check if the icon exists in Redis UI library first ### Custom Icons (Exception) Only create custom SVG icons if: - The icon doesn't exist in Redis UI library - It's a project-specific icon that won't be added to the library ## Testing Components ### Always Use Shared `renderComponent` Helper **CRITICAL**: Create a `renderComponent` helper function for each component test file: ```typescript describe('MyComponent', () => { const defaultProps: MyComponentProps = { id: faker.string.uuid(), name: faker.person.fullName(), onComplete: jest.fn(), } const renderComponent = (propsOverride?: Partial) => { const props = { ...defaultProps, ...propsOverride } return render( ) } it('should render', () => { renderComponent() // assertions }) }) ``` Benefits: - Centralized setup and providers - Default props in one place - Easy prop overrides per test - No duplicate render logic ### Testing Redux Create a test store with `configureStore` for components connected to Redux. ## Key Principles 1. **Separation of Concerns**: Keep styles, types, constants, logic separate 2. **Colocate Related Code**: Keep sub-components and hooks close to usage 3. **Consistent Naming**: Follow conventions across all components 4. **Type Safety**: Always define proper types, never `any` 5. **Testability**: Structure for easy testing with `renderComponent` helper 6. **Styled Components**: Prefer styled-components over SCSS modules 7. **Layout Components**: Use FlexGroup instead of div for flex containers, pass layout props as component props 8. **Type Safety**: Verify prop values match component type definitions (e.g., FlexGroup's align/justify values) ================================================ FILE: .ai/rules/git-safety.md ================================================ --- description: Critical safety guardrails for protected branches - prevents direct commits, pushes, and force pushes to main, latest, and release branches alwaysApply: true --- # Git Safety Rules for AI Agents ## 🚫 CRITICAL: Protected Branch Rules **AI agents must NEVER commit to or push to protected branches under any circumstances.** ### Protected Branches - `main` - Primary production branch - `latest` - Latest stable release - `release/*` - Release branches (e.g., `release/v2.0.0`) This is a non-negotiable rule that applies to all scenarios: ### Prohibited Actions - ❌ **Direct commits** - Never run `git commit` while on a protected branch - ❌ **Direct pushes** - Never run `git push origin ` or `git push` while on a protected branch - ❌ **Force pushes** - Never run `git push --force` or `git push -f` targeting protected branches - ❌ **Merging into protected branches locally** - Never run `git merge ` while on a protected branch - ❌ **Rebasing protected branches** - Never run `git rebase` while on a protected branch - ❌ **Resetting protected branches** - Never run `git reset` while on a protected branch ### Required Workflow 1. **Always create a feature branch** before making any changes 2. **Verify current branch** before any git operation using `git branch --show-current` 3. **Create Pull Requests** for all changes - let the review process handle merging ### Pre-Push Checklist Before executing any push command, AI agents must: 1. ✅ Confirm current branch is NOT a protected branch (`main`, `latest`, `release/*`) 2. ✅ Verify the remote and branch target ### Error Recovery If accidentally on a protected branch with uncommitted changes: 1. Stash changes: `git stash` 2. Create new branch: `git checkout -b ` 3. Apply changes: `git stash pop` 4. Continue work on the new branch ## Rationale - Protected branches represent production-ready or release code - All changes must go through code review via Pull Requests - Direct pushes bypass CI/CD checks and team review - Mistakes on protected branches can affect the entire team and deployment pipeline ================================================ FILE: .ai/rules/testing.md ================================================ --- description: Jest and Testing Library standards, test patterns, faker usage, renderComponent helper, and mocking globs: "redisinsight/**/*.spec.{ts,tsx}" alwaysApply: false --- # Testing Standards and Practices ## Core Principles - **Write tests for all new features** - Follow **AAA pattern**: Arrange, Act, Assert - Use **descriptive test names**: "should do X when Y" - **CRITICAL**: Never use fixed time waits - tests must be deterministic - **CRITICAL**: Use faker library (@faker-js/faker) for test data ## Test Organization ```typescript describe('FeatureService', () => { describe('findById', () => { it('should return entity when found', () => {}); it('should throw NotFoundException when not found', () => {}); }); describe('create', () => { it('should create entity with valid data', () => {}); it('should throw error with invalid data', () => {}); }); }); ``` ## Frontend Testing (Jest + Testing Library) ### Running Specific Tests ```bash # Run a specific test file node 'node_modules/.bin/jest' 'redisinsight/ui/src/path/to/Component.spec.tsx' -c 'jest.config.cjs' # Run a specific test by name (use -t flag) node 'node_modules/.bin/jest' 'redisinsight/ui/src/path/to/Component.spec.tsx' -c 'jest.config.cjs' -t 'test name pattern' # Example: node 'node_modules/.bin/jest' 'redisinsight/ui/src/slices/tests/browser/keys.spec.ts' -c 'jest.config.cjs' -t 'refreshKeyInfoAction' ``` ### CRITICAL: Always Use Shared `renderComponent` Helper **Create a `renderComponent` helper for each component test file**: ```typescript import { faker } from '@faker-js/faker'; describe('MyComponent', () => { // Define default props with faker const defaultProps: MyComponentProps = { id: faker.string.uuid(), name: faker.person.fullName(), email: faker.internet.email(), onComplete: jest.fn(), }; // Shared render helper const renderComponent = (propsOverride?: Partial) => { const props = { ...defaultProps, ...propsOverride }; return render( ); }; beforeEach(() => { jest.clearAllMocks(); }); it('should render component', () => { renderComponent(); expect(screen.getByText(defaultProps.name)).toBeInTheDocument(); }); it('should handle click', async () => { const mockOnComplete = jest.fn(); renderComponent({ onComplete: mockOnComplete }); fireEvent.click(screen.getByRole('button')); await waitFor(() => { expect(mockOnComplete).toHaveBeenCalledTimes(1); }); }); }); ``` **Benefits**: - Centralized setup (providers, router, theme) - Default props defined once - Easy prop overrides per test - No duplicate setup code ### Complex Component Setup For components requiring Router, ThemeProvider, etc., include them in `renderComponent`: ```typescript const renderComponent = (propsOverride?: Partial) => { const props = { ...defaultProps, ...propsOverride } return render( ) } ``` ### Testing with Redux Create a test store with `configureStore` for Redux-connected components: ```typescript const createTestStore = (initialState = {}) => { return configureStore({ reducer: { user: userSlice.reducer }, preloadedState: initialState, }); }; const renderComponent = (propsOverride?: Partial, storeState = {}) => { const testStore = createTestStore(storeState); // render with testStore }; ``` ### Query Priorities (Testing Library) **Prefer accessible queries** (as users would interact): ```typescript // ✅ PREFERRED screen.getByRole('button', { name: /submit/i }); screen.getByLabelText('Email'); screen.getByPlaceholderText('Enter name'); // ⚠️ LAST RESORT screen.getByTestId('user-profile'); // ❌ AVOID wrapper.find('.button-class'); ``` ### Testing Async Behavior ```typescript // ✅ GOOD: waitFor with proper queries await waitFor(() => { expect(screen.getByText('Data loaded')).toBeInTheDocument(); }); // ✅ GOOD: waitForElementToBeRemoved await waitForElementToBeRemoved(() => screen.queryByText('Loading...')); // ✅ GOOD: findBy queries (built-in waiting) const element = await screen.findByText('Async content'); // ❌ BAD: Fixed timeouts (flaky tests) await new Promise((resolve) => setTimeout(resolve, 1000)); ``` ### Mocking API Calls (MSW) Use Mock Service Worker for API mocking: ```typescript import { rest } from 'msw'; import { setupServer } from 'msw/node'; const server = setupServer( rest.get('/api/users/:id', (req, res, ctx) => { return res( ctx.json({ id: req.params.id, name: faker.person.fullName(), }), ); }), ); beforeAll(() => server.listen()); afterEach(() => server.resetHandlers()); afterAll(() => server.close()); ``` ## Backend Testing (NestJS/Jest) ### Service Test Pattern ```typescript import { Factory } from 'fishery'; import { faker } from '@faker-js/faker'; // Define factory for User entity const userFactory = Factory.define(() => ({ id: faker.string.uuid(), name: faker.person.fullName(), email: faker.internet.email(), })); describe('UserService', () => { let service: UserService; let repository: Repository; const mockRepository = { find: jest.fn(), findOne: jest.fn(), save: jest.fn(), update: jest.fn(), delete: jest.fn(), }; beforeEach(async () => { const module = await Test.createTestingModule({ providers: [ UserService, { provide: getRepositoryToken(User), useValue: mockRepository, }, ], }).compile(); service = module.get(UserService); repository = module.get>(getRepositoryToken(User)); }); afterEach(() => { jest.clearAllMocks(); }); it('should return user when found', async () => { const mockUser = userFactory.build(); mockRepository.findOne.mockResolvedValue(mockUser); const result = await service.findById(mockUser.id); expect(result).toEqual(mockUser); }); }); ``` ### Controller Test Pattern ```typescript import { Factory } from 'fishery'; import { faker } from '@faker-js/faker'; const userFactory = Factory.define(() => ({ id: faker.string.uuid(), name: faker.person.fullName(), email: faker.internet.email(), })); describe('UserController', () => { let controller: UserController; let service: UserService; const mockService = { findAll: jest.fn(), findById: jest.fn(), create: jest.fn(), }; beforeEach(async () => { const module = await Test.createTestingModule({ controllers: [UserController], providers: [{ provide: UserService, useValue: mockService }], }).compile(); controller = module.get(UserController); }); it('should return user from service', async () => { const mockUser = userFactory.build(); mockService.findById.mockResolvedValue(mockUser); const result = await controller.findById(mockUser.id); expect(result).toEqual(mockUser); }); }); ``` ### Integration Tests (E2E) ```typescript describe('UserController (e2e)', () => { let app: INestApplication; beforeAll(async () => { const module = await Test.createTestingModule({ imports: [AppModule], }).compile(); app = module.createNestApplication(); await app.init(); }); afterAll(async () => { await app.close(); }); it('/users (GET)', () => { return request(app.getHttpServer()) .get('/users') .expect(200) .expect((res) => { expect(Array.isArray(res.body)).toBe(true); }); }); }); ``` ## E2E Testing (Playwright) ```typescript import { Factory } from 'fishery'; import { faker } from '@faker-js/faker'; const userDataFactory = Factory.define(() => ({ name: faker.person.fullName(), email: faker.internet.email(), })); test.describe('User Management', () => { test('should create new user', async ({ page }) => { const userData = userDataFactory.build(); await page.goto('/users'); await page.click('text=Add User'); await page.fill('[name="name"]', userData.name); await page.fill('[name="email"]', userData.email); await page.click('text=Submit'); // ✅ Use proper waits await expect(page.locator(`text=${userData.name}`)).toBeVisible(); }); }); ``` ## Best Practices ### Always Use Faker for Test Data ```typescript // ✅ GOOD: Use faker const user = { id: faker.string.uuid(), name: faker.person.fullName(), email: faker.internet.email(), age: faker.number.int({ min: 18, max: 100 }), }; // ❌ BAD: Hardcoded data const user = { id: '123', name: 'Test User' }; ``` ### Use Factories Instead of Static Mocks **Use Fishery** for creating test data factories with sensible defaults and overrides: ```typescript // ✅ GOOD: Fishery factory import { Factory } from 'fishery'; import { faker } from '@faker-js/faker'; const userFactory = Factory.define(({ sequence }) => ({ id: faker.string.uuid(), name: faker.person.fullName(), email: faker.internet.email(), age: faker.number.int({ min: 18, max: 100 }), })); // Usage - flexible and reusable const user1 = userFactory.build(); const user2 = userFactory.build({ age: 25 }); const user3 = userFactory.build({ name: 'Specific Name' }); const users = userFactory.buildList(5); // Create multiple // ❌ BAD: Static mock objects const mockUser1 = { id: '123', name: 'User 1', email: 'user1@test.com', age: 30, }; ``` Benefits of Fishery factories: - Easy to override specific properties per test - Consistent default values across tests - Single source of truth for mock structure - Better maintainability when types change - Built-in support for sequences and traits ### Never Use Fixed Timeouts ```typescript // ❌ BAD: Fixed timeout await new Promise((resolve) => setTimeout(resolve, 1000)); await page.waitForTimeout(2000); // ✅ GOOD: Wait for condition await waitFor(() => { expect(element).toBeInTheDocument(); }); await page.waitForSelector('[data-test="result"]'); ``` ### Mock External Dependencies ```typescript // ✅ GOOD: Mock services jest.mock('uiSrc/services/api', () => ({ apiService: { get: jest.fn(), post: jest.fn(), }, })); ``` ### Parameterized Tests with `it.each` **Use `it.each` for multiple tests with the same body but different inputs:** ```typescript // ✅ GOOD: Parameterized tests it.each([ { description: 'null', value: null }, { description: 'undefined', value: undefined }, { description: 'empty string', value: '' }, { description: 'whitespace only', value: ' ' }, ])('should return error when input is $description', async ({ value }) => { const result = await service.processInput(value); expect(result.status).toBe('error'); }); ``` **Benefits:** - DRY: Single test body shared across all cases - Maintainability: Changes to test logic only need to be made once - Readability: Test cases are clearly defined in a table - Easier to extend: Adding new test cases is just adding a new row ### Test Edge Cases Always test: - Empty arrays/objects - Null/undefined values - Error scenarios - Boundary conditions - Loading states ## Testing Checklist - [ ] All new features have tests - [ ] Tests use faker for data generation - [ ] No fixed timeouts (use waitFor) - [ ] Tests follow AAA pattern - [ ] Descriptive test names - [ ] Shared `renderComponent` helper used - [ ] Default props defined - [ ] Edge cases covered - [ ] Error scenarios tested - [ ] Mocks cleaned up between tests - [ ] Integration tests for API endpoints - [ ] E2E tests for critical flows - [ ] Coverage meets thresholds (80%+) ================================================ FILE: .ai/skills/branches/SKILL.md ================================================ --- name: branches description: >- Create and name git branches following project conventions and GitHub Actions enforcement rules. Use when creating branches, checking out new branches, or the user mentions branch naming. --- # Branch Naming Conventions Use lowercase kebab-case with type prefix and issue/ticket identifier. **Branch names must match GitHub Actions workflow rules** (see `.github/workflows/enforce-branch-name-rules.yml`). ```bash # Pattern: // # INTERNAL (JIRA - RI-XXX) feature/RI-123/add-user-profile bugfix/RI-789/memory-leak fe/feature/RI-567/add-dark-mode be/bugfix/RI-345/fix-redis-connection docs/RI-333/update-docs test/RI-444/add-unit-tests e2e/RI-555/add-integration-tests # OPEN SOURCE (GitHub - XXX) feature/123/add-export-feature bugfix/789/fix-connection-timeout # Special branches release/v2.0.0 ric/RI-666/custom-prefix ``` ## Allowed Branch Types (GitHub Actions Enforced) - `feature/` - New features and refactoring (affects multiple areas) - `bugfix/` - Bug fixes (affects multiple areas) - `fe/feature/` - Frontend-only features (only `redisinsight/ui/` folder) - `fe/bugfix/` - Frontend-only bug fixes (only `redisinsight/ui/` folder) - `be/feature/` - Backend-only features (only `redisinsight/api/` folder) - `be/bugfix/` - Backend-only bug fixes (only `redisinsight/api/` folder) - `docs/` - Documentation changes - `test/` - Test-related changes - `e2e/` - End-to-end test changes - `release/` - Release branches - `ric/` - Custom prefix for special cases **Note:** When a bug fix affects only the `redisinsight/ui/` folder, use `fe/bugfix/` prefix instead of `bugfix/`. ## Issue References - **Internal**: `RI-XXX` (JIRA ticket) - **Open Source**: `XXX` (GitHub issue number) - Use `#` only in commit messages, not branch names ================================================ FILE: .ai/skills/commits/SKILL.md ================================================ --- name: commits description: >- Generate commit messages following Conventional Commits format. Use when creating commits, writing commit messages, or the user asks to commit changes. --- # Commit Message Guidelines Follow **Conventional Commits** format: ``` ():