diff --git a/packages/server/package.json b/packages/server/package.json index ff06a2160..14116b211 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -40,6 +40,9 @@ "@lemonsqueezy/lemonsqueezy.js": "^2.2.0", "@liaoliaots/nestjs-redis": "^10.0.0", "@nest-lab/throttler-storage-redis": "^1.1.0", + "@bull-board/api": "^5.22.0", + "@bull-board/express": "^5.22.0", + "@bull-board/nestjs": "^5.22.0", "@nestjs/bull": "^10.2.1", "@nestjs/bullmq": "^10.2.2", "@nestjs/cache-manager": "^2.2.2", diff --git a/packages/server/src/common/config/bull-board.ts b/packages/server/src/common/config/bull-board.ts new file mode 100644 index 000000000..74c686a86 --- /dev/null +++ b/packages/server/src/common/config/bull-board.ts @@ -0,0 +1,8 @@ +import { registerAs } from '@nestjs/config'; +import { parseBoolean } from '@/utils/parse-boolean'; + +export default registerAs('bullBoard', () => ({ + enabled: parseBoolean(process.env.BULL_BOARD_ENABLED, false), + username: process.env.BULL_BOARD_USERNAME, + password: process.env.BULL_BOARD_PASSWORD, +})); diff --git a/packages/server/src/common/config/index.ts b/packages/server/src/common/config/index.ts index 4e6cae00c..d8c5b7347 100644 --- a/packages/server/src/common/config/index.ts +++ b/packages/server/src/common/config/index.ts @@ -19,6 +19,7 @@ import throttle from './throttle'; import cloud from './cloud'; import redis from './redis'; import queue from './queue'; +import bullBoard from './bull-board'; export const config = [ app, @@ -42,4 +43,5 @@ export const config = [ throttle, redis, queue, + bullBoard, ]; diff --git a/packages/server/src/middleware/bull-board-auth.middleware.ts b/packages/server/src/middleware/bull-board-auth.middleware.ts new file mode 100644 index 000000000..dd733a486 --- /dev/null +++ b/packages/server/src/middleware/bull-board-auth.middleware.ts @@ -0,0 +1,59 @@ +import { Request, Response, NextFunction } from 'express'; + +/** + * Creates Express middleware for the Bull Board UI: + * - When disabled: responds with 404. + * - When enabled and username/password are set: enforces HTTP Basic Auth (401 if invalid). + * - When enabled and credentials are not set: allows access (no auth). + */ +export function createBullBoardAuthMiddleware( + enabled: boolean, + username: string | undefined, + password: string | undefined, +): (req: Request, res: Response, next: NextFunction) => void { + return (req: Request, res: Response, next: NextFunction) => { + if (!enabled) { + res.status(404).send('Not Found'); + return; + } + + if (!username || !password) { + return next(); + } + + const authHeader = req.headers.authorization; + if (!authHeader || !authHeader.startsWith('Basic ')) { + res.setHeader('WWW-Authenticate', 'Basic realm="Bull Board"'); + res.status(401).send('Authentication required'); + return; + } + + const base64Credentials = authHeader.slice(6); + let decoded: string; + try { + decoded = Buffer.from(base64Credentials, 'base64').toString('utf8'); + } catch { + res.setHeader('WWW-Authenticate', 'Basic realm="Bull Board"'); + res.status(401).send('Invalid credentials'); + return; + } + + const colonIndex = decoded.indexOf(':'); + if (colonIndex === -1) { + res.setHeader('WWW-Authenticate', 'Basic realm="Bull Board"'); + res.status(401).send('Invalid credentials'); + return; + } + + const reqUsername = decoded.slice(0, colonIndex); + const reqPassword = decoded.slice(colonIndex + 1); + + if (reqUsername !== username || reqPassword !== password) { + res.setHeader('WWW-Authenticate', 'Basic realm="Bull Board"'); + res.status(401).send('Invalid credentials'); + return; + } + + next(); + }; +} diff --git a/packages/server/src/modules/App/App.module.ts b/packages/server/src/modules/App/App.module.ts index 859bdd9bd..ef50f0efa 100644 --- a/packages/server/src/modules/App/App.module.ts +++ b/packages/server/src/modules/App/App.module.ts @@ -12,6 +12,9 @@ import { I18nModule, QueryResolver, } from 'nestjs-i18n'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { ExpressAdapter } from '@bull-board/express'; +import { createBullBoardAuthMiddleware } from '@/middleware/bull-board-auth.middleware'; import { BullModule } from '@nestjs/bullmq'; import { ScheduleModule } from '@nestjs/schedule'; import { PassportModule } from '@nestjs/passport'; @@ -143,6 +146,24 @@ import { AppThrottleModule } from './AppThrottle.module'; }), inject: [ConfigService], }), + BullBoardModule.forRootAsync({ + imports: [ConfigModule], + useFactory: (configService: ConfigService) => { + const enabled = configService.get('bullBoard.enabled'); + const username = configService.get('bullBoard.username'); + const password = configService.get('bullBoard.password'); + return { + route: '/queues', + adapter: ExpressAdapter, + middleware: createBullBoardAuthMiddleware( + enabled, + username, + password, + ), + }; + }, + inject: [ConfigService], + }), ClsModule.forRoot({ global: true, middleware: { diff --git a/packages/server/src/modules/Auth/Auth.module.ts b/packages/server/src/modules/Auth/Auth.module.ts index c86b503ea..ba8d001cd 100644 --- a/packages/server/src/modules/Auth/Auth.module.ts +++ b/packages/server/src/modules/Auth/Auth.module.ts @@ -17,6 +17,8 @@ import { PassportModule } from '@nestjs/passport'; import { APP_GUARD } from '@nestjs/core'; import { JwtAuthGuard } from './guards/jwt.guard'; import { AuthMailSubscriber } from './subscribers/AuthMail.subscriber'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullMQAdapter } from '@bull-board/api/bullMQAdapter'; import { BullModule } from '@nestjs/bullmq'; import { SendResetPasswordMailQueue, @@ -63,6 +65,14 @@ const models = [ TenancyModule, BullModule.registerQueue({ name: SendResetPasswordMailQueue }), BullModule.registerQueue({ name: SendSignupVerificationMailQueue }), + BullBoardModule.forFeature({ + name: SendResetPasswordMailQueue, + adapter: BullMQAdapter, + }), + BullBoardModule.forFeature({ + name: SendSignupVerificationMailQueue, + adapter: BullMQAdapter, + }), ], exports: [...models], providers: [ @@ -98,4 +108,4 @@ const models = [ AuthMailSubscriber, ], }) -export class AuthModule { } +export class AuthModule {} diff --git a/packages/server/src/modules/BankingPlaid/BankingPlaid.module.ts b/packages/server/src/modules/BankingPlaid/BankingPlaid.module.ts index c208c1f29..2f0a7be5a 100644 --- a/packages/server/src/modules/BankingPlaid/BankingPlaid.module.ts +++ b/packages/server/src/modules/BankingPlaid/BankingPlaid.module.ts @@ -1,3 +1,5 @@ +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullMQAdapter } from '@bull-board/api/bullMQAdapter'; import { BullModule } from '@nestjs/bullmq'; import { Module } from '@nestjs/common'; import { SocketModule } from '../Socket/Socket.module'; @@ -33,6 +35,10 @@ const models = [RegisterTenancyModel(PlaidItem)]; BankingCategorizeModule, BankingTransactionsModule, BullModule.registerQueue({ name: UpdateBankingPlaidTransitionsQueueJob }), + BullBoardModule.forFeature({ + name: UpdateBankingPlaidTransitionsQueueJob, + adapter: BullMQAdapter, + }), ...models, ], providers: [ @@ -51,4 +57,4 @@ const models = [RegisterTenancyModel(PlaidItem)]; exports: [...models], controllers: [BankingPlaidController, BankingPlaidWebhooksController], }) -export class BankingPlaidModule { } +export class BankingPlaidModule {} diff --git a/packages/server/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts b/packages/server/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts index 4092bee59..34c1714fa 100644 --- a/packages/server/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts +++ b/packages/server/src/modules/BankingTranasctionsRegonize/BankingTransactionsRegonize.module.ts @@ -10,6 +10,8 @@ import { BankingRecognizedTransactionsController } from './BankingRecognizedTran import { RecognizedTransactionsApplication } from './RecognizedTransactions.application'; import { GetRecognizedTransactionsService } from './GetRecongizedTransactions'; import { GetRecognizedTransactionService } from './queries/GetRecognizedTransaction.service'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullMQAdapter } from '@bull-board/api/bullMQAdapter'; import { BullModule } from '@nestjs/bullmq'; import { RecognizeUncategorizedTransactionsQueue } from './_types'; import { RegonizeTransactionsPrcessor } from './jobs/RecognizeTransactionsJob'; @@ -25,6 +27,10 @@ const models = [RegisterTenancyModel(RecognizedBankTransaction)]; BullModule.registerQueue({ name: RecognizeUncategorizedTransactionsQueue, }), + BullBoardModule.forFeature({ + name: RecognizeUncategorizedTransactionsQueue, + adapter: BullMQAdapter, + }), ...models, ], providers: [ diff --git a/packages/server/src/modules/InventoryCost/InventoryCost.module.ts b/packages/server/src/modules/InventoryCost/InventoryCost.module.ts index 07f14b908..d56a1c981 100644 --- a/packages/server/src/modules/InventoryCost/InventoryCost.module.ts +++ b/packages/server/src/modules/InventoryCost/InventoryCost.module.ts @@ -16,6 +16,8 @@ import { ComputeItemCostQueue, WriteInventoryTransactionsGLEntriesQueue, } from './types/InventoryCost.types'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullMQAdapter } from '@bull-board/api/bullMQAdapter'; import { BullModule } from '@nestjs/bullmq'; import { InventoryAverageCostMethodService } from './commands/InventoryAverageCostMethod.service'; import { InventoryItemCostService } from './commands/InventoryCosts.service'; @@ -39,6 +41,14 @@ const models = [ BullModule.registerQueue({ name: WriteInventoryTransactionsGLEntriesQueue, }), + BullBoardModule.forFeature({ + name: ComputeItemCostQueue, + adapter: BullMQAdapter, + }), + BullBoardModule.forFeature({ + name: WriteInventoryTransactionsGLEntriesQueue, + adapter: BullMQAdapter, + }), forwardRef(() => SaleInvoicesModule), ImportModule, ], @@ -56,7 +66,7 @@ const models = [ InventoryItemCostService, InventoryItemOpeningAvgCostService, InventoryCostSubscriber, - GetItemsInventoryValuationListService + GetItemsInventoryValuationListService, ], exports: [ ...models, @@ -64,6 +74,6 @@ const models = [ InventoryItemCostService, InventoryComputeCostService, ], - controllers: [InventoryCostController] + controllers: [InventoryCostController], }) export class InventoryCostModule {} diff --git a/packages/server/src/modules/Organization/Organization.module.ts b/packages/server/src/modules/Organization/Organization.module.ts index 271f3a75a..9da36b41b 100644 --- a/packages/server/src/modules/Organization/Organization.module.ts +++ b/packages/server/src/modules/Organization/Organization.module.ts @@ -3,6 +3,8 @@ import { GetCurrentOrganizationService } from './queries/GetCurrentOrganization. import { BuildOrganizationService } from './commands/BuildOrganization.service'; import { UpdateOrganizationService } from './commands/UpdateOrganization.service'; import { OrganizationController } from './Organization.controller'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullMQAdapter } from '@bull-board/api/bullMQAdapter'; import { BullModule } from '@nestjs/bullmq'; import { OrganizationBuildQueue } from './Organization.types'; import { OrganizationBuildProcessor } from './processors/OrganizationBuild.processor'; @@ -25,10 +27,14 @@ import { GetBuildOrganizationBuildJob } from './commands/GetBuildOrganizationJob OrganizationBaseCurrencyLocking, SyncSystemUserToTenantService, SyncSystemUserToTenantSubscriber, - GetBuildOrganizationBuildJob + GetBuildOrganizationBuildJob, ], imports: [ BullModule.registerQueue({ name: OrganizationBuildQueue }), + BullBoardModule.forFeature({ + name: OrganizationBuildQueue, + adapter: BullMQAdapter, + }), TenantDBManagerModule, ], controllers: [OrganizationController], diff --git a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts index ed7d034b3..2749541a8 100644 --- a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts +++ b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts @@ -1,4 +1,6 @@ import { Module } from '@nestjs/common'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullModule } from '@nestjs/bull'; import { PaymentReceivesController } from './PaymentsReceived.controller'; import { PaymentReceivesApplication } from './PaymentReceived.application'; @@ -95,6 +97,10 @@ import { ValidateBulkDeletePaymentReceivedService } from './ValidateBulkDeletePa DynamicListModule, MailModule, BullModule.registerQueue({ name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE }), + BullBoardModule.forFeature({ + name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE, + adapter: BullAdapter, + }), ], }) export class PaymentsReceivedModule {} diff --git a/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts b/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts index 0ed7b4c23..c9bb58fbb 100644 --- a/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts +++ b/packages/server/src/modules/SaleEstimates/SaleEstimates.module.ts @@ -1,4 +1,6 @@ import { Module } from '@nestjs/common'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullModule } from '@nestjs/bull'; import { TenancyContext } from '../Tenancy/TenancyContext.service'; import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module'; @@ -54,6 +56,10 @@ import { SendSaleEstimateMailProcess } from './processes/SendSaleEstimateMail.pr TemplateInjectableModule, PdfTemplatesModule, BullModule.registerQueue({ name: SendSaleEstimateMailQueue }), + BullBoardModule.forFeature({ + name: SendSaleEstimateMailQueue, + adapter: BullAdapter, + }), ], controllers: [SaleEstimatesController], providers: [ @@ -99,4 +105,4 @@ import { SendSaleEstimateMailProcess } from './processes/SendSaleEstimateMail.pr GetSaleEstimateMailTemplateService, ], }) -export class SaleEstimatesModule { } +export class SaleEstimatesModule {} diff --git a/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts b/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts index f21766f15..f66661188 100644 --- a/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts +++ b/packages/server/src/modules/SaleInvoices/SaleInvoices.module.ts @@ -45,6 +45,8 @@ import { SendSaleInvoiceMailCommon } from './commands/SendInvoiceInvoiceMailComm import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { MailNotificationModule } from '../MailNotification/MailNotification.module'; import { SendSaleInvoiceMailProcessor } from './processors/SendSaleInvoiceMail.processor'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullModule } from '@nestjs/bull'; import { SendSaleInvoiceQueue } from './constants'; import { InvoicePaymentIntegrationSubscriber } from './subscribers/InvoicePaymentIntegrationSubscriber'; @@ -81,6 +83,10 @@ import { ValidateBulkDeleteSaleInvoicesService } from './ValidateBulkDeleteSaleI forwardRef(() => PaymentLinksModule), DynamicListModule, BullModule.registerQueue({ name: SendSaleInvoiceQueue }), + BullBoardModule.forFeature({ + name: SendSaleInvoiceQueue, + adapter: BullAdapter, + }), ], controllers: [SaleInvoicesController], providers: [ @@ -139,4 +145,4 @@ import { ValidateBulkDeleteSaleInvoicesService } from './ValidateBulkDeleteSaleI SaleInvoicesImportable, ], }) -export class SaleInvoicesModule { } +export class SaleInvoicesModule {} diff --git a/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts b/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts index faf266e13..184bfe3a5 100644 --- a/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts +++ b/packages/server/src/modules/SaleReceipts/SaleReceipts.module.ts @@ -1,4 +1,6 @@ import { Module } from '@nestjs/common'; +import { BullBoardModule } from '@bull-board/nestjs'; +import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullModule } from '@nestjs/bull'; import { SaleReceiptApplication } from './SaleReceiptApplication.service'; import { CreateSaleReceipt } from './commands/CreateSaleReceipt.service'; @@ -62,6 +64,10 @@ import { ValidateBulkDeleteSaleReceiptsService } from './ValidateBulkDeleteSaleR MailModule, MailNotificationModule, BullModule.registerQueue({ name: SendSaleReceiptMailQueue }), + BullBoardModule.forFeature({ + name: SendSaleReceiptMailQueue, + adapter: BullAdapter, + }), ], providers: [ TenancyContext, @@ -95,4 +101,4 @@ import { ValidateBulkDeleteSaleReceiptsService } from './ValidateBulkDeleteSaleR ValidateBulkDeleteSaleReceiptsService, ], }) -export class SaleReceiptsModule { } +export class SaleReceiptsModule {} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 208d45cb3..d43f67b40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,15 @@ importers: '@bigcapital/utils': specifier: '*' version: link:../../shared/bigcapital-utils + '@bull-board/api': + specifier: ^5.22.0 + version: 5.23.0(@bull-board/ui@5.23.0) + '@bull-board/express': + specifier: ^5.22.0 + version: 5.23.0 + '@bull-board/nestjs': + specifier: ^5.22.0 + version: 5.23.0(@bull-board/api@5.23.0)(@bull-board/express@5.23.0)(@nestjs/common@10.4.7)(@nestjs/core@10.4.7)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@casl/ability': specifier: ^5.4.3 version: 5.4.4 @@ -4855,6 +4864,51 @@ packages: tslib: 2.5.3 dev: false + /@bull-board/api@5.23.0(@bull-board/ui@5.23.0): + resolution: {integrity: sha512-ZZGsWJ+XBG49GAlNgAL9tTEV6Ms7gMkQnZDbzwUhjGChCKWy62RWuPoZSefNXau9QH9+QzlzHRUeFvt4xr5wiw==} + peerDependencies: + '@bull-board/ui': 5.23.0 + dependencies: + '@bull-board/ui': 5.23.0 + redis-info: 3.1.0 + dev: false + + /@bull-board/express@5.23.0: + resolution: {integrity: sha512-t/mHzJMlZBtSKD8v81kbZoexOmtQxKVnHZfHJ0um5vrkHNJJuzKuwbR+n9nf1u89AGdyXoWxqDhBDslxv3zrrQ==} + dependencies: + '@bull-board/api': 5.23.0(@bull-board/ui@5.23.0) + '@bull-board/ui': 5.23.0 + ejs: 3.1.10 + express: 4.21.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@bull-board/nestjs@5.23.0(@bull-board/api@5.23.0)(@bull-board/express@5.23.0)(@nestjs/common@10.4.7)(@nestjs/core@10.4.7)(reflect-metadata@0.2.2)(rxjs@7.8.1): + resolution: {integrity: sha512-eRJCz6PqKzrlZfd7akc+6/1eXwNO7Fp468TmSo8avlPcKhStZH3fUmCF6xxfRQpm9kn/eDOp+H18CTnSafmwmw==} + peerDependencies: + '@bull-board/api': ^5.23.0 + '@bull-board/express': ^5.23.0 + '@nestjs/common': ^9.0.0 || ^10.0.0 + '@nestjs/core': ^9.0.0 || ^10.0.0 + reflect-metadata: ^0.1.13 || ^0.2.0 + rxjs: ^7.8.1 + dependencies: + '@bull-board/api': 5.23.0(@bull-board/ui@5.23.0) + '@bull-board/express': 5.23.0 + '@nestjs/bull-shared': 10.2.2(@nestjs/common@10.4.7)(@nestjs/core@10.4.7) + '@nestjs/common': 10.4.7(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) + '@nestjs/core': 10.4.7(@nestjs/common@10.4.7)(@nestjs/platform-express@10.4.7)(@nestjs/websockets@10.4.20)(reflect-metadata@0.2.2)(rxjs@7.8.1) + reflect-metadata: 0.2.2 + rxjs: 7.8.1 + dev: false + + /@bull-board/ui@5.23.0: + resolution: {integrity: sha512-iI/Ssl8T5ZEn9s899Qz67m92M6RU8thf/aqD7cUHB2yHmkCjqbw7s7NaODTsyArAsnyu7DGJMWm7EhbfFXDNgQ==} + dependencies: + '@bull-board/api': 5.23.0(@bull-board/ui@5.23.0) + dev: false + /@casl/ability@5.4.4: resolution: {integrity: sha512-7+GOnMUq6q4fqtDDesymBXTS9LSDVezYhFiSJ8Rn3f0aQLeRm7qHn66KWbej4niCOvm0XzNj9jzpkK0yz6hUww==} dependencies: @@ -15466,7 +15520,6 @@ packages: hasBin: true dependencies: jake: 10.9.1 - dev: true /electron-to-chromium@1.4.782: resolution: {integrity: sha512-JUfU61e8tr+i5Y1FKXcKs+Xe+rJ+CEqm4cgv1kMihPE2EvYHmYyVr3Im/+1+Z5B29Be2EEGCZCwAc6Tazdl1Yg==} @@ -16741,7 +16794,6 @@ packages: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} dependencies: minimatch: 5.1.6 - dev: true /fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} @@ -18481,7 +18533,6 @@ packages: chalk: 4.1.2 filelist: 1.0.4 minimatch: 3.1.2 - dev: true /javascript-natural-sort@0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} @@ -20042,7 +20093,6 @@ packages: engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 - dev: true /minimatch@8.0.4: resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} @@ -23172,6 +23222,12 @@ packages: engines: {node: '>=4'} dev: false + /redis-info@3.1.0: + resolution: {integrity: sha512-ER4L9Sh/vm63DkIE0bkSjxluQlioBiBgf5w1UuldaW/3vPcecdljVDisZhmnCMvsxHNiARTTDDHGg9cGwTfrKg==} + dependencies: + lodash: 4.17.21 + dev: false + /redis-parser@3.0.0: resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'}