From 7746326276b68e7a470fe872547b52742ca25139 Mon Sep 17 00:00:00 2001 From: ahonn Date: Fri, 2 Aug 2024 17:45:47 +1000 Subject: [PATCH 1/3] feat: add custom cacheable decorator and fix eslint issue --- backend/.eslintrc.js | 15 +- backend/.husky/pre-commit | 1 + backend/package.json | 14 +- backend/src/common/date.ts | 1 + backend/src/constants.ts | 1 - .../core/bitcoin-api/bitcoin-api.service.ts | 2 +- .../ckb-explorer/ckb-explorer.interface.ts | 4 +- .../core/ckb-explorer/ckb-explorer.service.ts | 34 ++- backend/src/core/ckb-rpc/ckb-rpc.interface.ts | 2 - backend/src/decorators/cacheable.decorator.ts | 40 +++ .../src/decorators/parent-field.decorator.ts | 1 - .../field-performance.middleware.ts | 19 ++ backend/src/modules/api.model.ts | 2 +- backend/src/modules/api.module.ts | 4 +- backend/src/modules/bitcoin/bitcoin.module.ts | 2 +- .../src/modules/bitcoin/bitcoin.resolver.ts | 7 +- .../modules/bitcoin/block/block.resolver.ts | 5 +- .../dataloader/block-transactions.loader.ts | 3 +- .../block/dataloader/block-txids.loader.ts | 3 +- .../transaction/transaction.resolver.ts | 4 +- .../src/modules/ckb/block/block.dataloader.ts | 10 +- backend/src/modules/ckb/cell/cell.resolver.ts | 2 +- backend/src/modules/ckb/cell/cell.service.ts | 5 +- backend/src/modules/ckb/ckb.resolver.ts | 2 +- .../ckb/script/base/base-script.service.ts | 2 +- .../src/modules/ckb/script/script.module.ts | 2 +- .../ckb/transaction/transaction.model.ts | 2 +- .../modules/rgbpp/address/address.resolver.ts | 4 +- .../modules/rgbpp/address/address.service.ts | 8 +- .../src/modules/rgbpp/asset/asset.model.ts | 5 +- backend/src/modules/rgbpp/rgbpp.module.ts | 2 +- backend/src/modules/rgbpp/rgbpp.service.ts | 2 +- .../rgbpp/transaction/transaction.resolver.ts | 2 +- .../rgbpp/transaction/transaction.service.ts | 2 +- backend/src/modules/search/search.model.ts | 2 +- backend/src/modules/search/search.resolver.ts | 2 +- backend/src/pipes/validate-address.pipe.ts | 9 +- pnpm-lock.yaml | 275 ++++++++++++++++++ 38 files changed, 447 insertions(+), 55 deletions(-) create mode 100644 backend/.husky/pre-commit create mode 100644 backend/src/decorators/cacheable.decorator.ts create mode 100644 backend/src/middlewares/field-performance.middleware.ts diff --git a/backend/.eslintrc.js b/backend/.eslintrc.js index 259de13c..835efd34 100644 --- a/backend/.eslintrc.js +++ b/backend/.eslintrc.js @@ -5,11 +5,8 @@ module.exports = { tsconfigRootDir: __dirname, sourceType: 'module', }, - plugins: ['@typescript-eslint/eslint-plugin'], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - ], + plugins: ['@typescript-eslint/eslint-plugin', 'import'], + extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], root: true, env: { node: true, @@ -21,5 +18,13 @@ module.exports = { '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', + 'no-restricted-imports': [ + 'error', + { + name: 'nestjs-cacheable', + importNames: ['Cacheable'], + message: "Please use 'src/decorators/cacheable.decorator' instead", + }, + ], }, }; diff --git a/backend/.husky/pre-commit b/backend/.husky/pre-commit new file mode 100644 index 00000000..50d08d03 --- /dev/null +++ b/backend/.husky/pre-commit @@ -0,0 +1 @@ +npm \ No newline at end of file diff --git a/backend/package.json b/backend/package.json index 2a424ccd..ac1283af 100644 --- a/backend/package.json +++ b/backend/package.json @@ -18,7 +18,12 @@ "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", - "postinstall": "npx prisma generate" + "postinstall": "npx prisma generate", + "precommit": "lint-staged", + "prepare": "husky" + }, + "lint-staged": { + "*.ts": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix" }, "dependencies": { "@applifting-io/nestjs-dataloader": "^1.1.5", @@ -70,13 +75,16 @@ "@types/jest": "^29.5.2", "@types/lodash": "^4.17.7", "@types/node": "^20.3.1", + "@types/serialize-javascript": "^5.0.4", "@types/supertest": "^6.0.0", "@typescript-eslint/eslint-plugin": "^7.0.0", "@typescript-eslint/parser": "^7.0.0", "eslint": "^8.42.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.0", + "husky": "^9.1.4", "jest": "^29.5.0", + "lint-staged": "^15.2.7", "prettier": "^3.0.0", "prisma": "^5.16.2", "source-map-support": "^0.5.21", @@ -94,7 +102,9 @@ "json", "ts" ], - "modulePaths": ["."], + "modulePaths": [ + "." + ], "testRegex": ".*\\.(spec|test)\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" diff --git a/backend/src/common/date.ts b/backend/src/common/date.ts index a0832e97..ed2705bb 100644 --- a/backend/src/common/date.ts +++ b/backend/src/common/date.ts @@ -1,3 +1,4 @@ export const ONE_MONTH_MS = 30 * 24 * 60 * 60 * 1000; +export const ONE_HOUR_MS = 60 * 60 * 1000; export const TEN_MINUTES_MS = 10 * 60 * 1000; export const ONE_MINUTE_MS = 60 * 1000; diff --git a/backend/src/constants.ts b/backend/src/constants.ts index 0b26c767..ac9a3b92 100644 --- a/backend/src/constants.ts +++ b/backend/src/constants.ts @@ -1,4 +1,3 @@ -import { Script } from '@ckb-lumos/lumos'; import * as RgbppBtc from '@rgbpp-sdk/btc'; import { BTCTestnetType } from '@rgbpp-sdk/ckb'; diff --git a/backend/src/core/bitcoin-api/bitcoin-api.service.ts b/backend/src/core/bitcoin-api/bitcoin-api.service.ts index b582cc67..54815e61 100644 --- a/backend/src/core/bitcoin-api/bitcoin-api.service.ts +++ b/backend/src/core/bitcoin-api/bitcoin-api.service.ts @@ -8,8 +8,8 @@ import { IBitcoinDataProvider } from './bitcoin-api.interface'; import { ElectrsService } from './provider/electrs.service'; import { MempoolService } from './provider/mempool.service'; import { ChainInfo } from './bitcoin-api.schema'; -import { Cacheable } from 'nestjs-cacheable'; import { ONE_MONTH_MS, TEN_MINUTES_MS } from 'src/common/date'; +import { Cacheable } from 'src/decorators/cacheable.decorator'; type MethodParameters = T[K] extends (...args: infer P) => any ? P : never; type MethodReturnType = T[K] extends (...args: any[]) => infer R ? R : never; diff --git a/backend/src/core/ckb-explorer/ckb-explorer.interface.ts b/backend/src/core/ckb-explorer/ckb-explorer.interface.ts index 7083358e..e14f38e2 100644 --- a/backend/src/core/ckb-explorer/ckb-explorer.interface.ts +++ b/backend/src/core/ckb-explorer/ckb-explorer.interface.ts @@ -52,7 +52,7 @@ export interface CkbExplorerResponse { meta: IsPaginated extends true ? PaginationMeta : never; } -export type NonPaginatedResponse = CkbExplorerResponse< +export type NonPaginatedResponse = CkbExplorerResponse< { id: string; type: string; @@ -61,7 +61,7 @@ export type NonPaginatedResponse = CkbExplorerResponse< false >; -export type PaginatedResponse = CkbExplorerResponse< +export type PaginatedResponse = CkbExplorerResponse< { id: string; type: string; diff --git a/backend/src/core/ckb-explorer/ckb-explorer.service.ts b/backend/src/core/ckb-explorer/ckb-explorer.service.ts index fe0c0c01..22fd97f2 100644 --- a/backend/src/core/ckb-explorer/ckb-explorer.service.ts +++ b/backend/src/core/ckb-explorer/ckb-explorer.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { Inject, Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import axios, { Axios } from 'axios'; import { Env } from 'src/env'; @@ -22,6 +22,10 @@ import { TransactionFeesStatistic, TransactionListSortType, } from './ckb-explorer.interface'; +import { ONE_HOUR_MS, ONE_MONTH_MS } from 'src/common/date'; +import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager'; +import { toNumber } from 'lodash'; +import { Cacheable } from 'src/decorators/cacheable.decorator'; type BasePaginationParams = { page?: number; @@ -62,7 +66,10 @@ export class CkbExplorerService { private logger = new Logger(CkbExplorerService.name); private request: Axios; - constructor(private configService: ConfigService) { + constructor( + private configService: ConfigService, + @Inject(CACHE_MANAGER) protected cacheManager: Cache, + ) { this.request = axios.create({ baseURL: this.configService.get('CKB_EXPLORER_API_URL'), headers: { @@ -118,11 +125,20 @@ export class CkbExplorerService { return response.data; } + @Cacheable({ + key: (heightOrHash: string) => `CkbExplorerService:getBlock:${heightOrHash}`, + ttl: ONE_MONTH_MS, + }) public async getBlock(heightOrHash: string): Promise> { const response = await this.request.get(`/v1/blocks/${heightOrHash}`); return response.data; } + @Cacheable({ + key: (heightOrHash: string, { page = 1, pageSize = 10 }: BasePaginationParams = {}) => + `CkbExplorerService:getBlockTransactions:${heightOrHash},${page},${pageSize}`, + ttl: ONE_MONTH_MS, + }) public async getBlockTransactions( blockHash: string, { page = 1, pageSize = 10 }: BasePaginationParams = {}, @@ -173,7 +189,21 @@ export class CkbExplorerService { return response.data; } + @Cacheable({ + key: (txHash: string) => `CkbExplorerService:getTransaction:${txHash}`, + ttl: ONE_HOUR_MS, + shouldCache: async (tx: NonPaginatedResponse) => { + // cache tx for 1 month if it's committed and older than 1 hour + const { tx_status, block_timestamp } = tx.data.attributes; + return tx_status === 'committed' && Date.now() - toNumber(block_timestamp) > ONE_HOUR_MS; + }, + }) public async getTransaction(txHash: string): Promise> { + const key = `CkbExplorerService:getTransaction:${txHash}`; + const cached = await this.cacheManager.get(key); + if (cached) { + return cached as NonPaginatedResponse; + } const response = await this.request.get(`/v1/transactions/${txHash}`); return response.data; } diff --git a/backend/src/core/ckb-rpc/ckb-rpc.interface.ts b/backend/src/core/ckb-rpc/ckb-rpc.interface.ts index 71470ec3..cd94714c 100644 --- a/backend/src/core/ckb-rpc/ckb-rpc.interface.ts +++ b/backend/src/core/ckb-rpc/ckb-rpc.interface.ts @@ -1,5 +1,3 @@ -import { RPC } from '@ckb-lumos/rpc'; - export interface CellDep { dep_type: string; out_point: { diff --git a/backend/src/decorators/cacheable.decorator.ts b/backend/src/decorators/cacheable.decorator.ts new file mode 100644 index 00000000..b99e588d --- /dev/null +++ b/backend/src/decorators/cacheable.decorator.ts @@ -0,0 +1,40 @@ +// eslint-disable-next-line no-restricted-imports +import { CacheableRegisterOptions, Cacheable as _Cacheable } from 'nestjs-cacheable'; + +export interface CustomCacheableRegisterOptions extends CacheableRegisterOptions { + shouldCache?: (result: any) => boolean | Promise; +} + +/** + * Cacheable decorator with custom options, based on the original Cacheable decorator from the nestjs-cacheable package. + * Adds a shouldCache option to determine whether the result should be cached. + * + * @example + * @Cacheable({ + * ttl: 1000, + * key: (args: any[]) => args[0], + * shouldCache: (result: any) => result !== null, + * }); + */ +export function Cacheable(options: CustomCacheableRegisterOptions): MethodDecorator { + return function (_, propertyKey, descriptor) { + // eslint-disable-next-line @typescript-eslint/ban-types + const originalMethod = descriptor.value as unknown as Function; + return { + ...descriptor, + value: async function (...args: any[]) { + const returnVal = await originalMethod.apply(this, args); + + const cacheable = options.shouldCache ? await options.shouldCache(returnVal) : true; + if (!cacheable) { + return returnVal; + } + + const fakeDescriptor = { + value: () => returnVal, + }; + return _Cacheable(options)(this, propertyKey, fakeDescriptor); + } as any, + }; + }; +} diff --git a/backend/src/decorators/parent-field.decorator.ts b/backend/src/decorators/parent-field.decorator.ts index ff612eb3..0b3e6dc0 100644 --- a/backend/src/decorators/parent-field.decorator.ts +++ b/backend/src/decorators/parent-field.decorator.ts @@ -6,4 +6,3 @@ export const ParentField = createParamDecorator((param: string, ctx: ExecutionCo const value = root[param]; return value; }); - diff --git a/backend/src/middlewares/field-performance.middleware.ts b/backend/src/middlewares/field-performance.middleware.ts new file mode 100644 index 00000000..2ab3c54d --- /dev/null +++ b/backend/src/middlewares/field-performance.middleware.ts @@ -0,0 +1,19 @@ +import { Logger } from '@nestjs/common'; +import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql'; + +export const fieldPerformanceMiddleware: FieldMiddleware = async ( + ctx: MiddlewareContext, + next: NextFn, +) => { + const now = performance.now(); + const value = await next(); + + const executionTime = performance.now() - now; + if (executionTime > 100) { + const { path } = ctx.info; + logger.debug(`[${path.typename}.${path.key}]: ${executionTime}ms`); + } + return value; +}; + +const logger = new Logger(fieldPerformanceMiddleware.name); diff --git a/backend/src/modules/api.model.ts b/backend/src/modules/api.model.ts index 81d866db..027a6cfc 100644 --- a/backend/src/modules/api.model.ts +++ b/backend/src/modules/api.model.ts @@ -1,4 +1,4 @@ -import { registerEnumType } from "@nestjs/graphql"; +import { registerEnumType } from '@nestjs/graphql'; export enum OrderType { Desc = 'desc', diff --git a/backend/src/modules/api.module.ts b/backend/src/modules/api.module.ts index 10f242a6..13443a6b 100644 --- a/backend/src/modules/api.module.ts +++ b/backend/src/modules/api.module.ts @@ -12,6 +12,7 @@ import { RgbppModule } from './rgbpp/rgbpp.module'; import { BitcoinModule } from './bitcoin/bitcoin.module'; import { FastifyReply, FastifyRequest } from 'fastify'; import { SearchModule } from './search/search.module'; +import { fieldPerformanceMiddleware } from 'src/middlewares/field-performance.middleware'; @Module({ imports: [ @@ -26,6 +27,7 @@ import { SearchModule } from './search/search.module'; autoSchemaFile: join(process.cwd(), 'src/schema.gql'), buildSchemaOptions: { dateScalarMode: 'timestamp', + fieldMiddleware: [fieldPerformanceMiddleware], }, context: (req: FastifyRequest, res: FastifyReply) => { if (req.method === 'GET') { @@ -53,4 +55,4 @@ import { SearchModule } from './search/search.module'; }, ], }) -export class ApiModule { } +export class ApiModule {} diff --git a/backend/src/modules/bitcoin/bitcoin.module.ts b/backend/src/modules/bitcoin/bitcoin.module.ts index f82d61d0..5ccb41fd 100644 --- a/backend/src/modules/bitcoin/bitcoin.module.ts +++ b/backend/src/modules/bitcoin/bitcoin.module.ts @@ -18,4 +18,4 @@ import { BitcoinOutputModule } from './output/output.module'; ], providers: [BitcoinResolver], }) -export class BitcoinModule { } +export class BitcoinModule {} diff --git a/backend/src/modules/bitcoin/bitcoin.resolver.ts b/backend/src/modules/bitcoin/bitcoin.resolver.ts index 408ba0e0..1f203789 100644 --- a/backend/src/modules/bitcoin/bitcoin.resolver.ts +++ b/backend/src/modules/bitcoin/bitcoin.resolver.ts @@ -2,14 +2,17 @@ import { Float, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql'; import { BitcoinApiService } from 'src/core/bitcoin-api/bitcoin-api.service'; import { BitcoinBaseChainInfo, BitcoinChainInfo, BitcoinFees } from './bitcoin.model'; import { Loader } from '@applifting-io/nestjs-dataloader'; -import { BitcoinBlockTxidsLoader, BitcoinBlockTxidsLoaderType } from './block/dataloader/block-txids.loader'; +import { + BitcoinBlockTxidsLoader, + BitcoinBlockTxidsLoaderType, +} from './block/dataloader/block-txids.loader'; // 60 * 24 = 1440 minutes const BLOCK_NUMBER_OF_24_HOURS = 144; @Resolver(() => BitcoinChainInfo) export class BitcoinResolver { - constructor(private bitcoinApiService: BitcoinApiService) { } + constructor(private bitcoinApiService: BitcoinApiService) {} @Query(() => BitcoinChainInfo, { name: 'btcChainInfo' }) public async chainInfo(): Promise { diff --git a/backend/src/modules/bitcoin/block/block.resolver.ts b/backend/src/modules/bitcoin/block/block.resolver.ts index 63be0132..96737f9c 100644 --- a/backend/src/modules/bitcoin/block/block.resolver.ts +++ b/backend/src/modules/bitcoin/block/block.resolver.ts @@ -5,7 +5,10 @@ import { BitcoinBaseTransaction, BitcoinTransaction } from '../transaction/trans import { BitcoinAddress, BitcoinBaseAddress } from '../address/address.model'; import { BitcoinBaseBlock, BitcoinBlock, FeeRateRange } from './block.model'; import { BitcoinBlockLoader, BitcoinBlockLoaderType } from './dataloader/block.loader'; -import { BitcoinBlockTransactionsLoader, BitcoinBlockTransactionsLoaderType } from './dataloader/block-transactions.loader'; +import { + BitcoinBlockTransactionsLoader, + BitcoinBlockTransactionsLoaderType, +} from './dataloader/block-transactions.loader'; @Resolver(() => BitcoinBlock) export class BitcoinBlockResolver { diff --git a/backend/src/modules/bitcoin/block/dataloader/block-transactions.loader.ts b/backend/src/modules/bitcoin/block/dataloader/block-transactions.loader.ts index 9a293540..a8d50fe2 100644 --- a/backend/src/modules/bitcoin/block/dataloader/block-transactions.loader.ts +++ b/backend/src/modules/bitcoin/block/dataloader/block-transactions.loader.ts @@ -17,7 +17,8 @@ export interface BitcoinBlockTransactionsLoaderParams { @Injectable() export class BitcoinBlockTransactionsLoader extends BitcoinBaseLoader - implements NestDataLoader { + implements NestDataLoader +{ protected logger = new Logger(BitcoinBlockTransactionsLoader.name); constructor( diff --git a/backend/src/modules/bitcoin/block/dataloader/block-txids.loader.ts b/backend/src/modules/bitcoin/block/dataloader/block-txids.loader.ts index d4136489..8bf86835 100644 --- a/backend/src/modules/bitcoin/block/dataloader/block-txids.loader.ts +++ b/backend/src/modules/bitcoin/block/dataloader/block-txids.loader.ts @@ -15,7 +15,8 @@ export interface BitcoinBlockTxidsLoaderParams { @Injectable() export class BitcoinBlockTxidsLoader extends BitcoinBaseLoader - implements NestDataLoader { + implements NestDataLoader +{ protected logger = new Logger(BitcoinBlockTxidsLoader.name); constructor( diff --git a/backend/src/modules/bitcoin/transaction/transaction.resolver.ts b/backend/src/modules/bitcoin/transaction/transaction.resolver.ts index c3536f29..eb969cb5 100644 --- a/backend/src/modules/bitcoin/transaction/transaction.resolver.ts +++ b/backend/src/modules/bitcoin/transaction/transaction.resolver.ts @@ -16,7 +16,7 @@ import { BitcoinBlockLoader, BitcoinBlockLoaderType } from '../block/dataloader/ @Resolver(() => BitcoinTransaction) export class BitcoinTransactionResolver { - constructor(private bitcoinApiService: BitcoinApiService) { } + constructor(private bitcoinApiService: BitcoinApiService) {} @Query(() => BitcoinTransaction, { name: 'btcTransaction', nullable: true }) public async getTransaction( @@ -47,7 +47,7 @@ export class BitcoinTransactionResolver { @Loader(BitcoinBlockLoader) blockLoader: BitcoinBlockLoaderType, ): Promise { if (!tx.blockHash) { - return null + return null; } const block = await blockLoader.load(tx.blockHash); if (!block) { diff --git a/backend/src/modules/ckb/block/block.dataloader.ts b/backend/src/modules/ckb/block/block.dataloader.ts index d0c49760..ebf889b1 100644 --- a/backend/src/modules/ckb/block/block.dataloader.ts +++ b/backend/src/modules/ckb/block/block.dataloader.ts @@ -8,7 +8,7 @@ import { CkbBlockService } from './block.service'; import { InjectSentry, SentryService } from '@ntegral/nestjs-sentry'; @Injectable() -export class CkbRpcBlockLoader implements NestDataLoader { +export class CkbRpcBlockLoader implements NestDataLoader { private logger = new Logger(CkbRpcBlockLoader.name); constructor( @@ -26,7 +26,9 @@ export class CkbRpcBlockLoader implements NestDataLoader CkbXUDTInfo, { nullable: true }) public async xudtInfo( diff --git a/backend/src/modules/ckb/cell/cell.service.ts b/backend/src/modules/ckb/cell/cell.service.ts index deb4bf7e..016c5ff8 100644 --- a/backend/src/modules/ckb/cell/cell.service.ts +++ b/backend/src/modules/ckb/cell/cell.service.ts @@ -6,7 +6,10 @@ import { computeScriptHash } from '@ckb-lumos/lumos/utils'; @Injectable() export class CkbCellService { - public getXUDTInfoFromOutput(cell: CkbBaseCell, output: CkbExplorer.DisplayOutput): CkbXUDTInfo | null { + public getXUDTInfoFromOutput( + cell: CkbBaseCell, + output: CkbExplorer.DisplayOutput, + ): CkbXUDTInfo | null { const info = output.xudt_info || output.omiga_inscription_info; if (!info) { return null; diff --git a/backend/src/modules/ckb/ckb.resolver.ts b/backend/src/modules/ckb/ckb.resolver.ts index 4ef30ebf..09c0d58c 100644 --- a/backend/src/modules/ckb/ckb.resolver.ts +++ b/backend/src/modules/ckb/ckb.resolver.ts @@ -9,7 +9,7 @@ export class CkbResolver { constructor( private ckbRpcService: CkbRpcWebsocketService, private ckbExplorerService: CkbExplorerService, - ) { } + ) {} @Query(() => CkbChainInfo, { name: 'ckbChainInfo' }) public async chainInfo(): Promise { diff --git a/backend/src/modules/ckb/script/base/base-script.service.ts b/backend/src/modules/ckb/script/base/base-script.service.ts index d0f836ec..5aa89cce 100644 --- a/backend/src/modules/ckb/script/base/base-script.service.ts +++ b/backend/src/modules/ckb/script/base/base-script.service.ts @@ -18,7 +18,7 @@ export abstract class BaseScriptService { protected configService: ConfigService, protected ckbRpcService: CkbRpcWebsocketService, @InjectSentry() protected sentryService: SentryService, - ) { } + ) {} public static sortTransactionCmp(a: CkbRpc.IndexerCell, b: CkbRpc.IndexerCell, order: OrderType) { const blockNumberCmp = BI.from(b.block_number).sub(BI.from(a.block_number)).toNumber(); diff --git a/backend/src/modules/ckb/script/script.module.ts b/backend/src/modules/ckb/script/script.module.ts index 0d5a261a..92bc9514 100644 --- a/backend/src/modules/ckb/script/script.module.ts +++ b/backend/src/modules/ckb/script/script.module.ts @@ -19,4 +19,4 @@ import { CkbRpcModule } from 'src/core/ckb-rpc/ckb-rpc.module'; ], exports: [CkbScriptService], }) -export class CkbScriptModule { } +export class CkbScriptModule {} diff --git a/backend/src/modules/ckb/transaction/transaction.model.ts b/backend/src/modules/ckb/transaction/transaction.model.ts index f48e45ed..4183257a 100644 --- a/backend/src/modules/ckb/transaction/transaction.model.ts +++ b/backend/src/modules/ckb/transaction/transaction.model.ts @@ -1,5 +1,5 @@ import { toNumber } from 'lodash'; -import { Field, Float, InputType, ObjectType, registerEnumType } from '@nestjs/graphql'; +import { Field, Float, InputType, ObjectType } from '@nestjs/graphql'; import { ResultFormatter, RPCTypes } from '@ckb-lumos/lumos/rpc'; import { blockchain } from '@ckb-lumos/lumos/codec'; import * as CkbRpc from 'src/core/ckb-rpc/ckb-rpc.interface'; diff --git a/backend/src/modules/rgbpp/address/address.resolver.ts b/backend/src/modules/rgbpp/address/address.resolver.ts index ba38935f..c8bbe5b6 100644 --- a/backend/src/modules/rgbpp/address/address.resolver.ts +++ b/backend/src/modules/rgbpp/address/address.resolver.ts @@ -90,7 +90,9 @@ export class RgbppAddressResolver { if (!balancesMap.has(key)) { balancesMap.set(key, xudt); } else { - const amount = BI.from(balancesMap.get(key)!.amount).add(BI.from(xudt.amount)).toHexString(); + const amount = BI.from(balancesMap.get(key)!.amount) + .add(BI.from(xudt.amount)) + .toHexString(); balancesMap.set(key, { ...balancesMap.get(key)!, amount, diff --git a/backend/src/modules/rgbpp/address/address.service.ts b/backend/src/modules/rgbpp/address/address.service.ts index 18904370..33cb0d9e 100644 --- a/backend/src/modules/rgbpp/address/address.service.ts +++ b/backend/src/modules/rgbpp/address/address.service.ts @@ -17,7 +17,7 @@ export class RgbppAddressService { private rgbppService: RgbppService, @Inject(CACHE_MANAGER) protected cacheManager: Cache, @InjectQueue('rgbpp-address') private readonly queue: Queue, - ) { } + ) {} public async getRgbppAddressCells(btcAddress: string) { const key = `${this.addressCellsCacheKey}:${btcAddress}`; @@ -41,7 +41,11 @@ export class RgbppAddressService { } public async setRgbppAddressCells(btcAddress: string, cells: CkbRpc.Cell[]) { - await this.cacheManager.set(`${this.addressCellsCacheKey}:${btcAddress}`, cells, TEN_MINUTES_MS); + await this.cacheManager.set( + `${this.addressCellsCacheKey}:${btcAddress}`, + cells, + TEN_MINUTES_MS, + ); } public async collectRgbppAddressCells(btcAddress: string): Promise { diff --git a/backend/src/modules/rgbpp/asset/asset.model.ts b/backend/src/modules/rgbpp/asset/asset.model.ts index b05367d6..c9c5ae79 100644 --- a/backend/src/modules/rgbpp/asset/asset.model.ts +++ b/backend/src/modules/rgbpp/asset/asset.model.ts @@ -18,10 +18,7 @@ export class RgbppAsset { @Field(() => BitcoinOutput, { nullable: true }) utxo: BitcoinOutput; - public static from( - address: string, - cell: CkbRpc.Cell, - ): RgbppBaseAsset { + public static from(address: string, cell: CkbRpc.Cell): RgbppBaseAsset { return { owner: address, cell: CkbCell.fromCell(cell), diff --git a/backend/src/modules/rgbpp/rgbpp.module.ts b/backend/src/modules/rgbpp/rgbpp.module.ts index 01d48c73..51b5e651 100644 --- a/backend/src/modules/rgbpp/rgbpp.module.ts +++ b/backend/src/modules/rgbpp/rgbpp.module.ts @@ -17,6 +17,6 @@ import { RgbppService } from './rgbpp.service'; RgbppStatisticModule, ], providers: [RgbppService], - exports: [RgbppService] + exports: [RgbppService], }) export class RgbppModule {} diff --git a/backend/src/modules/rgbpp/rgbpp.service.ts b/backend/src/modules/rgbpp/rgbpp.service.ts index 2da70499..802c8d67 100644 --- a/backend/src/modules/rgbpp/rgbpp.service.ts +++ b/backend/src/modules/rgbpp/rgbpp.service.ts @@ -3,12 +3,12 @@ import { bytes } from '@ckb-lumos/lumos/codec'; import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { getRgbppLockScript, remove0x, RGBPPLock } from '@rgbpp-sdk/ckb'; -import { Cacheable } from 'nestjs-cacheable'; import { ONE_MINUTE_MS } from 'src/common/date'; import { BtcTestnetTypeMap, NetworkType } from 'src/constants'; import { CkbExplorerService } from 'src/core/ckb-explorer/ckb-explorer.service'; import { CkbRpcWebsocketService } from 'src/core/ckb-rpc/ckb-rpc-websocket.service'; import * as CkbRpc from 'src/core/ckb-rpc/ckb-rpc.interface'; +import { Cacheable } from 'src/decorators/cacheable.decorator'; import { Env } from 'src/env'; @Injectable() diff --git a/backend/src/modules/rgbpp/transaction/transaction.resolver.ts b/backend/src/modules/rgbpp/transaction/transaction.resolver.ts index af805753..4fa5c6be 100644 --- a/backend/src/modules/rgbpp/transaction/transaction.resolver.ts +++ b/backend/src/modules/rgbpp/transaction/transaction.resolver.ts @@ -25,7 +25,7 @@ import { RgbppTransactionLoader, RgbppTransactionLoaderType } from './transactio @Resolver(() => RgbppTransaction) export class RgbppTransactionResolver { - constructor(private transactionService: RgbppTransactionService) { } + constructor(private transactionService: RgbppTransactionService) {} @Query(() => RgbppLatestTransactionList, { name: 'rgbppLatestTransactions' }) public async getLatestTransactions( diff --git a/backend/src/modules/rgbpp/transaction/transaction.service.ts b/backend/src/modules/rgbpp/transaction/transaction.service.ts index 91690000..182a7abe 100644 --- a/backend/src/modules/rgbpp/transaction/transaction.service.ts +++ b/backend/src/modules/rgbpp/transaction/transaction.service.ts @@ -21,7 +21,7 @@ export class RgbppTransactionService { private ckbRpcService: CkbRpcWebsocketService, private bitcoinApiService: BitcoinApiService, private configService: ConfigService, - ) { } + ) {} public async getLatestTransactions( page: number, diff --git a/backend/src/modules/search/search.model.ts b/backend/src/modules/search/search.model.ts index 8dec0170..23af5600 100644 --- a/backend/src/modules/search/search.model.ts +++ b/backend/src/modules/search/search.model.ts @@ -1,4 +1,4 @@ -import { Field, ObjectType } from "@nestjs/graphql"; +import { Field, ObjectType } from '@nestjs/graphql'; @ObjectType({ description: 'Search Result (including address/tx/block)' }) export class SearchResult { diff --git a/backend/src/modules/search/search.resolver.ts b/backend/src/modules/search/search.resolver.ts index ac7e22f3..6279a173 100644 --- a/backend/src/modules/search/search.resolver.ts +++ b/backend/src/modules/search/search.resolver.ts @@ -23,7 +23,7 @@ import { ParentField } from 'src/decorators/parent-field.decorator'; @Resolver(() => SearchResult) export class SearchResolver { - constructor(private ckbExplorerService: CkbExplorerService) { } + constructor(private ckbExplorerService: CkbExplorerService) {} @Query(() => SearchResult) public async search(@Args('query') query: string) { diff --git a/backend/src/pipes/validate-address.pipe.ts b/backend/src/pipes/validate-address.pipe.ts index 98e4571b..80f0cefa 100644 --- a/backend/src/pipes/validate-address.pipe.ts +++ b/backend/src/pipes/validate-address.pipe.ts @@ -1,10 +1,5 @@ import { config, helpers } from '@ckb-lumos/lumos'; -import { - PipeTransform, - Injectable, - BadRequestException, - Logger, -} from '@nestjs/common'; +import { PipeTransform, Injectable, BadRequestException, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { isValidAddress } from '@rgbpp-sdk/btc'; import { BtcNetworkTypeMap, NetworkType } from 'src/constants'; @@ -54,7 +49,7 @@ export class ValidateBtcAddressPipe extends BaseValidateAddressPipe { protected validateAddress(value: string): boolean { const network = this.configService.get('NETWORK', { infer: true }); - const isValid = isValidAddress(value, BtcNetworkTypeMap[network ?? NetworkType.testnet]); + const isValid = isValidAddress(value, BtcNetworkTypeMap[network ?? NetworkType.testnet]); return isValid; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ac20dd4..d1881aeb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -152,6 +152,9 @@ importers: '@types/node': specifier: ^20.3.1 version: 20.14.10 + '@types/serialize-javascript': + specifier: ^5.0.4 + version: 5.0.4 '@types/supertest': specifier: ^6.0.0 version: 6.0.2 @@ -170,9 +173,15 @@ importers: eslint-plugin-prettier: specifier: ^5.0.0 version: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2) + husky: + specifier: ^9.1.4 + version: 9.1.4 jest: specifier: ^29.5.0 version: 29.7.0(@types/node@20.14.10)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.14.10)(typescript@5.5.3)) + lint-staged: + specifier: ^15.2.7 + version: 15.2.7 prettier: specifier: ^3.0.0 version: 3.3.2 @@ -2876,6 +2885,9 @@ packages: '@types/send@0.17.4': resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + '@types/serialize-javascript@5.0.4': + resolution: {integrity: sha512-Z2R7UKFuNWCP8eoa2o9e5rkD3hmWxx/1L0CYz0k2BZzGh0PhEVMp9kfGiqEml/0IglwNERXZ2hwNzIrSz/KHTA==} + '@types/serve-static@1.15.7': resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} @@ -3536,6 +3548,10 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -3945,6 +3961,10 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} @@ -3957,6 +3977,10 @@ packages: resolution: {integrity: sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==} engines: {node: '>= 0.2.0'} + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + cli-width@3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} @@ -4003,6 +4027,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + colors@1.0.3: resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} @@ -4397,6 +4424,9 @@ packages: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4422,6 +4452,10 @@ packages: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -4681,6 +4715,10 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} @@ -4910,6 +4948,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -4926,6 +4968,10 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + get-symbol-description@1.0.2: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} @@ -5099,6 +5145,15 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + husky@9.1.4: + resolution: {integrity: sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==} + engines: {node: '>=18'} + hasBin: true + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -5231,6 +5286,14 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + is-generator-fn@2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} @@ -5286,6 +5349,10 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -5684,9 +5751,22 @@ packages: resolution: {integrity: sha512-V0RMVZzK1+rCHpymRv4URK2lNhIRyO8g7U7zOFwVAhJuat74HtkjIQpQRKNCwFEYkRGpafOpmXXLoaoBcyVtBg==} engines: {node: '>= 12.0.0'} + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lint-staged@15.2.7: + resolution: {integrity: sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==} + engines: {node: '>=18.12.0'} + hasBin: true + + listr2@8.2.4: + resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==} + engines: {node: '>=18.0.0'} + load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -5759,6 +5839,10 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} + look-it-up@2.1.0: resolution: {integrity: sha512-nMoGWW2HurtuJf6XAL56FWTDCWLOTSsanrgwOyaR5Y4e3zfG5N/0cU5xWZSEU3tBxhQugRbV1xL9jb+ug7yZww==} @@ -5882,6 +5966,14 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -6062,6 +6154,10 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -6127,6 +6223,14 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + opentelemetry-instrumentation-fetch-node@1.2.3: resolution: {integrity: sha512-Qb11T7KvoCevMaSeuamcLsAD+pZnavkhDnlVL0kRozfhl42dKG5Q3anUklAFKJZjY3twLR+BnRa6DlwwkIE/+A==} engines: {node: '>18.0.0'} @@ -6214,6 +6318,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -6265,6 +6373,11 @@ packages: resolution: {integrity: sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==} engines: {node: '>=12'} + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -6650,6 +6763,10 @@ packages: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + ret@0.4.3: resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} engines: {node: '>=10'} @@ -6804,6 +6921,14 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -6873,6 +6998,10 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -6889,6 +7018,10 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.includes@2.0.0: resolution: {integrity: sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==} @@ -6933,6 +7066,10 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -7451,6 +7588,10 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -10844,6 +10985,8 @@ snapshots: '@types/mime': 1.3.5 '@types/node': 20.14.10 + '@types/serialize-javascript@5.0.4': {} + '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 @@ -12135,6 +12278,10 @@ snapshots: dependencies: type-fest: 0.21.3 + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -12685,6 +12832,10 @@ snapshots: dependencies: restore-cursor: 3.1.0 + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + cli-spinners@2.9.2: {} cli-table3@0.6.5: @@ -12697,6 +12848,11 @@ snapshots: dependencies: colors: 1.0.3 + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.2.0 + cli-width@3.0.0: {} cli-width@4.1.0: {} @@ -12731,6 +12887,8 @@ snapshots: color-name@1.1.4: {} + colorette@2.0.20: {} + colors@1.0.3: {} combined-stream@1.0.8: @@ -13190,6 +13348,8 @@ snapshots: emittery@0.13.1: {} + emoji-regex@10.3.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -13209,6 +13369,8 @@ snapshots: env-paths@3.0.0: {} + environment@1.1.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -13657,6 +13819,18 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + exit@0.1.2: {} expect@29.7.0: @@ -13970,6 +14144,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.2.0: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -13984,6 +14160,8 @@ snapshots: get-stream@6.0.1: {} + get-stream@8.0.1: {} + get-symbol-description@1.0.2: dependencies: call-bind: 1.0.7 @@ -14161,6 +14339,10 @@ snapshots: human-signals@2.1.0: {} + human-signals@5.0.0: {} + + husky@9.1.4: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -14340,6 +14522,12 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + is-generator-fn@2.1.0: {} is-generator-function@1.0.10: @@ -14379,6 +14567,8 @@ snapshots: is-stream@2.0.1: {} + is-stream@3.0.0: {} + is-string@1.0.7: dependencies: has-tostringtag: 1.0.2 @@ -14937,8 +15127,34 @@ snapshots: lightningcss-linux-x64-musl: 1.25.1 lightningcss-win32-x64-msvc: 1.25.1 + lilconfig@3.1.2: {} + lines-and-columns@1.2.4: {} + lint-staged@15.2.7: + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + debug: 4.3.5 + execa: 8.0.1 + lilconfig: 3.1.2 + listr2: 8.2.4 + micromatch: 4.0.7 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.4.5 + transitivePeerDependencies: + - supports-color + + listr2@8.2.4: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.0 + load-yaml-file@0.2.0: dependencies: graceful-fs: 4.2.11 @@ -14998,6 +15214,14 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + log-update@6.1.0: + dependencies: + ansi-escapes: 7.0.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + look-it-up@2.1.0: {} loose-envify@1.4.0: @@ -15116,6 +15340,10 @@ snapshots: mimic-fn@2.1.0: {} + mimic-fn@4.0.0: {} + + mimic-function@5.0.1: {} + min-indent@1.0.1: {} minimalistic-assert@1.0.1: {} @@ -15296,6 +15524,10 @@ snapshots: dependencies: path-key: 3.1.1 + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -15367,6 +15599,14 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + opentelemetry-instrumentation-fetch-node@1.2.3(@opentelemetry/api@1.9.0): dependencies: '@opentelemetry/api': 1.9.0 @@ -15456,6 +15696,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -15495,6 +15737,8 @@ snapshots: picomatch@4.0.1: {} + pidtree@0.6.0: {} + pify@4.0.1: {} pino-abstract-transport@1.2.0: @@ -15890,6 +16134,11 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + ret@0.4.3: {} reusify@1.0.4: {} @@ -16062,6 +16311,16 @@ snapshots: slash@3.0.0: {} + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + snake-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -16125,6 +16384,8 @@ snapshots: streamsearch@1.1.0: {} + string-argv@0.3.2: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -16146,6 +16407,12 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string-width@7.2.0: + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + string.prototype.includes@2.0.0: dependencies: define-properties: 1.2.1 @@ -16207,6 +16474,8 @@ snapshots: strip-final-newline@2.0.0: {} + strip-final-newline@3.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -16746,6 +17015,12 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} write-file-atomic@4.0.2: From eaa040b4f4c0897970920a23d1a6d1bad7b2f8ea Mon Sep 17 00:00:00 2001 From: ahonn Date: Fri, 2 Aug 2024 18:41:31 +1000 Subject: [PATCH 2/3] fix: fix cacheable decorator --- .../core/bitcoin-api/bitcoin-api.service.ts | 18 +++++--- .../core/ckb-explorer/ckb-explorer.service.ts | 9 ++-- .../core/ckb-rpc/ckb-rpc-websocket.service.ts | 27 ++++++++++- backend/src/decorators/cacheable.decorator.ts | 46 ++++++++++++++----- 4 files changed, 76 insertions(+), 24 deletions(-) diff --git a/backend/src/core/bitcoin-api/bitcoin-api.service.ts b/backend/src/core/bitcoin-api/bitcoin-api.service.ts index 54815e61..dd8ddf73 100644 --- a/backend/src/core/bitcoin-api/bitcoin-api.service.ts +++ b/backend/src/core/bitcoin-api/bitcoin-api.service.ts @@ -7,8 +7,8 @@ import { Env } from 'src/env'; import { IBitcoinDataProvider } from './bitcoin-api.interface'; import { ElectrsService } from './provider/electrs.service'; import { MempoolService } from './provider/mempool.service'; -import { ChainInfo } from './bitcoin-api.schema'; -import { ONE_MONTH_MS, TEN_MINUTES_MS } from 'src/common/date'; +import { ChainInfo, Transaction } from './bitcoin-api.schema'; +import { ONE_HOUR_MS, ONE_MONTH_MS, TEN_MINUTES_MS } from 'src/common/date'; import { Cacheable } from 'src/decorators/cacheable.decorator'; type MethodParameters = T[K] extends (...args: infer P) => any ? P : never; @@ -185,9 +185,13 @@ export class BitcoinApiService { } @Cacheable({ - key: ({ txid }) => `getTx:${txid}`, namespace: 'bitcoinApiService', + key: ({ txid }) => `getTx:${txid}`, ttl: ONE_MONTH_MS, + shouldCache: (tx: Transaction) => + tx.status.confirmed && + !!tx.status.block_time && + tx.status.block_time - Date.now() < ONE_HOUR_MS, }) public async getTx({ txid }: { txid: string }) { return this.call('getTx', { txid }); @@ -202,8 +206,8 @@ export class BitcoinApiService { } @Cacheable({ - key: ({ hash }) => `getBlock:${hash}`, namespace: 'bitcoinApiService', + key: ({ hash }) => `getBlock:${hash}`, ttl: ONE_MONTH_MS, }) public async getBlock({ hash }: { hash: string }) { @@ -211,8 +215,8 @@ export class BitcoinApiService { } @Cacheable({ - key: ({ hash, startIndex }) => `getBlockTxs:${hash}:${startIndex}`, namespace: 'bitcoinApiService', + key: ({ hash, startIndex }) => `getBlockTxs:${hash}:${startIndex}`, ttl: ONE_MONTH_MS, }) public async getBlockTxs({ hash, startIndex }: { hash: string; startIndex?: number }) { @@ -220,8 +224,8 @@ export class BitcoinApiService { } @Cacheable({ - key: ({ height }) => `getBlockHeight:${height}`, namespace: 'bitcoinApiService', + key: ({ height }) => `getBlockHeight:${height}`, ttl: TEN_MINUTES_MS, }) public async getBlockHeight({ height }: { height: number }) { @@ -229,8 +233,8 @@ export class BitcoinApiService { } @Cacheable({ - key: ({ hash }) => `getBlockTxids:${hash}`, namespace: 'bitcoinApiService', + key: ({ hash }) => `getBlockTxids:${hash}`, ttl: ONE_MONTH_MS, }) public async getBlockTxids({ hash }: { hash: string }) { diff --git a/backend/src/core/ckb-explorer/ckb-explorer.service.ts b/backend/src/core/ckb-explorer/ckb-explorer.service.ts index 22fd97f2..19f701f3 100644 --- a/backend/src/core/ckb-explorer/ckb-explorer.service.ts +++ b/backend/src/core/ckb-explorer/ckb-explorer.service.ts @@ -126,7 +126,8 @@ export class CkbExplorerService { } @Cacheable({ - key: (heightOrHash: string) => `CkbExplorerService:getBlock:${heightOrHash}`, + namespace: 'CkbExplorerService', + key: (heightOrHash: string) => `getBlock:${heightOrHash}`, ttl: ONE_MONTH_MS, }) public async getBlock(heightOrHash: string): Promise> { @@ -135,8 +136,9 @@ export class CkbExplorerService { } @Cacheable({ + namespace: 'CkbExplorerService', key: (heightOrHash: string, { page = 1, pageSize = 10 }: BasePaginationParams = {}) => - `CkbExplorerService:getBlockTransactions:${heightOrHash},${page},${pageSize}`, + `getBlockTransactions:${heightOrHash},${page},${pageSize}`, ttl: ONE_MONTH_MS, }) public async getBlockTransactions( @@ -190,7 +192,8 @@ export class CkbExplorerService { } @Cacheable({ - key: (txHash: string) => `CkbExplorerService:getTransaction:${txHash}`, + namespace: 'CkbExplorerService', + key: (txHash: string) => `getTransaction:${txHash}`, ttl: ONE_HOUR_MS, shouldCache: async (tx: NonPaginatedResponse) => { // cache tx for 1 month if it's committed and older than 1 hour diff --git a/backend/src/core/ckb-rpc/ckb-rpc-websocket.service.ts b/backend/src/core/ckb-rpc/ckb-rpc-websocket.service.ts index 61637bbb..c0bf95db 100644 --- a/backend/src/core/ckb-rpc/ckb-rpc-websocket.service.ts +++ b/backend/src/core/ckb-rpc/ckb-rpc-websocket.service.ts @@ -11,6 +11,8 @@ import { SearchKey, TransactionWithStatusResponse, } from './ckb-rpc.interface'; +import { Cacheable } from 'src/decorators/cacheable.decorator'; +import { ONE_MONTH_MS } from 'src/common/date'; @Injectable() export class CkbRpcWebsocketService { @@ -19,11 +21,26 @@ export class CkbRpcWebsocketService { constructor(private configService: ConfigService) { this.websocket = new RpcWebsocketsClient(this.configService.get('CKB_RPC_WEBSOCKET_URL')); - this.websocket.on('error', (error) => { - this.logger.error(error.message); + + this.websocket.on('open', () => { + this.websocket.on('error', (error) => { + this.logger.error(error.message); + }); }); } + @Cacheable({ + namespace: 'CkbRpcWebsocketService', + key: (txHash: string) => `getTransaction:${txHash}`, + ttl: ONE_MONTH_MS, + shouldCache: async (tx: TransactionWithStatusResponse, that: CkbRpcWebsocketService) => { + if (tx.tx_status.status !== 'committed') { + return false; + } + const block = await that.getTipBlockNumber(); + return BI.from(tx.tx_status.block_number).lt(BI.from(block)); + }, + }) public async getTransaction(txHash: string): Promise { this.logger.debug(`get_transaction - txHash: ${txHash}`); const tx = await this.websocket.call('get_transaction', [txHash]); @@ -50,6 +67,12 @@ export class CkbRpcWebsocketService { return blockEconomicState as BlockEconomicState; } + @Cacheable({ + namespace: 'CkbRpcWebsocketService', + key: 'getTipBlockNumber', + // just cache for 1 second to avoid too many requests + ttl: 1000, + }) public async getTipBlockNumber(): Promise { this.logger.debug('get_tip_block_number'); const tipBlockNumber = await this.websocket.call('get_tip_block_number', []); diff --git a/backend/src/decorators/cacheable.decorator.ts b/backend/src/decorators/cacheable.decorator.ts index b99e588d..f0295535 100644 --- a/backend/src/decorators/cacheable.decorator.ts +++ b/backend/src/decorators/cacheable.decorator.ts @@ -1,10 +1,15 @@ // eslint-disable-next-line no-restricted-imports +import { Cache, CACHE_MANAGER } from '@nestjs/cache-manager'; +import { Inject, Logger } from '@nestjs/common'; import { CacheableRegisterOptions, Cacheable as _Cacheable } from 'nestjs-cacheable'; +import { cacheableHandle, generateComposedKey } from 'nestjs-cacheable/dist/cacheable.helper'; export interface CustomCacheableRegisterOptions extends CacheableRegisterOptions { - shouldCache?: (result: any) => boolean | Promise; + shouldCache?: (result: any, target: any) => boolean | Promise; } +const logger = new Logger('Cacheable'); + /** * Cacheable decorator with custom options, based on the original Cacheable decorator from the nestjs-cacheable package. * Adds a shouldCache option to determine whether the result should be cached. @@ -17,23 +22,40 @@ export interface CustomCacheableRegisterOptions extends CacheableRegisterOptions * }); */ export function Cacheable(options: CustomCacheableRegisterOptions): MethodDecorator { - return function (_, propertyKey, descriptor) { + const injectCacheService = Inject(CACHE_MANAGER); + + return function(target, propertyKey, descriptor) { // eslint-disable-next-line @typescript-eslint/ban-types const originalMethod = descriptor.value as unknown as Function; + + injectCacheService(target, '__cacheManager'); return { ...descriptor, - value: async function (...args: any[]) { - const returnVal = await originalMethod.apply(this, args); + value: async function(...args: any[]) { + const cacheManager = this.__cacheManager as Cache; + if (!cacheManager) return originalMethod.apply(this, args); + const composeOptions: Parameters[0] = { + methodName: String(propertyKey), + key: options.key, + namespace: options.namespace, + args, + }; + const [key] = generateComposedKey(composeOptions); + const returnVal = await cacheableHandle( + key, + () => originalMethod.apply(this, args), + options.ttl, + ); - const cacheable = options.shouldCache ? await options.shouldCache(returnVal) : true; - if (!cacheable) { - return returnVal; + // Remove the cache if shouldCache returns false + const shouldCache = options.shouldCache + ? await options.shouldCache(returnVal, this) + : true; + if (!shouldCache) { + logger.debug(`Removing cache for key: ${key}`); + await cacheManager.del(key); } - - const fakeDescriptor = { - value: () => returnVal, - }; - return _Cacheable(options)(this, propertyKey, fakeDescriptor); + return returnVal; } as any, }; }; From b28213cd68ae8b5e9a22065fcd9e54cd7fa4c997 Mon Sep 17 00:00:00 2001 From: ahonn Date: Fri, 2 Aug 2024 19:35:43 +1000 Subject: [PATCH 3/3] fix: fix sentry module and add make more methods cacheable --- backend/package.json | 6 +- backend/src/app.module.ts | 4 +- .../core/ckb-explorer/ckb-explorer.service.ts | 10 +- .../field-performance.middleware.ts | 2 +- backend/src/modules/rgbpp/coin/coin.model.ts | 5 +- .../src/modules/rgbpp/coin/coin.resolver.ts | 10 +- backend/src/schema.gql | 2 +- pnpm-lock.yaml | 679 ++---------------- 8 files changed, 98 insertions(+), 620 deletions(-) diff --git a/backend/package.json b/backend/package.json index ac1283af..6c062f41 100644 --- a/backend/package.json +++ b/backend/package.json @@ -41,12 +41,12 @@ "@nestjs/platform-express": "^10.0.0", "@nestjs/platform-fastify": "^10.3.10", "@nestjs/schedule": "^4.1.0", - "@ntegral/nestjs-sentry": "^4.0.1", "@prisma/client": "^5.16.2", "@rgbpp-sdk/btc": "^0.0.0-snap-20240727021715", "@rgbpp-sdk/ckb": "^0.0.0-snap-20240727021715", - "@sentry/node": "^8.17.0", - "@sentry/profiling-node": "^8.17.0", + "@ntegral/nestjs-sentry": "^4.0.1", + "@sentry/node": "^7.116.0", + "@sentry/profiling-node": "^7.116.0", "@types/ws": "^8.5.11", "axios": "^1.7.2", "bullmq": "^5.11.0", diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index ee0f15cb..5857e330 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -22,8 +22,8 @@ import configModule from './config'; useFactory: async (configService: ConfigService) => ({ dsn: configService.get('SENTRY_DSN'), environment: configService.get('NODE_ENV'), - tracesSampleRate: 0.1, - profilesSampleRate: 0.1, + tracesSampleRate: 0.5, + profilesSampleRate: 0.5, integrations: [nodeProfilingIntegration()], logLevels: configService.get('NODE_ENV') === 'production' diff --git a/backend/src/core/ckb-explorer/ckb-explorer.service.ts b/backend/src/core/ckb-explorer/ckb-explorer.service.ts index 19f701f3..b1c22e56 100644 --- a/backend/src/core/ckb-explorer/ckb-explorer.service.ts +++ b/backend/src/core/ckb-explorer/ckb-explorer.service.ts @@ -202,15 +202,15 @@ export class CkbExplorerService { }, }) public async getTransaction(txHash: string): Promise> { - const key = `CkbExplorerService:getTransaction:${txHash}`; - const cached = await this.cacheManager.get(key); - if (cached) { - return cached as NonPaginatedResponse; - } const response = await this.request.get(`/v1/transactions/${txHash}`); return response.data; } + @Cacheable({ + namespace: 'CkbExplorerService', + key: (txHash: string) => `getRgbppDigest:${txHash}`, + ttl: ONE_MONTH_MS, + }) public async getRgbppDigest(txHash: string): Promise> { const response = await this.request.get(`/v2/ckb_transactions/${txHash}/rgb_digest`); return response.data; diff --git a/backend/src/middlewares/field-performance.middleware.ts b/backend/src/middlewares/field-performance.middleware.ts index 2ab3c54d..c8ff97e5 100644 --- a/backend/src/middlewares/field-performance.middleware.ts +++ b/backend/src/middlewares/field-performance.middleware.ts @@ -9,7 +9,7 @@ export const fieldPerformanceMiddleware: FieldMiddleware = async ( const value = await next(); const executionTime = performance.now() - now; - if (executionTime > 100) { + if (executionTime > 300) { const { path } = ctx.info; logger.debug(`[${path.typename}.${path.key}]: ${executionTime}ms`); } diff --git a/backend/src/modules/rgbpp/coin/coin.model.ts b/backend/src/modules/rgbpp/coin/coin.model.ts index 5d2afe31..cac0131d 100644 --- a/backend/src/modules/rgbpp/coin/coin.model.ts +++ b/backend/src/modules/rgbpp/coin/coin.model.ts @@ -54,7 +54,10 @@ export class RgbppCoin { @Field(() => Float, { nullable: true }) transactionsCount: number; - public static from(xudt: CkbExplorer.XUDT): RgbppBaseCoin { + public static from(xudt: CkbExplorer.XUDT): RgbppBaseCoin | null { + if (!xudt) { + return null; + } return { name: xudt.full_name, description: xudt.description, diff --git a/backend/src/modules/rgbpp/coin/coin.resolver.ts b/backend/src/modules/rgbpp/coin/coin.resolver.ts index ebac6bf0..d815a714 100644 --- a/backend/src/modules/rgbpp/coin/coin.resolver.ts +++ b/backend/src/modules/rgbpp/coin/coin.resolver.ts @@ -11,7 +11,7 @@ import { @Resolver(() => RgbppCoin) export class RgbppCoinResolver { - constructor(private ckbExplorerService: CkbExplorerService) {} + constructor(private ckbExplorerService: CkbExplorerService) { } @Query(() => RgbppCoinList, { name: 'rgbppCoins' }) public async coins( @@ -26,7 +26,9 @@ export class RgbppCoinResolver { sort, tags: [XUDTTag.RgbppCompatible], }); - const coins = response.data.map((coin) => RgbppCoin.from(coin.attributes)); + const coins = response.data + .map((coin) => RgbppCoin.from(coin.attributes)) + .filter((coin) => coin !== null); return { coins, total: response.meta.total, @@ -34,10 +36,10 @@ export class RgbppCoinResolver { }; } - @Query(() => RgbppCoin, { name: 'rgbppCoin' }) + @Query(() => RgbppCoin, { name: 'rgbppCoin', nullable: true }) public async coin( @Args('typeHash', { type: () => String }) typeHash: string, - ): Promise { + ): Promise { const response = await this.ckbExplorerService.getXUDT(typeHash); return RgbppCoin.from(response.data.attributes); } diff --git a/backend/src/schema.gql b/backend/src/schema.gql index 5fda7cb3..1f2b6cbb 100644 --- a/backend/src/schema.gql +++ b/backend/src/schema.gql @@ -303,7 +303,7 @@ type Query { btcAddress(address: String!): BitcoinAddress rgbppAddress(address: String!): RgbppAddress rgbppCoins(page: Int, pageSize: Int, sort: TransactionListSortType): RgbppCoinList! - rgbppCoin(typeHash: String!): RgbppCoin! + rgbppCoin(typeHash: String!): RgbppCoin rgbppStatistic: RgbppStatistic! search(query: String!): SearchResult! } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d1881aeb..923a3aad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,7 +57,7 @@ importers: version: 4.1.0(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1)) '@ntegral/nestjs-sentry': specifier: ^4.0.1 - version: 4.0.1(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@sentry/hub@7.114.0)(@sentry/node@8.17.0)(bufferutil@4.0.8)(graphql@16.9.0)(reflect-metadata@0.2.2)(rimraf@3.0.2)(rxjs@7.8.1)(utf-8-validate@5.0.10) + version: 4.0.1(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@sentry/hub@7.114.0)(@sentry/node@7.118.0)(bufferutil@4.0.8)(graphql@16.9.0)(reflect-metadata@0.2.2)(rimraf@3.0.2)(rxjs@7.8.1)(utf-8-validate@5.0.10) '@prisma/client': specifier: ^5.16.2 version: 5.17.0(prisma@5.17.0) @@ -68,11 +68,11 @@ importers: specifier: ^0.0.0-snap-20240727021715 version: 0.0.0-snap-20240727021715(@ckb-lumos/lumos@0.23.0)(lodash@4.17.21) '@sentry/node': - specifier: ^8.17.0 - version: 8.17.0 + specifier: ^7.116.0 + version: 7.118.0 '@sentry/profiling-node': - specifier: ^8.17.0 - version: 8.17.0 + specifier: ^7.116.0 + version: 7.118.0 '@types/ws': specifier: ^8.5.11 version: 8.5.11 @@ -2290,160 +2290,10 @@ packages: engines: {node: '>=8.0.0', npm: '>=5.0.0'} hasBin: true - '@opentelemetry/api-logs@0.52.1': - resolution: {integrity: sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==} - engines: {node: '>=14'} - '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@1.25.1': - resolution: {integrity: sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/core@1.25.1': - resolution: {integrity: sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/instrumentation-connect@0.38.0': - resolution: {integrity: sha512-2/nRnx3pjYEmdPIaBwtgtSviTKHWnDZN3R+TkRUnhIVrvBKVcq+I5B2rtd6mr6Fe9cHlZ9Ojcuh7pkNh/xdWWg==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-express@0.41.0': - resolution: {integrity: sha512-/B7fbMdaf3SYe5f1P973tkqd6s7XZirjpfkoJ63E7nltU30qmlgm9tY5XwZOzAFI0rHS9tbrFI2HFPAvQUFe/A==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-fastify@0.38.0': - resolution: {integrity: sha512-HBVLpTSYpkQZ87/Df3N0gAw7VzYZV3n28THIBrJWfuqw3Or7UqdhnjeuMIPQ04BKk3aZc0cWn2naSQObbh5vXw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-graphql@0.42.0': - resolution: {integrity: sha512-N8SOwoKL9KQSX7z3gOaw5UaTeVQcfDO1c21csVHnmnmGUoqsXbArK2B8VuwPWcv6/BC/i3io+xTo7QGRZ/z28Q==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-hapi@0.40.0': - resolution: {integrity: sha512-8U/w7Ifumtd2bSN1OLaSwAAFhb9FyqWUki3lMMB0ds+1+HdSxYBe9aspEJEgvxAqOkrQnVniAPTEGf1pGM7SOw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-http@0.52.1': - resolution: {integrity: sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-ioredis@0.42.0': - resolution: {integrity: sha512-P11H168EKvBB9TUSasNDOGJCSkpT44XgoM6d3gRIWAa9ghLpYhl0uRkS8//MqPzcJVHr3h3RmfXIpiYLjyIZTw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-koa@0.42.0': - resolution: {integrity: sha512-H1BEmnMhho8o8HuNRq5zEI4+SIHDIglNB7BPKohZyWG4fWNuR7yM4GTlR01Syq21vODAS7z5omblScJD/eZdKw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongodb@0.46.0': - resolution: {integrity: sha512-VF/MicZ5UOBiXrqBslzwxhN7TVqzu1/LN/QDpkskqM0Zm0aZ4CVRbUygL8d7lrjLn15x5kGIe8VsSphMfPJzlA==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongoose@0.40.0': - resolution: {integrity: sha512-niRi5ZUnkgzRhIGMOozTyoZIvJKNJyhijQI4nF4iFSb+FUx2v5fngfR+8XLmdQAO7xmsD8E5vEGdDVYVtKbZew==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql2@0.40.0': - resolution: {integrity: sha512-0xfS1xcqUmY7WE1uWjlmI67Xg3QsSUlNT+AcXHeA4BDUPwZtWqF4ezIwLgpVZfHOnkAEheqGfNSWd1PIu3Wnfg==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql@0.40.0': - resolution: {integrity: sha512-d7ja8yizsOCNMYIJt5PH/fKZXjb/mS48zLROO4BzZTtDfhNCl2UM/9VIomP2qkGIFVouSJrGr/T00EzY7bPtKA==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-nestjs-core@0.39.0': - resolution: {integrity: sha512-mewVhEXdikyvIZoMIUry8eb8l3HUjuQjSjVbmLVTt4NQi35tkpnHQrG9bTRBrl3403LoWZ2njMPJyg4l6HfKvA==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-pg@0.43.0': - resolution: {integrity: sha512-og23KLyoxdnAeFs1UWqzSonuCkePUzCX30keSYigIzJe/6WSYA8rnEI5lobcxPEzg+GcU06J7jzokuEHbjVJNw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-redis-4@0.41.0': - resolution: {integrity: sha512-H7IfGTqW2reLXqput4yzAe8YpDC0fmVNal95GHMLOrS89W+qWUKIqxolSh63hJyfmwPSFwXASzj7wpSk8Az+Dg==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.46.0': - resolution: {integrity: sha512-a9TijXZZbk0vI5TGLZl+0kxyFfrXHhX6Svtz7Pp2/VBlCSKrazuULEyoJQrOknJyFWNMEmbbJgOciHCCpQcisw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.52.1': - resolution: {integrity: sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/redis-common@0.36.2': - resolution: {integrity: sha512-faYX1N0gpLhej/6nyp6bgRjzAKXn5GOEMYY7YhciSfCoITAktLUtQ36d24QEWNA1/WA1y6qQunCe0OhHRkVl9g==} - engines: {node: '>=14'} - - '@opentelemetry/resources@1.25.1': - resolution: {integrity: sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/sdk-metrics@1.25.1': - resolution: {integrity: sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - - '@opentelemetry/sdk-trace-base@1.25.1': - resolution: {integrity: sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/semantic-conventions@1.25.1': - resolution: {integrity: sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==} - engines: {node: '>=14'} - - '@opentelemetry/sql-common@0.40.1': - resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@pandacss/config@0.42.0': resolution: {integrity: sha512-DXxQTwuFhsBau619WVuKcUA7LkQMJaPr6eDo8q9mDx579qCcbmBdRkcjqihMTxjJVxUJ7CwcOohq3nbOOhQWHw==} @@ -2527,9 +2377,6 @@ packages: '@prisma/get-platform@5.17.0': resolution: {integrity: sha512-UlDgbRozCP1rfJ5Tlkf3Cnftb6srGrEQ4Nm3og+1Se2gWmCZ0hmPIi+tQikGDUVLlvOWx3Gyi9LzgRP+HTXV9w==} - '@prisma/instrumentation@5.16.1': - resolution: {integrity: sha512-4m5gRFWnQb8s/yTyGbMZkL7A5uJgqOWcWJxapwcAD0T0kh5sGPEVSQl/zTQvE9aduXhFAxOtC3gO+R8Hb5xO1Q==} - '@radix-ui/colors@3.0.0': resolution: {integrity: sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==} @@ -2577,52 +2424,50 @@ packages: '@scure/base@1.1.7': resolution: {integrity: sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g==} + '@sentry-internal/tracing@7.118.0': + resolution: {integrity: sha512-dERAshKlQLrBscHSarhHyUeGsu652bDTUN1FK0m4e3X48M3I5/s+0N880Qjpe5MprNLcINlaIgdQ9jkisvxjfw==} + engines: {node: '>=8'} + '@sentry/core@7.114.0': resolution: {integrity: sha512-YnanVlmulkjgZiVZ9BfY9k6I082n+C+LbZo52MTvx3FY6RE5iyiPMpaOh67oXEZRWcYQEGm+bKruRxLVP6RlbA==} engines: {node: '>=8'} - '@sentry/core@8.17.0': - resolution: {integrity: sha512-s62O0Re6WcvaVbH1IEeAWmj/ca8UhaRoFaDnc5TR68reOycBrgnqCNq3qHxBsELOA6NJowoK+T29DDGs9QVXhQ==} - engines: {node: '>=14.18'} + '@sentry/core@7.118.0': + resolution: {integrity: sha512-ol0xBdp3/K11IMAYSQE0FMxBOOH9hMsb/rjxXWe0hfM5c72CqYWL3ol7voPci0GELJ5CZG+9ImEU1V9r6gK64g==} + engines: {node: '>=8'} '@sentry/hub@7.114.0': resolution: {integrity: sha512-1Q3S5O9fMZ4vB9GJJQB8gw//VZRt8LzlHvMhqMS+K7mm215Rj2qM2wY0js7QSTupHBlZ0+M9j8o7C8XUXAeXbQ==} engines: {node: '>=8'} - '@sentry/node@8.17.0': - resolution: {integrity: sha512-HJ7B/zlpGMOIN+TnLzp6gbOpOzTk3Co19N39Y17T9MrR+5Z4eHdgEKWORFyE0Wy2KYKkVRwJ5zZJbfldc0EsEA==} - engines: {node: '>=14.18'} + '@sentry/integrations@7.118.0': + resolution: {integrity: sha512-C2rR4NvIMjokF8jP5qzSf1o2zxDx7IeYnr8u15Kb2+HdZtX559owALR0hfgwnfeElqMhGlJBaKUWZ48lXJMzCQ==} + engines: {node: '>=8'} + + '@sentry/node@7.118.0': + resolution: {integrity: sha512-79N63DvYKkNPqzmc0cjO+vMZ/nU7+CbE3K3COQNiV7gk58+666G9mRZQJuZVOVebatq5wM5UR0G4LPkwD+J84g==} + engines: {node: '>=8'} - '@sentry/opentelemetry@8.17.0': - resolution: {integrity: sha512-SKHfvHECIs7kqcXVRypXC6bQ7AQ4TTILamamZS5Ro1FP+i+yT8qEIoVWljoFZUIyO4J42mAP98THa1lCPK4BXA==} - engines: {node: '>=14.18'} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - '@opentelemetry/core': ^1.25.1 - '@opentelemetry/instrumentation': ^0.52.1 - '@opentelemetry/sdk-trace-base': ^1.25.1 - '@opentelemetry/semantic-conventions': ^1.25.1 - - '@sentry/profiling-node@8.17.0': - resolution: {integrity: sha512-gtuRZMU1PnceWe/a18hyzj9GqUkXLl7uYstAW5iCiOB/bMpBDoYh1Cz7Dg3u841zFPKobC4t39KKVcVWLrZagg==} - engines: {node: '>=14.18'} + '@sentry/profiling-node@7.118.0': + resolution: {integrity: sha512-CHxNwufyBJN44CrwFubYCj0g0h4CLQpx08mcny+b01TRgSdplJ0cMBChVLrQVsoL5i4nmifyyqpjuSRcvMMaiA==} + engines: {node: '>=8.0.0'} hasBin: true '@sentry/types@7.114.0': resolution: {integrity: sha512-tsqkkyL3eJtptmPtT0m9W/bPLkU7ILY7nvwpi1hahA5jrM7ppoU0IMaQWAgTD+U3rzFH40IdXNBFb8Gnqcva4w==} engines: {node: '>=8'} - '@sentry/types@8.17.0': - resolution: {integrity: sha512-v0nI0+ajiGTijhF1W/ryn2+zFVFr6VPn6lao3W4qKj9MlltIHa4/uuGzTaiCFwoPw7g5bZ1Q09SStpDXVMkz2A==} - engines: {node: '>=14.18'} + '@sentry/types@7.118.0': + resolution: {integrity: sha512-2drqrD2+6kgeg+W/ycmiti3G4lJrV3hGjY9PpJ3bJeXrh6T2+LxKPzlgSEnKFaeQWkXdZ4eaUbtTXVebMjb5JA==} + engines: {node: '>=8'} '@sentry/utils@7.114.0': resolution: {integrity: sha512-319N90McVpupQ6vws4+tfCy/03AdtsU0MurIE4+W5cubHME08HtiEWlfacvAxX+yuKFhvdsO4K4BB/dj54ideg==} engines: {node: '>=8'} - '@sentry/utils@8.17.0': - resolution: {integrity: sha512-HHtAPLOlvzhwgfYzxtuPnLUoGRMtMrFvopkii74zmx/1ZD4VN4PYPB2E5KFf3c18pTovw+kxF0ux6VrGiyAHsw==} - engines: {node: '>=14.18'} + '@sentry/utils@7.118.0': + resolution: {integrity: sha512-43qItc/ydxZV1Zb3Kn2M54RwL9XXFa3IAYBO8S82Qvq5YUYmU2AmJ1jgg7DabXlVSWgMA1HntwqnOV3JLaEnTQ==} + engines: {node: '>=8'} '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -2771,9 +2616,6 @@ packages: '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - '@types/connect@3.4.36': - resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} - '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -2840,9 +2682,6 @@ packages: '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/mysql@2.15.22': - resolution: {integrity: sha512-wK1pzsJVVAjYCSZWQoWHziQZbNggXFDUEIGf54g4ZM/ERuP86uGdWeKZWMYlqTPMZfHJJvLPyogXGvCOg87yLQ==} - '@types/negotiator@0.6.3': resolution: {integrity: sha512-JkXTOdKs5MF086b/pt8C3+yVp3iDUwG635L7oCH6HvJvvr6lSUU5oe/gLXnPEfYRROHjJIPgCV6cuAg8gGkntQ==} @@ -2858,12 +2697,6 @@ packages: '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} - '@types/pg-pool@2.0.4': - resolution: {integrity: sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==} - - '@types/pg@8.6.1': - resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} - '@types/prop-types@15.7.12': resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} @@ -2891,9 +2724,6 @@ packages: '@types/serve-static@1.15.7': resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} - '@types/shimmer@1.2.0': - resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} - '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} @@ -3478,11 +3308,6 @@ packages: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} - acorn-import-assertions@1.9.0: - resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} - peerDependencies: - acorn: ^8 - acorn-import-attributes@1.9.5: resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} peerDependencies: @@ -5165,6 +4990,9 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + immutable@4.3.7: resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} @@ -5172,12 +5000,6 @@ packages: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} - import-in-the-middle@1.7.1: - resolution: {integrity: sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==} - - import-in-the-middle@1.9.0: - resolution: {integrity: sha512-Ng1SJINJDBzyUEkx9Mj32XD8G0TQCUb5TMoL9V91CTn6F3wYZLygLuhNFrv0cNMBZaeptnL1zecV6XrIdHJ+xQ==} - import-local@3.1.0: resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} engines: {node: '>=8'} @@ -5690,6 +5512,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lie@3.1.1: + resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + light-my-request@5.13.0: resolution: {integrity: sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==} @@ -5775,6 +5600,9 @@ packages: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} + localforage@1.10.0: + resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} @@ -6021,9 +5849,6 @@ packages: mnemonist@0.39.6: resolution: {integrity: sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA==} - module-details-from-path@1.0.3: - resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} - moo@0.5.2: resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} @@ -6231,12 +6056,6 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} - opentelemetry-instrumentation-fetch-node@1.2.3: - resolution: {integrity: sha512-Qb11T7KvoCevMaSeuamcLsAD+pZnavkhDnlVL0kRozfhl42dKG5Q3anUklAFKJZjY3twLR+BnRa6DlwwkIE/+A==} - engines: {node: '>18.0.0'} - peerDependencies: - '@opentelemetry/api': ^1.6.0 - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -6351,17 +6170,6 @@ packages: perfect-freehand@1.2.2: resolution: {integrity: sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ==} - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-protocol@1.6.1: - resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} @@ -6476,22 +6284,6 @@ packages: resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} engines: {node: ^10 || ^12 || >=14} - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - preferred-pm@3.1.2: resolution: {integrity: sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q==} engines: {node: '>=10'} @@ -6728,10 +6520,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - require-in-the-middle@7.3.0: - resolution: {integrity: sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==} - engines: {node: '>=8.6.0'} - resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -6897,9 +6685,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shimmer@1.2.1: - resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} - side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} @@ -10090,12 +9875,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - '@ntegral/nestjs-sentry@4.0.1(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@sentry/hub@7.114.0)(@sentry/node@8.17.0)(bufferutil@4.0.8)(graphql@16.9.0)(reflect-metadata@0.2.2)(rimraf@3.0.2)(rxjs@7.8.1)(utf-8-validate@5.0.10)': + '@ntegral/nestjs-sentry@4.0.1(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@sentry/hub@7.114.0)(@sentry/node@7.118.0)(bufferutil@4.0.8)(graphql@16.9.0)(reflect-metadata@0.2.2)(rimraf@3.0.2)(rxjs@7.8.1)(utf-8-validate@5.0.10)': dependencies: '@nestjs/common': 10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@sentry/hub': 7.114.0 - '@sentry/node': 8.17.0 + '@sentry/node': 7.118.0 reflect-metadata: 0.2.2 rimraf: 3.0.2 rxjs: 7.8.1 @@ -10118,210 +9903,9 @@ snapshots: transitivePeerDependencies: - encoding - '@opentelemetry/api-logs@0.52.1': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/api@1.9.0': {} - - '@opentelemetry/context-async-hooks@1.25.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - - '@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.25.1 - - '@opentelemetry/instrumentation-connect@0.38.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - '@types/connect': 3.4.36 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-express@0.41.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-fastify@0.38.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-graphql@0.42.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-hapi@0.40.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-http@0.52.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - semver: 7.6.2 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-ioredis@0.42.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-koa@0.42.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mongodb@0.46.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mongoose@0.40.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mysql2@0.40.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-mysql@0.40.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - '@types/mysql': 2.15.22 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-nestjs-core@0.39.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-pg@0.43.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) - '@types/pg': 8.6.1 - '@types/pg-pool': 2.0.4 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation-redis-4@0.41.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/instrumentation@0.46.0(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@types/shimmer': 1.2.0 - import-in-the-middle: 1.7.1 - require-in-the-middle: 7.3.0 - semver: 7.6.2 - shimmer: 1.2.1 - transitivePeerDependencies: - - supports-color + '@opentelemetry/api@1.9.0': optional: true - '@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.52.1 - '@types/shimmer': 1.2.0 - import-in-the-middle: 1.9.0 - require-in-the-middle: 7.3.0 - semver: 7.6.2 - shimmer: 1.2.1 - transitivePeerDependencies: - - supports-color - - '@opentelemetry/redis-common@0.36.2': {} - - '@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - - '@opentelemetry/sdk-metrics@1.25.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - lodash.merge: 4.6.2 - - '@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - - '@opentelemetry/semantic-conventions@1.25.1': {} - - '@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0)': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@pandacss/config@0.42.0': dependencies: '@pandacss/logger': 0.42.0 @@ -10522,14 +10106,6 @@ snapshots: dependencies: '@prisma/debug': 5.17.0 - '@prisma/instrumentation@5.16.1': - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color - '@radix-ui/colors@3.0.0': {} '@redis/bloom@1.2.0(@redis/client@1.6.0)': @@ -10603,15 +10179,21 @@ snapshots: '@scure/base@1.1.7': {} + '@sentry-internal/tracing@7.118.0': + dependencies: + '@sentry/core': 7.118.0 + '@sentry/types': 7.118.0 + '@sentry/utils': 7.118.0 + '@sentry/core@7.114.0': dependencies: '@sentry/types': 7.114.0 '@sentry/utils': 7.114.0 - '@sentry/core@8.17.0': + '@sentry/core@7.118.0': dependencies: - '@sentry/types': 8.17.0 - '@sentry/utils': 8.17.0 + '@sentry/types': 7.118.0 + '@sentry/utils': 7.118.0 '@sentry/hub@7.114.0': dependencies: @@ -10619,73 +10201,37 @@ snapshots: '@sentry/types': 7.114.0 '@sentry/utils': 7.114.0 - '@sentry/node@8.17.0': + '@sentry/integrations@7.118.0': dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-connect': 0.38.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-express': 0.41.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-fastify': 0.38.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-graphql': 0.42.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-hapi': 0.40.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-http': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-ioredis': 0.42.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-koa': 0.42.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongodb': 0.46.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongoose': 0.40.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql': 0.40.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql2': 0.40.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-nestjs-core': 0.39.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-pg': 0.43.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-redis-4': 0.41.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - '@prisma/instrumentation': 5.16.1 - '@sentry/core': 8.17.0 - '@sentry/opentelemetry': 8.17.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1) - '@sentry/types': 8.17.0 - '@sentry/utils': 8.17.0 - optionalDependencies: - opentelemetry-instrumentation-fetch-node: 1.2.3(@opentelemetry/api@1.9.0) - transitivePeerDependencies: - - supports-color + '@sentry/core': 7.118.0 + '@sentry/types': 7.118.0 + '@sentry/utils': 7.118.0 + localforage: 1.10.0 - '@sentry/opentelemetry@8.17.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)': + '@sentry/node@7.118.0': + dependencies: + '@sentry-internal/tracing': 7.118.0 + '@sentry/core': 7.118.0 + '@sentry/integrations': 7.118.0 + '@sentry/types': 7.118.0 + '@sentry/utils': 7.118.0 + + '@sentry/profiling-node@7.118.0': dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - '@sentry/core': 8.17.0 - '@sentry/types': 8.17.0 - '@sentry/utils': 8.17.0 - - '@sentry/profiling-node@8.17.0': - dependencies: - '@sentry/core': 8.17.0 - '@sentry/node': 8.17.0 - '@sentry/types': 8.17.0 - '@sentry/utils': 8.17.0 detect-libc: 2.0.3 node-abi: 3.65.0 - transitivePeerDependencies: - - supports-color '@sentry/types@7.114.0': {} - '@sentry/types@8.17.0': {} + '@sentry/types@7.118.0': {} '@sentry/utils@7.114.0': dependencies: '@sentry/types': 7.114.0 - '@sentry/utils@8.17.0': + '@sentry/utils@7.118.0': dependencies: - '@sentry/types': 8.17.0 + '@sentry/types': 7.118.0 '@sinclair/typebox@0.27.8': {} @@ -10858,10 +10404,6 @@ snapshots: '@types/connect': 3.4.38 '@types/node': 20.14.10 - '@types/connect@3.4.36': - dependencies: - '@types/node': 20.14.10 - '@types/connect@3.4.38': dependencies: '@types/node': 20.14.10 @@ -10937,10 +10479,6 @@ snapshots: '@types/mime@1.3.5': {} - '@types/mysql@2.15.22': - dependencies: - '@types/node': 20.14.10 - '@types/negotiator@0.6.3': {} '@types/node@17.0.45': {} @@ -10953,16 +10491,6 @@ snapshots: '@types/parse-json@4.0.2': {} - '@types/pg-pool@2.0.4': - dependencies: - '@types/pg': 8.6.1 - - '@types/pg@8.6.1': - dependencies: - '@types/node': 20.14.10 - pg-protocol: 1.6.1 - pg-types: 2.2.0 - '@types/prop-types@15.7.12': {} '@types/qs@6.9.15': {} @@ -10993,8 +10521,6 @@ snapshots: '@types/node': 20.14.10 '@types/send': 0.17.4 - '@types/shimmer@1.2.0': {} - '@types/stack-utils@2.0.3': {} '@types/superagent@8.1.7': @@ -12209,11 +11735,6 @@ snapshots: mime-types: 2.1.35 negotiator: 0.6.3 - acorn-import-assertions@1.9.0(acorn@8.12.1): - dependencies: - acorn: 8.12.1 - optional: true - acorn-import-attributes@1.9.5(acorn@8.12.1): dependencies: acorn: 8.12.1 @@ -14351,6 +13872,8 @@ snapshots: ignore@5.3.1: {} + immediate@3.0.6: {} + immutable@4.3.7: {} import-fresh@3.3.0: @@ -14358,21 +13881,6 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-in-the-middle@1.7.1: - dependencies: - acorn: 8.12.1 - acorn-import-assertions: 1.9.0(acorn@8.12.1) - cjs-module-lexer: 1.3.1 - module-details-from-path: 1.0.3 - optional: true - - import-in-the-middle@1.9.0: - dependencies: - acorn: 8.12.1 - acorn-import-attributes: 1.9.5(acorn@8.12.1) - cjs-module-lexer: 1.3.1 - module-details-from-path: 1.0.3 - import-local@3.1.0: dependencies: pkg-dir: 4.2.0 @@ -15080,6 +14588,10 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lie@3.1.1: + dependencies: + immediate: 3.0.6 + light-my-request@5.13.0: dependencies: cookie: 0.6.0 @@ -15164,6 +14676,10 @@ snapshots: loader-runner@4.3.0: {} + localforage@1.10.0: + dependencies: + lie: 3.1.1 + locate-path@3.0.0: dependencies: p-locate: 3.0.0 @@ -15387,8 +14903,6 @@ snapshots: dependencies: obliterator: 2.0.4 - module-details-from-path@1.0.3: {} - moo@0.5.2: {} mqemitter@5.0.0: @@ -15607,15 +15121,6 @@ snapshots: dependencies: mimic-function: 5.0.1 - opentelemetry-instrumentation-fetch-node@1.2.3(@opentelemetry/api@1.9.0): - dependencies: - '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.1 - transitivePeerDependencies: - - supports-color - optional: true - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -15719,18 +15224,6 @@ snapshots: perfect-freehand@1.2.2: {} - pg-int8@1.0.1: {} - - pg-protocol@1.6.1: {} - - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.0 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - picocolors@1.0.1: {} picomatch@2.3.1: {} @@ -15847,16 +15340,6 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 - postgres-array@2.0.0: {} - - postgres-bytea@1.0.0: {} - - postgres-date@1.0.7: {} - - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - preferred-pm@3.1.2: dependencies: find-up: 5.0.0 @@ -16097,14 +15580,6 @@ snapshots: require-from-string@2.0.2: {} - require-in-the-middle@7.3.0: - dependencies: - debug: 4.3.5 - module-details-from-path: 1.0.3 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -16290,8 +15765,6 @@ snapshots: shebang-regex@3.0.0: {} - shimmer@1.2.1: {} - side-channel@1.0.6: dependencies: call-bind: 1.0.7