diff --git a/controlplane/.eslintrc b/controlplane/.eslintrc index ee239b4a75..8bb98a4c4e 100644 --- a/controlplane/.eslintrc +++ b/controlplane/.eslintrc @@ -1,6 +1,6 @@ { "extends": ["eslint-config-unjs", "plugin:require-extensions/recommended"], - "plugins": ["require-extensions"], + "plugins": ["require-extensions", "local-rules"], "rules": { "space-before-function-paren": 0, "arrow-parens": 0, @@ -25,5 +25,6 @@ "no-useless-constructor": 0, "unicorn/prefer-ternary": 0, "unicorn/no-nested-ternary": 0, + "local-rules/no-arrow-in-traced": "error", }, } diff --git a/controlplane/eslint-local-rules.cjs b/controlplane/eslint-local-rules.cjs new file mode 100644 index 0000000000..5129b46b3e --- /dev/null +++ b/controlplane/eslint-local-rules.cjs @@ -0,0 +1,71 @@ +'use strict'; + +function isTraced(node) { + if (node.decorators && node.decorators.some((d) => d.expression && d.expression.name === 'traced')) { + return true; + } + + let container = node.parent; + let classNode = node; + // export default class wraps the ClassDeclaration in ExportDefaultDeclaration + if (container && container.type === 'ExportDefaultDeclaration') { + classNode = container; + container = container.parent; + } + if (!container || !container.body) { + return false; + } + const siblings = container.body; + const idx = siblings.indexOf(classNode); + for (let i = idx + 1; i < siblings.length; i++) { + const sibling = siblings[i]; + if ( + sibling.type === 'ExpressionStatement' && + sibling.expression && + sibling.expression.type === 'CallExpression' && + sibling.expression.callee && + sibling.expression.callee.name === 'traced' && + sibling.expression.arguments.length === 1 && + sibling.expression.arguments[0].name === node.id?.name + ) { + return true; + } + if (sibling.type === 'ClassDeclaration' || sibling.type === 'FunctionDeclaration') { + break; + } + } + return false; +} + +module.exports = { + 'no-arrow-in-traced': { + meta: { + type: 'problem', + docs: { + description: 'Disallow arrow function class fields in @traced classes', + }, + messages: { + noArrowInTraced: + 'Arrow function class fields are not traced by the @traced decorator. Convert to a regular method.', + }, + }, + create(context) { + return { + ClassDeclaration(node) { + if (!isTraced(node)) { + return; + } + for (const member of node.body.body) { + if ( + member.type === 'PropertyDefinition' && + member.value && + member.value.type === 'ArrowFunctionExpression' + ) { + context.report({ node: member, messageId: 'noArrowInTraced' }); + } + } + }, + }; + }, + }, +}; diff --git a/controlplane/package.json b/controlplane/package.json index bfd7c01159..07ed919f23 100644 --- a/controlplane/package.json +++ b/controlplane/package.json @@ -28,6 +28,7 @@ "lint": "eslint --cache --ext .ts,.mjs,.cjs . && prettier -c src", "lint:fix": "eslint --cache --fix --ext .ts,.mjs,.cjs . && pnpm format", "format": "prettier -w .", + "sentry:spotlight": "spotlight", "migrate": "pnpm db:migrate && pnpm ch:migrate", "drizzle:up": "drizzle-kit up", "ch:down": "dbmate -d \"./clickhouse/migrations\" down", @@ -106,6 +107,7 @@ "@bufbuild/protobuf": "^1.9.0", "@bufbuild/protoc-gen-es": "^1.9.0", "@connectrpc/protoc-gen-connect-es": "^1.4.0", + "@spotlightjs/spotlight": "^4.10.0", "@types/cookie": "^0.6.0", "@types/ejs": "^3.1.5", "@types/eslint": "^9.6.1", @@ -118,6 +120,7 @@ "del-cli": "^5.1.0", "drizzle-kit": "^0.26.2", "eslint-config-unjs": "^0.2.1", + "eslint-plugin-local-rules": "^3.0.2", "eslint-plugin-require-extensions": "^0.1.3", "msw": "^2.2.11", "pino-pretty": "^10.3.1", diff --git a/controlplane/src/core/auth-utils.ts b/controlplane/src/core/auth-utils.ts index 18dc266b14..26f87bf3b5 100644 --- a/controlplane/src/core/auth-utils.ts +++ b/controlplane/src/core/auth-utils.ts @@ -26,7 +26,7 @@ import { OrganizationGroupRepository } from './repositories/OrganizationGroupRep import { DefaultNamespace, NamespaceRepository } from './repositories/NamespaceRepository.js'; import Keycloak from './services/Keycloak.js'; import { IPlatformWebhookService } from './webhooks/PlatformWebhookService.js'; - +import { traced } from './tracing.js'; export type AuthUtilsOptions = { webBaseUrl: string; webErrorPath: string; @@ -711,3 +711,5 @@ export default class AuthUtils { return 0; } } + +traced(AuthUtils); diff --git a/controlplane/src/core/blobstorage/dual.ts b/controlplane/src/core/blobstorage/dual.ts index 14c2467fcb..f24f566425 100644 --- a/controlplane/src/core/blobstorage/dual.ts +++ b/controlplane/src/core/blobstorage/dual.ts @@ -1,3 +1,4 @@ +import { traced } from '../tracing.js'; import type { BlobObject, BlobStorage } from './index.js'; /** @@ -6,6 +7,7 @@ import type { BlobObject, BlobStorage } from './index.js'; * - Writes and deletes go to both stores concurrently; both must succeed. * - Reads try the primary first, falling back to the secondary on failure. */ +@traced export class DualBlobStorage implements BlobStorage { constructor( private primary: BlobStorage, diff --git a/controlplane/src/core/blobstorage/s3.ts b/controlplane/src/core/blobstorage/s3.ts index 279259db45..f23f7d0d78 100644 --- a/controlplane/src/core/blobstorage/s3.ts +++ b/controlplane/src/core/blobstorage/s3.ts @@ -7,6 +7,7 @@ import { PutObjectCommand, S3Client, } from '@aws-sdk/client-s3'; +import { traced } from '../tracing.js'; import { BlobNotFoundError, BlobObject, type BlobStorage } from './index.js'; const maxConcurrency = 10; // Maximum number of concurrent operations @@ -26,6 +27,7 @@ export interface S3BlobStorageConfig { /** * Stores objects in S3 given an S3Client and a bucket name */ +@traced export class S3BlobStorage implements BlobStorage { private readonly useIndividualDeletes: boolean; diff --git a/controlplane/src/core/build-server.ts b/controlplane/src/core/build-server.ts index a6f9d8f9d0..d6e4ed6467 100644 --- a/controlplane/src/core/build-server.ts +++ b/controlplane/src/core/build-server.ts @@ -1,6 +1,7 @@ import Fastify, { FastifyBaseLogger } from 'fastify'; import { S3Client } from '@aws-sdk/client-s3'; import { fastifyConnectPlugin } from '@connectrpc/connect-fastify'; +import * as Sentry from '@sentry/node'; import { cors, createContextValues } from '@connectrpc/connect'; import fastifyCors from '@fastify/cors'; import { pino, stdTimeFunctions, LoggerOptions } from 'pino'; @@ -37,7 +38,13 @@ import { BillingRepository } from './repositories/BillingRepository.js'; import { BillingService } from './services/BillingService.js'; import { UserRepository } from './repositories/UserRepository.js'; import { AIGraphReadmeQueue, createAIGraphReadmeWorker } from './workers/AIGraphReadmeWorker.js'; -import { fastifyLoggerId, createS3ClientConfig, extractS3BucketName, isGoogleCloudStorageUrl } from './util.js'; +import { + fastifyLoggerId, + sentrySpanId, + createS3ClientConfig, + extractS3BucketName, + isGoogleCloudStorageUrl, +} from './util.js'; import { ApiKeyRepository } from './repositories/ApiKeyRepository.js'; import { createDeleteOrganizationWorker, DeleteOrganizationQueue } from './workers/DeleteOrganizationWorker.js'; import { @@ -531,6 +538,16 @@ export default async function build(opts: BuildConfig) { keycloakRealm: opts.keycloak.realm, }); + // Capture the active Sentry span in preHandler (where OTEL context is still available) + // and store it on the request so Connect interceptors can use it as parentSpan. + fastify.addHook('preHandler', (req, _reply, done) => { + const span = Sentry.getActiveSpan(); + if (span) { + (req.raw as any).__sentrySpan = span; + } + done(); + }); + // Must be registered after custom fastify routes // Because it registers an all-catch route for connect handlers @@ -567,7 +584,16 @@ export default async function build(opts: BuildConfig) { cdnBaseUrl: opts.cdnBaseUrl, }), contextValues(req) { - return createContextValues().set({ id: fastifyLoggerId, defaultValue: req.log }, req.log); + const values = createContextValues().set( + { id: fastifyLoggerId, defaultValue: req.log }, + req.log, + ); + // Read the parent span captured during the preHandler hook + const parentSpan = (req.raw as any).__sentrySpan; + if (parentSpan) { + values.set({ id: sentrySpanId, defaultValue: undefined }, parentSpan); + } + return values; }, logLevel: opts.logger.level as pino.LevelWithSilent, // Avoid compression for small requests @@ -578,6 +604,18 @@ export default async function build(opts: BuildConfig) { // We go with 32MiB to avoid allocating too much memory for large requests writeMaxBytes: 32 * 1024 * 1024, acceptCompression: [compressionBrotli, compressionGzip], + interceptors: [ + (next) => (req) => { + const parentSpan = req.contextValues?.get({ + id: sentrySpanId, + defaultValue: undefined, + }); + if (parentSpan) { + return Sentry.withActiveSpan(parentSpan, () => next(req)); + } + return next(req); + }, + ], }); await fastify.register(fastifyGracefulShutdown, { diff --git a/controlplane/src/core/clickhouse/client/ClickHouseClient.ts b/controlplane/src/core/clickhouse/client/ClickHouseClient.ts index f32991dcd0..bc266e0597 100644 --- a/controlplane/src/core/clickhouse/client/ClickHouseClient.ts +++ b/controlplane/src/core/clickhouse/client/ClickHouseClient.ts @@ -7,6 +7,7 @@ import pkg from 'stream-json'; import { Observable, Subscriber } from 'rxjs'; +import { traced } from '../../tracing.js'; import { ClickHouseCompressionMethod, ClickHouseDataFormat } from './enums/index.js'; import { ClickHouseClientOptions } from './interfaces/index.js'; @@ -16,6 +17,7 @@ const { Parser } = pkg; * ClickHouse Client * Most of the code is taken from https://github.com/depyronick/clickhouse-client */ +@traced export class ClickHouseClient { /** * ClickHouse Endpoint without path and query diff --git a/controlplane/src/core/composition/composer.ts b/controlplane/src/core/composition/composer.ts index eeba61d781..50056960f2 100644 --- a/controlplane/src/core/composition/composer.ts +++ b/controlplane/src/core/composition/composer.ts @@ -33,6 +33,7 @@ import { CacheWarmerRepository } from '../repositories/CacheWarmerRepository.js' import { NamespaceRepository } from '../repositories/NamespaceRepository.js'; import { InspectorSchemaChange } from '../services/SchemaUsageTrafficInspector.js'; import { SchemaCheckChangeAction } from '../../db/models.js'; +import { traced } from '../tracing.js'; import { composeGraphsInWorker, DeserializedComposedGraph, @@ -136,6 +137,7 @@ export type CheckSubgraph = { // will be used only for new subgraphs labels?: Label[]; }; +@traced export class Composer { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/ApiKeyRepository.ts b/controlplane/src/core/repositories/ApiKeyRepository.ts index a0c4443582..2c9f9a599f 100644 --- a/controlplane/src/core/repositories/ApiKeyRepository.ts +++ b/controlplane/src/core/repositories/ApiKeyRepository.ts @@ -4,10 +4,12 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import * as schema from '../../db/schema.js'; import { apiKeyPermissions, apiKeyResources, apiKeys, users } from '../../db/schema.js'; import { APIKeyDTO } from '../../types/index.js'; +import { traced } from '../tracing.js'; /** * Repository for organization related operations. */ +@traced export class ApiKeyRepository { constructor(private db: PostgresJsDatabase) {} diff --git a/controlplane/src/core/repositories/AuditLogRepository.ts b/controlplane/src/core/repositories/AuditLogRepository.ts index 6c07ebff9d..c6103f1b30 100644 --- a/controlplane/src/core/repositories/AuditLogRepository.ts +++ b/controlplane/src/core/repositories/AuditLogRepository.ts @@ -2,6 +2,7 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import { desc, eq, gt, lt, and, sql, count } from 'drizzle-orm'; import * as schema from '../../db/schema.js'; import { AuditableType, AuditActorType, AuditLogAction, AuditLogFullAction, AuditTargetType } from '../../db/models.js'; +import { traced } from '../tracing.js'; export type AddAuditLogInput = { organizationId: string; @@ -25,6 +26,7 @@ export type AddAuditLogInput = { /** * Repository for audit log related operations. */ +@traced export class AuditLogRepository { constructor(private db: PostgresJsDatabase) {} diff --git a/controlplane/src/core/repositories/BillingRepository.ts b/controlplane/src/core/repositories/BillingRepository.ts index 05bff34e30..e9eedd107a 100644 --- a/controlplane/src/core/repositories/BillingRepository.ts +++ b/controlplane/src/core/repositories/BillingRepository.ts @@ -4,6 +4,7 @@ import type { DB } from '../../db/index.js'; import { billingPlans, billingSubscriptions, organizationBilling } from '../../db/schema.js'; import { BillingPlanDTO } from '../../types/index.js'; import { BillingService } from '../services/BillingService.js'; +import { traced } from '../tracing.js'; export const billingSchema = z.object({ plans: z.record( @@ -26,6 +27,7 @@ export const billingSchema = z.object({ /** * BillingRepository for billing related operations. */ +@traced export class BillingRepository { constructor(private db: DB) {} diff --git a/controlplane/src/core/repositories/CacheWarmerRepository.ts b/controlplane/src/core/repositories/CacheWarmerRepository.ts index 2fa75f4eba..ffdba6fdd3 100644 --- a/controlplane/src/core/repositories/CacheWarmerRepository.ts +++ b/controlplane/src/core/repositories/CacheWarmerRepository.ts @@ -17,6 +17,7 @@ import { BlobStorage } from '../blobstorage/index.js'; import { ClickHouseClient } from '../clickhouse/index.js'; import { S3RouterConfigMetadata } from '../composition/composer.js'; import { CacheWarmupOperation } from '../../db/models.js'; +import { traced } from '../tracing.js'; import { getDateRange, isoDateRangeToTimestamps } from './analytics/util.js'; import { OperationsRepository } from './OperationsRepository.js'; @@ -28,6 +29,7 @@ interface ComputeCacheWarmerOperationsProps { maxOperationsCount: number; } +@traced export class CacheWarmerRepository { constructor( private client: ClickHouseClient, diff --git a/controlplane/src/core/repositories/ContractRepository.ts b/controlplane/src/core/repositories/ContractRepository.ts index 5cc2c4eb6d..ba6bec2801 100644 --- a/controlplane/src/core/repositories/ContractRepository.ts +++ b/controlplane/src/core/repositories/ContractRepository.ts @@ -3,8 +3,10 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import { FastifyBaseLogger } from 'fastify'; import * as schema from '../../db/schema.js'; import { FederatedGraphDTO } from '../../types/index.js'; +import { traced } from '../tracing.js'; import { FederatedGraphRepository } from './FederatedGraphRepository.js'; +@traced export class ContractRepository { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/FeatureFlagRepository.ts b/controlplane/src/core/repositories/FeatureFlagRepository.ts index 5aa80a8725..921a027388 100644 --- a/controlplane/src/core/repositories/FeatureFlagRepository.ts +++ b/controlplane/src/core/repositories/FeatureFlagRepository.ts @@ -31,6 +31,7 @@ import { } from '../../types/index.js'; import { normalizeLabels } from '../util.js'; import { RBACEvaluator } from '../services/RBACEvaluator.js'; +import { traced } from '../tracing.js'; import { FederatedGraphRepository } from './FederatedGraphRepository.js'; import { SubgraphRepository } from './SubgraphRepository.js'; import { UserRepository } from './UserRepository.js'; @@ -62,6 +63,7 @@ export type CheckConstituentFeatureSubgraphsResult = { featureSubgraphIds: Array; }; +@traced export class FeatureFlagRepository { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/FederatedGraphRepository.ts b/controlplane/src/core/repositories/FederatedGraphRepository.ts index e3ca573246..d04d57ae25 100644 --- a/controlplane/src/core/repositories/FederatedGraphRepository.ts +++ b/controlplane/src/core/repositories/FederatedGraphRepository.ts @@ -74,6 +74,7 @@ import { checkIfLabelMatchersChanged, normalizeLabelMatchers, normalizeLabels } import { unsuccessfulBaseCompositionError } from '../errors/errors.js'; import { ClickHouseClient } from '../clickhouse/index.js'; import { RBACEvaluator } from '../services/RBACEvaluator.js'; +import { traced } from '../tracing.js'; import { ContractRepository } from './ContractRepository.js'; import { FeatureFlagRepository, SubgraphsToCompose } from './FeatureFlagRepository.js'; import { GraphCompositionRepository } from './GraphCompositionRepository.js'; @@ -85,6 +86,7 @@ export interface FederatedGraphConfig { trafficCheckDays: number; } +@traced export class FederatedGraphRepository { constructor( private logger: FastifyBaseLogger, @@ -1501,7 +1503,7 @@ export class FederatedGraphRepository { /** * This method recomposes and deploys federated graphs and their respective contract graphs. */ - public composeAndDeployGraphs = ({ + public composeAndDeployGraphs({ actorId, admissionConfig, compositionOptions, @@ -1520,7 +1522,7 @@ export class FederatedGraphRepository { federatedGraphs: FederatedGraphDTO[]; compositionOptions?: CompositionOptions; webhookProxyUrl?: string; - }) => { + }) { return this.db.transaction(async (tx) => { const subgraphRepo = new SubgraphRepository(this.logger, tx, this.organizationId); const fedGraphRepo = new FederatedGraphRepository(this.logger, tx, this.organizationId); @@ -1860,7 +1862,7 @@ export class FederatedGraphRepository { compositionWarnings: allCompositionWarnings, }; }); - }; + } public updateRouterCompatibilityVersion(id: string, version: string) { return this.db diff --git a/controlplane/src/core/repositories/GitHubRepository.ts b/controlplane/src/core/repositories/GitHubRepository.ts index e784107395..d1871d5fa4 100644 --- a/controlplane/src/core/repositories/GitHubRepository.ts +++ b/controlplane/src/core/repositories/GitHubRepository.ts @@ -4,7 +4,9 @@ import { eq } from 'drizzle-orm'; import { CompositionError, GitInfo } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb'; import { PlainMessage } from '@bufbuild/protobuf'; import * as schema from '../../db/schema.js'; +import { traced } from '../tracing.js'; +@traced export class GitHubRepository { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/repositories/GraphCompositionRepository.ts b/controlplane/src/core/repositories/GraphCompositionRepository.ts index 7651a79968..557dcd13b3 100644 --- a/controlplane/src/core/repositories/GraphCompositionRepository.ts +++ b/controlplane/src/core/repositories/GraphCompositionRepository.ts @@ -12,8 +12,10 @@ import { } from '../../db/schema.js'; import { DateRange, GraphCompositionDTO } from '../../types/index.js'; import { CompositionSubgraphRecord } from '../composition/composer.js'; +import { traced } from '../tracing.js'; import { FederatedGraphRepository } from './FederatedGraphRepository.js'; +@traced export class GraphCompositionRepository { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/NamespaceRepository.ts b/controlplane/src/core/repositories/NamespaceRepository.ts index b7b28b03c0..6139e0c678 100644 --- a/controlplane/src/core/repositories/NamespaceRepository.ts +++ b/controlplane/src/core/repositories/NamespaceRepository.ts @@ -3,9 +3,11 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import * as schema from '../../db/schema.js'; import { NamespaceDTO } from '../../types/index.js'; import { RBACEvaluator } from '../services/RBACEvaluator.js'; +import { traced } from '../tracing.js'; export const DefaultNamespace = 'default'; +@traced export class NamespaceRepository { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/repositories/OidcRepository.ts b/controlplane/src/core/repositories/OidcRepository.ts index 41616374ce..8f20d41b6c 100644 --- a/controlplane/src/core/repositories/OidcRepository.ts +++ b/controlplane/src/core/repositories/OidcRepository.ts @@ -2,7 +2,9 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import { eq } from 'drizzle-orm'; import * as schema from '../../db/schema.js'; import { oidcProviders } from '../../db/schema.js'; +import { traced } from '../tracing.js'; +@traced export class OidcRepository { constructor(private db: PostgresJsDatabase) {} diff --git a/controlplane/src/core/repositories/OperationsRepository.ts b/controlplane/src/core/repositories/OperationsRepository.ts index ab999bc3f8..f82ffc7241 100644 --- a/controlplane/src/core/repositories/OperationsRepository.ts +++ b/controlplane/src/core/repositories/OperationsRepository.ts @@ -17,6 +17,7 @@ import { SchemaCheckDetailsDTO, UpdatedPersistedOperation, } from '../../types/index.js'; +import { traced } from '../tracing.js'; import { SchemaCheckRepository } from './SchemaCheckRepository.js'; export const MAX_MANIFEST_OPERATIONS = 3000; @@ -42,6 +43,7 @@ type IgnoreAllOverride = { hash: string; }; +@traced export class OperationsRepository { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/repositories/OrganizationGroupRepository.ts b/controlplane/src/core/repositories/OrganizationGroupRepository.ts index 64f6719f6a..fed654fb96 100644 --- a/controlplane/src/core/repositories/OrganizationGroupRepository.ts +++ b/controlplane/src/core/repositories/OrganizationGroupRepository.ts @@ -5,7 +5,9 @@ import { OrganizationGroupDTO } from '../../types/index.js'; import { OrganizationRole } from '../../db/models.js'; import { organizationRoleEnum } from '../../db/schema.js'; import { defaultGroupDescription } from '../test-util.js'; +import { traced } from '../tracing.js'; +@traced export class OrganizationGroupRepository { constructor(private db: PostgresJsDatabase) {} diff --git a/controlplane/src/core/repositories/OrganizationInvitationRepository.ts b/controlplane/src/core/repositories/OrganizationInvitationRepository.ts index ca2d9eb2b2..7e8472ae04 100644 --- a/controlplane/src/core/repositories/OrganizationInvitationRepository.ts +++ b/controlplane/src/core/repositories/OrganizationInvitationRepository.ts @@ -5,10 +5,12 @@ import { FastifyBaseLogger } from 'fastify'; import * as schema from '../../db/schema.js'; import { organizationInvitations, organizations, users } from '../../db/schema.js'; import { OrganizationDTO, OrganizationInvitationDTO, UserDTO } from '../../types/index.js'; +import { traced } from '../tracing.js'; import { OrganizationRepository } from './OrganizationRepository.js'; import { UserRepository } from './UserRepository.js'; import { OrganizationGroupRepository } from './OrganizationGroupRepository.js'; +@traced export class OrganizationInvitationRepository { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/OrganizationRepository.ts b/controlplane/src/core/repositories/OrganizationRepository.ts index 4879a81a9d..c132f647e7 100644 --- a/controlplane/src/core/repositories/OrganizationRepository.ts +++ b/controlplane/src/core/repositories/OrganizationRepository.ts @@ -40,6 +40,7 @@ import { BlobStorage } from '../blobstorage/index.js'; import { delayForManualOrgDeletionInDays, delayForOrgAuditLogsDeletionInDays } from '../constants.js'; import { DeleteOrganizationAuditLogsQueue } from '../workers/DeleteOrganizationAuditLogsWorker.js'; import { RBACEvaluator } from '../services/RBACEvaluator.js'; +import { traced } from '../tracing.js'; import { BillingRepository } from './BillingRepository.js'; import { FederatedGraphRepository } from './FederatedGraphRepository.js'; import { TargetRepository } from './TargetRepository.js'; @@ -48,6 +49,7 @@ import { OrganizationGroupRepository } from './OrganizationGroupRepository.js'; /** * Repository for organization related operations. */ +@traced export class OrganizationRepository { protected billing: BillingRepository; diff --git a/controlplane/src/core/repositories/PlaygroundScriptsRepository.ts b/controlplane/src/core/repositories/PlaygroundScriptsRepository.ts index 5cc69caccb..e1d8cdc1ba 100644 --- a/controlplane/src/core/repositories/PlaygroundScriptsRepository.ts +++ b/controlplane/src/core/repositories/PlaygroundScriptsRepository.ts @@ -1,7 +1,9 @@ import { and, asc, eq } from 'drizzle-orm'; import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import * as schema from '../../db/schema.js'; +import { traced } from '../tracing.js'; +@traced export class PlaygroundScriptsRepository { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/repositories/PluginRepository.ts b/controlplane/src/core/repositories/PluginRepository.ts index 16ecf68285..88e4e9929e 100644 --- a/controlplane/src/core/repositories/PluginRepository.ts +++ b/controlplane/src/core/repositories/PluginRepository.ts @@ -3,7 +3,9 @@ import { FastifyBaseLogger } from 'fastify'; import { and, eq, count } from 'drizzle-orm'; import * as schema from '../../db/schema.js'; import { subgraphs, targets } from '../../db/schema.js'; +import { traced } from '../tracing.js'; +@traced export class PluginRepository { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/repositories/ProposalRepository.ts b/controlplane/src/core/repositories/ProposalRepository.ts index 6363f7beb0..4e336075ce 100644 --- a/controlplane/src/core/repositories/ProposalRepository.ts +++ b/controlplane/src/core/repositories/ProposalRepository.ts @@ -13,11 +13,13 @@ import { } from '../../types/index.js'; import { getDiffBetweenGraphs } from '../composition/schemaCheck.js'; import { isCheckSuccessful, normalizeLabels } from '../util.js'; +import { traced } from '../tracing.js'; import { SchemaCheckRepository } from './SchemaCheckRepository.js'; /** * Repository for organization related operations. */ +@traced export class ProposalRepository { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/repositories/SchemaCheckRepository.ts b/controlplane/src/core/repositories/SchemaCheckRepository.ts index 793971a601..aec0d407ec 100644 --- a/controlplane/src/core/repositories/SchemaCheckRepository.ts +++ b/controlplane/src/core/repositories/SchemaCheckRepository.ts @@ -56,6 +56,7 @@ import { import { OrganizationWebhookService } from '../webhooks/OrganizationWebhookService.js'; import { BlobStorage } from '../blobstorage/index.js'; import { defaultRetentionLimitInDays } from '../constants.js'; +import { traced } from '../tracing.js'; import { FederatedGraphConfig, FederatedGraphRepository } from './FederatedGraphRepository.js'; import { OrganizationRepository } from './OrganizationRepository.js'; import { ProposalRepository } from './ProposalRepository.js'; @@ -64,6 +65,7 @@ import { SchemaLintRepository } from './SchemaLintRepository.js'; import { SubgraphRepository } from './SubgraphRepository.js'; import { NamespaceRepository } from './NamespaceRepository.js'; +@traced export class SchemaCheckRepository { constructor(private db: PostgresJsDatabase) {} @@ -284,7 +286,7 @@ export class SchemaCheckRepository { await Promise.all(promises); } - private mapChangesFromDriverValue = (val: any) => { + private mapChangesFromDriverValue(val: any) { if (typeof val === 'string' && val.length > 0 && val !== '{}') { const pairs = val.slice(2, -2).split('","'); @@ -294,7 +296,7 @@ export class SchemaCheckRepository { }); } return []; - }; + } public async checkClientTrafficAgainstOverrides(data: { changes: { id: string; changeType: string | null; path: string | null }[]; diff --git a/controlplane/src/core/repositories/SchemaGraphPruningRepository.ts b/controlplane/src/core/repositories/SchemaGraphPruningRepository.ts index 71e0836a41..4f48df18f9 100644 --- a/controlplane/src/core/repositories/SchemaGraphPruningRepository.ts +++ b/controlplane/src/core/repositories/SchemaGraphPruningRepository.ts @@ -19,10 +19,12 @@ import { import { ClickHouseClient } from '../clickhouse/index.js'; import { GetDiffBetweenGraphsSuccess } from '../composition/schemaCheck.js'; import SchemaGraphPruner from '../services/SchemaGraphPruner.js'; +import { traced } from '../tracing.js'; import { UsageRepository } from './analytics/UsageRepository.js'; import { FederatedGraphRepository } from './FederatedGraphRepository.js'; import { SubgraphRepository } from './SubgraphRepository.js'; +@traced export class SchemaGraphPruningRepository { constructor(private db: PostgresJsDatabase) {} diff --git a/controlplane/src/core/repositories/SchemaLintRepository.ts b/controlplane/src/core/repositories/SchemaLintRepository.ts index d7a5237161..6cc0c8f57e 100644 --- a/controlplane/src/core/repositories/SchemaLintRepository.ts +++ b/controlplane/src/core/repositories/SchemaLintRepository.ts @@ -5,7 +5,9 @@ import * as schema from '../../db/schema.js'; import { namespaceLintCheckConfig, schemaCheckLintAction, schemaCheckSubgraphs } from '../../db/schema.js'; import { SchemaLintDTO, LintSeverityLevel, LintIssueResult, LintRule, SchemaLintIssues } from '../../types/index.js'; import SchemaLinter from '../services/SchemaLinter.js'; +import { traced } from '../tracing.js'; +@traced export class SchemaLintRepository { constructor(private db: PostgresJsDatabase) {} diff --git a/controlplane/src/core/repositories/SubgraphCheckExtensionsRepository.ts b/controlplane/src/core/repositories/SubgraphCheckExtensionsRepository.ts index 24b4856311..775f45206e 100644 --- a/controlplane/src/core/repositories/SubgraphCheckExtensionsRepository.ts +++ b/controlplane/src/core/repositories/SubgraphCheckExtensionsRepository.ts @@ -1,7 +1,9 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import { eq } from 'drizzle-orm'; import * as schema from '../../db/schema.js'; +import { traced } from '../tracing.js'; +@traced export class SubgraphCheckExtensionsRepository { constructor(private db: PostgresJsDatabase) {} diff --git a/controlplane/src/core/repositories/SubgraphRepository.ts b/controlplane/src/core/repositories/SubgraphRepository.ts index 1b18b66006..18c073319c 100644 --- a/controlplane/src/core/repositories/SubgraphRepository.ts +++ b/controlplane/src/core/repositories/SubgraphRepository.ts @@ -66,6 +66,7 @@ import { sanitizeReadme, } from '../util.js'; import { OrganizationWebhookService } from '../webhooks/OrganizationWebhookService.js'; +import { traced } from '../tracing.js'; import { ContractRepository } from './ContractRepository.js'; import { FeatureFlagRepository } from './FeatureFlagRepository.js'; import { FederatedGraphRepository } from './FederatedGraphRepository.js'; @@ -82,6 +83,7 @@ type SubscriptionProtocol = 'ws' | 'sse' | 'sse_post'; /** * Repository for managing subgraphs. */ +@traced export class SubgraphRepository { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/TargetRepository.ts b/controlplane/src/core/repositories/TargetRepository.ts index c799158618..ad7e3d0c58 100644 --- a/controlplane/src/core/repositories/TargetRepository.ts +++ b/controlplane/src/core/repositories/TargetRepository.ts @@ -3,8 +3,10 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import * as schema from '../../db/schema.js'; import { targets } from '../../db/schema.js'; import { sanitizeReadme } from '../util.js'; +import { traced } from '../tracing.js'; import { NamespaceRepository } from './NamespaceRepository.js'; +@traced export class TargetRepository { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/repositories/UserRepository.ts b/controlplane/src/core/repositories/UserRepository.ts index 1b4305e59c..018fe7d85d 100644 --- a/controlplane/src/core/repositories/UserRepository.ts +++ b/controlplane/src/core/repositories/UserRepository.ts @@ -8,6 +8,7 @@ import { BlobStorage } from '../blobstorage/index.js'; import Keycloak from '../services/Keycloak.js'; import OidcProvider from '../services/OidcProvider.js'; import { DeleteOrganizationAuditLogsQueue } from '../workers/DeleteOrganizationAuditLogsWorker.js'; +import { traced } from '../tracing.js'; import { BillingRepository } from './BillingRepository.js'; import { OidcRepository } from './OidcRepository.js'; import { OrganizationRepository } from './OrganizationRepository.js'; @@ -15,6 +16,7 @@ import { OrganizationRepository } from './OrganizationRepository.js'; /** * Repository for user related operations. */ +@traced export class UserRepository { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/analytics/AnalyticsDashboardViewRepository.ts b/controlplane/src/core/repositories/analytics/AnalyticsDashboardViewRepository.ts index 33a8b0ed77..9c3771082d 100644 --- a/controlplane/src/core/repositories/analytics/AnalyticsDashboardViewRepository.ts +++ b/controlplane/src/core/repositories/analytics/AnalyticsDashboardViewRepository.ts @@ -14,7 +14,9 @@ import { SubgraphRequestRateResult, TimeFilters, } from '../../../types/index.js'; +import { traced } from '../../tracing.js'; +@traced export class AnalyticsDashboardViewRepository { constructor(private client: ClickHouseClient) {} diff --git a/controlplane/src/core/repositories/analytics/AnalyticsRequestViewRepository.ts b/controlplane/src/core/repositories/analytics/AnalyticsRequestViewRepository.ts index ef2a4a7d56..a9fa6d6fee 100644 --- a/controlplane/src/core/repositories/analytics/AnalyticsRequestViewRepository.ts +++ b/controlplane/src/core/repositories/analytics/AnalyticsRequestViewRepository.ts @@ -12,6 +12,7 @@ import { Unit, } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb'; import { ClickHouseClient } from '../../clickhouse/index.js'; +import { traced } from '../../tracing.js'; import { BaseFilters, ColumnMetaData, @@ -28,6 +29,7 @@ import { /** * Repository for clickhouse analytics data */ +@traced export class AnalyticsRequestViewRepository { constructor(private client: ClickHouseClient) {} @@ -555,7 +557,7 @@ export class AnalyticsRequestViewRepository { return httpStatusCodes; } - private getBaseFiltersForGroup = (name: AnalyticsViewGroupName) => { + private getBaseFiltersForGroup(name: AnalyticsViewGroupName) { const filters = { ...this.baseFilters }; let baseFiltersForGroup: BaseFilters = {}; @@ -606,7 +608,7 @@ export class AnalyticsRequestViewRepository { } return baseFiltersForGroup; - }; + } private getFilters( name: AnalyticsViewGroupName, @@ -677,13 +679,13 @@ export class AnalyticsRequestViewRepository { return filters.filter((f) => allowedColumnNames.has(f.field)); } - private getSortOrder = (id?: string, desc?: boolean) => { + private getSortOrder(id?: string, desc?: boolean) { const allowedColumns = Object.keys(this.columnMetadata); if (id && allowedColumns.includes(id)) { return `ORDER BY ${id} ${desc ? 'DESC' : 'ASC'}`; } - }; + } public async getView( organizationId: string, diff --git a/controlplane/src/core/repositories/analytics/MetricsRepository.ts b/controlplane/src/core/repositories/analytics/MetricsRepository.ts index 156fe66071..a7b8b2fe90 100644 --- a/controlplane/src/core/repositories/analytics/MetricsRepository.ts +++ b/controlplane/src/core/repositories/analytics/MetricsRepository.ts @@ -6,6 +6,7 @@ import { import { DateRange } from '../../../types/index.js'; import { ClickHouseClient } from '../../clickhouse/index.js'; import { flipDateRangeValuesIfNeeded } from '../../util.js'; +import { traced } from '../../tracing.js'; import { BaseFilters, buildAnalyticsViewFilters, @@ -53,6 +54,7 @@ interface LatencySeries { p99?: number; } +@traced export class MetricsRepository { constructor(private client: ClickHouseClient) {} diff --git a/controlplane/src/core/repositories/analytics/MonthlyRequestViewRepository.ts b/controlplane/src/core/repositories/analytics/MonthlyRequestViewRepository.ts index 26ab5e0aaf..f547379746 100644 --- a/controlplane/src/core/repositories/analytics/MonthlyRequestViewRepository.ts +++ b/controlplane/src/core/repositories/analytics/MonthlyRequestViewRepository.ts @@ -1,5 +1,7 @@ import { ClickHouseClient } from '../../../core/clickhouse/index.js'; +import { traced } from '../../tracing.js'; +@traced export class MonthlyRequestViewRepository { constructor(private client: ClickHouseClient) {} diff --git a/controlplane/src/core/repositories/analytics/RouterMetricsRepository.ts b/controlplane/src/core/repositories/analytics/RouterMetricsRepository.ts index b6f0a1e4fd..0862b0443a 100644 --- a/controlplane/src/core/repositories/analytics/RouterMetricsRepository.ts +++ b/controlplane/src/core/repositories/analytics/RouterMetricsRepository.ts @@ -1,4 +1,5 @@ import { ClickHouseClient } from '../../clickhouse/index.js'; +import { traced } from '../../tracing.js'; export interface RouterDTO { hostname: string; @@ -23,6 +24,7 @@ export interface RouterRuntimeDTO { }; } +@traced export class RouterMetricsRepository { constructor(private client: ClickHouseClient) {} diff --git a/controlplane/src/core/repositories/analytics/SubgraphMetricsRepository.ts b/controlplane/src/core/repositories/analytics/SubgraphMetricsRepository.ts index f16c99bae4..4b6784e560 100644 --- a/controlplane/src/core/repositories/analytics/SubgraphMetricsRepository.ts +++ b/controlplane/src/core/repositories/analytics/SubgraphMetricsRepository.ts @@ -10,6 +10,7 @@ import { DateRange, Label } from '../../../types/index.js'; import { FederatedGraphRepository } from '../FederatedGraphRepository.js'; import * as schema from '../../../db/schema.js'; import { flipDateRangeValuesIfNeeded } from '../../util.js'; +import { traced } from '../../tracing.js'; import { BaseFilters, buildAnalyticsViewFilters, @@ -61,6 +62,7 @@ interface LatencySeries { p99?: number; } +@traced export class SubgraphMetricsRepository { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/repositories/analytics/TraceRepository.ts b/controlplane/src/core/repositories/analytics/TraceRepository.ts index b506352dcf..0b585a8477 100644 --- a/controlplane/src/core/repositories/analytics/TraceRepository.ts +++ b/controlplane/src/core/repositories/analytics/TraceRepository.ts @@ -1,8 +1,10 @@ import { PlainMessage } from '@bufbuild/protobuf'; import { Span } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb'; import { ClickHouseClient } from '../../clickhouse/index.js'; +import { traced } from '../../tracing.js'; import { timestampToNanoseconds } from './util.js'; +@traced export class TraceRepository { constructor(private client: ClickHouseClient) {} diff --git a/controlplane/src/core/repositories/analytics/UsageRepository.ts b/controlplane/src/core/repositories/analytics/UsageRepository.ts index f9747713f4..eade89c67a 100644 --- a/controlplane/src/core/repositories/analytics/UsageRepository.ts +++ b/controlplane/src/core/repositories/analytics/UsageRepository.ts @@ -7,8 +7,10 @@ import { import { ClickHouseClient } from '../../clickhouse/index.js'; import { DateRange, Field, TimeFilters } from '../../../types/index.js'; import { flipDateRangeValuesIfNeeded } from '../../util.js'; +import { traced } from '../../tracing.js'; import { parseTimeFilters } from './util.js'; +@traced export class UsageRepository { constructor(private client: ClickHouseClient) {} diff --git a/controlplane/src/core/sentry.config.ts b/controlplane/src/core/sentry.config.ts index 923a609f2a..8a95cb79a9 100644 --- a/controlplane/src/core/sentry.config.ts +++ b/controlplane/src/core/sentry.config.ts @@ -29,6 +29,7 @@ if (SENTRY_ENABLED && SENTRY_DSN) { tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE, profileLifecycle: SENTRY_PROFILE_LIFECYCLE, enableLogs: SENTRY_ENABLE_LOGS, + spotlight: process.env.NODE_ENV !== 'production', }); console.log('Sentry is initialized.'); } diff --git a/controlplane/src/core/services/AccessTokenAuthenticator.ts b/controlplane/src/core/services/AccessTokenAuthenticator.ts index 3f98013b7b..4f3dba7886 100644 --- a/controlplane/src/core/services/AccessTokenAuthenticator.ts +++ b/controlplane/src/core/services/AccessTokenAuthenticator.ts @@ -2,6 +2,7 @@ import { EnumStatusCode } from '@wundergraph/cosmo-connect/dist/common/common_pb import AuthUtils from '../auth-utils.js'; import { AuthenticationError } from '../errors/errors.js'; import { OrganizationRepository } from '../repositories/OrganizationRepository.js'; +import { traced } from '../tracing.js'; import { RBACEvaluator } from './RBACEvaluator.js'; export type AccessTokenAuthContext = { @@ -14,6 +15,7 @@ export type AccessTokenAuthContext = { rbac: RBACEvaluator; }; +@traced export default class AccessTokenAuthenticator { constructor( private orgRepo: OrganizationRepository, diff --git a/controlplane/src/core/services/AdmissionWebhookController.ts b/controlplane/src/core/services/AdmissionWebhookController.ts index 43f8ca7c5a..c000be480b 100644 --- a/controlplane/src/core/services/AdmissionWebhookController.ts +++ b/controlplane/src/core/services/AdmissionWebhookController.ts @@ -10,6 +10,7 @@ import { HttpsProxyAgent } from 'https-proxy-agent'; import * as schema from '../../db/schema.js'; import { WebhookDeliveryInfo } from '../../db/models.js'; import { webhookAxiosRetryCond } from '../util.js'; +import { traced } from '../tracing.js'; export class AdmissionError extends Error { constructor(message: string, cause?: Error) { @@ -34,6 +35,7 @@ export interface ValidateConfigResponse { error?: string; } +@traced export class AdmissionWebhookController { httpClient: AxiosInstance; constructor( diff --git a/controlplane/src/core/services/ApiGenerator.ts b/controlplane/src/core/services/ApiGenerator.ts index cc1b7e01a6..a13de4d65a 100644 --- a/controlplane/src/core/services/ApiGenerator.ts +++ b/controlplane/src/core/services/ApiGenerator.ts @@ -1,5 +1,7 @@ import { uid } from 'uid/secure'; +import { traced } from '../tracing.js'; +@traced export class ApiKeyGenerator { public static generate(): string { return `cosmo_${uid(32)}`; diff --git a/controlplane/src/core/services/ApiKeyAuthenticator.ts b/controlplane/src/core/services/ApiKeyAuthenticator.ts index 70c4401b4d..7355f0f1d0 100644 --- a/controlplane/src/core/services/ApiKeyAuthenticator.ts +++ b/controlplane/src/core/services/ApiKeyAuthenticator.ts @@ -4,6 +4,7 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import * as schema from '../../db/schema.js'; import { AuthenticationError } from '../errors/errors.js'; import { OrganizationRepository } from '../repositories/OrganizationRepository.js'; +import { traced } from '../tracing.js'; import { RBACEvaluator } from './RBACEvaluator.js'; export type ApiKeyAuthContext = { @@ -17,6 +18,7 @@ export type ApiKeyAuthContext = { rbac: RBACEvaluator; }; +@traced export default class ApiKeyAuthenticator { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/services/ApolloMigrator.ts b/controlplane/src/core/services/ApolloMigrator.ts index aa3ee04682..ce80064b52 100644 --- a/controlplane/src/core/services/ApolloMigrator.ts +++ b/controlplane/src/core/services/ApolloMigrator.ts @@ -5,7 +5,9 @@ import { FederatedGraphDTO, MigrationSubgraph } from '../../types/index.js'; import { FederatedGraphRepository } from '../repositories/FederatedGraphRepository.js'; import { SubgraphRepository } from '../repositories/SubgraphRepository.js'; import { sanitizeMigratedGraphName } from '../util.js'; +import { traced } from '../tracing.js'; +@traced export default class ApolloMigrator { apiKey = ''; organizationSlug = ''; diff --git a/controlplane/src/core/services/Authentication.ts b/controlplane/src/core/services/Authentication.ts index 02b5f59c71..b96a49e08b 100644 --- a/controlplane/src/core/services/Authentication.ts +++ b/controlplane/src/core/services/Authentication.ts @@ -4,6 +4,7 @@ import { FastifyBaseLogger } from 'fastify'; import { AuthContext, UserInfoEndpointResponse } from '../../types/index.js'; import { AuthenticationError } from '../errors/errors.js'; import { OrganizationRepository } from '../repositories/OrganizationRepository.js'; +import { traced } from '../tracing.js'; import AccessTokenAuthenticator from './AccessTokenAuthenticator.js'; import ApiKeyAuthenticator from './ApiKeyAuthenticator.js'; import GraphApiTokenAuthenticator, { GraphKeyAuthContext } from './GraphApiTokenAuthenticator.js'; @@ -19,6 +20,7 @@ export interface Authenticator { getUserInfo(token: string): Promise; } +@traced export class Authentication implements Authenticator { #cache = lru(1000, maxAuthCacheTtl); diff --git a/controlplane/src/core/services/Authorization.ts b/controlplane/src/core/services/Authorization.ts index 6d5e048096..33763b2919 100644 --- a/controlplane/src/core/services/Authorization.ts +++ b/controlplane/src/core/services/Authorization.ts @@ -8,7 +8,9 @@ import { FederatedGraphRepository } from '../repositories/FederatedGraphReposito import { OrganizationRepository } from '../repositories/OrganizationRepository.js'; import { SubgraphRepository } from '../repositories/SubgraphRepository.js'; import { AuthContext } from '../../types/index.js'; +import { traced } from '../tracing.js'; +@traced export class Authorization { constructor( private logger: FastifyBaseLogger, diff --git a/controlplane/src/core/services/BillingService.ts b/controlplane/src/core/services/BillingService.ts index 17d32111b1..a1d9b4eb7c 100644 --- a/controlplane/src/core/services/BillingService.ts +++ b/controlplane/src/core/services/BillingService.ts @@ -6,10 +6,12 @@ import { toISODateTime } from '../webhooks/utils.js'; import { NewBillingSubscription } from '../../db/models.js'; import { BillingRepository } from '../repositories/BillingRepository.js'; import { AuditLogRepository } from '../repositories/AuditLogRepository.js'; +import { traced } from '../tracing.js'; /** * BillingService for billing related operations. */ +@traced export class BillingService { public stripe: Stripe; @@ -25,7 +27,7 @@ export class BillingService { }); } - private upsertStripeCustomerId = async ({ id, organizationSlug }: { id: string; organizationSlug: string }) => { + private async upsertStripeCustomerId({ id, organizationSlug }: { id: string; organizationSlug: string }) { const billing = await this.db.query.organizationBilling.findFirst({ where: eq(organizationBilling.organizationId, id), columns: { @@ -61,7 +63,7 @@ export class BillingService { }); return customer.id; - }; + } public async completeCheckoutSession(subscriptionId: string, organizationId: string) { const billing = await this.db.query.billingSubscriptions.findFirst({ @@ -396,7 +398,7 @@ export class BillingService { } } - cancelSubscription = async (organizationId: string, subscriptionId: string, comment: string) => { + async cancelSubscription(organizationId: string, subscriptionId: string, comment: string) { await this.stripe.subscriptions.cancel(subscriptionId, { cancellation_details: { comment, @@ -404,5 +406,5 @@ export class BillingService { }); await this.db.delete(organizationBilling).where(eq(organizationBilling.organizationId, organizationId)); - }; + } } diff --git a/controlplane/src/core/services/GraphApiTokenAuthenticator.ts b/controlplane/src/core/services/GraphApiTokenAuthenticator.ts index 5af82cb019..4e7ab8efdf 100644 --- a/controlplane/src/core/services/GraphApiTokenAuthenticator.ts +++ b/controlplane/src/core/services/GraphApiTokenAuthenticator.ts @@ -1,5 +1,6 @@ import { JWTPayload } from 'jose'; import { verifyJwt } from '../crypto/jwt.js'; +import { traced } from '../tracing.js'; export type GraphKeyAuthContext = { organizationId: string; @@ -11,6 +12,7 @@ export interface GraphApiJwtPayload extends JWTPayload { federated_graph_id: string; } +@traced export default class GraphApiTokenAuthenticator { constructor(private jwtSecret: string) {} diff --git a/controlplane/src/core/services/Keycloak.ts b/controlplane/src/core/services/Keycloak.ts index 8615e9ad76..1eb85b4cf2 100644 --- a/controlplane/src/core/services/Keycloak.ts +++ b/controlplane/src/core/services/Keycloak.ts @@ -7,7 +7,9 @@ import { decodeJwt } from 'jose'; import { MemberRole } from '../../db/models.js'; import { organizationRoleEnum } from '../../db/schema.js'; import { AuthenticationError } from '../errors/errors.js'; +import { traced } from '../tracing.js'; +@traced export default class Keycloak { client: KeycloakAdminClient; adminUser = ''; diff --git a/controlplane/src/core/services/Mailer.ts b/controlplane/src/core/services/Mailer.ts index 1cdeb3cb68..70b0d12e7f 100644 --- a/controlplane/src/core/services/Mailer.ts +++ b/controlplane/src/core/services/Mailer.ts @@ -3,6 +3,7 @@ import { join } from 'node:path'; import { createTransport, Transporter } from 'nodemailer'; import * as ejs from 'ejs'; import { MailerParams } from '../../types/index.js'; +import { traced } from '../tracing.js'; interface OrganizationInviteBody { organizationName: string; @@ -10,6 +11,7 @@ interface OrganizationInviteBody { inviteLink: string; } +@traced export default class Mailer { client: Transporter; diff --git a/controlplane/src/core/services/OidcProvider.ts b/controlplane/src/core/services/OidcProvider.ts index 30eaaf7c96..6dca4cc00a 100644 --- a/controlplane/src/core/services/OidcProvider.ts +++ b/controlplane/src/core/services/OidcProvider.ts @@ -4,8 +4,10 @@ import { validate as isValidUuid } from 'uuid'; import { and, eq, inArray } from 'drizzle-orm'; import * as schema from '../../db/schema.js'; import { OidcRepository } from '../repositories/OidcRepository.js'; +import { traced } from '../tracing.js'; import Keycloak from './Keycloak.js'; +@traced export default class OidcProvider { constructor() {} diff --git a/controlplane/src/core/services/RBACEvaluator.ts b/controlplane/src/core/services/RBACEvaluator.ts index 68ffa75489..cfafb93deb 100644 --- a/controlplane/src/core/services/RBACEvaluator.ts +++ b/controlplane/src/core/services/RBACEvaluator.ts @@ -1,5 +1,6 @@ import { OrganizationRole } from '../../db/models.js'; import { OrganizationGroupDTO } from '../../types/index.js'; +import { traced } from '../tracing.js'; interface RuleData { namespaces: string[]; @@ -21,6 +22,7 @@ interface Target { creatorUserId?: string; } +@traced export class RBACEvaluator { readonly isApiKey: boolean; /** diff --git a/controlplane/src/core/services/SchemaGraphPruner.ts b/controlplane/src/core/services/SchemaGraphPruner.ts index 1f1596a566..c3da04e2d0 100644 --- a/controlplane/src/core/services/SchemaGraphPruner.ts +++ b/controlplane/src/core/services/SchemaGraphPruner.ts @@ -17,7 +17,9 @@ import { UsageRepository } from '../repositories/analytics/UsageRepository.js'; import { FederatedGraphRepository } from '../repositories/FederatedGraphRepository.js'; import { buildSchema } from '../composition/composition.js'; import { getFederatedGraphRouterCompatibilityVersion } from '../util.js'; +import { traced } from '../tracing.js'; +@traced export default class SchemaGraphPruner { constructor( private federatedGraphRepo: FederatedGraphRepository, @@ -26,7 +28,7 @@ export default class SchemaGraphPruner { private schema: GraphQLSchema, ) {} - getAllFields = ({ schema, onlyDeprecated }: { schema?: GraphQLSchema; onlyDeprecated?: boolean }): Field[] => { + getAllFields({ schema, onlyDeprecated }: { schema?: GraphQLSchema; onlyDeprecated?: boolean }): Field[] { const fields: Field[] = []; const schemaToBeUsed = schema || this.schema; @@ -70,9 +72,9 @@ export default class SchemaGraphPruner { } return fields; - }; + } - fetchUnusedFields = async ({ + async fetchUnusedFields({ subgraphId, namespaceId, organizationId, @@ -89,7 +91,7 @@ export default class SchemaGraphPruner { // fields that were added in the proposed schema passed to the check command addedFields: SchemaDiff[]; severityLevel: LintSeverityLevel; - }): Promise => { + }): Promise { const limit = pLimit(5); const allFields = this.getAllFields({}); // fetching all the fields of this subgraph that are in grace period @@ -147,9 +149,9 @@ export default class SchemaGraphPruner { } return graphPruningIssues; - }; + } - fetchDeprecatedFields = async ({ + async fetchDeprecatedFields({ subgraphId, namespaceId, organizationId, @@ -165,7 +167,7 @@ export default class SchemaGraphPruner { rangeInDays: number; severityLevel: LintSeverityLevel; addedDeprecatedFields: SchemaDiff[]; - }): Promise => { + }): Promise { const limit = pLimit(5); const allDeprecatedFields = this.getAllFields({ onlyDeprecated: true }); // fetching all the deprecated fields of this subgraph that are in grace period @@ -237,9 +239,9 @@ export default class SchemaGraphPruner { } return graphPruningIssues; - }; + } - fetchNonDeprecatedDeletedFields = ({ + fetchNonDeprecatedDeletedFields({ federatedGraphs, severityLevel, removedFields, @@ -249,7 +251,7 @@ export default class SchemaGraphPruner { severityLevel: LintSeverityLevel; removedFields: SchemaDiff[]; oldSchema: string; - }): GraphPruningIssueResult[] => { + }): GraphPruningIssueResult[] { let oldGraphQLSchema: GraphQLSchema | undefined; try { @@ -306,9 +308,9 @@ export default class SchemaGraphPruner { } return graphPruningIssues; - }; + } - schemaGraphPruneCheck = async ({ + async schemaGraphPruneCheck({ subgraph, graphPruningConfigs, organizationId, @@ -323,7 +325,7 @@ export default class SchemaGraphPruner { // fields that were added/updated in the proposed schema passed to the check command updatedFields: SchemaDiff[]; removedFields: SchemaDiff[]; - }): Promise => { + }): Promise { const graphPruneWarnings: GraphPruningIssueResult[] = []; const graphPruneErrors: GraphPruningIssueResult[] = []; @@ -401,5 +403,5 @@ export default class SchemaGraphPruner { warnings: graphPruneWarnings, errors: graphPruneErrors, }; - }; + } } diff --git a/controlplane/src/core/services/SchemaLinter.ts b/controlplane/src/core/services/SchemaLinter.ts index 32423c9090..bc1030dfab 100644 --- a/controlplane/src/core/services/SchemaLinter.ts +++ b/controlplane/src/core/services/SchemaLinter.ts @@ -10,14 +10,16 @@ import { SchemaLintDTO, SchemaLintIssues, } from '../../types/index.js'; +import { traced } from '../tracing.js'; +@traced export default class SchemaLinter { linter: Linter; constructor() { this.linter = new Linter(); } - getRuleModule = (rule: LintRule) => { + getRuleModule(rule: LintRule) { switch (rule) { case 'FIELD_NAMES_SHOULD_BE_CAMEL_CASE': case 'TYPE_NAMES_SHOULD_BE_PASCAL_CASE': @@ -53,9 +55,9 @@ export default class SchemaLinter { throw new Error(`Rule ${rule} doesnt exist`); } } - }; + } - createRulesConfig = (rules: SchemaLintDTO[]) => { + createRulesConfig(rules: SchemaLintDTO[]) { const rulesConfig: RulesConfig = {}; for (const rule of rules) { const ruleName = rule.ruleName; @@ -227,9 +229,9 @@ export default class SchemaLinter { } } return rulesConfig; - }; + } - schemaLintCheck = ({ schema, rulesInput }: { schema: string; rulesInput: SchemaLintDTO[] }): SchemaLintIssues => { + schemaLintCheck({ schema, rulesInput }: { schema: string; rulesInput: SchemaLintDTO[] }): SchemaLintIssues { const rulesConfig: RulesConfig = this.createRulesConfig(rulesInput); this.linter.defineParser('@graphql-eslint/eslint-plugin', { @@ -289,7 +291,7 @@ export default class SchemaLinter { warnings: lintWarnings, errors: lintErrors, }; - }; + } static createIgnorePatternFromReservedDefinitionList(list: Set): string { return `^(${[...list].join('|')})$`; diff --git a/controlplane/src/core/services/SchemaUsageTrafficInspector.ts b/controlplane/src/core/services/SchemaUsageTrafficInspector.ts index f5973127a7..5dead11852 100644 --- a/controlplane/src/core/services/SchemaUsageTrafficInspector.ts +++ b/controlplane/src/core/services/SchemaUsageTrafficInspector.ts @@ -10,6 +10,7 @@ import pLimit from 'p-limit'; import { SchemaCheckChangeAction } from '../../db/models.js'; import { ClickHouseClient } from '../clickhouse/index.js'; import { SchemaDiff } from '../composition/schemaCheck.js'; +import { traced } from '../tracing.js'; export enum FieldTypeChangeCategory { /** @@ -167,6 +168,7 @@ export interface InspectorOperationResult { isSafeOverride: boolean; } +@traced export class SchemaUsageTrafficInspector { constructor(private client: ClickHouseClient) {} diff --git a/controlplane/src/core/services/Slack.ts b/controlplane/src/core/services/Slack.ts index 59fe1dea7e..d42fc91f19 100644 --- a/controlplane/src/core/services/Slack.ts +++ b/controlplane/src/core/services/Slack.ts @@ -1,7 +1,9 @@ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import * as schema from '../../db/schema.js'; import { SlackAccessTokenResponse } from '../../types/index.js'; +import { traced } from '../tracing.js'; +@traced export default class Slack { clientID = ''; clientSecret = ''; diff --git a/controlplane/src/core/services/UserInviteService.ts b/controlplane/src/core/services/UserInviteService.ts index f961aca498..61dea6ddc1 100644 --- a/controlplane/src/core/services/UserInviteService.ts +++ b/controlplane/src/core/services/UserInviteService.ts @@ -9,9 +9,11 @@ import { OrganizationGroupRepository } from '../repositories/OrganizationGroupRe import { OrganizationInvitationRepository } from '../repositories/OrganizationInvitationRepository.js'; import { UserRepository } from '../repositories/UserRepository.js'; import { OrganizationInvitationDTO, UserDTO } from '../../types/index.js'; +import { traced } from '../tracing.js'; import Keycloak from './Keycloak.js'; import Mailer from './Mailer.js'; +@traced export class UserInviteService { private readonly db: PostgresJsDatabase; private readonly logger: FastifyBaseLogger; diff --git a/controlplane/src/core/services/WebSessionAuthenticator.ts b/controlplane/src/core/services/WebSessionAuthenticator.ts index 6f45decfa3..c44ddad5cb 100644 --- a/controlplane/src/core/services/WebSessionAuthenticator.ts +++ b/controlplane/src/core/services/WebSessionAuthenticator.ts @@ -8,6 +8,7 @@ import { UserRepository } from '../repositories/UserRepository.js'; import * as schema from '../../db/schema.js'; import AuthUtils from '../auth-utils.js'; import { AuthenticationError } from '../errors/errors.js'; +import { traced } from '../tracing.js'; export const OrganizationSlugHeader = 'cosmo-org-slug'; @@ -18,6 +19,7 @@ export type WebAuthAuthContext = { userDisplayName: string; }; +@traced export default class WebSessionAuthenticator { constructor( private db: PostgresJsDatabase, diff --git a/controlplane/src/core/services/WorkspaceService.ts b/controlplane/src/core/services/WorkspaceService.ts index bac592a63d..7d848c8c1a 100644 --- a/controlplane/src/core/services/WorkspaceService.ts +++ b/controlplane/src/core/services/WorkspaceService.ts @@ -10,8 +10,10 @@ import * as schema from '../../db/schema.js'; import { NamespaceRepository } from '../repositories/NamespaceRepository.js'; import { FederatedGraphRepository } from '../repositories/FederatedGraphRepository.js'; import { SubgraphRepository } from '../repositories/SubgraphRepository.js'; +import { traced } from '../tracing.js'; import { RBACEvaluator } from './RBACEvaluator.js'; +@traced export class WorkspaceService { constructor( private organizationId: string, diff --git a/controlplane/src/core/tracing.ts b/controlplane/src/core/tracing.ts new file mode 100644 index 0000000000..b0979d28c4 --- /dev/null +++ b/controlplane/src/core/tracing.ts @@ -0,0 +1,44 @@ +import * as Sentry from '@sentry/node'; + +// eslint-disable-next-line @typescript-eslint/ban-types +function wrapMethod(className: string, key: string, original: Function) { + return function (this: any, ...args: any[]) { + return Sentry.startSpan({ name: `${className}.${key}` }, () => original.apply(this, args)); + }; +} + +/** + * Class decorator that wraps all prototype methods with Sentry spans. + * Every method call creates a child span named "ClassName.methodName" + * under the active transaction. + * + * When Sentry is disabled, startSpan is a no-op passthrough. + */ +export function traced any>(target: T): T { + const className = target.name; + const proto = target.prototype; + + for (const key of Object.getOwnPropertyNames(proto)) { + if (key === 'constructor') { + continue; + } + const descriptor = Object.getOwnPropertyDescriptor(proto, key); + if (!descriptor || typeof descriptor.value !== 'function') { + continue; + } + Object.defineProperty(proto, key, { + ...descriptor, + value: wrapMethod(className, key, descriptor.value), + }); + } + + return target; +} + +/** + * Wraps a function call with a Sentry span. + * Use for ad-hoc tracing of service calls, auth, etc. + */ +export function withSpan(name: string, fn: () => Promise | T): Promise { + return Sentry.startSpan({ name }, () => fn()) as Promise; +} diff --git a/controlplane/src/core/util.ts b/controlplane/src/core/util.ts index 6941ad532d..0b6e405b5f 100644 --- a/controlplane/src/core/util.ts +++ b/controlplane/src/core/util.ts @@ -2,6 +2,7 @@ import { randomFill } from 'node:crypto'; import { isIPv4, isIPv6 } from 'node:net'; import { S3ClientConfig } from '@aws-sdk/client-s3'; import { HandlerContext } from '@connectrpc/connect'; +import * as Sentry from '@sentry/node'; import { GraphQLSubscriptionProtocol, GraphQLWebsocketSubprotocol, @@ -74,6 +75,7 @@ export async function handleError( } export const fastifyLoggerId = Symbol('logger'); +export const sentrySpanId = Symbol('sentrySpan'); export const getLogger = (ctx: HandlerContext, defaultLogger: FastifyBaseLogger) => { return ctx.values.get({ id: fastifyLoggerId, defaultValue: defaultLogger }); @@ -95,6 +97,25 @@ export const enrichLogger = ( ctx.values.set({ id: fastifyLoggerId, defaultValue: newLogger }, newLogger); + Sentry.setUser({ + id: authContext.userId, + username: authContext.userDisplayName, + }); + + const spanAttributes = Object.fromEntries( + Object.entries({ + 'user.id': authContext.userId, + 'user.displayName': authContext.userDisplayName, + 'organization.id': authContext.organizationId, + 'organization.slug': authContext.organizationSlug, + }).filter(([, v]) => v), + ); + + const activeSpan = Sentry.getActiveSpan(); + if (activeSpan) { + Sentry.getRootSpan(activeSpan).setAttributes(spanAttributes); + } + return newLogger; }; diff --git a/controlplane/src/core/webhooks/OrganizationWebhookService.ts b/controlplane/src/core/webhooks/OrganizationWebhookService.ts index 0ae67d6640..2348a8662c 100644 --- a/controlplane/src/core/webhooks/OrganizationWebhookService.ts +++ b/controlplane/src/core/webhooks/OrganizationWebhookService.ts @@ -29,6 +29,7 @@ import { SubgraphCheckExtensionsRepository } from '../repositories/SubgraphCheck import { BlobStorage } from '../blobstorage/index.js'; import { audiences, nowInSeconds, signJwtHS256 } from '../crypto/jwt.js'; import { InspectorOperationResult } from '../services/SchemaUsageTrafficInspector.js'; +import { traced } from '../tracing.js'; import { makeWebhookRequest } from './utils.js'; const subgraphCheckExtensionSchema = z.object({ @@ -121,6 +122,7 @@ type Config = { type: 'webhook' | 'slack'; }; +@traced export class OrganizationWebhookService { private readonly logger: pino.Logger; private readonly defaultBillingPlanId?: string; @@ -590,8 +592,7 @@ export class OrganizationWebhookService { await this.sendEvent(eventData, configs, actorId); } catch (e: any) { const logger = this.logger.child({ eventName: OrganizationEventName[eventData.eventName] }); - logger.child({ message: e.message }); - logger.error(`Could not send webhook event`); + logger.error(e, 'Could not send webhook event'); } } diff --git a/controlplane/src/core/webhooks/PlatformWebhookService.ts b/controlplane/src/core/webhooks/PlatformWebhookService.ts index 7022cfb647..3d4d54e467 100644 --- a/controlplane/src/core/webhooks/PlatformWebhookService.ts +++ b/controlplane/src/core/webhooks/PlatformWebhookService.ts @@ -5,6 +5,7 @@ import axios, { AxiosError, AxiosInstance } from 'axios'; import axiosRetry, { exponentialDelay } from 'axios-retry'; import { HttpsProxyAgent } from 'https-proxy-agent'; import { webhookAxiosRetryCond } from '../util.js'; +import { traced } from '../tracing.js'; import { makeWebhookRequest } from './utils.js'; interface User { @@ -43,6 +44,7 @@ export interface IPlatformWebhookService { send(eventName: T, eventData: EventMap[T]): Promise; } +@traced export class PlatformWebhookService implements IPlatformWebhookService { private url: string; private key: string; @@ -107,6 +109,7 @@ export class PlatformWebhookService implements IPlatformWebhookService { } } +@traced export class MockPlatformWebhookService implements IPlatformWebhookService { public sentEvents: Array<{ eventName: keyof EventMap; eventPayload: PlainMessage }> = []; diff --git a/controlplane/src/core/webhooks/RedeliverWebhookService.ts b/controlplane/src/core/webhooks/RedeliverWebhookService.ts index 00c0b5e102..8497c379e8 100644 --- a/controlplane/src/core/webhooks/RedeliverWebhookService.ts +++ b/controlplane/src/core/webhooks/RedeliverWebhookService.ts @@ -5,7 +5,9 @@ import { FastifyBaseLogger } from 'fastify'; import { WebhookDeliveryInfo } from '../../db/models.js'; import * as schema from '../../db/schema.js'; import { webhookAxiosRetryCond } from '../util.js'; +import { traced } from '../tracing.js'; +@traced export class RedeliverWebhookService { private readonly logger: FastifyBaseLogger; private httpClient: AxiosInstance; diff --git a/controlplane/test/tracing.test.ts b/controlplane/test/tracing.test.ts new file mode 100644 index 0000000000..0b0d055747 --- /dev/null +++ b/controlplane/test/tracing.test.ts @@ -0,0 +1,133 @@ +import { describe, expect, test, vi, beforeEach } from 'vitest'; +import * as Sentry from '@sentry/node'; +import { traced, withSpan } from '../src/core/tracing.js'; + +vi.mock('@sentry/node', () => { + return { + startSpan: vi.fn((opts: { name: string }, cb: (span: any) => any) => cb({ name: opts.name })), + }; +}); + +const startSpanMock = vi.mocked(Sentry.startSpan); + +beforeEach(() => { + startSpanMock.mockClear(); +}); + +describe('traced decorator', () => { + test('wraps prototype methods', () => { + @traced + class MyService { + greet(name: string) { + return `hello ${name}`; + } + } + + const svc = new MyService(); + const result = svc.greet('world'); + + expect(result).toBe('hello world'); + expect(startSpanMock).toHaveBeenCalledWith({ name: 'MyService.greet' }, expect.any(Function)); + }); + + test('wraps async prototype methods', async () => { + @traced + class MyRepo { + findById(id: string) { + return Promise.resolve({ id, name: 'test' }); + } + } + + const repo = new MyRepo(); + const result = await repo.findById('123'); + + expect(result).toEqual({ id: '123', name: 'test' }); + expect(startSpanMock).toHaveBeenCalledWith({ name: 'MyRepo.findById' }, expect.any(Function)); + }); + + test('preserves this context for prototype methods', () => { + @traced + class Counter { + count = 0; + + increment() { + this.count += 1; + return this.count; + } + } + + const counter = new Counter(); + expect(counter.increment()).toBe(1); + expect(counter.increment()).toBe(2); + }); + + test('skips non-function properties', () => { + @traced + class Config { + name = 'test'; + count = 42; + + getValue() { + return this.name; + } + } + + const config = new Config(); + expect(config.name).toBe('test'); + expect(config.count).toBe(42); + expect(config.getValue()).toBe('test'); + expect(startSpanMock).toHaveBeenCalledTimes(1); + expect(startSpanMock).toHaveBeenCalledWith({ name: 'Config.getValue' }, expect.any(Function)); + }); + + test('preserves class name', () => { + @traced + class OriginalName {} + + expect(OriginalName.name).toBe('OriginalName'); + }); + + test('works with traced() as a function call', () => { + class ManualService { + doWork() { + return 'done'; + } + } + traced(ManualService); + + const svc = new ManualService(); + expect(svc.doWork()).toBe('done'); + expect(startSpanMock).toHaveBeenCalledWith({ name: 'ManualService.doWork' }, expect.any(Function)); + }); + + test('does not wrap constructor', () => { + @traced + class MyClass { + value: string; + constructor() { + this.value = 'init'; + } + } + + const obj = new MyClass(); + expect(obj.value).toBe('init'); + const constructorCalls = startSpanMock.mock.calls.filter(([opts]) => opts.name.includes('constructor')); + expect(constructorCalls).toHaveLength(0); + }); +}); + +describe('withSpan', () => { + test('wraps sync function', async () => { + const result = await withSpan('test-span', () => 42); + + expect(result).toBe(42); + expect(startSpanMock).toHaveBeenCalledWith({ name: 'test-span' }, expect.any(Function)); + }); + + test('wraps async function', async () => { + const result = await withSpan('async-span', () => Promise.resolve('hello')); + + expect(result).toBe('hello'); + expect(startSpanMock).toHaveBeenCalledWith({ name: 'async-span' }, expect.any(Function)); + }); +}); diff --git a/controlplane/tsconfig.json b/controlplane/tsconfig.json index 4bfc01278c..ffd26c38fc 100644 --- a/controlplane/tsconfig.json +++ b/controlplane/tsconfig.json @@ -9,7 +9,8 @@ "sourceMap": true, "outDir": "./dist", "module": "NodeNext", - "resolveJsonModule": true + "resolveJsonModule": true, + "experimentalDecorators": true }, "include": ["src/**/*"], "exclude": ["node_modules"] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a407dc9c24..828fdf5deb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -547,7 +547,7 @@ importers: version: 16.4.5 drizzle-orm: specifier: ^0.35.3 - version: 0.35.3(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(@types/react@18.3.3)(bun-types@1.2.12)(postgres@3.4.5)(react@18.3.1) + version: 0.35.3(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(@types/react@18.3.3)(bun-types@1.2.12)(postgres@3.4.5)(react@18.3.1) ejs: specifier: ^3.1.10 version: 3.1.10 @@ -654,6 +654,9 @@ importers: '@connectrpc/protoc-gen-connect-es': specifier: ^1.4.0 version: 1.4.0(@bufbuild/protoc-gen-es@1.9.0(@bufbuild/protobuf@1.9.0))(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.9.0)) + '@spotlightjs/spotlight': + specifier: ^4.10.0 + version: 4.11.3(hono-rate-limiter@0.4.2(hono@4.12.12)) '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -690,6 +693,9 @@ importers: eslint-config-unjs: specifier: ^0.2.1 version: 0.2.1(eslint@8.57.1)(typescript@5.5.2) + eslint-plugin-local-rules: + specifier: ^3.0.2 + version: 3.0.2 eslint-plugin-require-extensions: specifier: ^0.1.3 version: 0.1.3(eslint@8.57.1) @@ -725,7 +731,7 @@ importers: version: 18.3.1 react-email: specifier: 4.0.3 - version: 4.0.3(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 4.0.3(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) docs-website: {} @@ -3676,6 +3682,11 @@ packages: '@fastify/fast-json-stringify-compiler@4.3.0': resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} + '@fastify/otel@0.18.0': + resolution: {integrity: sha512-3TASCATfw+ctICSb4ymrv7iCm0qJ0N9CarB+CZ7zIJ7KqNbwI5JjyDL1/sxoC0ccTO1Zyd1iQ+oqncPg5FJXaA==} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@floating-ui/core@1.3.1': resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==} @@ -3869,6 +3880,14 @@ packages: peerDependencies: react: 18.3.1 + '@hono/mcp@0.2.5': + resolution: {integrity: sha512-JsaJes7VlNvUrUQ9j2b9C13xjFLvyKQY515aWtsdJ9cwhBmWz5od2yUCbDu7cX38GeADmlLmpu4BKNNAV6G27w==} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.1 + hono: '*' + hono-rate-limiter: ^0.4.2 + zod: ^3.25.0 + '@hono/node-server@1.19.13': resolution: {integrity: sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==} engines: {node: '>=18.14.1'} @@ -4691,6 +4710,18 @@ packages: resolution: {integrity: sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==} engines: {node: '>=8.0.0'} + '@opentelemetry/api-logs@0.207.0': + resolution: {integrity: sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api-logs@0.212.0': + resolution: {integrity: sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api-logs@0.214.0': + resolution: {integrity: sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==} + engines: {node: '>=8.0.0'} + '@opentelemetry/api-logs@0.52.1': resolution: {integrity: sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==} engines: {node: '>=14'} @@ -4707,6 +4738,10 @@ packages: resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} + '@opentelemetry/api@1.9.1': + resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} + engines: {node: '>=8.0.0'} + '@opentelemetry/context-async-hooks@1.30.1': resolution: {integrity: sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==} engines: {node: '>=14'} @@ -4737,6 +4772,12 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/core@2.6.1': + resolution: {integrity: sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + '@opentelemetry/instrumentation-amqplib@0.43.0': resolution: {integrity: sha512-ALjfQC+0dnIEcvNYsbZl/VLh7D2P1HhFF4vicRKHhHFIUV3Shpg4kXgiek5PLhmeKSIPiUB25IYH5RIneclL4A==} engines: {node: '>=14'} @@ -4749,6 +4790,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-amqplib@0.61.0': + resolution: {integrity: sha512-mCKoyTGfRNisge4br0NpOFSy2Z1NnEW8hbCJdUDdJFHrPqVzc4IIBPA/vX0U+LUcQqrQvJX+HMIU0dbDRe0i0Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-connect@0.40.0': resolution: {integrity: sha512-3aR/3YBQ160siitwwRLjwqrv2KBT16897+bo6yz8wIfel6nWOxTZBJudcbsK3p42pTC7qrbotJ9t/1wRLpv79Q==} engines: {node: '>=14'} @@ -4761,6 +4808,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-connect@0.57.0': + resolution: {integrity: sha512-FMEBChnI4FLN5TE9DHwfH7QpNir1JzXno1uz/TAucVdLCyrG0jTrKIcNHt/i30A0M2AunNBCkcd8Ei26dIPKdg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-dataloader@0.12.0': resolution: {integrity: sha512-pnPxatoFE0OXIZDQhL2okF//dmbiWFzcSc8pUg9TqofCLYZySSxDCgQc69CJBo5JnI3Gz1KP+mOjS4WAeRIH4g==} engines: {node: '>=14'} @@ -4773,6 +4826,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-dataloader@0.31.0': + resolution: {integrity: sha512-f654tZFQXS5YeLDNb9KySrwtg7SnqZN119FauD7acBoTzuLduaiGTNz88ixcVSOOMGZ+EjJu/RFtx5klObC95g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-express@0.44.0': resolution: {integrity: sha512-GWgibp6Q0wxyFaaU8ERIgMMYgzcHmGrw3ILUtGchLtLncHNOKk0SNoWGqiylXWWT4HTn5XdV8MGawUgpZh80cA==} engines: {node: '>=14'} @@ -4803,6 +4862,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-fs@0.33.0': + resolution: {integrity: sha512-sCZWXGalQ01wr3tAhSR9ucqFJ0phidpAle6/17HVjD6gN8FLmZMK/8sKxdXYHy3PbnlV1P4zeiSVFNKpbFMNLA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-generic-pool@0.39.0': resolution: {integrity: sha512-y4v8Y+tSfRB3NNBvHjbjrn7rX/7sdARG7FuK6zR8PGb28CTa0kHpEGCJqvL9L8xkTNvTXo+lM36ajFGUaK1aNw==} engines: {node: '>=14'} @@ -4815,6 +4880,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-generic-pool@0.57.0': + resolution: {integrity: sha512-orhmlaK+ZIW9hKU+nHTbXrCSXZcH83AescTqmpamHRobRmYSQwRbD0a1odc0yAzuzOtxYiHiXAnpnIpaSSY7Ow==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-graphql@0.44.0': resolution: {integrity: sha512-FYXTe3Bv96aNpYktqm86BFUTpjglKD0kWI5T5bxYkLUPEPvFn38vWGMJTGrDMVou/i55E4jlWvcm6hFIqLsMbg==} engines: {node: '>=14'} @@ -4827,6 +4898,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-graphql@0.62.0': + resolution: {integrity: sha512-3YNuLVPUxafXkH1jBAbGsKNsP3XVzcFDhCDCE3OqBwCwShlqQbLMRMFh1T/d5jaVZiGVmSsfof+ICKD2iOV8xg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-hapi@0.41.0': resolution: {integrity: sha512-jKDrxPNXDByPlYcMdZjNPYCvw0SQJjN+B1A+QH+sx+sAHsKSAf9hwFiJSrI6C4XdOls43V/f/fkp9ITkHhKFbQ==} engines: {node: '>=14'} @@ -4839,12 +4916,24 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-hapi@0.60.0': + resolution: {integrity: sha512-aNljZKYrEa7obLAxd1bCEDxF7kzCLGXTuTJZ8lMR9rIVEjmuKBXN1gfqpm/OB//Zc2zP4iIve1jBp7sr3mQV6w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-http@0.204.0': resolution: {integrity: sha512-1afJYyGRA4OmHTv0FfNTrTAzoEjPQUYgd+8ih/lX0LlZBnGio/O80vxA0lN3knsJPS7FiDrsDrWq25K7oAzbkw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-http@0.214.0': + resolution: {integrity: sha512-FlkDhZDRjDJDcO2LcSCtjRpkal1NJ8y0fBqBhTvfAR3JSYY2jAIj1kSS5IjmEBt4c3aWv+u/lqLuoCDrrKCSKg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-http@0.53.0': resolution: {integrity: sha512-H74ErMeDuZfj7KgYCTOFGWF5W9AfaPnqLQQxeFq85+D29wwV2yqHbz2IKLYpkOh7EI6QwDEl7rZCIxjJLyc/CQ==} engines: {node: '>=14'} @@ -4863,12 +4952,24 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-ioredis@0.62.0': + resolution: {integrity: sha512-ZYt//zcPve8qklaZX+5Z4MkU7UpEkFRrxsf2cnaKYBitqDnsCN69CPAuuMOX6NYdW2rG9sFy7V/QWtBlP5XiNQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-kafkajs@0.14.0': resolution: {integrity: sha512-kbB5yXS47dTIdO/lfbbXlzhvHFturbux4EpP0+6H78Lk0Bn4QXiZQW7rmZY1xBCY16mNcCb8Yt0mhz85hTnSVA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-kafkajs@0.23.0': + resolution: {integrity: sha512-4K+nVo+zI+aDz0Z85SObwbdixIbzS9moIuKJaYsdlzcHYnKOPtB7ya8r8Ezivy/GVIBHiKJVq4tv+BEkgOMLaQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-kafkajs@0.4.0': resolution: {integrity: sha512-I9VwDG314g7SDL4t8kD/7+1ytaDBRbZQjhVaQaVIDR8K+mlsoBhLsWH79yHxhHQKvwCSZwqXF+TiTOhoQVUt7A==} engines: {node: '>=14'} @@ -4887,6 +4988,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-knex@0.58.0': + resolution: {integrity: sha512-Hc/o8fSsaWxZ8r1Yw4rNDLwTpUopTf4X32y4W6UhlHmW8Wizz8wfhgOKIelSeqFVTKBBPIDUOsQWuIMxBmu8Bw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-koa@0.43.0': resolution: {integrity: sha512-lDAhSnmoTIN6ELKmLJBplXzT/Jqs5jGZehuG22EdSMaTwgjMpxMDI1YtlKEhiWPWkrz5LUsd0aOO0ZRc9vn3AQ==} engines: {node: '>=14'} @@ -4899,6 +5006,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-koa@0.62.0': + resolution: {integrity: sha512-uVip0VuGUQXZ+vFxkKxAUNq8qNl+VFlyHDh/U6IQ8COOEDfbEchdaHnpFrMYF3psZRUuoSIgb7xOeXj00RdwDA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/instrumentation-lru-memoizer@0.40.0': resolution: {integrity: sha512-21xRwZsEdMPnROu/QsaOIODmzw59IYpGFmuC4aFWvMj6stA8+Ei1tX67nkarJttlNjoM94um0N4X26AD7ff54A==} engines: {node: '>=14'} @@ -4911,6 +5024,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-lru-memoizer@0.58.0': + resolution: {integrity: sha512-6grM3TdMyHzlGY1cUA+mwoPueB1F3dYKgKtZIH6jOFXqfHAByyLTc+6PFjGM9tKh52CFBJaDwodNlL/Td39z7Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mongodb@0.48.0': resolution: {integrity: sha512-9YWvaGvrrcrydMsYGLu0w+RgmosLMKe3kv/UNlsPy8RLnCkN2z+bhhbjjjuxtUmvEuKZMCoXFluABVuBr1yhjw==} engines: {node: '>=14'} @@ -4923,6 +5042,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mongodb@0.67.0': + resolution: {integrity: sha512-1WJp5N1lYfHq2IhECOTewFs5Tf2NfUOwQRqs/rZdXKTezArMlucxgzAaqcgp3A3YREXopXTpXHsxZTGHjNhMdQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mongoose@0.42.0': resolution: {integrity: sha512-AnWv+RaR86uG3qNEMwt3plKX1ueRM7AspfszJYVkvkehiicC3bHQA6vWdb6Zvy5HAE14RyFbu9+2hUUjR2NSyg==} engines: {node: '>=14'} @@ -4935,6 +5060,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mongoose@0.60.0': + resolution: {integrity: sha512-8BahAZpKsOoc+lrZGb7Ofn4g3z8qtp5IxDfvAVpKXsEheQN7ONMH5djT5ihy6yf8yyeQJGS0gXFfpEAEeEHqQg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mysql2@0.41.0': resolution: {integrity: sha512-REQB0x+IzVTpoNgVmy5b+UnH1/mDByrneimP6sbDHkp1j8QOl1HyWOrBH/6YWR0nrbU3l825Em5PlybjT3232g==} engines: {node: '>=14'} @@ -4947,6 +5078,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mysql2@0.60.0': + resolution: {integrity: sha512-m/5d3bxQALllCzezYDk/6vajh0tj5OijMMvOZGr+qN1NMXm1dzMNwyJ0gNZW7Fo3YFRyj/jJMxIw+W7d525dlw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mysql@0.41.0': resolution: {integrity: sha512-jnvrV6BsQWyHS2qb2fkfbfSb1R/lmYwqEZITwufuRl37apTopswu9izc0b1CYRp/34tUG/4k/V39PND6eyiNvw==} engines: {node: '>=14'} @@ -4959,6 +5096,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-mysql@0.60.0': + resolution: {integrity: sha512-08pO8GFPEIz2zquKDGteBZDNmwketdgH8hTe9rVYgW9kCJXq1Psj3wPQGx+VaX4ZJKCfPeoLMYup9+cxHvZyVQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-nestjs-core@0.40.0': resolution: {integrity: sha512-WF1hCUed07vKmf5BzEkL0wSPinqJgH7kGzOjjMAiTGacofNXjb/y4KQ8loj2sNsh5C/NN7s1zxQuCgbWbVTGKg==} engines: {node: '>=14'} @@ -4977,6 +5120,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-pg@0.66.0': + resolution: {integrity: sha512-KxfLGXBb7k2ueaPJfq2GXBDXBly8P+SpR/4Mj410hhNgmQF3sCqwXvUBQxZQkDAmsdBAoenM+yV1LhtsMRamcA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-redis-4@0.42.0': resolution: {integrity: sha512-NaD+t2JNcOzX/Qa7kMy68JbmoVIV37fT/fJYzLKu2Wwd+0NCxt+K2OOsOakA8GVg8lSpFdbx4V/suzZZ2Pvdjg==} engines: {node: '>=14'} @@ -4989,6 +5138,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-redis@0.62.0': + resolution: {integrity: sha512-y3pPpot7WzR/8JtHcYlTYsyY8g+pbFhAqbwAuG5bLPnR6v6pt1rQc0DpH0OlGP/9CZbWBP+Zhwp9yFoygf/ZXQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-tedious@0.15.0': resolution: {integrity: sha512-Kb7yo8Zsq2TUwBbmwYgTAMPK0VbhoS8ikJ6Bup9KrDtCx2JC01nCb+M0VJWXt7tl0+5jARUbKWh5jRSoImxdCw==} engines: {node: '>=14'} @@ -5001,12 +5156,24 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-tedious@0.33.0': + resolution: {integrity: sha512-Q6WQwAD01MMTub31GlejoiFACYNw26J426wyjvU7by7fDIr2nZXNW4vhTGs7i7F0TnXBO3xN688g1tdUgYwJ5w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-undici@0.15.0': resolution: {integrity: sha512-sNFGA/iCDlVkNjzTzPRcudmI11vT/WAfAguRdZY9IspCw02N4WSC72zTuQhSMheh2a1gdeM9my1imnKRvEEvEg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.7.0 + '@opentelemetry/instrumentation-undici@0.24.0': + resolution: {integrity: sha512-oKzZ3uvqP17sV0EsoQcJgjEfIp0kiZRbYu/eD8p13Cbahumf8lb/xpYeNr/hfAJ4owzEtIDcGIjprfLcYbIKBQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.7.0 + '@opentelemetry/instrumentation-undici@0.6.0': resolution: {integrity: sha512-ABJBhm5OdhGmbh0S/fOTE4N69IZ00CsHC5ijMYfzbw3E5NwLgpQk5xsljaECrJ8wz1SfXbO03FiSuu5AyRAkvQ==} engines: {node: '>=14'} @@ -5019,6 +5186,24 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation@0.207.0': + resolution: {integrity: sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.212.0': + resolution: {integrity: sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.214.0': + resolution: {integrity: sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation@0.52.1': resolution: {integrity: sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==} engines: {node: '>=14'} @@ -5045,6 +5230,10 @@ packages: resolution: {integrity: sha512-4Wc0AWURII2cfXVVoZ6vDqK+s5n4K5IssdrlVrvGsx6OEOKdghKtJZqXAHWFiZv4nTDLH2/2fldjIHY8clMOjQ==} engines: {node: ^18.19.0 || >=20.6.0} + '@opentelemetry/redis-common@0.38.2': + resolution: {integrity: sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==} + engines: {node: ^18.19.0 || >=20.6.0} + '@opentelemetry/resources@1.30.1': resolution: {integrity: sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==} engines: {node: '>=14'} @@ -5057,6 +5246,12 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/resources@2.6.1': + resolution: {integrity: sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/sdk-trace-base@1.30.1': resolution: {integrity: sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==} engines: {node: '>=14'} @@ -5069,6 +5264,12 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/sdk-trace-base@2.6.1': + resolution: {integrity: sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + '@opentelemetry/semantic-conventions@1.27.0': resolution: {integrity: sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg==} engines: {node: '>=14'} @@ -5085,6 +5286,10 @@ packages: resolution: {integrity: sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==} engines: {node: '>=14'} + '@opentelemetry/semantic-conventions@1.40.0': + resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} + engines: {node: '>=14'} + '@opentelemetry/sql-common@0.40.1': resolution: {integrity: sha512-nSDlnHSqzC3pXn/wZEZVLuAuJ1MYMXPBwtv2qAbCa3847SaHItdE7SzUq/Jtb0KZmh1zfAbNi3AAMjztTT4Ugg==} engines: {node: '>=14'} @@ -5097,6 +5302,12 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 + '@opentelemetry/sql-common@0.41.2': + resolution: {integrity: sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@peculiar/asn1-schema@2.3.8': resolution: {integrity: sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==} @@ -5127,6 +5338,11 @@ packages: peerDependencies: '@opentelemetry/api': ^1.8 + '@prisma/instrumentation@7.6.0': + resolution: {integrity: sha512-ZPW2gRiwpPzEfgeZgaekhqXrbW+Y2RJKHVqUmlhZhKzRNCcvR6DykzylDrynpArKKRQtLxoZy36fK7U0p3pdgQ==} + peerDependencies: + '@opentelemetry/api': ^1.8 + '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -6705,6 +6921,10 @@ packages: resolution: {integrity: sha512-OqZjYDYsK6ZmBG5UzML0uKiKq//G6mMwPcszfuCsFgPt+pg5giUCrCUbt5VIVkHdN1qEEBk321JO2haU5n2Eig==} engines: {node: '>=18'} + '@sentry/core@10.49.0': + resolution: {integrity: sha512-UaFeum3LUM1mB0d67jvKnqId1yWQjyqmaDV6kWngG03x+jqXb08tJdGpSoxjXZe13jFBbiBL/wKDDYIK7rCK4g==} + engines: {node: '>=18'} + '@sentry/core@8.42.0': resolution: {integrity: sha512-ac6O3pgoIbU6rpwz6LlwW0wp3/GAHuSI0C5IsTgIY6baN8rOBnlAtG6KrHDDkGmUQ2srxkDJu9n1O6Td3cBCqw==} engines: {node: '>=14.18'} @@ -6727,6 +6947,30 @@ packages: '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 '@opentelemetry/semantic-conventions': ^1.37.0 + '@sentry/node-core@10.49.0': + resolution: {integrity: sha512-7WO0KuCDPSq3G54TVUSI1CKFJwB67LasG+n/gDMBqbrarzs/Yh/s34OOMU5gfVQpncxQAmQsy4nEboQms8iNqA==} + engines: {node: '>=18'} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/core': ^1.30.1 || ^2.1.0 + '@opentelemetry/exporter-trace-otlp-http': '>=0.57.0 <1' + '@opentelemetry/instrumentation': '>=0.57.1 <1' + '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 + '@opentelemetry/semantic-conventions': ^1.39.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@opentelemetry/core': + optional: true + '@opentelemetry/exporter-trace-otlp-http': + optional: true + '@opentelemetry/instrumentation': + optional: true + '@opentelemetry/sdk-trace-base': + optional: true + '@opentelemetry/semantic-conventions': + optional: true + '@sentry/node-native@10.19.0': resolution: {integrity: sha512-mUMn2GnC8RInQCrqOKv1GCEgkQNYyX4cnHhqOOJMGvQDoXqZ6X81xU4m4gvUY+whg7bNiIf6TGloeeuWRDWG/A==} engines: {node: '>=18'} @@ -6735,6 +6979,10 @@ packages: resolution: {integrity: sha512-GUN/UVRsqnXd4O8GCxR8F682nyYemeO4mr0Yc5JPz0CxT2gYkemuifT29bFOont8V5o055WJv32NrQnZcm/nyg==} engines: {node: '>=18'} + '@sentry/node@10.49.0': + resolution: {integrity: sha512-xr+HXABCiO5mgAJRQxsXRdNOLO0+Ee6CvXAAIqovL2A1GlhxNWc5ooPWeIrrLDJ/KGyT8zI91O5scpVXdXs0uQ==} + engines: {node: '>=18'} + '@sentry/node@8.42.0': resolution: {integrity: sha512-MsNrmAIwDaxf1jTX1FsgZ+3mUq6G6IuU6FAqyp7TDnvUTsbWUtr0OM6EvVUz0zCImybIh9dcTQ+6KTmUyA7URw==} engines: {node: '>=14.18'} @@ -6749,6 +6997,15 @@ packages: '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 '@opentelemetry/semantic-conventions': ^1.37.0 + '@sentry/opentelemetry@10.49.0': + resolution: {integrity: sha512-XNLm4dXmtegXQf+EEE2Cs84Ymlo/f5wMx+lg2S2XS4qLbXaPN/HttjhwKftd8D+8iUNfmH+xNMCSshx4s1B/1w==} + engines: {node: '>=18'} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/core': ^1.30.1 || ^2.1.0 + '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 + '@opentelemetry/semantic-conventions': ^1.39.0 + '@sentry/opentelemetry@8.42.0': resolution: {integrity: sha512-QPb9kMFgl35TIwIz0u+BFTbPG461CofMiloidJ44GFZ9cB33T5cB0oIN7ut/5tsH/AvqUmucydsV/Nj3HNQx9g==} engines: {node: '>=14.18'} @@ -7063,6 +7320,11 @@ packages: '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@spotlightjs/spotlight@4.11.3': + resolution: {integrity: sha512-0vSx3r1qkScyJtilISn2+vfMCq1M9LEGhKfAv5Wgd4soWEwhtSpU8obCd/dWrNdPdpyD5OwiUuynxqxvq0cVpg==} + engines: {node: '>=20'} + hasBin: true + '@standard-schema/utils@0.3.0': resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} @@ -7603,12 +7865,18 @@ packages: '@types/pg-pool@2.0.6': resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} + '@types/pg-pool@2.0.7': + resolution: {integrity: sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==} + '@types/pg@8.15.4': resolution: {integrity: sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==} '@types/pg@8.15.5': resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} + '@types/pg@8.15.6': + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} + '@types/pg@8.6.1': resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} @@ -8004,6 +8272,9 @@ packages: alien-signals@0.4.14: resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} + anser@2.3.5: + resolution: {integrity: sha512-vcZjxvvVoxTeR5XBNJB38oTu/7eDCZlwdz32N1eNgpyPF7j/Z7Idf+CUwQOkKKpJ7RJyjxgLHCM7vdIK0iCNMQ==} + ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -8443,6 +8714,10 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + change-case@4.1.2: resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} @@ -8499,6 +8774,9 @@ packages: cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + cjs-module-lexer@2.2.0: + resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + class-variance-authority@0.6.1: resolution: {integrity: sha512-eurOEGc7YVx3majOrOb099PNKgO3KnKSApOprXI4BTq6bcfbqbQXPN2u+rPPmIJ2di23bMwhk0SxCCthBmszEQ==} @@ -9621,6 +9899,9 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint-plugin-local-rules@3.0.2: + resolution: {integrity: sha512-IWME7GIYHXogTkFsToLdBCQVJ0U4kbSuVyDT+nKoR4UgtnVrrVeNWuAZkdEu1nxkvi9nsPccGehEEF6dgA28IQ==} + eslint-plugin-n@16.6.2: resolution: {integrity: sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==} engines: {node: '>=16.0.0'} @@ -9748,6 +10029,10 @@ packages: resolution: {integrity: sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==} engines: {node: '>=18.0.0'} + eventsource@4.1.0: + resolution: {integrity: sha512-2GuF51iuHX6A9xdTccMTsNb7VO0lHZihApxhvQzJB5A03DvHDd2FQepodbMaztPBmBcE/ox7o2gqaxGhYB9LhQ==} + engines: {node: '>=20.0.0'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -9824,6 +10109,9 @@ packages: resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==} engines: {node: '>=6.0.0'} + fast-fuzzy@1.12.0: + resolution: {integrity: sha512-sXxGgHS+ubYpsdLnvOvJ9w5GYYZrtL9mkosG3nfuD446ahvoWEsSKBP7ieGmWIKVLnaxRDgUJkZMdxRgA2Ni+Q==} + fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} @@ -10249,6 +10537,9 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphemesplit@2.6.0: + resolution: {integrity: sha512-rG9w2wAfkpg0DILa1pjnjNfucng3usON360shisqIMUBw/87pojcBSrHmeE4UwryAuBih7g8m1oilf5/u8EWdQ==} + graphiql-explorer@0.9.0: resolution: {integrity: sha512-fZC/wsuatqiQDO2otchxriFO0LaWIo/ovF/CQJ1yOudmY0P7pzDiP+l9CEHUiWbizk3e99x6DQG4XG1VxA+d6A==} peerDependencies: @@ -10423,6 +10714,11 @@ packages: hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hono-rate-limiter@0.4.2: + resolution: {integrity: sha512-AAtFqgADyrmbDijcRTT/HJfwqfvhalya2Zo+MgfdrMPas3zSMD8SU03cv+ZsYwRU1swv7zgVt0shwN059yzhjw==} + peerDependencies: + hono: ^4.1.1 + hono@4.12.12: resolution: {integrity: sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==} engines: {node: '>=16.9.0'} @@ -10579,6 +10875,13 @@ packages: import-in-the-middle@1.14.2: resolution: {integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==} + import-in-the-middle@2.0.6: + resolution: {integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==} + + import-in-the-middle@3.0.1: + resolution: {integrity: sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==} + engines: {node: '>=18'} + import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} engines: {node: '>=8'} @@ -11113,6 +11416,9 @@ packages: language-tags@1.0.5: resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + leac@0.6.0: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} @@ -11256,6 +11562,10 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} + logfmt@1.4.0: + resolution: {integrity: sha512-p1Ow0C2dDJYaQBhRHt+HVMP6ELuBm4jYSYNHPMfz0J5wJ9qA6/7oBOlBZBfT1InqguTYcvJzNea5FItDxTcbyw==} + hasBin: true + long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} @@ -11354,6 +11664,10 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + mcp-proxy@5.12.5: + resolution: {integrity: sha512-Vawdc8vi36fXxKCaDpluRvbGcmrUXJdvXcDhkh30HYsws8XqX2rWPBflZpavzeS+6SwijRFV7g+9ypQRJZlrEQ==} + hasBin: true + md-to-react-email@5.0.5: resolution: {integrity: sha512-OvAXqwq57uOk+WZqFFNCMZz8yDp8BD3WazW1wAKHUrPbbdr89K9DWS6JXY09vd9xNdPNeurI8DU/X4flcfaD8A==} peerDependencies: @@ -12074,6 +12388,9 @@ packages: engines: {node: ^20.17.0 || >=22.9.0} hasBin: true + pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} @@ -13033,6 +13350,10 @@ packages: resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} engines: {node: '>=8.6.0'} + require-in-the-middle@8.0.1: + resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} + engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} + requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -13265,6 +13586,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + shimmer@1.2.1: resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} @@ -13405,6 +13730,9 @@ packages: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} + split@0.2.10: + resolution: {integrity: sha512-e0pKq+UUH2Xq/sXbYpZBZc3BawsfDZ7dgv+JtRTUPNcvF5CMR4Y9cvJqkMY0MoxWzTHvZuz1beg6pNEKlszPiQ==} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -13702,6 +14030,9 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tiny-invariant@1.3.1: resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} @@ -14038,6 +14369,9 @@ packages: resolution: {integrity: sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA==} engines: {node: '>=18.17'} + unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} @@ -14213,6 +14547,10 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + uuidv7@1.2.1: + resolution: {integrity: sha512-4kPkK3/XTQW9Hbm4CaqfICn+kY9LJtDVEOfgsRRra/+n2Ofg4NqzRFceAkxvQ/Ud/6BpHOPzj8cirqM7TzTN5Q==} + hasBin: true + v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -15357,10 +15695,10 @@ snapshots: '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-module-transforms': 7.27.3(@babel/core@7.24.5) '@babel/helpers': 7.28.2 - '@babel/parser': 7.28.0 + '@babel/parser': 7.29.2 '@babel/template': 7.27.2 '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 + '@babel/types': 7.29.0 convert-source-map: 2.0.0 debug: 4.4.1 gensync: 1.0.0-beta.2 @@ -15378,8 +15716,8 @@ snapshots: '@babel/generator@7.28.0': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -15408,7 +15746,7 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -15416,7 +15754,7 @@ snapshots: dependencies: '@babel/core': 7.24.5 '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color @@ -15446,7 +15784,7 @@ snapshots: '@babel/helpers@7.28.2': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.29.0 '@babel/highlight@7.23.4': dependencies: @@ -15515,8 +15853,8 @@ snapshots: '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 '@babel/traverse@7.23.7': dependencies: @@ -15550,9 +15888,9 @@ snapshots: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.0 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.0 + '@babel/parser': 7.29.2 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.29.0 debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -17293,6 +17631,16 @@ snapshots: dependencies: fast-json-stringify: 5.9.1 + '@fastify/otel@0.18.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + minimatch: 10.2.4 + transitivePeerDependencies: + - supports-color + '@floating-ui/core@1.3.1': {} '@floating-ui/dom@1.4.5': @@ -17623,6 +17971,14 @@ snapshots: dependencies: react: 18.3.1 + '@hono/mcp@0.2.5(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(hono-rate-limiter@0.4.2(hono@4.12.12))(hono@4.12.12)(zod@3.25.76)': + dependencies: + '@modelcontextprotocol/sdk': 1.26.0(zod@3.25.76) + hono: 4.12.12 + hono-rate-limiter: 0.4.2(hono@4.12.12) + pkce-challenge: 5.0.0 + zod: 3.25.76 + '@hono/node-server@1.19.13(hono@4.12.12)': dependencies: hono: 4.12.12 @@ -18688,6 +19044,18 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs@0.207.0': + dependencies: + '@opentelemetry/api': 1.9.1 + + '@opentelemetry/api-logs@0.212.0': + dependencies: + '@opentelemetry/api': 1.9.1 + + '@opentelemetry/api-logs@0.214.0': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs@0.52.1': dependencies: '@opentelemetry/api': 1.9.0 @@ -18702,6 +19070,8 @@ snapshots: '@opentelemetry/api@1.9.0': {} + '@opentelemetry/api@1.9.1': {} + '@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18725,6 +19095,11 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/instrumentation-amqplib@0.43.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18743,6 +19118,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-amqplib@0.61.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-connect@0.40.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18763,6 +19147,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-connect@0.57.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/connect': 3.4.38 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-dataloader@0.12.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18777,6 +19171,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-dataloader@0.31.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-express@0.44.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18820,6 +19221,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-fs@0.33.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-generic-pool@0.39.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18834,6 +19243,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-generic-pool@0.57.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-graphql@0.44.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18848,6 +19264,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-graphql@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-hapi@0.41.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18866,6 +19289,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-hapi@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-http@0.204.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18876,6 +19308,16 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-http@0.214.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + forwarded-parse: 2.1.2 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-http@0.53.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18904,6 +19346,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-ioredis@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/redis-common': 0.38.2 + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-kafkajs@0.14.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18912,6 +19363,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-kafkajs@0.23.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-kafkajs@0.4.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18936,6 +19395,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-knex@0.58.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-koa@0.43.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18954,6 +19421,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-koa@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-lru-memoizer@0.40.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18968,6 +19444,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-lru-memoizer@0.58.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-mongodb@0.48.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18984,6 +19467,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-mongodb@0.67.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-mongoose@0.42.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19002,6 +19493,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-mongoose@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-mysql2@0.41.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19020,6 +19520,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-mysql2@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-mysql@0.41.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19038,6 +19547,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-mysql@0.60.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/mysql': 2.15.27 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-nestjs-core@0.40.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19069,6 +19587,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-pg@0.66.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) + '@types/pg': 8.15.6 + '@types/pg-pool': 2.0.7 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-redis-4@0.42.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19087,6 +19617,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-redis@0.62.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/redis-common': 0.38.2 + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-tedious@0.15.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19105,6 +19644,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-tedious@0.33.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/tedious': 4.0.14 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-undici@0.15.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19113,6 +19661,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-undici@0.24.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-undici@0.6.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19130,6 +19687,33 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation@0.207.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.207.0 + import-in-the-middle: 2.0.6 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.212.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.212.0 + import-in-the-middle: 2.0.6 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/api-logs': 0.214.0 + import-in-the-middle: 3.0.1 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19170,6 +19754,8 @@ snapshots: '@opentelemetry/redis-common@0.38.0': {} + '@opentelemetry/redis-common@0.38.2': {} + '@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19182,6 +19768,12 @@ snapshots: '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/resources@2.6.1(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19196,6 +19788,13 @@ snapshots: '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.37.0 + '@opentelemetry/sdk-trace-base@2.6.1(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/resources': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/semantic-conventions@1.27.0': {} '@opentelemetry/semantic-conventions@1.28.0': {} @@ -19204,6 +19803,8 @@ snapshots: '@opentelemetry/semantic-conventions@1.37.0': {} + '@opentelemetry/semantic-conventions@1.40.0': {} + '@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -19214,6 +19815,11 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@peculiar/asn1-schema@2.3.8': dependencies: asn1js: 3.0.5 @@ -19261,6 +19867,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@prisma/instrumentation@7.6.0(@opentelemetry/api@1.9.1)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.1) + transitivePeerDependencies: + - supports-color + '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} @@ -20987,6 +21600,8 @@ snapshots: '@sentry/core@10.19.0': {} + '@sentry/core@10.49.0': {} + '@sentry/core@8.42.0': {} '@sentry/nextjs@8.42.0(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.4.11(@babel/core@7.24.5)(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.98.0)': @@ -21032,6 +21647,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@sentry/node-core@10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0)': + dependencies: + '@sentry/core': 10.49.0 + '@sentry/opentelemetry': 10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0) + import-in-the-middle: 3.0.1 + optionalDependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@sentry/node-native@10.19.0': dependencies: '@sentry-internal/node-native-stacktrace': 0.2.2 @@ -21080,6 +21707,44 @@ snapshots: transitivePeerDependencies: - supports-color + '@sentry/node@10.49.0': + dependencies: + '@fastify/otel': 0.18.0(@opentelemetry/api@1.9.1) + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-amqplib': 0.61.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-connect': 0.57.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-dataloader': 0.31.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-fs': 0.33.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-generic-pool': 0.57.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-graphql': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-hapi': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-http': 0.214.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-ioredis': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-kafkajs': 0.23.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-knex': 0.58.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-koa': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-lru-memoizer': 0.58.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mongodb': 0.67.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mongoose': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mysql': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-mysql2': 0.60.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-pg': 0.66.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-redis': 0.62.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-tedious': 0.33.0(@opentelemetry/api@1.9.1) + '@opentelemetry/instrumentation-undici': 0.24.0(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@prisma/instrumentation': 7.6.0(@opentelemetry/api@1.9.1) + '@sentry/core': 10.49.0 + '@sentry/node-core': 10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0) + '@sentry/opentelemetry': 10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0) + import-in-the-middle: 3.0.1 + transitivePeerDependencies: + - '@opentelemetry/exporter-trace-otlp-http' + - supports-color + '@sentry/node@8.42.0': dependencies: '@opentelemetry/api': 1.9.0 @@ -21129,6 +21794,14 @@ snapshots: '@opentelemetry/semantic-conventions': 1.37.0 '@sentry/core': 10.19.0 + '@sentry/opentelemetry@10.49.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.6.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.40.0)': + dependencies: + '@opentelemetry/api': 1.9.1 + '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/sdk-trace-base': 2.6.1(@opentelemetry/api@1.9.1) + '@opentelemetry/semantic-conventions': 1.40.0 + '@sentry/core': 10.49.0 + '@sentry/opentelemetry@8.42.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.54.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.30.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -21578,6 +22251,32 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} + '@spotlightjs/spotlight@4.11.3(hono-rate-limiter@0.4.2(hono@4.12.12))': + dependencies: + '@hono/mcp': 0.2.5(@modelcontextprotocol/sdk@1.26.0(zod@3.25.76))(hono-rate-limiter@0.4.2(hono@4.12.12))(hono@4.12.12)(zod@3.25.76) + '@hono/node-server': 1.19.13(hono@4.12.12) + '@jridgewell/trace-mapping': 0.3.31 + '@modelcontextprotocol/sdk': 1.26.0(zod@3.25.76) + '@sentry/core': 10.49.0 + '@sentry/node': 10.49.0 + anser: 2.3.5 + chalk: 5.6.2 + eventsource: 4.1.0 + fast-fuzzy: 1.12.0 + hono: 4.12.12 + launch-editor: 2.13.2 + logfmt: 1.4.0 + mcp-proxy: 5.12.5 + semver: 7.7.4 + uuidv7: 1.2.1 + yaml: 2.8.2 + zod: 3.25.76 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@opentelemetry/exporter-trace-otlp-http' + - hono-rate-limiter + - supports-color + '@standard-schema/utils@0.3.0': {} '@stripe/stripe-js@2.2.2': {} @@ -22184,6 +22883,10 @@ snapshots: dependencies: '@types/pg': 8.15.4 + '@types/pg-pool@2.0.7': + dependencies: + '@types/pg': 8.15.6 + '@types/pg@8.15.4': dependencies: '@types/node': 20.12.12 @@ -22196,6 +22899,12 @@ snapshots: pg-protocol: 1.10.3 pg-types: 2.2.0 + '@types/pg@8.15.6': + dependencies: + '@types/node': 20.12.12 + pg-protocol: 1.10.3 + pg-types: 2.2.0 + '@types/pg@8.6.1': dependencies: '@types/node': 20.12.12 @@ -22711,6 +23420,10 @@ snapshots: dependencies: acorn: 8.15.0 + acorn-import-attributes@1.9.5(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -22788,6 +23501,8 @@ snapshots: alien-signals@0.4.14: {} + anser@2.3.5: {} + ansi-align@3.0.1: dependencies: string-width: 4.2.3 @@ -23151,7 +23866,7 @@ snapshots: bun-types@1.2.12: dependencies: - '@types/node': 20.12.12 + '@types/node': 18.19.21 optional: true bun-types@1.2.3: @@ -23288,6 +24003,8 @@ snapshots: chalk@5.3.0: {} + chalk@5.6.2: {} + change-case@4.1.2: dependencies: camel-case: 4.1.2 @@ -23355,6 +24072,8 @@ snapshots: cjs-module-lexer@1.4.3: {} + cjs-module-lexer@2.2.0: {} + class-variance-authority@0.6.1: dependencies: clsx: 1.2.1 @@ -24063,12 +24782,12 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.35.3(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/pg@8.15.5)(@types/react@18.3.3)(bun-types@1.2.12)(postgres@3.4.5)(react@18.3.1): + drizzle-orm@0.35.3(@libsql/client-wasm@0.14.0)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(@types/react@18.3.3)(bun-types@1.2.12)(postgres@3.4.5)(react@18.3.1): dependencies: '@libsql/client-wasm': 0.14.0 optionalDependencies: '@opentelemetry/api': 1.9.0 - '@types/pg': 8.15.5 + '@types/pg': 8.15.6 '@types/react': 18.3.3 bun-types: 1.2.12 postgres: 3.4.5 @@ -24670,6 +25389,8 @@ snapshots: object.fromentries: 2.0.6 semver: 6.3.1 + eslint-plugin-local-rules@3.0.2: {} + eslint-plugin-n@16.6.2(eslint@8.57.1): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) @@ -24851,6 +25572,10 @@ snapshots: dependencies: eventsource-parser: 3.0.1 + eventsource@4.1.0: + dependencies: + eventsource-parser: 3.0.1 + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -24987,6 +25712,10 @@ snapshots: fast-equals@5.0.1: {} + fast-fuzzy@1.12.0: + dependencies: + graphemesplit: 2.6.0 + fast-glob@3.3.1: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -25481,6 +26210,11 @@ snapshots: graphemer@1.4.0: {} + graphemesplit@2.6.0: + dependencies: + js-base64: 3.7.8 + unicode-trie: 2.0.0 + graphiql-explorer@0.9.0(graphql@16.9.0(patch_hash=hafdlc54qtxpqvetpefk646rly))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: graphql: 16.9.0(patch_hash=hafdlc54qtxpqvetpefk646rly) @@ -25698,6 +26432,10 @@ snapshots: dependencies: react-is: 16.13.1 + hono-rate-limiter@0.4.2(hono@4.12.12): + dependencies: + hono: 4.12.12 + hono@4.12.12: {} hosted-git-info@2.8.9: {} @@ -25880,6 +26618,20 @@ snapshots: cjs-module-lexer: 1.4.3 module-details-from-path: 1.0.3 + import-in-the-middle@2.0.6: + dependencies: + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) + cjs-module-lexer: 2.2.0 + module-details-from-path: 1.0.4 + + import-in-the-middle@3.0.1: + dependencies: + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) + cjs-module-lexer: 2.2.0 + module-details-from-path: 1.0.4 + import-lazy@4.0.0: {} import-local@3.2.0: @@ -26380,6 +27132,11 @@ snapshots: dependencies: language-subtag-registry: 0.3.22 + launch-editor@2.13.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + leac@0.6.0: {} levn@0.4.1: @@ -26534,6 +27291,11 @@ snapshots: strip-ansi: 7.1.2 wrap-ansi: 8.1.0 + logfmt@1.4.0: + dependencies: + split: 0.2.10 + through: 2.3.8 + long@5.3.2: {} longest-streak@3.1.0: {} @@ -26635,6 +27397,8 @@ snapshots: math-intrinsics@1.1.0: {} + mcp-proxy@5.12.5: {} + md-to-react-email@5.0.5(react@18.3.1): dependencies: marked: 7.0.4 @@ -27251,7 +28015,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.4.11(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.4.11(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 15.4.11 '@swc/helpers': 0.5.15 @@ -27269,7 +28033,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.4.8 '@next/swc-win32-arm64-msvc': 15.4.8 '@next/swc-win32-x64-msvc': 15.4.8 - '@opentelemetry/api': 1.9.0 + '@opentelemetry/api': 1.9.1 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' @@ -27650,6 +28414,8 @@ snapshots: transitivePeerDependencies: - supports-color + pako@0.2.9: {} + param-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -28328,7 +29094,7 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-email@4.0.3(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-email@4.0.3(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/parser': 7.24.5 '@babel/traverse': 7.25.6 @@ -28340,7 +29106,7 @@ snapshots: glob: 10.3.4 log-symbols: 4.1.0 mime-types: 2.1.35 - next: 15.4.11(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.4.11(@opentelemetry/api@1.9.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) normalize-path: 3.0.0 ora: 5.4.1 socket.io: 4.8.1 @@ -28720,6 +29486,13 @@ snapshots: transitivePeerDependencies: - supports-color + require-in-the-middle@8.0.1: + dependencies: + debug: 4.4.1 + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color + requires-port@1.0.0: {} resolve-cwd@3.0.0: @@ -29018,6 +29791,8 @@ snapshots: shebang-regex@3.0.0: {} + shell-quote@1.8.3: {} + shimmer@1.2.1: {} side-channel-list@1.0.0: @@ -29188,6 +29963,10 @@ snapshots: split2@4.2.0: {} + split@0.2.10: + dependencies: + through: 2.3.8 + sprintf-js@1.0.3: {} sprintf-js@1.1.3: {} @@ -29554,6 +30333,8 @@ snapshots: through@2.3.8: {} + tiny-inflate@1.0.3: {} + tiny-invariant@1.3.1: {} tiny-lru@11.2.11: {} @@ -29914,6 +30695,11 @@ snapshots: undici@6.24.0: {} + unicode-trie@2.0.0: + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + unicorn-magic@0.1.0: {} unicorn-magic@0.3.0: {} @@ -30078,6 +30864,8 @@ snapshots: uuid@9.0.1: {} + uuidv7@1.2.1: {} + v8-compile-cache-lib@3.0.1: {} validate-npm-package-license@3.0.4: