diff --git a/apps/api/.env.example b/apps/api/.env.example index 43d6ee2a..e5fe9539 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -6,16 +6,11 @@ # ------------------------------------------------------------------------------ DATABASE_URL= + JWT_SECRET= SENTRY_DSN= -GCP_PROJECT_ID= -GCP_LOG_NAME='local-dev' -METADATA_SERVER_DETECTION='none' - +STRIPE_PUBLISHABLE_KEY= STRIPE_SECRET_KEY= - -WORKOS_CLIENT_ID= -WORKOS_API_KEY= -WORKOS_SESSION_SECRET= +STRIPE_WEBHOOK_SECRET= diff --git a/apps/api/package.json b/apps/api/package.json index 3dd2e71c..2363a10e 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -39,7 +39,6 @@ "@agentic/validators": "workspace:*", "@fisch0920/drizzle-orm": "^0.43.7", "@fisch0920/drizzle-zod": "^0.7.9", - "@google-cloud/logging": "^11.2.0", "@hono/node-server": "^1.14.1", "@hono/sentry": "^1.2.1", "@hono/zod-openapi": "^0.19.6", @@ -52,8 +51,6 @@ "hono": "^4.7.9", "jsonwebtoken": "^9.0.2", "p-all": "^5.0.0", - "pino": "^9.6.0", - "pino-abstract-transport": "^2.0.0", "postgres": "^3.4.5", "restore-cursor": "catalog:", "stripe": "^18.1.0", diff --git a/apps/api/src/api-v1/consumers/upsert-consumer.ts b/apps/api/src/api-v1/consumers/upsert-consumer.ts index d7a6481d..4cd971cf 100644 --- a/apps/api/src/api-v1/consumers/upsert-consumer.ts +++ b/apps/api/src/api-v1/consumers/upsert-consumer.ts @@ -131,20 +131,21 @@ export function registerV1ConsumersUpsertConsumer( // consumer._stripeAccount = project._stripeAccount await upsertStripeConnectCustomer({ stripeCustomer, consumer, project }) - console.log('SUBSCRIPTION', existing ? 'UPDATE' : 'CREATE', { + const logger = c.get('logger') + logger.info('SUBSCRIPTION', existing ? 'UPDATE' : 'CREATE', { project, deployment, consumer }) const { subscription, consumer: updatedConsumer } = - await upsertStripeSubscription({ + await upsertStripeSubscription(c, { consumer, user, project, deployment }) - console.log({ subscription }) + logger.info('subscription', subscription) return c.json(parseZodSchema(schema.consumerSelectSchema, updatedConsumer)) }) diff --git a/apps/api/src/api-v1/projects/create-project.ts b/apps/api/src/api-v1/projects/create-project.ts index 12dbd62f..ef5f6141 100644 --- a/apps/api/src/api-v1/projects/create-project.ts +++ b/apps/api/src/api-v1/projects/create-project.ts @@ -3,7 +3,7 @@ import { createRoute, type OpenAPIHono } from '@hono/zod-openapi' import type { AuthenticatedEnv } from '@/lib/types' import { db, schema } from '@/db' import { aclTeamMember } from '@/lib/acl-team-member' -import { getProviderToken } from '@/lib/auth/get-provider-token' +import { createProviderToken } from '@/lib/auth/create-provider-token' import { ensureAuthUser } from '@/lib/ensure-auth-user' import { openapiAuthenticatedSecuritySchemas, @@ -64,7 +64,7 @@ export function registerV1ProjectsCreateProject( userId: user.id, id, _secret: sha256(), - _providerToken: getProviderToken({ id }) + _providerToken: createProviderToken({ id }) }) .returning() assert(project, 500, `Failed to create project "${body.name}"`) diff --git a/apps/api/src/lib/auth/get-provider-token.ts b/apps/api/src/lib/auth/create-provider-token.ts similarity index 80% rename from apps/api/src/lib/auth/get-provider-token.ts rename to apps/api/src/lib/auth/create-provider-token.ts index 76e626a5..10c667dc 100644 --- a/apps/api/src/lib/auth/get-provider-token.ts +++ b/apps/api/src/lib/auth/create-provider-token.ts @@ -2,7 +2,7 @@ import jwt from 'jsonwebtoken' import { env } from '@/lib/env' -export function getProviderToken(project: { id: string }) { +export function createProviderToken(project: { id: string }) { // TODO: Possibly in the future store stripe account ID as well and require // provider tokens to refresh after account changes? return jwt.sign({ projectId: project.id }, env.JWT_SECRET) diff --git a/apps/api/src/lib/billing/upsert-stripe-subscription.ts b/apps/api/src/lib/billing/upsert-stripe-subscription.ts index e3a7605f..15268d9b 100644 --- a/apps/api/src/lib/billing/upsert-stripe-subscription.ts +++ b/apps/api/src/lib/billing/upsert-stripe-subscription.ts @@ -13,20 +13,26 @@ import { import { stripe } from '@/lib/stripe' import { assert } from '@/lib/utils' -export async function upsertStripeSubscription({ - consumer, - user, - deployment, - project -}: { - consumer: RawConsumer - user: RawUser - deployment: RawDeployment - project: RawProject -}): Promise<{ +import type { AuthenticatedContext } from '../types' + +export async function upsertStripeSubscription( + ctx: AuthenticatedContext, + { + consumer, + user, + deployment, + project + }: { + consumer: RawConsumer + user: RawUser + deployment: RawDeployment + project: RawProject + } +): Promise<{ subscription: Stripe.Subscription consumer: RawConsumer }> { + const logger = ctx.get('logger') const stripeConnectParams = project._stripeAccountId ? [ { @@ -61,9 +67,9 @@ export async function upsertStripeSubscription({ ...stripeConnectParams ) const existingItems = existing.items.data - console.log() - console.log('existing subscription', JSON.stringify(existing, null, 2)) - console.log() + logger.debug() + logger.debug('existing subscription', JSON.stringify(existing, null, 2)) + logger.debug() const update: Stripe.SubscriptionUpdateParams = {} @@ -87,7 +93,7 @@ export async function upsertStripeSubscription({ for (const metric of pricingPlan.metrics) { const { slug: metricSlug } = metric - console.log({ + logger.debug({ metricSlug, plan: pricingPlan.stripeMetricPlans[metricSlug], id: consumer.stripeSubscriptionMetricItems[metricSlug] @@ -101,7 +107,7 @@ export async function upsertStripeSubscription({ const invalidItems = items.filter((item) => !item.plan) if (plan && invalidItems.length) { - console.error('billing warning found invalid items', invalidItems) + logger.error('billing warning found invalid items', invalidItems) } items = items.filter((item) => item.plan) @@ -113,7 +119,7 @@ export async function upsertStripeSubscription({ ) if (!existingItem) { - console.error( + logger.error( 'billing warning found new item that has a subscription item id but should not', { item } ) @@ -166,7 +172,7 @@ export async function upsertStripeSubscription({ 24 * 60 * 60 * pricingPlan.trialPeriodDays } - console.log('subscription', action, { items }) + logger.debug('subscription', action, { items }) } else { update.cancel_at_period_end = true } @@ -234,7 +240,7 @@ export async function upsertStripeSubscription({ createParams.application_fee_percent = project.applicationFeePercent } - console.log('subscription', action, { items }) + logger.debug('subscription', action, { items }) subscription = await stripe.subscriptions.create( createParams, ...stripeConnectParams @@ -244,10 +250,7 @@ export async function upsertStripeSubscription({ } assert(subscription, 500, 'Missing stripe subscription') - - console.log() - console.log('subscription', JSON.stringify(subscription, null, 2)) - console.log() + logger.debug('subscription', subscription) const consumerUpdate: ConsumerUpdate = consumer @@ -309,7 +312,7 @@ export async function upsertStripeSubscription({ pricingPlan?.metrics.find((metric) => metric.slug === metricSlug) for (const metricSlug of metricSlugs) { - console.log({ + logger.debug({ metricSlug, pricingPlan }) @@ -340,13 +343,11 @@ export async function upsertStripeSubscription({ } } - console.log() - console.log() - console.log('consumer update', { + logger.debug() + logger.debug('consumer update', { ...consumer, ...consumerUpdate }) - console.log() const [updatedConsumer] = await db .update(schema.consumers) diff --git a/apps/api/src/lib/env.ts b/apps/api/src/lib/env.ts index 6806becc..3a5dd14a 100644 --- a/apps/api/src/lib/env.ts +++ b/apps/api/src/lib/env.ts @@ -8,15 +8,13 @@ export const envSchema = z.object({ NODE_ENV: z .enum(['development', 'test', 'production']) .default('development'), + DATABASE_URL: z.string().url(), + JWT_SECRET: z.string(), PORT: z.number().default(3000), SENTRY_DSN: z.string().url(), - WORKOS_CLIENT_ID: z.string(), - WORKOS_API_KEY: z.string(), - WORKOS_SESSION_SECRET: z.string(), - STRIPE_SECRET_KEY: z.string(), STRIPE_PUBLISHABLE_KEY: z.string(), STRIPE_WEBHOOK_SECRET: z.string() diff --git a/apps/api/src/lib/logger/gcp-formatters.ts b/apps/api/src/lib/logger/gcp-formatters.ts deleted file mode 100644 index 0d584b4f..00000000 --- a/apps/api/src/lib/logger/gcp-formatters.ts +++ /dev/null @@ -1,129 +0,0 @@ -import type { pino } from 'pino' -import { EventId } from 'eventid' - -/** ========================================================================== - * GCP logging helpers taken from their official repo. - * @see https://github.com/GoogleCloudPlatform/cloud-solutions/blob/main/projects/pino-logging-gcp-config/src/pino_gcp_config.ts - * ======================================================================== */ - -/** Monotonically increasing ID for insertId. */ -const eventId = new EventId() - -const PINO_TO_GCP_LOG_LEVELS = Object.freeze( - Object.fromEntries([ - ['trace', 'DEBUG'], - ['debug', 'DEBUG'], - ['info', 'INFO'], - ['warn', 'WARNING'], - ['error', 'ERROR'], - ['fatal', 'CRITICAL'] - ]) -) as Record - -/** - * Converts pino log level to Google severity level. - * - * @see pino.LoggerOptions.formatters.level - */ -export function pinoLevelToGcpSeverity( - pinoSeverityLabel: string, - pinoSeverityLevel: number -): Record { - const pinoLevel = pinoSeverityLabel as pino.Level - const severity = PINO_TO_GCP_LOG_LEVELS[pinoLevel] ?? 'INFO' - return { - severity, - level: pinoSeverityLevel - } -} - -/** - * Creates a JSON fragment string containing the timestamp in GCP logging - * format. - * - * @example ', "timestamp": { "seconds": 123456789, "nanos": 123000000 }' - * - * Creating a string with seconds/nanos is ~10x faster than formatting the - * timestamp as an ISO string. - * - * @see https://cloud.google.com/logging/docs/agent/logging/configuration#timestamp-processing - * - * As Javascript Date uses millisecond precision, in - * {@link formatLogObject} the logger adds a monotonically increasing insertId - * into the log object to preserve log order inside GCP logging. - * - * @see https://github.com/googleapis/nodejs-logging/blob/main/src/entry.ts#L189 - */ -export function getGcpLoggingTimestamp() { - const seconds = Date.now() / 1000 - const secondsRounded = Math.floor(seconds) - - // The following line is 2x as fast as seconds % 1000 - // Uses Math.round, not Math.floor due to JS floating point... - // eg for a Date.now()=1713024754120 - // (seconds-secondsRounded)*1000 => 119.99988555908203 - const millis = Math.round((seconds - secondsRounded) * 1000) - - return `,"timestamp":{"seconds":${secondsRounded},"nanos":${millis}000000}` -} - -/** - * Reformats log entry record for GCP. - * - * * Adds OpenTelemetry properties with correct key. - * * Adds stack_trace if an Error is given in the err property. - * * Adds serviceContext - * * Adds sequential insertId to preserve logging order. - */ -export function formatGcpLogObject( - entry: Record -): Record { - // OpenTelemetry adds properties trace_id, span_id, trace_flags. If these - // are present, not null and not blank, convert them to the property keys - // specified by GCP logging. - // - // @see https://cloud.google.com/logging/docs/structured-logging#special-payload-fields - // @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#trace-context-fields - if ((entry.trace_id as string | undefined)?.length) { - entry['logging.googleapis.com/trace'] = entry.trace_id - delete entry.trace_id - } - - if ((entry.span_id as string | undefined)?.length) { - entry['logging.googleapis.com/spanId'] = entry.span_id - delete entry.span_id - } - - // Trace flags is a bit field even though there is one on defined bit, - // so lets convert it to an int and test against a bitmask. - // @see https://www.w3.org/TR/trace-context/#trace-flags - const traceFlagsBits = Number.parseInt(entry.trace_flags as string) - if (!!traceFlagsBits && (traceFlagsBits & 0x1) === 1) { - entry['logging.googleapis.com/trace_sampled'] = true - } - delete entry.trace_flags - - // If there is an Error, add the stack trace for Event Reporting. - if (entry.err instanceof Error && entry.err.stack) { - entry.stack_trace = entry.err.stack - } - - // Add a sequential EventID. - // - // This is required because Javascript Date has a very coarse granularity - // (millisecond), which makes it quite likely that multiple log entries - // would have the same timestamp. - // - // The GCP Logging API doesn't guarantee to preserve insertion order for - // entries with the same timestamp. The service does use `insertId` as a - // secondary ordering for entries with the same timestamp. `insertId` needs - // to be globally unique (within the project) however. - // - // We use a globally unique monotonically increasing EventId as the - // insertId. - // - // @see https://github.com/googleapis/nodejs-logging/blob/main/src/entry.ts#L189 - entry['logging.googleapis.com/insertId'] = eventId.new() - - return entry -} diff --git a/apps/api/src/lib/logger/gcp-transport.ts b/apps/api/src/lib/logger/gcp-transport.ts deleted file mode 100644 index 43e8cf2d..00000000 --- a/apps/api/src/lib/logger/gcp-transport.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable no-process-env */ - -import build from 'pino-abstract-transport' - -/** - * Pino transport that send logs to GCP cloud logging. - * - * Google Cloud setup and auth instructions are in the root readme. - * - * For information about Pino transports: - * @see https://getpino.io/#/docs/transports?id=writing-a-transport - */ -export default async function gcpTransport() { - // Dynamically import @google-cloud/logging only if/when this function is called - // This prevent the GCP bloatware from being loaded in prod, where this is not used. - const { Logging } = await import('@google-cloud/logging') - - const projectId = process.env.GCP_PROJECT_ID || 'agentic-426105' - const logName = process.env.GCP_LOG_NAME || 'local-dev' - - if (!process.env.METADATA_SERVER_DETECTION) { - console.error( - 'Metadata server detection is not set. Set `METADATA_SERVER_DETECTION=none` in the repo root `.env`.' - ) - } - - const logging = new Logging({ projectId }) - const log = logging.log(logName) - - return build(async function (source: AsyncIterable>) { - for await (const obj of source) { - try { - const { severity, ...rest } = obj - const entry = log.entry( - { - severity, - resource: { type: 'global' } - }, - rest - ) - await log.write(entry) - } catch (err) { - console.error( - 'Error sending log to GCP. Consult `readme.md` for setup instructions.', - err - ) - } - } - }) -} diff --git a/apps/api/src/lib/logger/logger.test.ts b/apps/api/src/lib/logger/logger.test.ts deleted file mode 100644 index 604fd460..00000000 --- a/apps/api/src/lib/logger/logger.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* eslint-disable simple-import-sort/imports */ -/* eslint-disable import/first */ - -import { afterEach, describe, expect, it, vi } from 'vitest' - -import { mockSentryNode } from '../test' - -// Mock Sentry before importing logger -mockSentryNode() - -import * as Sentry from '@sentry/node' -import { logger } from './logger' - -describe('logger', () => { - afterEach(() => { - // We only clear the usage data so it remains a spy. - vi.clearAllMocks() - }) - - it('should call Sentry.captureException when calling logger.error() with an Error', () => { - const error = new Error('test error') - logger.error(error) - expect(Sentry.captureException).toHaveBeenCalledWith(error) - }) - - it('should call Sentry.captureException when calling logger.error() with an {err: Error}', () => { - const error = new Error('test error') - logger.error({ err: error }, 'With some message') - expect(Sentry.captureException).toHaveBeenCalledWith(error) - }) - - it('should not call Sentry.captureException for logger.warn()', () => { - logger.warn('some warning message') - expect(Sentry.captureException).not.toHaveBeenCalled() - }) -}) diff --git a/apps/api/src/lib/logger/logger.ts b/apps/api/src/lib/logger/logger.ts index f8f27d35..dd56d3a1 100644 --- a/apps/api/src/lib/logger/logger.ts +++ b/apps/api/src/lib/logger/logger.ts @@ -1,116 +1,113 @@ -import fs from 'node:fs' - import * as Sentry from '@sentry/node' -import { type Logger, pino } from 'pino' -import { isBrowser, isDev, isProd } from '@/lib/env' +import type { Environment, Service } from '@/lib/types' +import { env } from '@/lib/env' -import { - formatGcpLogObject, - getGcpLoggingTimestamp, - pinoLevelToGcpSeverity -} from './gcp-formatters' import { getTraceId } from './utils' -const gcpTransportPath = `${import.meta.dirname}/gcp-transport.js` - -// TODO: Transport imports are hacky; find a better workaround -const transportExists = fs.existsSync(gcpTransportPath) - -export const logger = pino({ - messageKey: 'message', - level: isProd ? 'info' : 'trace', - timestamp: () => getGcpLoggingTimestamp(), - // Add the Sentry trace ID to the log context - mixin(_obj, _level, mixinLogger) { - try { - // Check if the logger already has a traceId in its bindings - const currentBindings = mixinLogger.bindings() - if ( - currentBindings && - typeof currentBindings === 'object' && - 'traceId' in currentBindings && - currentBindings.traceId - ) { - // If traceId already exists in bindings, use that - const traceId = currentBindings.traceId - return { traceId, meta: { traceId } } - } - - // Otherwise, get the trace ID from Sentry - const traceId = getTraceId() - - // Duplicate in the `meta` field - return traceId ? { traceId, meta: { traceId } } : {} - } catch (err) { - Sentry.captureException(err) - return {} - } - }, - formatters: { - level: pinoLevelToGcpSeverity, - log: (entry: Record) => formatGcpLogObject(entry) - }, - transport: - isDev && !isBrowser && transportExists - ? { target: gcpTransportPath } - : undefined, - hooks: { - logMethod(args, method, level) { - // Only capture errors if the log level is at least 50 (error) - if (level >= 50) { - let foundError: Error | undefined - const arg0 = args[0] as unknown - const arg1 = args[1] as unknown - - for (const arg of [arg0, arg1]) { - if (arg instanceof Error) { - foundError = arg - } else if (arg && typeof arg === 'object') { - if ('err' in arg && arg.err instanceof Error) { - foundError = arg.err - } - - if ('error' in arg && arg.error instanceof Error) { - foundError = arg.error - } - } - - if (foundError) { - break - } - } - - if (foundError) { - Sentry.captureException(foundError) - } - } - - return method.apply(this, args) - } - } -}) - -// TODO: Add more groups -export type LogGroup = 'api' - -/** Standardized way to extend the logger with helpful info */ -export function extendedLogger({ - logger: baseLogger = logger, - ...args -}: { - group: LogGroup - name: string - /** A more specific subtype of the name */ - nameSubtype?: string - /** The eventId to add to the logger */ - eventId?: string - logger?: Logger -}): Logger { - const { group, name, nameSubtype } = args - return baseLogger.child(args, { - msgPrefix: `[${group}:${name}${nameSubtype ? `:${nameSubtype}` : ''}] ` - }) +export interface Logger { + trace(message?: any, ...detail: any[]): void + debug(message?: any, ...detail: any[]): void + info(message?: any, ...detail: any[]): void + warn(message?: any, ...detail: any[]): void + error(message?: any, ...detail: any[]): void } -export type { Logger } from 'pino' +export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' + +export class ConsoleLogger implements Logger { + protected readonly environment: Environment + protected readonly service: Service + protected readonly requestId: string + protected readonly metadata: Record + protected readonly console: Console + + constructor({ + requestId, + service, + environment = env.NODE_ENV, + metadata = {}, + console = globalThis.console + }: { + requestId: string + service: Service + environment?: Environment + metadata?: Record + console?: Console + }) { + this.requestId = requestId + this.service = service + this.environment = environment + this.metadata = metadata + this.console = console + } + + trace(message?: any, ...detail: any[]) { + this.console.trace(this._marshal('trace', message, ...detail)) + } + + debug(message?: any, ...detail: any[]) { + this.console.debug(this._marshal('debug', message, ...detail)) + } + + info(message?: any, ...detail: any[]) { + this.console.info(this._marshal('info', message, ...detail)) + } + + warn(message?: any, ...detail: any[]) { + this.console.warn(this._marshal('warn', message, ...detail)) + } + + error(message?: any, ...detail: any[]) { + this.console.error(this._marshal('error', message, ...detail)) + } + + protected _marshal(level: LogLevel, message?: any, ...detail: any[]): string { + const log = { + type: 'log', + level, + message, + detail, + time: Date.now(), + env: this.environment, + service: this.service, + requestId: this.requestId, + traceId: getTraceId(), + metadata: this.metadata + } + + if (level === 'error') { + let foundError: Error | undefined + for (const arg of detail) { + if (!arg) { + continue + } + + if (arg instanceof Error) { + foundError = arg + break + } + + if (typeof arg !== 'object') { + continue + } + + if ('err' in arg && arg.err instanceof Error) { + foundError = arg.err + break + } + + if ('error' in arg && arg.error instanceof Error) { + foundError = arg.error + break + } + } + + if (foundError) { + Sentry.captureException(foundError) + } + } + + return JSON.stringify(log, null, this.environment === 'development' ? 2 : 0) + } +} diff --git a/apps/api/src/lib/logger/utils.ts b/apps/api/src/lib/logger/utils.ts index 67f7344c..8bf3f356 100644 --- a/apps/api/src/lib/logger/utils.ts +++ b/apps/api/src/lib/logger/utils.ts @@ -1,26 +1,5 @@ import * as Sentry from '@sentry/node' -/** Get the URL for the logs in the GCP console. */ -function getGCPLogsUrl(): string { - const timestamp = new Date().toISOString() - const queryParts = [ - 'resource.type = "cloud_run_revision"', - 'resource.labels.service_name = "agentic"' - ] - const traceId = getTraceId() - - if (traceId) { - queryParts.push(`jsonPayload.meta.traceId = "${traceId}"`) - } - - const query = queryParts.join(' AND ') - const url = `https://console.cloud.google.com/logs/query;query=${encodeURIComponent( - query - )};summaryFields=jsonPayload%252Fmeta%252FtraceId:false:32:beginning;aroundTime=${timestamp};duration=PT1H?project=agentic-internal-tools` - - return url -} - /** Get the ID of the trace from the root span of the current span. */ export function getTraceId(): string | undefined { try { @@ -37,18 +16,8 @@ export function getTraceId(): string | undefined { } } -/** Get the Sentry trace link for the current span. */ -function getSentryTraceURL(): string { +/** Get the Sentry trace URL for the current span. */ +export function getSentryTraceURL(): string { const traceId = getTraceId() return `https://agentic-platform.sentry.io/performance/trace/${traceId}` } - -/** - * Get the logs and trace URLs for the current event. - */ -export function getDebugURLs(): { logs: string; trace: string } { - return { - logs: getGCPLogsUrl(), - trace: getSentryTraceURL() - } -} diff --git a/apps/api/src/lib/middleware/access-logger.ts b/apps/api/src/lib/middleware/access-logger.ts index 7e724b06..795aa477 100644 --- a/apps/api/src/lib/middleware/access-logger.ts +++ b/apps/api/src/lib/middleware/access-logger.ts @@ -1,7 +1,14 @@ +import { createMiddleware } from 'hono/factory' import { logger as honoLogger } from 'hono/logger' -import { logger } from '@/lib/logger' +import type { DefaultEnv } from '@/lib/types' import { unless } from './unless' -export const accessLogger = unless(honoLogger(logger.trace), '/v1/health') +export const accessLogger = unless( + createMiddleware(async (ctx, next) => { + const logger = ctx.get('logger') + await honoLogger(logger.trace)(ctx, next) + }), + '/v1/health' +) diff --git a/apps/api/src/lib/middleware/authenticate.ts b/apps/api/src/lib/middleware/authenticate.ts index 130171b9..86be0099 100644 --- a/apps/api/src/lib/middleware/authenticate.ts +++ b/apps/api/src/lib/middleware/authenticate.ts @@ -23,7 +23,6 @@ export const authenticate = createMiddleware( assert(token, 401, 'Unauthorized') const payload = await jwt.verify(token, env.JWT_SECRET) - console.log({ payload }) assert(payload, 401, 'Unauthorized') assert(payload.type === 'user', 401, 'Unauthorized') assert( diff --git a/apps/api/src/lib/middleware/error-handler.ts b/apps/api/src/lib/middleware/error-handler.ts index 2e826bcb..e3422689 100644 --- a/apps/api/src/lib/middleware/error-handler.ts +++ b/apps/api/src/lib/middleware/error-handler.ts @@ -3,11 +3,12 @@ import * as Sentry from '@sentry/node' import { createMiddleware } from 'hono/factory' import { HTTPException } from 'hono/http-exception' -import type { AuthenticatedEnv } from '@/lib/types' +import type { DefaultEnv } from '@/lib/types' import { HttpError } from '@/lib/errors' -import { logger } from '@/lib/logger' -export const errorHandler = createMiddleware( +import { env } from '../env' + +export const errorHandler = createMiddleware( async function errorHandlerMiddleware(ctx, next) { try { await next() @@ -15,7 +16,7 @@ export const errorHandler = createMiddleware( if (!ctx.res.status) { throw new HttpError({ statusCode: 404, message: 'Not Found' }) } - } catch (err) { + } catch (err: any) { let message = 'Internal Server Error' let status: ContentfulStatusCode = 500 @@ -25,11 +26,16 @@ export const errorHandler = createMiddleware( } else if (err instanceof HttpError) { message = err.message status = err.statusCode + } else if (env.NODE_ENV === 'development' || env.NODE_ENV === 'test') { + message = err.message ?? message } + const logger = ctx.get('logger') if (status >= 500) { - logger.error({ err, status, message }) + logger.error(message, { err, status }) Sentry.captureException(err) + } else { + logger.warn(message, { err, status }) } ctx.json({ error: message }, status) diff --git a/apps/api/src/lib/middleware/index.ts b/apps/api/src/lib/middleware/index.ts index 6c94637c..8bdb5534 100644 --- a/apps/api/src/lib/middleware/index.ts +++ b/apps/api/src/lib/middleware/index.ts @@ -1,6 +1,7 @@ export * from './access-logger' export * from './authenticate' export * from './error-handler' +export * from './init' export * from './me' export * from './response-time' export * from './team' diff --git a/apps/api/src/lib/middleware/init.ts b/apps/api/src/lib/middleware/init.ts new file mode 100644 index 00000000..7a5bc522 --- /dev/null +++ b/apps/api/src/lib/middleware/init.ts @@ -0,0 +1,25 @@ +import { EventId } from 'eventid' +import { createMiddleware } from 'hono/factory' + +import type { DefaultEnv } from '@/lib/types' + +import { ConsoleLogger } from '../logger' + +/** Monotonically increasing ID for insertId. */ +const eventId = new EventId() + +export const init = createMiddleware( + async function initMiddleware(ctx, next) { + const requestId = eventId.new() + ctx.set('requestId', requestId) + ctx.res.headers.set('X-Request-Id', requestId) + + const logger = new ConsoleLogger({ + requestId, + service: 'api' + }) + ctx.set('logger', logger) + + await next() + } +) diff --git a/apps/api/src/lib/middleware/response-time.ts b/apps/api/src/lib/middleware/response-time.ts index 5f2b4e03..d70806fd 100644 --- a/apps/api/src/lib/middleware/response-time.ts +++ b/apps/api/src/lib/middleware/response-time.ts @@ -1,8 +1,8 @@ import { createMiddleware } from 'hono/factory' -import type { AuthenticatedEnv } from '@/lib/types' +import type { DefaultEnv } from '@/lib/types' -export const responseTime = createMiddleware( +export const responseTime = createMiddleware( async function responseTimeMiddleware(ctx, next) { const start = Date.now() await next() diff --git a/apps/api/src/lib/instrument.ts b/apps/api/src/lib/sentry.ts similarity index 86% rename from apps/api/src/lib/instrument.ts rename to apps/api/src/lib/sentry.ts index 1b0e1523..7466e625 100644 --- a/apps/api/src/lib/instrument.ts +++ b/apps/api/src/lib/sentry.ts @@ -7,7 +7,6 @@ import * as Sentry from '@sentry/node' Sentry.init({ dsn: process.env.SENTRY_DSN, // eslint-disable-line no-process-env environment: process.env.NODE_ENV || 'development', // eslint-disable-line no-process-env - release: process.env.COMMIT_SHA, // eslint-disable-line no-process-env tracesSampleRate: 1.0, integrations: [Sentry.extraErrorDataIntegration()] }) diff --git a/apps/api/src/lib/test/setup-mock-logger.ts b/apps/api/src/lib/test/setup-mock-logger.ts index 3986c92f..98c2eb52 100644 --- a/apps/api/src/lib/test/setup-mock-logger.ts +++ b/apps/api/src/lib/test/setup-mock-logger.ts @@ -1,20 +1,13 @@ -import type { Logger } from 'pino' import { vi } from 'vitest' +import type { Logger } from '@/lib/logger' + export function setupMockLogger() { return { - child: () => - ({ - trace: vi.fn(), - debug: vi.fn(), - info: vi.fn(), - warn: vi.fn(), - error: vi.fn() - }) as unknown as Logger, trace: vi.fn(), debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() - } as unknown as Logger + } as Logger } diff --git a/apps/api/src/lib/types.ts b/apps/api/src/lib/types.ts index ea39f9c3..0cd775a0 100644 --- a/apps/api/src/lib/types.ts +++ b/apps/api/src/lib/types.ts @@ -2,16 +2,32 @@ import type { Context } from 'hono' import type { RawTeamMember, RawUser } from '@/db' -export type AuthenticatedEnvVariables = { +import type { Env } from './env' +import type { Logger } from './logger' + +export type Environment = Env['NODE_ENV'] +export type Service = 'api' + +export type DefaultEnvVariables = { + requestId: string + logger: Logger +} + +export type AuthenticatedEnvVariables = DefaultEnvVariables & { userId: string user?: RawUser teamMember?: RawTeamMember } +export type DefaultEnv = { + Variables: DefaultEnvVariables +} + export type AuthenticatedEnv = { Variables: AuthenticatedEnvVariables } +export type DefaultContext = Context export type AuthenticatedContext = Context // TODO: currently unused diff --git a/apps/api/src/lib/utils.ts b/apps/api/src/lib/utils.ts index 5ab8536d..f8dea67f 100644 --- a/apps/api/src/lib/utils.ts +++ b/apps/api/src/lib/utils.ts @@ -1,7 +1,7 @@ import { createHash, randomUUID } from 'node:crypto' import type { ContentfulStatusCode } from 'hono/utils/http-status' -import type { ZodSchema } from 'zod' +import type { ZodSchema, ZodTypeDef } from 'zod' import { HttpError, ZodValidationError } from './errors' @@ -31,15 +31,19 @@ export function assert( } } -export function parseZodSchema( - schema: ZodSchema, +export function parseZodSchema< + Output, + Def extends ZodTypeDef = ZodTypeDef, + Input = Output +>( + schema: ZodSchema, input: unknown, { error }: { error?: string } = {} -): T { +): Output { try { return schema.parse(input) } catch (err) { diff --git a/apps/api/src/server.ts b/apps/api/src/server.ts index 110941e8..9233029a 100644 --- a/apps/api/src/server.ts +++ b/apps/api/src/server.ts @@ -1,4 +1,4 @@ -import '@/lib/instrument' +import '@/lib/sentry' import { serve } from '@hono/node-server' import { sentry } from '@hono/sentry' @@ -16,10 +16,11 @@ export const app = new OpenAPIHono() app.use(sentry()) app.use(compress()) -// app.use(middleware.accessLogger) +app.use(cors()) +app.use(middleware.init) +app.use(middleware.accessLogger) app.use(middleware.responseTime) app.use(middleware.errorHandler) -app.use(cors()) app.route('/v1', apiV1) @@ -32,6 +33,8 @@ const server = serve({ fetch: app.fetch, port: env.PORT }) + +// eslint-disable-next-line no-console console.log(`Server running on port ${env.PORT}`) initExitHooks({ server }) diff --git a/apps/api/tsconfig.json b/apps/api/tsconfig.json index 58380243..25fe1792 100644 --- a/apps/api/tsconfig.json +++ b/apps/api/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "@fisch0920/config/tsconfig-node", "compilerOptions": { - "strictNullChecks": true, "baseUrl": ".", "paths": { "@/*": ["src/*"] diff --git a/eslint.config.js b/eslint.config.js index e3403519..b0dae551 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -10,7 +10,8 @@ export default [ drizzle }, rules: { - ...drizzle.configs.recommended.rules + ...drizzle.configs.recommended.rules, + 'no-console': 'error' } } ] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c4eaac4..b94697e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,60 +6,15 @@ settings: catalogs: default: - '@fisch0920/config': - specifier: ^1.1.0 - version: 1.1.0 - '@types/node': - specifier: ^22.15.18 - version: 22.15.18 - del-cli: - specifier: ^6.0.0 - version: 6.0.0 - dotenv: - specifier: ^16.5.0 - version: 16.5.0 - eslint: - specifier: ^9.26.0 - version: 9.26.0 exit-hook: specifier: ^4.0.0 version: 4.0.0 - lint-staged: - specifier: ^16.0.0 - version: 16.0.0 - npm-run-all2: - specifier: ^8.0.1 - version: 8.0.1 - only-allow: - specifier: ^1.2.1 - version: 1.2.1 - prettier: - specifier: ^3.5.3 - version: 3.5.3 restore-cursor: specifier: ^5.1.0 version: 5.1.0 - simple-git-hooks: - specifier: ^2.13.0 - version: 2.13.0 - tsup: - specifier: ^8.4.0 - version: 8.4.0 - tsx: - specifier: ^4.19.4 - version: 4.19.4 - turbo: - specifier: ^2.5.3 - version: 2.5.3 type-fest: specifier: ^4.41.0 version: 4.41.0 - typescript: - specifier: ^5.8.3 - version: 5.8.3 - vitest: - specifier: ^3.1.3 - version: 3.1.3 zod: specifier: ^3.24.4 version: 3.24.4 @@ -134,9 +89,6 @@ importers: '@fisch0920/drizzle-zod': specifier: ^0.7.9 version: 0.7.9(@fisch0920/drizzle-orm@0.43.7(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(postgres@3.4.5))(zod@3.24.4) - '@google-cloud/logging': - specifier: ^11.2.0 - version: 11.2.0 '@hono/node-server': specifier: ^1.14.1 version: 1.14.1(hono@4.7.9) @@ -173,12 +125,6 @@ importers: p-all: specifier: ^5.0.0 version: 5.0.0 - pino: - specifier: ^9.6.0 - version: 9.6.0 - pino-abstract-transport: - specifier: ^2.0.0 - version: 2.0.0 postgres: specifier: ^3.4.5 version: 3.4.5 @@ -833,35 +779,6 @@ packages: '@fisch0920/drizzle-orm': '>=0.36.0' zod: '>=3.0.0' - '@google-cloud/common@5.0.2': - resolution: {integrity: sha512-V7bmBKYQyu0eVG2BFejuUjlBt+zrya6vtsKdY+JxMM/dNntPF41vZ9+LhOshEUH01zOHEqBSvI7Dad7ZS6aUeA==} - engines: {node: '>=14.0.0'} - - '@google-cloud/logging@11.2.0': - resolution: {integrity: sha512-Ma94jvuoMpbgNniwtelOt8w82hxK62FuOXZonEv0Hyk3B+/YVuLG/SWNyY9yMso/RXnPEc1fP2qo9kDrjf/b2w==} - engines: {node: '>=14.0.0'} - - '@google-cloud/paginator@5.0.2': - resolution: {integrity: sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==} - engines: {node: '>=14.0.0'} - - '@google-cloud/projectify@4.0.0': - resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} - engines: {node: '>=14.0.0'} - - '@google-cloud/promisify@4.1.0': - resolution: {integrity: sha512-G/FQx5cE/+DqBbOpA5jKsegGwdPniU6PuIEMt+qxWgFxvxuFOzVmp6zYchtYuwAWV5/8Dgs0yAmjvNZv3uXLQg==} - engines: {node: '>=18'} - - '@grpc/grpc-js@1.13.3': - resolution: {integrity: sha512-FTXHdOoPbZrBjlVLHuKbDZnsTxXv2BlHF57xw6LuThXacXvtkahEPED0CKMk6obZDf65Hv4k3z62eyPNpvinIg==} - engines: {node: '>=12.10.0'} - - '@grpc/proto-loader@0.7.15': - resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} - engines: {node: '>=6'} - hasBin: true - '@hono/node-server@1.14.1': resolution: {integrity: sha512-vmbuM+HPinjWzPe7FFPWMMQMsbKE9gDPhaH0FFdqbGpkT5lp++tcWDTxwBl5EgS5y6JVgIaCdjeHRfQ4XRBRjQ==} engines: {node: '>=18.14.1'} @@ -928,9 +845,6 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@js-sdsl/ordered-map@4.4.2': - resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - '@modelcontextprotocol/sdk@1.11.2': resolution: {integrity: sha512-H9vwztj5OAqHg9GockCQC06k1natgcxWQSRpQcPJf6i5+MWBzfKkRtxGbjQf0X2ihii0ffLZCRGbYV2f2bjNCQ==} engines: {node: '>=18'} @@ -1151,36 +1065,6 @@ packages: peerDependencies: '@opentelemetry/api': ^1.8 - '@protobufjs/aspromise@1.1.2': - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - - '@protobufjs/base64@1.1.2': - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - - '@protobufjs/codegen@2.0.4': - resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - - '@protobufjs/eventemitter@1.1.0': - resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - - '@protobufjs/fetch@1.1.0': - resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} - - '@protobufjs/float@1.0.2': - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - - '@protobufjs/inquire@1.1.0': - resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - - '@protobufjs/path@1.1.2': - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - - '@protobufjs/pool@1.1.0': - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - - '@protobufjs/utf8@1.1.0': - resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - '@rollup/rollup-android-arm-eabi@4.40.0': resolution: {integrity: sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==} cpu: [arm] @@ -1319,16 +1203,9 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - '@total-typescript/ts-reset@0.6.1': resolution: {integrity: sha512-cka47fVSo6lfQDIATYqb/vO1nvFfbPw7uWLayIXIhGETj0wcOOlrlkobOMDNQOFr9QOafegUPq13V2+6vtD7yg==} - '@types/caseless@0.12.5': - resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} - '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -1344,9 +1221,6 @@ packages: '@types/jsonwebtoken@9.0.9': resolution: {integrity: sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ==} - '@types/long@4.0.2': - resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} - '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -1365,18 +1239,12 @@ packages: '@types/pg@8.6.1': resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} - '@types/request@2.48.12': - resolution: {integrity: sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==} - '@types/shimmer@1.2.0': resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} '@types/tedious@4.0.14': resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - '@typescript-eslint/eslint-plugin@8.31.0': resolution: {integrity: sha512-evaQJZ/J/S4wisevDvC1KFZkPzRetH8kYZbkgcTRyql3mcKsf+ZFDV1BVWUGTCAW5pQHoqn5gK5b8kn7ou9aFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1466,10 +1334,6 @@ packages: '@vitest/utils@3.1.3': resolution: {integrity: sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==} - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -1489,14 +1353,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - - agent-base@7.1.3: - resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} - engines: {node: '>= 14'} - ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -1562,10 +1418,6 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} - arrify@2.0.1: - resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} - engines: {node: '>=8'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1577,13 +1429,6 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - atomic-sleep@1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} - available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -1599,16 +1444,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - bcryptjs@3.0.2: resolution: {integrity: sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==} hasBin: true - bignumber.js@9.3.0: - resolution: {integrity: sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA==} - body-parser@2.2.0: resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} engines: {node: '>=18'} @@ -1710,10 +1549,6 @@ packages: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1724,10 +1559,6 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - commander@13.1.0: resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} engines: {node: '>=18'} @@ -1835,10 +1666,6 @@ packages: resolution: {integrity: sha512-R6ep6JJ+eOBZsBr9esiNN1gxFbZE4Q2cULkUSFumGYecAiS6qodDvcPx/sFuWHMNul7DWmrtoEOpYSm7o6tbSA==} engines: {node: '>=18'} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -1847,10 +1674,6 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} - dot-prop@6.0.1: - resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} - engines: {node: '>=10'} - dotenv@16.5.0: resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} @@ -1952,9 +1775,6 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - duplexify@4.1.3: - resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -1984,9 +1804,6 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -2204,10 +2021,6 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -2241,9 +2054,6 @@ packages: resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} engines: {node: '>= 18'} - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2257,10 +2067,6 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-redact@3.5.0: - resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} - engines: {node: '>=6'} - fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -2307,10 +2113,6 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - form-data@2.5.3: - resolution: {integrity: sha512-XHIrMD0NpDrNM/Ckf7XJiBbLl57KEhT3+i3yY+eWm+cqYZJQTZrKo8Y8AWKnuV5GT4scfuUGt9LzNoIx3dU1nQ==} - engines: {node: '>= 0.12'} - forwarded-parse@2.1.2: resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} @@ -2337,18 +2139,6 @@ packages: functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - gaxios@6.7.1: - resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} - engines: {node: '>=14'} - - gcp-metadata@6.1.1: - resolution: {integrity: sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==} - engines: {node: '>=14'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.3.0: resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} engines: {node: '>=18'} @@ -2399,18 +2189,6 @@ packages: globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - google-auth-library@9.15.1: - resolution: {integrity: sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==} - engines: {node: '>=14'} - - google-gax@4.6.0: - resolution: {integrity: sha512-zKKLeLfcYBVOzzM48Brtn4EQkKcTli9w6c1ilzFK2NbJvcd4ATD8/XqFExImvE/W5IwMlKKwa5qqVufji3ioNQ==} - engines: {node: '>=14'} - - google-logging-utils@0.0.2: - resolution: {integrity: sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==} - engines: {node: '>=14'} - gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -2418,10 +2196,6 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - gtoken@7.1.0: - resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} - engines: {node: '>=14.0.0'} - has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -2457,25 +2231,10 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} - html-entities@2.6.0: - resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} - http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2598,10 +2357,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - is-path-cwd@3.0.0: resolution: {integrity: sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2629,10 +2384,6 @@ packages: resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - is-string@1.1.1: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} @@ -2695,9 +2446,6 @@ packages: engines: {node: '>=6'} hasBin: true - json-bigint@1.0.0: - resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} - json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -2726,15 +2474,9 @@ packages: jwa@1.4.2: resolution: {integrity: sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==} - jwa@2.0.1: - resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} - jws@3.2.2: resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} - jws@4.0.0: - resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2773,9 +2515,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} @@ -2807,9 +2546,6 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} - long@5.3.2: - resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} - loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -2851,18 +2587,10 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - mime-types@3.0.1: resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} engines: {node: '>= 0.6'} @@ -2918,15 +2646,6 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -2947,10 +2666,6 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -2979,10 +2694,6 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - on-exit-leak-free@2.1.2: - resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} - engines: {node: '>=14.0.0'} - on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -3101,16 +2812,6 @@ packages: engines: {node: '>=0.10'} hasBin: true - pino-abstract-transport@2.0.0: - resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} - - pino-std-serializers@7.0.0: - resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} - - pino@9.6.0: - resolution: {integrity: sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==} - hasBin: true - pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -3178,30 +2879,13 @@ packages: engines: {node: '>=14'} hasBin: true - process-warning@4.0.1: - resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} - prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - proto3-json-serializer@2.0.2: - resolution: {integrity: sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==} - engines: {node: '>=14.0.0'} - - protobufjs@7.5.1: - resolution: {integrity: sha512-3qx3IRjR9WPQKagdwrKjO3Gu8RgQR2qqw+1KnigWhoVjFqegIj1K3bP11sGqhxrO46/XL7lekuG4jmjL+4cLsw==} - engines: {node: '>=12.0.0'} - proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} - - pumpify@2.0.1: - resolution: {integrity: sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3213,9 +2897,6 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -3239,18 +2920,10 @@ packages: resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} engines: {node: '>=18'} - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} - real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} - reflect.getprototypeof@1.0.10: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} @@ -3270,10 +2943,6 @@ packages: resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - require-in-the-middle@7.5.2: resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} engines: {node: '>=8.6.0'} @@ -3306,10 +2975,6 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} - retry-request@7.0.2: - resolution: {integrity: sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==} - engines: {node: '>=14'} - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -3347,10 +3012,6 @@ packages: safe-regex@2.1.1: resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} - safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -3445,9 +3106,6 @@ packages: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} - sonic-boom@4.2.0: - resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -3475,10 +3133,6 @@ packages: spdx-license-ids@3.0.21: resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -3489,12 +3143,6 @@ packages: std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - stream-events@1.0.5: - resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} - - stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} - string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -3534,9 +3182,6 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -3566,9 +3211,6 @@ packages: '@types/node': optional: true - stubs@3.0.0: - resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} - sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -3582,10 +3224,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - teeny-request@9.0.0: - resolution: {integrity: sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==} - engines: {node: '>=14'} - thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -3593,9 +3231,6 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -3629,9 +3264,6 @@ packages: toucan-js@4.1.1: resolution: {integrity: sha512-GTPwEaCRN8IbYe5/VeGiwxYvMO0dKaC16fTeLbF+QGswjkLZ9JUqAfDhLMyH2SWukYhmetH+uxWa1Bhluv/evQ==} - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} @@ -3791,17 +3423,10 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -3890,15 +3515,9 @@ packages: jsdom: optional: true - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - whatwg-url@7.1.0: resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} @@ -3960,23 +3579,11 @@ packages: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - yaml@2.7.1: resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} engines: {node: '>= 14'} hasBin: true - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -4338,64 +3945,6 @@ snapshots: '@fisch0920/drizzle-orm': 0.43.7(@opentelemetry/api@1.9.0)(@types/pg@8.6.1)(postgres@3.4.5) zod: 3.24.4 - '@google-cloud/common@5.0.2': - dependencies: - '@google-cloud/projectify': 4.0.0 - '@google-cloud/promisify': 4.1.0 - arrify: 2.0.1 - duplexify: 4.1.3 - extend: 3.0.2 - google-auth-library: 9.15.1 - html-entities: 2.6.0 - retry-request: 7.0.2 - teeny-request: 9.0.0 - transitivePeerDependencies: - - encoding - - supports-color - - '@google-cloud/logging@11.2.0': - dependencies: - '@google-cloud/common': 5.0.2 - '@google-cloud/paginator': 5.0.2 - '@google-cloud/projectify': 4.0.0 - '@google-cloud/promisify': 4.1.0 - '@opentelemetry/api': 1.9.0 - arrify: 2.0.1 - dot-prop: 6.0.1 - eventid: 2.0.1 - extend: 3.0.2 - gcp-metadata: 6.1.1 - google-auth-library: 9.15.1 - google-gax: 4.6.0 - on-finished: 2.4.1 - pumpify: 2.0.1 - stream-events: 1.0.5 - uuid: 9.0.1 - transitivePeerDependencies: - - encoding - - supports-color - - '@google-cloud/paginator@5.0.2': - dependencies: - arrify: 2.0.1 - extend: 3.0.2 - - '@google-cloud/projectify@4.0.0': {} - - '@google-cloud/promisify@4.1.0': {} - - '@grpc/grpc-js@1.13.3': - dependencies: - '@grpc/proto-loader': 0.7.15 - '@js-sdsl/ordered-map': 4.4.2 - - '@grpc/proto-loader@0.7.15': - dependencies: - lodash.camelcase: 4.3.0 - long: 5.3.2 - protobufjs: 7.5.1 - yargs: 17.7.2 - '@hono/node-server@1.14.1(hono@4.7.9)': dependencies: hono: 4.7.9 @@ -4456,8 +4005,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@js-sdsl/ordered-map@4.4.2': {} - '@modelcontextprotocol/sdk@1.11.2': dependencies: content-type: 1.0.5 @@ -4743,29 +4290,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@protobufjs/aspromise@1.1.2': {} - - '@protobufjs/base64@1.1.2': {} - - '@protobufjs/codegen@2.0.4': {} - - '@protobufjs/eventemitter@1.1.0': {} - - '@protobufjs/fetch@1.1.0': - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - - '@protobufjs/float@1.0.2': {} - - '@protobufjs/inquire@1.1.0': {} - - '@protobufjs/path@1.1.2': {} - - '@protobufjs/pool@1.1.0': {} - - '@protobufjs/utf8@1.1.0': {} - '@rollup/rollup-android-arm-eabi@4.40.0': optional: true @@ -4892,12 +4416,8 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} - '@tootallnate/once@2.0.0': {} - '@total-typescript/ts-reset@0.6.1': {} - '@types/caseless@0.12.5': {} - '@types/connect@3.4.38': dependencies: '@types/node': 22.15.18 @@ -4913,8 +4433,6 @@ snapshots: '@types/ms': 2.1.0 '@types/node': 22.15.18 - '@types/long@4.0.2': {} - '@types/ms@2.1.0': {} '@types/mysql@2.15.26': @@ -4937,21 +4455,12 @@ snapshots: pg-protocol: 1.10.0 pg-types: 2.2.0 - '@types/request@2.48.12': - dependencies: - '@types/caseless': 0.12.5 - '@types/node': 22.15.18 - '@types/tough-cookie': 4.0.5 - form-data: 2.5.3 - '@types/shimmer@1.2.0': {} '@types/tedious@4.0.14': dependencies: '@types/node': 22.15.18 - '@types/tough-cookie@4.0.5': {} - '@typescript-eslint/eslint-plugin@8.31.0(@typescript-eslint/parser@8.31.0(eslint@9.26.0)(typescript@5.8.3))(eslint@9.26.0)(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -5077,10 +4586,6 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 - accepts@2.0.0: dependencies: mime-types: 3.0.1 @@ -5096,14 +4601,6 @@ snapshots: acorn@8.14.1: {} - agent-base@6.0.2: - dependencies: - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - - agent-base@7.1.3: {} - ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -5196,18 +4693,12 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 - arrify@2.0.1: {} - assertion-error@2.0.1: {} ast-types-flow@0.0.8: {} async-function@1.0.0: {} - asynckit@0.4.0: {} - - atomic-sleep@1.0.0: {} - available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 @@ -5218,12 +4709,8 @@ snapshots: balanced-match@1.0.2: {} - base64-js@1.5.1: {} - bcryptjs@3.0.2: {} - bignumber.js@9.3.0: {} - body-parser@2.2.0: dependencies: bytes: 3.1.2 @@ -5332,12 +4819,6 @@ snapshots: slice-ansi: 5.0.0 string-width: 7.2.0 - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -5346,10 +4827,6 @@ snapshots: colorette@2.0.20: {} - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - commander@13.1.0: {} commander@4.1.1: {} @@ -5445,18 +4922,12 @@ snapshots: p-map: 7.0.3 slash: 5.1.0 - delayed-stream@1.0.0: {} - depd@2.0.0: {} doctrine@2.1.0: dependencies: esutils: 2.0.3 - dot-prop@6.0.1: - dependencies: - is-obj: 2.0.0 - dotenv@16.5.0: {} drizzle-kit@0.31.1: @@ -5480,13 +4951,6 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - duplexify@4.1.3: - dependencies: - end-of-stream: 1.4.4 - inherits: 2.0.4 - readable-stream: 3.6.2 - stream-shift: 1.0.3 - eastasianwidth@0.2.0: {} ecdsa-sig-formatter@1.0.11: @@ -5507,10 +4971,6 @@ snapshots: encodeurl@2.0.0: {} - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - environment@1.1.0: {} es-abstract@1.23.9: @@ -5928,8 +5388,6 @@ snapshots: etag@1.8.1: {} - event-target-shim@5.0.1: {} - eventemitter3@5.0.1: {} eventid@2.0.1: @@ -5982,8 +5440,6 @@ snapshots: transitivePeerDependencies: - supports-color - extend@3.0.2: {} - fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -5998,8 +5454,6 @@ snapshots: fast-levenshtein@2.0.6: {} - fast-redact@3.5.0: {} - fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -6050,14 +5504,6 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data@2.5.3: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - mime-types: 2.1.35 - safe-buffer: 5.2.1 - forwarded-parse@2.1.2: {} forwarded@0.2.0: {} @@ -6080,28 +5526,6 @@ snapshots: functions-have-names@1.2.3: {} - gaxios@6.7.1: - dependencies: - extend: 3.0.2 - https-proxy-agent: 7.0.6 - is-stream: 2.0.1 - node-fetch: 2.7.0 - uuid: 9.0.1 - transitivePeerDependencies: - - encoding - - supports-color - - gcp-metadata@6.1.1: - dependencies: - gaxios: 6.7.1 - google-logging-utils: 0.0.2 - json-bigint: 1.0.0 - transitivePeerDependencies: - - encoding - - supports-color - - get-caller-file@2.0.5: {} - get-east-asian-width@1.3.0: {} get-intrinsic@1.3.0: @@ -6169,50 +5593,10 @@ snapshots: globrex@0.1.2: {} - google-auth-library@9.15.1: - dependencies: - base64-js: 1.5.1 - ecdsa-sig-formatter: 1.0.11 - gaxios: 6.7.1 - gcp-metadata: 6.1.1 - gtoken: 7.1.0 - jws: 4.0.0 - transitivePeerDependencies: - - encoding - - supports-color - - google-gax@4.6.0: - dependencies: - '@grpc/grpc-js': 1.13.3 - '@grpc/proto-loader': 0.7.15 - '@types/long': 4.0.2 - abort-controller: 3.0.0 - duplexify: 4.1.3 - google-auth-library: 9.15.1 - node-fetch: 2.7.0 - object-hash: 3.0.0 - proto3-json-serializer: 2.0.2 - protobufjs: 7.5.1 - retry-request: 7.0.2 - uuid: 9.0.1 - transitivePeerDependencies: - - encoding - - supports-color - - google-logging-utils@0.0.2: {} - gopd@1.2.0: {} graphemer@1.4.0: {} - gtoken@7.1.0: - dependencies: - gaxios: 6.7.1 - jws: 4.0.0 - transitivePeerDependencies: - - encoding - - supports-color - has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -6241,8 +5625,6 @@ snapshots: dependencies: lru-cache: 10.4.3 - html-entities@2.6.0: {} - http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -6251,28 +5633,6 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 - http-proxy-agent@5.0.0: - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.3 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color - iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -6389,8 +5749,6 @@ snapshots: is-number@7.0.0: {} - is-obj@2.0.0: {} - is-path-cwd@3.0.0: {} is-path-inside@4.0.0: {} @@ -6414,8 +5772,6 @@ snapshots: dependencies: call-bound: 1.0.4 - is-stream@2.0.1: {} - is-string@1.1.1: dependencies: call-bound: 1.0.4 @@ -6475,10 +5831,6 @@ snapshots: jsesc@3.1.0: {} - json-bigint@1.0.0: - dependencies: - bignumber.js: 9.3.0 - json-buffer@3.0.1: {} json-parse-even-better-errors@4.0.0: {} @@ -6517,22 +5869,11 @@ snapshots: ecdsa-sig-formatter: 1.0.11 safe-buffer: 5.2.1 - jwa@2.0.1: - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - jws@3.2.2: dependencies: jwa: 1.4.2 safe-buffer: 5.2.1 - jws@4.0.0: - dependencies: - jwa: 2.0.1 - safe-buffer: 5.2.1 - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -6582,8 +5923,6 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash.camelcase@4.3.0: {} - lodash.includes@4.3.0: {} lodash.isboolean@3.0.3: {} @@ -6610,8 +5949,6 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 9.0.0 - long@5.3.2: {} - loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -6641,14 +5978,8 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - mime-db@1.52.0: {} - mime-db@1.54.0: {} - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - mime-types@3.0.1: dependencies: mime-db: 1.54.0 @@ -6691,10 +6022,6 @@ snapshots: negotiator@1.0.0: {} - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - node-releases@2.0.19: {} normalize-package-data@6.0.2: @@ -6718,8 +6045,6 @@ snapshots: object-assign@4.1.1: {} - object-hash@3.0.0: {} - object-inspect@1.13.4: {} object-keys@1.1.1: {} @@ -6760,8 +6085,6 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - on-exit-leak-free@2.1.2: {} - on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -6866,26 +6189,6 @@ snapshots: pidtree@0.6.0: {} - pino-abstract-transport@2.0.0: - dependencies: - split2: 4.2.0 - - pino-std-serializers@7.0.0: {} - - pino@9.6.0: - dependencies: - atomic-sleep: 1.0.0 - fast-redact: 3.5.0 - on-exit-leak-free: 2.1.2 - pino-abstract-transport: 2.0.0 - pino-std-serializers: 7.0.0 - process-warning: 4.0.1 - quick-format-unescaped: 4.0.4 - real-require: 0.2.0 - safe-stable-stringify: 2.5.0 - sonic-boom: 4.2.0 - thread-stream: 3.1.0 - pirates@4.0.7: {} pkce-challenge@5.0.0: {} @@ -6924,49 +6227,17 @@ snapshots: prettier@3.5.3: {} - process-warning@4.0.1: {} - prop-types@15.8.1: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - proto3-json-serializer@2.0.2: - dependencies: - protobufjs: 7.5.1 - - protobufjs@7.5.1: - dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.4 - '@protobufjs/eventemitter': 1.1.0 - '@protobufjs/fetch': 1.1.0 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.0 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.0 - '@types/node': 22.15.18 - long: 5.3.2 - proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 - pump@3.0.2: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - - pumpify@2.0.1: - dependencies: - duplexify: 4.1.3 - inherits: 2.0.4 - pump: 3.0.2 - punycode@2.3.1: {} qs@6.14.0: @@ -6975,8 +6246,6 @@ snapshots: queue-microtask@1.2.3: {} - quick-format-unescaped@4.0.4: {} - range-parser@1.2.1: {} raw-body@3.0.0: @@ -7007,16 +6276,8 @@ snapshots: type-fest: 4.40.1 unicorn-magic: 0.1.0 - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - readdirp@4.1.2: {} - real-require@0.2.0: {} - reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 @@ -7045,8 +6306,6 @@ snapshots: dependencies: jsesc: 3.0.2 - require-directory@2.1.1: {} - require-in-the-middle@7.5.2: dependencies: debug: 4.4.1 @@ -7080,15 +6339,6 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 - retry-request@7.0.2: - dependencies: - '@types/request': 2.48.12 - extend: 3.0.2 - teeny-request: 9.0.0 - transitivePeerDependencies: - - encoding - - supports-color - reusify@1.1.0: {} rfdc@1.4.1: {} @@ -7158,8 +6408,6 @@ snapshots: dependencies: regexp-tree: 0.1.27 - safe-stable-stringify@2.5.0: {} - safer-buffer@2.1.2: {} semver@6.3.1: {} @@ -7273,10 +6521,6 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 5.0.0 - sonic-boom@4.2.0: - dependencies: - atomic-sleep: 1.0.0 - source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -7304,20 +6548,12 @@ snapshots: spdx-license-ids@3.0.21: {} - split2@4.2.0: {} - stackback@0.0.2: {} statuses@2.0.1: {} std-env@3.9.0: {} - stream-events@1.0.5: - dependencies: - stubs: 3.0.0 - - stream-shift@1.0.3: {} - string-argv@0.3.2: {} string-width@4.2.3: @@ -7388,10 +6624,6 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -7414,8 +6646,6 @@ snapshots: optionalDependencies: '@types/node': 22.15.18 - stubs@3.0.0: {} - sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.8 @@ -7432,17 +6662,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - teeny-request@9.0.0: - dependencies: - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - node-fetch: 2.7.0 - stream-events: 1.0.5 - uuid: 9.0.1 - transitivePeerDependencies: - - encoding - - supports-color - thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -7451,10 +6670,6 @@ snapshots: dependencies: any-promise: 1.3.0 - thread-stream@3.1.0: - dependencies: - real-require: 0.2.0 - tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -7482,8 +6697,6 @@ snapshots: '@sentry/types': 8.9.2 '@sentry/utils': 8.9.2 - tr46@0.0.3: {} - tr46@1.0.1: dependencies: punycode: 2.3.1 @@ -7652,12 +6865,8 @@ snapshots: dependencies: punycode: 2.3.1 - util-deprecate@1.0.2: {} - uuid@8.3.2: {} - uuid@9.0.1: {} - validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 @@ -7750,15 +6959,8 @@ snapshots: - tsx - yaml - webidl-conversions@3.0.1: {} - webidl-conversions@4.0.2: {} - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - whatwg-url@7.1.0: dependencies: lodash.sortby: 4.7.0 @@ -7845,22 +7047,8 @@ snapshots: xtend@4.0.2: {} - y18n@5.0.8: {} - yaml@2.7.1: {} - yargs-parser@21.1.1: {} - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - yocto-queue@0.1.0: {} zod-to-json-schema@3.24.5(zod@3.24.4): diff --git a/readme.md b/readme.md index 60854e5c..abd6d292 100644 --- a/readme.md +++ b/readme.md @@ -5,10 +5,6 @@ # Agentic -## TODO - -- simplify logger - ## License UNLICENSED PROPRIETARY © [Agentic](https://x.com/transitive_bs)