diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a887d6..4904d83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,34 @@ All notable changes to LogTide will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.5.2] - 2026-02-03 + +### Security + +- **Fastify Security Vulnerabilities**: Upgraded Fastify from 4.x to 5.7.3+ to fix critical CVEs + - CVE: Content-Type header tab character allows body validation bypass (fixed in 5.7.2) + - CVE: DoS via Unbounded Memory Allocation in sendWebStream (fixed in 5.7.3) + - Updated all @fastify/* plugins to compatible v5 versions + +### Fixed + +- **API Batch Request Limit**: Fixed `logIds must NOT have more than 100 items` error in log search tail mode + - `getLogIdentifiersBatch` now automatically splits requests into batches of 100 + - Supports up to 1000 logs in tail mode without errors + - Batches executed in parallel for performance + +- **Unicode Escape Sequences**: Fixed `unsupported Unicode escape sequence` error during log ingestion + - Sanitizes `\u0000` (null characters) from log data before PostgreSQL insertion + - Affects message, service, metadata, trace_id, and span_id fields + +- **POST Requests Without Body**: Fixed CDN/proxy compatibility issues with empty POST requests + - `disablePack`: Now sends `organizationId` in request body instead of query string + - `notification-channels/test`: Now sends `organizationId` in request body + - `resendInvitation`, `testConnection`, `leaveOrganization`: Now send empty `{}` body + - Backend routes accept `organizationId` from body or query for backwards compatibility + +--- + ## [0.5.1] - 2026-02-01 ### Added diff --git a/README.md b/README.md index b885062..0e7e3f2 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Coverage Docker Artifact Hub - Version + Version License Status Free Cloud @@ -136,7 +136,7 @@ Total control over your data. **No build required** - uses pre-built images from **Docker Images:** [Docker Hub](https://hub.docker.com/r/logtide/backend) | [GitHub Container Registry](https://github.com/logtide-dev/logtide/pkgs/container/logtide-backend) -> **Production:** Pin versions with `LOGTIDE_BACKEND_IMAGE=logtide/backend:0.5.1` in your `.env` file. +> **Production:** Pin versions with `LOGTIDE_BACKEND_IMAGE=logtide/backend:0.5.2` in your `.env` file. > **ARM64 / Raspberry Pi:** LogTide images support `linux/amd64` and `linux/arm64`. For Fluent Bit on ARM64, set `FLUENT_BIT_IMAGE=cr.fluentbit.io/fluent/fluent-bit:4.2.2` in your `.env` file. diff --git a/package.json b/package.json index 61c7e66..9deb0d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@logtide/root", - "version": "0.5.1", + "version": "0.5.2", "private": true, "description": "LogTide - Self-hosted log management platform", "author": "LogTide Team", diff --git a/packages/backend/package.json b/packages/backend/package.json index 733a65f..4a914d4 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "@logtide/backend", - "version": "0.5.1", + "version": "0.5.2", "private": true, "description": "LogTide Backend API", "type": "module", @@ -35,11 +35,11 @@ "seed:load-test": "tsx src/scripts/seed-load-test.ts" }, "dependencies": { - "@fastify/cors": "^9.0.1", - "@fastify/env": "^4.4.0", - "@fastify/helmet": "^11.1.1", - "@fastify/rate-limit": "^9.1.0", - "@fastify/websocket": "^10.0.1", + "@fastify/cors": "^10.0.2", + "@fastify/env": "^5.0.1", + "@fastify/helmet": "^13.0.1", + "@fastify/rate-limit": "^10.2.1", + "@fastify/websocket": "^11.0.2", "@logtide/sdk-node": "^0.1.0", "@logtide/shared": "workspace:*", "@maxmind/geoip2-node": "^6.3.4", @@ -47,8 +47,8 @@ "bcrypt": "^6.0.0", "bullmq": "^5.65.1", "dotenv": "^17.2.3", - "fastify": "^4.29.1", - "fastify-plugin": "^4.5.1", + "fastify": "^5.7.3", + "fastify-plugin": "^5.0.1", "graphile-worker": "^0.16.6", "ioredis": "^5.8.2", "js-yaml": "^4.1.1", diff --git a/packages/backend/src/modules/auth/plugin.ts b/packages/backend/src/modules/auth/plugin.ts index 3fa2697..d77800d 100644 --- a/packages/backend/src/modules/auth/plugin.ts +++ b/packages/backend/src/modules/auth/plugin.ts @@ -21,8 +21,8 @@ declare module 'fastify' { */ const authPlugin: FastifyPluginAsync = async (fastify) => { fastify.decorateRequest('authenticated', false); - fastify.decorateRequest('projectId', null); - fastify.decorateRequest('organizationId', null); + fastify.decorateRequest('projectId', undefined); + fastify.decorateRequest('organizationId', undefined); fastify.addHook('onRequest', async (request: FastifyRequest, reply: FastifyReply) => { // Skip auth for public routes and session-based auth routes @@ -121,5 +121,5 @@ const authPlugin: FastifyPluginAsync = async (fastify) => { export default fp(authPlugin, { name: 'auth', - fastify: '4.x', + fastify: '5.x', }); diff --git a/packages/backend/src/modules/detection-packs/routes.ts b/packages/backend/src/modules/detection-packs/routes.ts index f3ffaa0..6025c28 100644 --- a/packages/backend/src/modules/detection-packs/routes.ts +++ b/packages/backend/src/modules/detection-packs/routes.ts @@ -186,11 +186,12 @@ export async function detectionPacksRoutes(fastify: FastifyInstance) { fastify.post('/:packId/disable', async (request: any, reply) => { try { const { packId } = packIdSchema.parse(request.params); - const organizationId = request.query.organizationId as string; + // Accept from body (preferred) or query (legacy) + const organizationId = (request.body?.organizationId || request.query.organizationId) as string; if (!organizationId) { return reply.status(400).send({ - error: 'organizationId query parameter is required', + error: 'organizationId is required', }); } diff --git a/packages/backend/src/modules/ingestion/routes.ts b/packages/backend/src/modules/ingestion/routes.ts index 481dacd..e2f3980 100644 --- a/packages/backend/src/modules/ingestion/routes.ts +++ b/packages/backend/src/modules/ingestion/routes.ts @@ -171,9 +171,15 @@ const ingestionRoutes: FastifyPluginAsync = async (fastify) => { // Override default JSON parser to handle NDJSON disguised as application/json // Fluent Bit sometimes sends json_lines with application/json content-type + fastify.removeContentTypeParser('application/json'); fastify.addContentTypeParser('application/json', { parseAs: 'string' }, (_req, body, done) => { try { - const bodyStr = body.toString().trim(); + const bodyStr = body?.toString()?.trim() || ''; + if (!bodyStr) { + // Empty body - return empty object (Fastify 5 compatibility) + done(null, {}); + return; + } // Check if it looks like NDJSON (multiple lines, each starting with {) const lines = bodyStr.split('\n').filter(line => line.trim()); if (lines.length > 1 && lines.every(line => line.trim().startsWith('{'))) { @@ -225,6 +231,19 @@ const ingestionRoutes: FastifyPluginAsync = async (fastify) => { timestamp: { type: 'string' }, }, }, + 400: { + type: 'object', + properties: { + error: { type: 'string' }, + details: { type: 'object' }, + }, + }, + 401: { + type: 'object', + properties: { + error: { type: 'string' }, + }, + }, }, }, handler: async (request: any, reply) => { @@ -305,6 +324,19 @@ const ingestionRoutes: FastifyPluginAsync = async (fastify) => { timestamp: { type: 'string' }, }, }, + 400: { + type: 'object', + properties: { + error: { type: 'string' }, + details: { type: 'object' }, + }, + }, + 401: { + type: 'object', + properties: { + error: { type: 'string' }, + }, + }, }, }, handler: async (request: any, reply) => { diff --git a/packages/backend/src/modules/ingestion/service.ts b/packages/backend/src/modules/ingestion/service.ts index 90b2174..287f5ce 100644 --- a/packages/backend/src/modules/ingestion/service.ts +++ b/packages/backend/src/modules/ingestion/service.ts @@ -6,6 +6,27 @@ import { CacheManager } from '../../utils/cache.js'; import { notificationPublisher } from '../streaming/index.js'; import { correlationService, type IdentifierMatch } from '../correlation/service.js'; +/** + * Remove null characters (\u0000) that PostgreSQL doesn't support in text fields. + */ +function sanitizeForPostgres(value: T): T { + if (value === null || value === undefined) return value; + if (typeof value === 'string') { + return value.replace(/\u0000/g, '') as T; + } + if (Array.isArray(value)) { + return value.map(sanitizeForPostgres) as T; + } + if (typeof value === 'object') { + const result: Record = {}; + for (const [k, v] of Object.entries(value)) { + result[k] = sanitizeForPostgres(v); + } + return result as T; + } + return value; +} + export class IngestionService { /** * Ingest logs in batch @@ -40,16 +61,16 @@ export class IngestionService { } } - // Convert logs to database format + // Convert logs to database format (sanitize to remove \u0000 which PostgreSQL doesn't support) const dbLogs = logs.map((log) => ({ time: typeof log.time === 'string' ? new Date(log.time) : log.time, project_id: projectId, - service: log.service, + service: sanitizeForPostgres(log.service), level: log.level, - message: log.message, - metadata: log.metadata || null, - trace_id: log.trace_id || null, - span_id: (log as { span_id?: string }).span_id || null, + message: sanitizeForPostgres(log.message), + metadata: sanitizeForPostgres(log.metadata) || null, + trace_id: sanitizeForPostgres(log.trace_id) || null, + span_id: sanitizeForPostgres((log as { span_id?: string }).span_id) || null, })); // Insert logs in batch and return IDs diff --git a/packages/backend/src/modules/notification-channels/routes.ts b/packages/backend/src/modules/notification-channels/routes.ts index 2c58ac1..99b39a7 100644 --- a/packages/backend/src/modules/notification-channels/routes.ts +++ b/packages/backend/src/modules/notification-channels/routes.ts @@ -277,7 +277,8 @@ export async function notificationChannelsRoutes(fastify: FastifyInstance) { fastify.post('/:id/test', async (request: any, reply) => { try { const { id } = channelIdSchema.parse(request.params); - const organizationId = request.query.organizationId as string; + // Accept from body (preferred) or query (legacy) + const organizationId = (request.body?.organizationId || request.query.organizationId) as string; if (!organizationId) { return reply.status(400).send({ error: 'organizationId is required' }); diff --git a/packages/backend/src/modules/sigma/routes.ts b/packages/backend/src/modules/sigma/routes.ts index fd405d0..b60cefc 100644 --- a/packages/backend/src/modules/sigma/routes.ts +++ b/packages/backend/src/modules/sigma/routes.ts @@ -182,6 +182,12 @@ export async function sigmaRoutes(fastify: FastifyInstance) { }, }, response: { + 403: { + type: 'object', + properties: { + error: { type: 'string' }, + }, + }, 404: { type: 'object', properties: { @@ -347,6 +353,12 @@ export async function sigmaRoutes(fastify: FastifyInstance) { success: { type: 'boolean' }, }, }, + 403: { + type: 'object', + properties: { + error: { type: 'string' }, + }, + }, }, }, }, diff --git a/packages/backend/src/plugins/internal-logging-plugin.ts b/packages/backend/src/plugins/internal-logging-plugin.ts index 153873a..2d76024 100644 --- a/packages/backend/src/plugins/internal-logging-plugin.ts +++ b/packages/backend/src/plugins/internal-logging-plugin.ts @@ -125,6 +125,6 @@ const internalLoggingPlugin: FastifyPluginCallback = (fastify, _options, done) = }; export default fp(internalLoggingPlugin, { - fastify: '4.x', + fastify: '5.x', name: 'internal-logging-plugin', }); diff --git a/packages/backend/src/server.ts b/packages/backend/src/server.ts index 470848e..e3a66fe 100644 --- a/packages/backend/src/server.ts +++ b/packages/backend/src/server.ts @@ -48,6 +48,26 @@ export async function build(opts = {}) { ...opts, }); + // Override default JSON parser to allow empty bodies (Fastify 5 breaking change) + // This is needed because some routes may receive requests with Content-Type: application/json + // but empty body (e.g., POST requests without body from some clients) + fastify.removeContentTypeParser('application/json'); + fastify.addContentTypeParser('application/json', { parseAs: 'string' }, (_req, body, done) => { + try { + const bodyStr = body?.toString()?.trim() || ''; + if (!bodyStr) { + // Empty body - return empty object + done(null, {}); + } else { + done(null, JSON.parse(bodyStr)); + } + } catch (err: any) { + const error = new Error(`Invalid JSON: ${err.message}`); + (error as any).statusCode = 400; + done(error, undefined); + } + }); + await fastify.register(cors, { origin: true, credentials: true, @@ -88,7 +108,7 @@ export async function build(opts = {}) { return { status: 'ok', timestamp: new Date().toISOString(), - version: '0.5.1', + version: '0.5.2', }; }); diff --git a/packages/backend/src/utils/internal-logger.ts b/packages/backend/src/utils/internal-logger.ts index deabcc5..f81c515 100644 --- a/packages/backend/src/utils/internal-logger.ts +++ b/packages/backend/src/utils/internal-logger.ts @@ -54,7 +54,7 @@ export async function initializeInternalLogging(): Promise { globalMetadata: { service: process.env.SERVICE_NAME || 'logtide-backend', env: process.env.NODE_ENV || 'development', - version: process.env.npm_package_version || '0.5.1', + version: process.env.npm_package_version || '0.5.2', hostname: process.env.HOSTNAME || 'unknown', }, }); diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 9ddf488..c2c2d56 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -1,6 +1,6 @@ { "name": "@logtide/frontend", - "version": "0.5.1", + "version": "0.5.2", "private": true, "description": "LogTide Frontend Dashboard", "type": "module", diff --git a/packages/frontend/src/lib/api/admin-auth.ts b/packages/frontend/src/lib/api/admin-auth.ts index e08943f..d7c154c 100644 --- a/packages/frontend/src/lib/api/admin-auth.ts +++ b/packages/frontend/src/lib/api/admin-auth.ts @@ -106,6 +106,7 @@ export class AdminAuthAPI { async testConnection(id: string): Promise { return this.request(`/admin/auth/providers/${id}/test`, { method: 'POST', + body: JSON.stringify({}), }); } diff --git a/packages/frontend/src/lib/api/auth.ts b/packages/frontend/src/lib/api/auth.ts index ef7e6ce..bdb075f 100644 --- a/packages/frontend/src/lib/api/auth.ts +++ b/packages/frontend/src/lib/api/auth.ts @@ -91,8 +91,10 @@ export class AuthAPI { const response = await fetch(`${getApiBaseUrl()}/auth/logout`, { method: 'POST', headers: { + 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, + body: JSON.stringify({}), }); if (!response.ok) { diff --git a/packages/frontend/src/lib/api/correlation.ts b/packages/frontend/src/lib/api/correlation.ts index d12873a..24e5c0d 100644 --- a/packages/frontend/src/lib/api/correlation.ts +++ b/packages/frontend/src/lib/api/correlation.ts @@ -94,16 +94,35 @@ class CorrelationAPI { return {}; } + const BATCH_SIZE = 100; const url = `${getApiBaseUrl()}/logs/identifiers/batch`; - const response = await this.fetch<{ - success: boolean; - data: { identifiers: Record }; - }>(url, { - method: 'POST', - body: JSON.stringify({ logIds }), - }); - return response.data.identifiers; + // Split into batches of 100 to respect API limits + const batches: string[][] = []; + for (let i = 0; i < logIds.length; i += BATCH_SIZE) { + batches.push(logIds.slice(i, i + BATCH_SIZE)); + } + + // Execute all batches in parallel + const results = await Promise.all( + batches.map((batch) => + this.fetch<{ + success: boolean; + data: { identifiers: Record }; + }>(url, { + method: 'POST', + body: JSON.stringify({ logIds: batch }), + }) + ) + ); + + // Merge all results + const merged: Record = {}; + for (const response of results) { + Object.assign(merged, response.data.identifiers); + } + + return merged; } } diff --git a/packages/frontend/src/lib/api/detection-packs.ts b/packages/frontend/src/lib/api/detection-packs.ts index b66c222..8aa82bb 100644 --- a/packages/frontend/src/lib/api/detection-packs.ts +++ b/packages/frontend/src/lib/api/detection-packs.ts @@ -65,10 +65,10 @@ export class DetectionPacksAPI { } async disablePack(packId: string, organizationId: string): Promise { - return this.request( - `/api/v1/detection-packs/${packId}/disable?organizationId=${organizationId}`, - { method: 'POST' } - ); + return this.request(`/api/v1/detection-packs/${packId}/disable`, { + method: 'POST', + body: JSON.stringify({ organizationId }), + }); } async updateThresholds( diff --git a/packages/frontend/src/lib/api/invitations.ts b/packages/frontend/src/lib/api/invitations.ts index e4c5f4c..e009184 100644 --- a/packages/frontend/src/lib/api/invitations.ts +++ b/packages/frontend/src/lib/api/invitations.ts @@ -103,6 +103,7 @@ export class InvitationsAPI { async resendInvitation(organizationId: string, invitationId: string): Promise<{ success: boolean; message: string }> { return this.request(`/invitations/${organizationId}/${invitationId}/resend`, { method: 'POST', + body: JSON.stringify({}), }); } } diff --git a/packages/frontend/src/lib/api/notification-channels.ts b/packages/frontend/src/lib/api/notification-channels.ts index 76fa956..2526981 100644 --- a/packages/frontend/src/lib/api/notification-channels.ts +++ b/packages/frontend/src/lib/api/notification-channels.ts @@ -158,9 +158,9 @@ export const notificationChannelsAPI = { * Test a notification channel */ async test(id: string, organizationId: string): Promise { - const params = new URLSearchParams({ organizationId }); - const response = await fetchWithAuth(`${getApiUrl()}/api/v1/notification-channels/${id}/test?${params}`, { + const response = await fetchWithAuth(`${getApiUrl()}/api/v1/notification-channels/${id}/test`, { method: 'POST', + body: JSON.stringify({ organizationId }), }); if (!response.ok) { diff --git a/packages/frontend/src/lib/api/organizations.ts b/packages/frontend/src/lib/api/organizations.ts index 3c48a0b..ae2b22d 100644 --- a/packages/frontend/src/lib/api/organizations.ts +++ b/packages/frontend/src/lib/api/organizations.ts @@ -101,6 +101,7 @@ export class OrganizationsAPI { async leaveOrganization(organizationId: string): Promise { await this.request(`/organizations/${organizationId}/leave`, { method: 'POST', + body: JSON.stringify({}), }); } diff --git a/packages/frontend/src/lib/components/Footer.svelte b/packages/frontend/src/lib/components/Footer.svelte index 3f873b2..ecc1ead 100644 --- a/packages/frontend/src/lib/components/Footer.svelte +++ b/packages/frontend/src/lib/components/Footer.svelte @@ -1,7 +1,7 @@ diff --git a/packages/frontend/tests/fixtures/auth.ts b/packages/frontend/tests/fixtures/auth.ts index cda45f0..14ad3e3 100644 --- a/packages/frontend/tests/fixtures/auth.ts +++ b/packages/frontend/tests/fixtures/auth.ts @@ -398,6 +398,7 @@ export class TestApiClient { async resendInvitation(organizationId: string, invitationId: string) { return this.request<{ success: boolean; message: string }>(`/invitations/${organizationId}/${invitationId}/resend`, { method: 'POST', + body: JSON.stringify({}), }); } diff --git a/packages/frontend/tests/journeys/alerts.spec.ts b/packages/frontend/tests/journeys/alerts.spec.ts index 3db7c6b..6358c25 100644 --- a/packages/frontend/tests/journeys/alerts.spec.ts +++ b/packages/frontend/tests/journeys/alerts.spec.ts @@ -184,7 +184,7 @@ test.describe('Alert Journey', () => { test('5. User can delete an alert rule', async ({ page }) => { // First create an alert via API const alertName = `Delete Test Alert ${Date.now()}`; - await apiClient.createAlertRule(projectId, { + const createdAlert = await apiClient.createAlertRule(projectId, { organizationId, projectId, name: alertName, @@ -199,23 +199,37 @@ test.describe('Alert Journey', () => { await page.waitForLoadState('load'); await page.waitForTimeout(2000); - // Find and click delete button - const deleteButton = page.locator('button:has-text("Delete")').first(); - if (await deleteButton.isVisible({ timeout: 5000 }).catch(() => false)) { - await deleteButton.click(); - await page.waitForTimeout(500); + // Find the alert name in the page (CardTitle is a div with role="heading") + const alertTitle = page.locator(`div[role="heading"]:has-text("${alertName}")`).first(); + await expect(alertTitle).toBeVisible({ timeout: 5000 }); - // Confirm deletion in dialog - const confirmButton = page.locator('[role="alertdialog"] button:has-text("Delete"), [class*="AlertDialog"] button:has-text("Delete")'); - if (await confirmButton.isVisible({ timeout: 2000 }).catch(() => false)) { - await confirmButton.click(); - await page.waitForTimeout(2000); - } + // Find the card that contains this alert - go up to the Card element + // Card structure: div.grid > Card (div) > CardHeader > div > div > CardTitle + // We need to find the Delete button in the same Card + const cardWithAlert = page.locator(`div.grid.gap-4 > div:has(div[role="heading"]:has-text("${alertName}"))`).first(); + const deleteButton = cardWithAlert.locator('button:has-text("Delete")'); - // Verify the alert was deleted - const pageContent = await page.content(); - expect(pageContent).not.toContain(alertName); - } + await expect(deleteButton).toBeVisible({ timeout: 5000 }); + await deleteButton.click(); + await page.waitForTimeout(500); + + // Wait for confirmation dialog + const dialogTitle = page.locator('text=Delete Alert Rule'); + await expect(dialogTitle).toBeVisible({ timeout: 5000 }); + + // Confirm deletion + const confirmButton = page.getByRole('button', { name: 'Delete', exact: true }).last(); + await confirmButton.click(); + + // Wait for the dialog to close (indicates action was taken) + await expect(dialogTitle).toBeHidden({ timeout: 10000 }); + + // Verify via API that the alert count decreased or specific alert is gone + // This is more reliable than checking UI on CI + await page.waitForTimeout(1000); // Give backend time to process + const alerts = await apiClient.getAlertRules(organizationId, projectId); + const alertStillExists = alerts.alertRules?.some((a: any) => a.name === alertName) ?? false; + expect(alertStillExists).toBe(false); }); test('6. Alert is triggered when threshold is reached', async ({ page }) => { diff --git a/packages/shared/package.json b/packages/shared/package.json index a9c227b..e934e3f 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@logtide/shared", - "version": "0.5.1", + "version": "0.5.2", "private": true, "description": "Shared types, schemas and utilities for LogTide", "type": "module", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 36e2949..e2cf92b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,23 +23,23 @@ importers: packages/backend: dependencies: '@fastify/cors': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^10.0.2 + version: 10.1.0 '@fastify/env': - specifier: ^4.4.0 - version: 4.4.0 + specifier: ^5.0.1 + version: 5.0.3 '@fastify/helmet': - specifier: ^11.1.1 - version: 11.1.1 + specifier: ^13.0.1 + version: 13.0.2 '@fastify/rate-limit': - specifier: ^9.1.0 - version: 9.1.0 + specifier: ^10.2.1 + version: 10.3.0 '@fastify/websocket': - specifier: ^10.0.1 - version: 10.0.1 + specifier: ^11.0.2 + version: 11.2.0 '@logtide/sdk-node': specifier: ^0.1.0 - version: 0.1.1(fastify@4.29.1) + version: 0.1.1(fastify@5.7.4) '@logtide/shared': specifier: workspace:* version: link:../shared @@ -59,11 +59,11 @@ importers: specifier: ^17.2.3 version: 17.2.3 fastify: - specifier: ^4.29.1 - version: 4.29.1 + specifier: ^5.7.3 + version: 5.7.4 fastify-plugin: - specifier: ^4.5.1 - version: 4.5.1 + specifier: ^5.0.1 + version: 5.1.0 graphile-worker: specifier: ^0.16.6 version: 0.16.6(typescript@5.9.3) @@ -705,32 +705,38 @@ packages: cpu: [x64] os: [win32] - '@fastify/ajv-compiler@3.6.0': - resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} + '@fastify/ajv-compiler@4.0.5': + resolution: {integrity: sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==} - '@fastify/cors@9.0.1': - resolution: {integrity: sha512-YY9Ho3ovI+QHIL2hW+9X4XqQjXLjJqsU+sMV/xFsxZkE8p3GNnYVFpoOxF7SsP5ZL76gwvbo3V9L+FIekBGU4Q==} + '@fastify/cors@10.1.0': + resolution: {integrity: sha512-MZyBCBJtII60CU9Xme/iE4aEy8G7QpzGR8zkdXZkDFt7ElEMachbE61tfhAG/bvSaULlqlf0huMT12T7iqEmdQ==} - '@fastify/env@4.4.0': - resolution: {integrity: sha512-JEg6wo05KOhmRJ1lBTjJ8zQVUJmxInaavsMkfO1cfYWXOfdQXO48k01LneOmM5Y8dwwQ6ff7WUEi/dHl8YidIQ==} + '@fastify/env@5.0.3': + resolution: {integrity: sha512-VqXKcw+keaZaCry9dDtphDQy6l+B1UOodk4q57NdIK/tjZsPMYEBTXjEDiZCAiD9KaGJXbJOMgYdgejU1iD0jA==} - '@fastify/error@3.4.1': - resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} + '@fastify/error@4.2.0': + resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==} - '@fastify/fast-json-stringify-compiler@4.3.0': - resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} + '@fastify/fast-json-stringify-compiler@5.0.3': + resolution: {integrity: sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==} - '@fastify/helmet@11.1.1': - resolution: {integrity: sha512-pjJxjk6SLEimITWadtYIXt6wBMfFC1I6OQyH/jYVCqSAn36sgAIFjeNiibHtifjCd+e25442pObis3Rjtame6A==} + '@fastify/forwarded@3.0.1': + resolution: {integrity: sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==} - '@fastify/merge-json-schemas@0.1.1': - resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} + '@fastify/helmet@13.0.2': + resolution: {integrity: sha512-tO1QMkOfNeCt9l4sG/FiWErH4QMm+RjHzbMTrgew1DYOQ2vb/6M1G2iNABBrD7Xq6dUk+HLzWW8u+rmmhQHifA==} - '@fastify/rate-limit@9.1.0': - resolution: {integrity: sha512-h5dZWCkuZXN0PxwqaFQLxeln8/LNwQwH9popywmDCFdKfgpi4b/HoMH1lluy6P+30CG9yzzpSpwTCIPNB9T1JA==} + '@fastify/merge-json-schemas@0.2.1': + resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} - '@fastify/websocket@10.0.1': - resolution: {integrity: sha512-8/pQIxTPRD8U94aILTeJ+2O3el/r19+Ej5z1O1mXlqplsUH7KzCjAI0sgd5DM/NoPjAi5qLFNIjgM5+9/rGSNw==} + '@fastify/proxy-addr@5.1.0': + resolution: {integrity: sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==} + + '@fastify/rate-limit@10.3.0': + resolution: {integrity: sha512-eIGkG9XKQs0nyynatApA3EVrojHOuq4l6fhB4eeCk4PIOeadvOJz9/4w3vGI44Go17uaXOWEcPkaD8kuKm7g6Q==} + + '@fastify/websocket@11.2.0': + resolution: {integrity: sha512-3HrDPbAG1CzUCqnslgJxppvzaAZffieOVbLp1DAy1huCSynUWPifSvfdEDUR8HlJLp3sp1A36uOM2tJogADS8w==} '@floating-ui/core@1.7.3': resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} @@ -1468,14 +1474,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: @@ -1544,8 +1542,8 @@ packages: peerDependencies: postcss: ^8.1.0 - avvio@8.4.0: - resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} + avvio@9.1.0: + resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -1871,9 +1869,6 @@ packages: resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} engines: {node: '>=12.0.0'} - fast-content-type-parse@1.1.0: - resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} - fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -1884,8 +1879,8 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fast-json-stringify@5.16.1: - resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} + fast-json-stringify@6.2.0: + resolution: {integrity: sha512-Eaf/KNIDwHkzfyeQFNfLXJnQ7cl1XQI3+zRqmPlvtkMigbXnAcasTrvJQmquBSxKfFGeRA6PFog8t+hFmpDoWw==} fast-querystring@1.1.2: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} @@ -1893,9 +1888,6 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@2.4.0: - resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} - fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} @@ -1903,11 +1895,11 @@ packages: resolution: {integrity: sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==} hasBin: true - fastify-plugin@4.5.1: - resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} + fastify-plugin@5.1.0: + resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} - fastify@4.29.1: - resolution: {integrity: sha512-m2kMNHIG92tSNWv+Z3UeTR9AWLLuo7KctC7mlFPtMEVrfjIhmQhkQnT9v15qA/BfVq3vvj134Y0jl9SBje3jXQ==} + fastify@5.7.4: + resolution: {integrity: sha512-e6l5NsRdaEP8rdD8VR0ErJASeyaRbzXYpmkrpr2SuvuMq6Si3lvsaVy5C+7gLanEkvjpMDzBXWE5HPeb/hgTxA==} fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -1925,9 +1917,9 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - find-my-way@8.2.2: - resolution: {integrity: sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==} - engines: {node: '>=14'} + find-my-way@9.4.0: + resolution: {integrity: sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==} + engines: {node: '>=20'} foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} @@ -1941,10 +1933,6 @@ packages: resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} engines: {node: '>=14.0.0'} - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - fraction.js@5.3.4: resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} @@ -2023,9 +2011,9 @@ packages: hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - helmet@7.2.0: - resolution: {integrity: sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==} - engines: {node: '>=16.0.0'} + helmet@8.1.0: + resolution: {integrity: sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==} + engines: {node: '>=18.0.0'} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -2051,9 +2039,9 @@ packages: resolution: {integrity: sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q==} engines: {node: '>=12.22.0'} - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -2130,8 +2118,8 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-ref-resolver@1.0.1: - resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} + json-schema-ref-resolver@3.0.0: + resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==} json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -2156,8 +2144,8 @@ packages: leaflet@1.9.4: resolution: {integrity: sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==} - light-my-request@5.14.0: - resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} + light-my-request@6.6.0: + resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} @@ -2266,8 +2254,8 @@ packages: resolution: {integrity: sha512-dyAyMR+cRykZd1mw5altC9f4vKpCsuywPwo8l/L5fKqDay2zmqT0mF/BvUoXnQiqGn+nceO914rkPKJoyFnGxA==} engines: {node: '>=10', npm: '>=6'} - mnemonist@0.39.6: - resolution: {integrity: sha512-A/0v5Z59y63US00cRSLiloEIw3t5G+MiKz4BhX21FI+YBJXBOGW0ohFxTxO08dsOYlzxo87T7vGfZKYp2bcAWA==} + mnemonist@0.40.0: + resolution: {integrity: sha512-kdd8AFNig2AD5Rkih7EPCXhu/iMvwevQFX/uEiGhZyPZi7fHqOoF4V4kHLpCfysxXMgQ4B52kdPMCwARshKvEg==} mode-watcher@1.1.0: resolution: {integrity: sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g==} @@ -2449,14 +2437,14 @@ packages: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} - pino-abstract-transport@2.0.0: - resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + pino-abstract-transport@3.0.0: + resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} pino-std-serializers@7.0.0: resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} - pino@9.14.0: - resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} + pino@10.3.0: + resolution: {integrity: sha512-0GNPNzHXBKw6U/InGe79A3Crzyk9bcSyObF9/Gfo9DLEf5qj5RF50RSjsu0W1rZ6ZqRGdzDFCRBQvi9/rSGPtA==} hasBin: true pirates@4.0.7: @@ -2536,8 +2524,8 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} - process-warning@3.0.0: - resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + process-warning@4.0.1: + resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} @@ -2549,10 +2537,6 @@ packages: resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} engines: {node: '>=12.0.0'} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2619,10 +2603,6 @@ packages: engines: {node: '>= 0.4'} hasBin: true - ret@0.4.3: - resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} - engines: {node: '>=10'} - ret@0.5.0: resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} engines: {node: '>=10'} @@ -2662,9 +2642,6 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-regex2@3.1.0: - resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} - safe-regex2@5.0.0: resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} @@ -2675,8 +2652,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - secure-json-parse@2.7.0: - resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + secure-json-parse@4.1.0: + resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} @@ -2860,8 +2837,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + thread-stream@4.0.0: + resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==} + engines: {node: '>=20'} tiny-lru@11.4.5: resolution: {integrity: sha512-hkcz3FjNJfKXjV4mjQ1OrXSLAehg8Hw+cEZclOVT+5c/cWQWImQ9wolzTjth+dmmDe++p3bme3fTxz6Q4Etsqw==} @@ -3702,47 +3680,54 @@ snapshots: '@esbuild/win32-x64@0.27.0': optional: true - '@fastify/ajv-compiler@3.6.0': + '@fastify/ajv-compiler@4.0.5': dependencies: ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - fast-uri: 2.4.0 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-uri: 3.1.0 - '@fastify/cors@9.0.1': + '@fastify/cors@10.1.0': dependencies: - fastify-plugin: 4.5.1 - mnemonist: 0.39.6 + fastify-plugin: 5.1.0 + mnemonist: 0.40.0 - '@fastify/env@4.4.0': + '@fastify/env@5.0.3': dependencies: env-schema: 6.1.0 - fastify-plugin: 4.5.1 + fastify-plugin: 5.1.0 - '@fastify/error@3.4.1': {} + '@fastify/error@4.2.0': {} - '@fastify/fast-json-stringify-compiler@4.3.0': + '@fastify/fast-json-stringify-compiler@5.0.3': dependencies: - fast-json-stringify: 5.16.1 + fast-json-stringify: 6.2.0 + + '@fastify/forwarded@3.0.1': {} - '@fastify/helmet@11.1.1': + '@fastify/helmet@13.0.2': dependencies: - fastify-plugin: 4.5.1 - helmet: 7.2.0 + fastify-plugin: 5.1.0 + helmet: 8.1.0 - '@fastify/merge-json-schemas@0.1.1': + '@fastify/merge-json-schemas@0.2.1': dependencies: - fast-deep-equal: 3.1.3 + dequal: 2.0.3 + + '@fastify/proxy-addr@5.1.0': + dependencies: + '@fastify/forwarded': 3.0.1 + ipaddr.js: 2.3.0 - '@fastify/rate-limit@9.1.0': + '@fastify/rate-limit@10.3.0': dependencies: '@lukeed/ms': 2.0.2 - fastify-plugin: 4.5.1 + fastify-plugin: 5.1.0 toad-cache: 3.7.0 - '@fastify/websocket@10.0.1': + '@fastify/websocket@11.2.0': dependencies: duplexify: 4.1.3 - fastify-plugin: 4.5.1 + fastify-plugin: 5.1.0 ws: 8.18.3 transitivePeerDependencies: - bufferutil @@ -3797,9 +3782,9 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@logtide/sdk-node@0.1.1(fastify@4.29.1)': + '@logtide/sdk-node@0.1.1(fastify@5.7.4)': optionalDependencies: - fastify: 4.29.1 + fastify: 5.7.4 '@lucide/svelte@0.482.0(svelte@5.45.3)': dependencies: @@ -4567,10 +4552,6 @@ snapshots: acorn@8.15.0: {} - ajv-formats@2.1.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 - ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -4627,9 +4608,9 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 - avvio@8.4.0: + avvio@9.1.0: dependencies: - '@fastify/error': 3.4.1 + '@fastify/error': 4.2.0 fastq: 1.19.1 axobject-query@4.1.0: {} @@ -4984,8 +4965,6 @@ snapshots: expect-type@1.2.2: {} - fast-content-type-parse@1.1.0: {} - fast-decode-uri-component@1.0.1: {} fast-deep-equal@3.1.3: {} @@ -4998,14 +4977,13 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-json-stringify@5.16.1: + fast-json-stringify@6.2.0: dependencies: - '@fastify/merge-json-schemas': 0.1.1 + '@fastify/merge-json-schemas': 0.2.1 ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) - fast-deep-equal: 3.1.3 - fast-uri: 2.4.0 - json-schema-ref-resolver: 1.0.1 + fast-uri: 3.1.0 + json-schema-ref-resolver: 3.0.0 rfdc: 1.4.1 fast-querystring@1.1.2: @@ -5014,32 +4992,29 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@2.4.0: {} - fast-uri@3.1.0: {} fast-xml-parser@5.3.4: dependencies: strnum: 2.1.1 - fastify-plugin@4.5.1: {} + fastify-plugin@5.1.0: {} - fastify@4.29.1: + fastify@5.7.4: dependencies: - '@fastify/ajv-compiler': 3.6.0 - '@fastify/error': 3.4.1 - '@fastify/fast-json-stringify-compiler': 4.3.0 + '@fastify/ajv-compiler': 4.0.5 + '@fastify/error': 4.2.0 + '@fastify/fast-json-stringify-compiler': 5.0.3 + '@fastify/proxy-addr': 5.1.0 abstract-logging: 2.0.1 - avvio: 8.4.0 - fast-content-type-parse: 1.1.0 - fast-json-stringify: 5.16.1 - find-my-way: 8.2.2 - light-my-request: 5.14.0 - pino: 9.14.0 - process-warning: 3.0.0 - proxy-addr: 2.0.7 + avvio: 9.1.0 + fast-json-stringify: 6.2.0 + find-my-way: 9.4.0 + light-my-request: 6.6.0 + pino: 10.3.0 + process-warning: 5.0.0 rfdc: 1.4.1 - secure-json-parse: 2.7.0 + secure-json-parse: 4.1.0 semver: 7.7.3 toad-cache: 3.7.0 @@ -5055,11 +5030,11 @@ snapshots: dependencies: to-regex-range: 5.0.1 - find-my-way@8.2.2: + find-my-way@9.4.0: dependencies: fast-deep-equal: 3.1.3 fast-querystring: 1.1.2 - safe-regex2: 3.1.0 + safe-regex2: 5.0.0 foreground-child@3.3.1: dependencies: @@ -5080,8 +5055,6 @@ snapshots: dezalgo: 1.0.4 once: 1.4.0 - forwarded@0.2.0: {} - fraction.js@5.3.4: {} fsevents@2.3.2: @@ -5195,7 +5168,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 - helmet@7.2.0: {} + helmet@8.1.0: {} html-escaper@2.0.2: {} @@ -5226,7 +5199,7 @@ snapshots: transitivePeerDependencies: - supports-color - ipaddr.js@1.9.1: {} + ipaddr.js@2.3.0: {} is-arrayish@0.2.1: {} @@ -5299,9 +5272,9 @@ snapshots: json-parse-even-better-errors@2.3.1: {} - json-schema-ref-resolver@1.0.1: + json-schema-ref-resolver@3.0.0: dependencies: - fast-deep-equal: 3.1.3 + dequal: 2.0.3 json-schema-traverse@1.0.0: {} @@ -5324,10 +5297,10 @@ snapshots: leaflet@1.9.4: {} - light-my-request@5.14.0: + light-my-request@6.6.0: dependencies: cookie: 0.7.2 - process-warning: 3.0.0 + process-warning: 4.0.1 set-cookie-parser: 2.7.2 lilconfig@3.1.3: {} @@ -5427,7 +5400,7 @@ snapshots: mmdb-lib@3.0.1: {} - mnemonist@0.39.6: + mnemonist@0.40.0: dependencies: obliterator: 2.0.5 @@ -5588,25 +5561,25 @@ snapshots: pify@2.3.0: {} - pino-abstract-transport@2.0.0: + pino-abstract-transport@3.0.0: dependencies: split2: 4.2.0 pino-std-serializers@7.0.0: {} - pino@9.14.0: + pino@10.3.0: dependencies: '@pinojs/redact': 0.4.0 atomic-sleep: 1.0.0 on-exit-leak-free: 2.1.2 - pino-abstract-transport: 2.0.0 + pino-abstract-transport: 3.0.0 pino-std-serializers: 7.0.0 process-warning: 5.0.0 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 + thread-stream: 4.0.0 pirates@4.0.7: {} @@ -5666,7 +5639,7 @@ snapshots: dependencies: xtend: 4.0.2 - process-warning@3.0.0: {} + process-warning@4.0.1: {} process-warning@5.0.0: {} @@ -5687,11 +5660,6 @@ snapshots: '@types/node': 20.19.25 long: 5.3.2 - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - punycode@2.3.1: {} qs@6.14.1: @@ -5748,8 +5716,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - ret@0.4.3: {} - ret@0.5.0: {} reusify@1.1.0: {} @@ -5808,10 +5774,6 @@ snapshots: safe-buffer@5.2.1: {} - safe-regex2@3.1.0: - dependencies: - ret: 0.4.3 - safe-regex2@5.0.0: dependencies: ret: 0.5.0 @@ -5820,7 +5782,7 @@ snapshots: safer-buffer@2.1.2: {} - secure-json-parse@2.7.0: {} + secure-json-parse@4.1.0: {} semver@7.7.3: {} @@ -6067,7 +6029,7 @@ snapshots: dependencies: any-promise: 1.3.0 - thread-stream@3.1.0: + thread-stream@4.0.0: dependencies: real-require: 0.2.0