diff --git a/.changeset/orange-eagles-tap.md b/.changeset/orange-eagles-tap.md new file mode 100644 index 000000000..7a21eec33 --- /dev/null +++ b/.changeset/orange-eagles-tap.md @@ -0,0 +1,5 @@ +--- +'@powersync/lib-services-framework': minor +--- + +Added disposable listeners and observers diff --git a/.changeset/popular-snails-cough.md b/.changeset/popular-snails-cough.md new file mode 100644 index 000000000..5dc9e2d4d --- /dev/null +++ b/.changeset/popular-snails-cough.md @@ -0,0 +1,6 @@ +--- +'@powersync/service-core': minor +'@powersync/service-sync-rules': minor +--- + +Added ability to emit data replication events diff --git a/.changeset/sour-turkeys-collect.md b/.changeset/sour-turkeys-collect.md new file mode 100644 index 000000000..d9bc279fb --- /dev/null +++ b/.changeset/sour-turkeys-collect.md @@ -0,0 +1,7 @@ +--- +'@powersync/service-module-postgres': patch +'@powersync/service-rsocket-router': patch +'@powersync/service-types': patch +--- + +Updates from Replication events changes diff --git a/libs/lib-services/src/utils/BaseObserver.ts b/libs/lib-services/src/utils/BaseObserver.ts index 4c5b689ce..937fde59a 100644 --- a/libs/lib-services/src/utils/BaseObserver.ts +++ b/libs/lib-services/src/utils/BaseObserver.ts @@ -1,6 +1,10 @@ import { v4 as uuid } from 'uuid'; -export class BaseObserver { +export interface ObserverClient { + registerListener(listener: Partial): () => void; +} + +export class BaseObserver implements ObserverClient { protected listeners: { [id: string]: Partial }; constructor() { diff --git a/libs/lib-services/src/utils/DisposableObserver.ts b/libs/lib-services/src/utils/DisposableObserver.ts new file mode 100644 index 000000000..1440d57e7 --- /dev/null +++ b/libs/lib-services/src/utils/DisposableObserver.ts @@ -0,0 +1,37 @@ +import { BaseObserver, ObserverClient } from './BaseObserver.js'; + +export interface DisposableListener { + /** + * Event which is fired when the `[Symbol.disposed]` method is called. + */ + disposed: () => void; +} + +export interface DisposableObserverClient extends ObserverClient, Disposable { + /** + * Registers a listener that is automatically disposed when the parent is disposed. + * This is useful for disposing nested listeners. + */ + registerManagedListener: (parent: DisposableObserverClient, cb: Partial) => () => void; +} + +export class DisposableObserver + extends BaseObserver + implements DisposableObserverClient +{ + registerManagedListener(parent: DisposableObserverClient, cb: Partial) { + const disposer = this.registerListener(cb); + parent.registerListener({ + disposed: () => { + disposer(); + } + }); + return disposer; + } + + [Symbol.dispose]() { + this.iterateListeners((cb) => cb.disposed?.()); + // Delete all callbacks + Object.keys(this.listeners).forEach((key) => delete this.listeners[key]); + } +} diff --git a/libs/lib-services/src/utils/utils-index.ts b/libs/lib-services/src/utils/utils-index.ts index ee42d4057..59b89d274 100644 --- a/libs/lib-services/src/utils/utils-index.ts +++ b/libs/lib-services/src/utils/utils-index.ts @@ -1,2 +1,3 @@ export * from './BaseObserver.js'; +export * from './DisposableObserver.js'; export * from './environment-variables.js'; diff --git a/libs/lib-services/test/src/DisposeableObserver.test.ts b/libs/lib-services/test/src/DisposeableObserver.test.ts new file mode 100644 index 000000000..1cde6a58b --- /dev/null +++ b/libs/lib-services/test/src/DisposeableObserver.test.ts @@ -0,0 +1,58 @@ +import { describe, expect, test } from 'vitest'; + +import { DisposableListener, DisposableObserver } from '../../src/utils/DisposableObserver.js'; + +describe('DisposableObserver', () => { + test('it should dispose all listeners on dispose', () => { + const listener = new DisposableObserver(); + + let wasDisposed = false; + listener.registerListener({ + disposed: () => { + wasDisposed = true; + } + }); + + listener[Symbol.dispose](); + + expect(wasDisposed).equals(true); + expect(Object.keys(listener['listeners']).length).equals(0); + }); + + test('it should dispose nested listeners for managed listeners', () => { + interface ParentListener extends DisposableListener { + childCreated: (child: DisposableObserver) => void; + } + class ParentObserver extends DisposableObserver { + createChild() { + const child = new DisposableObserver(); + this.iterateListeners((cb) => cb.childCreated?.(child)); + } + } + + const parent = new ParentObserver(); + let aChild: DisposableObserver | null = null; + + parent.registerListener({ + childCreated: (child) => { + aChild = child; + child.registerManagedListener(parent, { + test: () => { + // this does nothing + } + }); + } + }); + + parent.createChild(); + + // The managed listener should add a `disposed` listener + expect(Object.keys(parent['listeners']).length).equals(2); + expect(Object.keys(aChild!['listeners']).length).equals(1); + + parent[Symbol.dispose](); + expect(Object.keys(parent['listeners']).length).equals(0); + // The listener attached to the child should be disposed when the parent was disposed + expect(Object.keys(aChild!['listeners']).length).equals(0); + }); +}); diff --git a/modules/module-postgres/src/module/PostgresModule.ts b/modules/module-postgres/src/module/PostgresModule.ts index 5dc0caf79..eabffca0a 100644 --- a/modules/module-postgres/src/module/PostgresModule.ts +++ b/modules/module-postgres/src/module/PostgresModule.ts @@ -1,20 +1,13 @@ -import { - api, - auth, - ConfigurationFileSyncRulesProvider, - replication, - system, - TearDownOptions -} from '@powersync/service-core'; +import { api, auth, ConfigurationFileSyncRulesProvider, modules, replication, system } from '@powersync/service-core'; import * as jpgwire from '@powersync/service-jpgwire'; -import * as types from '../types/types.js'; import { PostgresRouteAPIAdapter } from '../api/PostgresRouteAPIAdapter.js'; import { SupabaseKeyCollector } from '../auth/SupabaseKeyCollector.js'; -import { WalStreamReplicator } from '../replication/WalStreamReplicator.js'; import { ConnectionManagerFactory } from '../replication/ConnectionManagerFactory.js'; +import { PgManager } from '../replication/PgManager.js'; import { PostgresErrorRateLimiter } from '../replication/PostgresErrorRateLimiter.js'; import { cleanUpReplicationSlot } from '../replication/replication-utils.js'; -import { PgManager } from '../replication/PgManager.js'; +import { WalStreamReplicator } from '../replication/WalStreamReplicator.js'; +import * as types from '../types/types.js'; export class PostgresModule extends replication.ReplicationModule { constructor() { @@ -70,7 +63,7 @@ export class PostgresModule extends replication.ReplicationModule { + async teardown(options: modules.TearDownOptions): Promise { const normalisedConfig = this.resolveConfig(this.decodedConfig!); const connectionManager = new PgManager(normalisedConfig, { idleTimeout: 30_000, diff --git a/modules/module-postgres/src/replication/WalStream.ts b/modules/module-postgres/src/replication/WalStream.ts index cd856c2c8..80b11df0e 100644 --- a/modules/module-postgres/src/replication/WalStream.ts +++ b/modules/module-postgres/src/replication/WalStream.ts @@ -1,11 +1,11 @@ -import * as pgwire from '@powersync/service-jpgwire'; -import * as util from '../utils/pgwire_utils.js'; import { container, errors, logger } from '@powersync/lib-services-framework'; +import { getUuidReplicaIdentityBson, Metrics, SourceEntityDescriptor, storage } from '@powersync/service-core'; +import * as pgwire from '@powersync/service-jpgwire'; import { DatabaseInputRow, SqliteRow, SqlSyncRules, TablePattern, toSyncRulesRow } from '@powersync/service-sync-rules'; +import * as pg_utils from '../utils/pgwire_utils.js'; +import { PgManager } from './PgManager.js'; import { getPgOutputRelation, getRelId } from './PgRelation.js'; -import { getUuidReplicaIdentityBson, Metrics, SourceEntityDescriptor, storage } from '@powersync/service-core'; import { checkSourceConfiguration, getReplicationIdentityColumns } from './replication-utils.js'; -import { PgManager } from './PgManager.js'; export const ZERO_LSN = '00000000/00000000'; export const PUBLICATION_NAME = 'powersync'; @@ -60,7 +60,7 @@ export class WalStream { // Ping to speed up cancellation of streaming replication // We're not using pg_snapshot here, since it could be in the middle of // an initial replication transaction. - const promise = util.retriedQuery( + const promise = pg_utils.retriedQuery( this.connections.pool, `SELECT * FROM pg_logical_emit_message(false, 'powersync', 'ping')` ); @@ -347,7 +347,6 @@ WHERE oid = $1::regclass`, for (let table of tables) { await this.snapshotTable(batch, db, table); await batch.markSnapshotDone([table], lsn); - await touch(); } } @@ -395,7 +394,7 @@ WHERE oid = $1::regclass`, throw new Error(`Aborted initial replication of ${this.slot_name}`); } - for (let record of WalStream.getQueryData(rows)) { + for (const record of WalStream.getQueryData(rows)) { // This auto-flushes when the batch reaches its size limit await batch.save({ tag: 'insert', @@ -406,6 +405,7 @@ WHERE oid = $1::regclass`, afterReplicaId: getUuidReplicaIdentityBson(record, table.replicaIdColumns) }); } + at += rows.length; Metrics.getInstance().rows_replicated_total.add(rows.length); @@ -495,7 +495,7 @@ WHERE oid = $1::regclass`, if (msg.tag == 'insert') { Metrics.getInstance().rows_replicated_total.add(1); - const baseRecord = util.constructAfterRecord(msg); + const baseRecord = pg_utils.constructAfterRecord(msg); return await batch.save({ tag: 'insert', sourceTable: table, @@ -508,8 +508,8 @@ WHERE oid = $1::regclass`, Metrics.getInstance().rows_replicated_total.add(1); // "before" may be null if the replica id columns are unchanged // It's fine to treat that the same as an insert. - const before = util.constructBeforeRecord(msg); - const after = util.constructAfterRecord(msg); + const before = pg_utils.constructBeforeRecord(msg); + const after = pg_utils.constructAfterRecord(msg); return await batch.save({ tag: 'update', sourceTable: table, @@ -520,7 +520,7 @@ WHERE oid = $1::regclass`, }); } else if (msg.tag == 'delete') { Metrics.getInstance().rows_replicated_total.add(1); - const before = util.constructBeforeRecord(msg)!; + const before = pg_utils.constructBeforeRecord(msg)!; return await batch.save({ tag: 'delete', @@ -592,7 +592,6 @@ WHERE oid = $1::regclass`, // chunkLastLsn may come from normal messages in the chunk, // or from a PrimaryKeepalive message. const { messages, lastLsn: chunkLastLsn } = chunk; - for (const msg of messages) { if (msg.tag == 'relation') { await this.handleRelation(batch, getPgOutputRelation(msg), true); @@ -609,7 +608,7 @@ WHERE oid = $1::regclass`, } count += 1; - const result = await this.writeChange(batch, msg); + await this.writeChange(batch, msg); } } diff --git a/modules/module-postgres/src/replication/WalStreamReplicationJob.ts b/modules/module-postgres/src/replication/WalStreamReplicationJob.ts index 8d82840d6..40247452a 100644 --- a/modules/module-postgres/src/replication/WalStreamReplicationJob.ts +++ b/modules/module-postgres/src/replication/WalStreamReplicationJob.ts @@ -1,6 +1,6 @@ -import { MissingReplicationSlotError, WalStream } from './WalStream.js'; import { container } from '@powersync/lib-services-framework'; import { PgManager } from './PgManager.js'; +import { MissingReplicationSlotError, WalStream } from './WalStream.js'; import { replication } from '@powersync/service-core'; import { ConnectionManagerFactory } from './ConnectionManagerFactory.js'; diff --git a/modules/module-postgres/src/replication/WalStreamReplicator.ts b/modules/module-postgres/src/replication/WalStreamReplicator.ts index fb068ba14..14a21725e 100644 --- a/modules/module-postgres/src/replication/WalStreamReplicator.ts +++ b/modules/module-postgres/src/replication/WalStreamReplicator.ts @@ -1,7 +1,7 @@ -import { storage, replication } from '@powersync/service-core'; -import { WalStreamReplicationJob } from './WalStreamReplicationJob.js'; +import { replication, storage } from '@powersync/service-core'; import { ConnectionManagerFactory } from './ConnectionManagerFactory.js'; import { cleanUpReplicationSlot } from './replication-utils.js'; +import { WalStreamReplicationJob } from './WalStreamReplicationJob.js'; export interface WalStreamReplicatorOptions extends replication.AbstractReplicatorOptions { connectionFactory: ConnectionManagerFactory; diff --git a/modules/module-postgres/test/src/slow_tests.test.ts b/modules/module-postgres/test/src/slow_tests.test.ts index ad7c6753d..7c5bad017 100644 --- a/modules/module-postgres/test/src/slow_tests.test.ts +++ b/modules/module-postgres/test/src/slow_tests.test.ts @@ -2,16 +2,16 @@ import * as bson from 'bson'; import { afterEach, describe, expect, test } from 'vitest'; import { WalStream, WalStreamOptions } from '../../src/replication/WalStream.js'; import { env } from './env.js'; -import { TEST_CONNECTION_OPTIONS, clearTestDb, connectPgPool, getClientCheckpoint } from './util.js'; +import { clearTestDb, connectPgPool, getClientCheckpoint, TEST_CONNECTION_OPTIONS } from './util.js'; import * as pgwire from '@powersync/service-jpgwire'; import { SqliteRow } from '@powersync/service-sync-rules'; import { mapOpEntry, MongoBucketStorage } from '@/storage/storage-index.js'; -import * as timers from 'node:timers/promises'; +import { reduceBucket, validateCompactedBucket } from '@core-tests/bucket_validation.js'; import { MONGO_STORAGE_FACTORY, StorageFactory } from '@core-tests/util.js'; import { PgManager } from '@module/replication/PgManager.js'; -import { reduceBucket, validateCompactedBucket } from '@core-tests/bucket_validation.js'; +import * as timers from 'node:timers/promises'; describe('slow tests - mongodb', function () { // These are slow, inconsistent tests. @@ -82,7 +82,7 @@ bucket_definitions: - SELECT * FROM "test_data" `; const syncRules = await f.updateSyncRules({ content: syncRuleContent }); - const storage = f.getInstance(syncRules); + using storage = f.getInstance(syncRules); abortController = new AbortController(); const options: WalStreamOptions = { abort_signal: abortController.signal, @@ -234,7 +234,7 @@ bucket_definitions: - SELECT id, description FROM "test_data" `; const syncRules = await f.updateSyncRules({ content: syncRuleContent }); - const storage = f.getInstance(syncRules); + using storage = f.getInstance(syncRules); // 1. Setup some base data that will be replicated in initial replication await pool.query(`CREATE TABLE test_data(id uuid primary key default uuid_generate_v4(), description text)`); diff --git a/modules/module-postgres/test/src/util.ts b/modules/module-postgres/test/src/util.ts index d4e2b7170..c8142739d 100644 --- a/modules/module-postgres/test/src/util.ts +++ b/modules/module-postgres/test/src/util.ts @@ -1,11 +1,11 @@ +import { connectMongo } from '@core-tests/util.js'; import * as types from '@module/types/types.js'; import * as pg_utils from '@module/utils/pgwire_utils.js'; +import { logger } from '@powersync/lib-services-framework'; import { BucketStorageFactory, Metrics, MongoBucketStorage, OpId } from '@powersync/service-core'; import * as pgwire from '@powersync/service-jpgwire'; -import { env } from './env.js'; import { pgwireRows } from '@powersync/service-jpgwire'; -import { logger } from '@powersync/lib-services-framework'; -import { connectMongo } from '@core-tests/util.js'; +import { env } from './env.js'; // The metrics need to be initialized before they can be used await Metrics.initialise({ @@ -35,7 +35,9 @@ export const INITIALIZED_MONGO_STORAGE_FACTORY: StorageFactory = async () => { await db.clear(); - return new MongoBucketStorage(db, { slot_name_prefix: 'test_' }); + return new MongoBucketStorage(db, { + slot_name_prefix: 'test_' + }); }; export async function clearTestDb(db: pgwire.PgClient) { diff --git a/modules/module-postgres/test/src/wal_stream_utils.ts b/modules/module-postgres/test/src/wal_stream_utils.ts index 8af286baa..23eced2e7 100644 --- a/modules/module-postgres/test/src/wal_stream_utils.ts +++ b/modules/module-postgres/test/src/wal_stream_utils.ts @@ -1,9 +1,9 @@ -import { BucketStorageFactory, SyncRulesBucketStorage } from '@powersync/service-core'; -import * as pgwire from '@powersync/service-jpgwire'; -import { TEST_CONNECTION_OPTIONS, clearTestDb, getClientCheckpoint } from './util.js'; -import { WalStream, WalStreamOptions, PUBLICATION_NAME } from '@module/replication/WalStream.js'; import { fromAsync } from '@core-tests/stream_utils.js'; import { PgManager } from '@module/replication/PgManager.js'; +import { PUBLICATION_NAME, WalStream, WalStreamOptions } from '@module/replication/WalStream.js'; +import { BucketStorageFactory, SyncRulesBucketStorage } from '@powersync/service-core'; +import * as pgwire from '@powersync/service-jpgwire'; +import { clearTestDb, getClientCheckpoint, TEST_CONNECTION_OPTIONS } from './util.js'; /** * Tests operating on the wal stream need to configure the stream and manage asynchronous @@ -20,16 +20,12 @@ export function walStreamTest( const connectionManager = new PgManager(TEST_CONNECTION_OPTIONS, {}); await clearTestDb(connectionManager.pool); - const context = new WalStreamTestContext(f, connectionManager); - try { - await test(context); - } finally { - await context.dispose(); - } + await using context = new WalStreamTestContext(f, connectionManager); + await test(context); }; } -export class WalStreamTestContext { +export class WalStreamTestContext implements AsyncDisposable { private _walStream?: WalStream; private abortController = new AbortController(); private streamPromise?: Promise; @@ -41,10 +37,11 @@ export class WalStreamTestContext { public connectionManager: PgManager ) {} - async dispose() { + async [Symbol.asyncDispose]() { this.abortController.abort(); await this.streamPromise; await this.connectionManager.destroy(); + this.storage?.[Symbol.dispose](); } get pool() { diff --git a/packages/service-core/src/api/diagnostics.ts b/packages/service-core/src/api/diagnostics.ts index 2ebf5ada5..d323fcf81 100644 --- a/packages/service-core/src/api/diagnostics.ts +++ b/packages/service-core/src/api/diagnostics.ts @@ -57,7 +57,7 @@ export async function getSyncRulesStatus( // This method can run under some situations if no connection is configured yet. // It will return a default tag in such a case. This default tag is not module specific. const tag = sourceConfig.tag ?? DEFAULT_TAG; - const systemStorage = live_status ? bucketStorage.getInstance(sync_rules) : undefined; + using systemStorage = live_status ? bucketStorage.getInstance(sync_rules) : undefined; const status = await systemStorage?.getStatus(); let replication_lag_bytes: number | undefined = undefined; diff --git a/packages/service-core/src/entry/commands/compact-action.ts b/packages/service-core/src/entry/commands/compact-action.ts index e5f34ea9c..128c54841 100644 --- a/packages/service-core/src/entry/commands/compact-action.ts +++ b/packages/service-core/src/entry/commands/compact-action.ts @@ -36,13 +36,15 @@ export function registerCompactAction(program: Command) { const client = psdb.client; await client.connect(); try { - const bucketStorage = new storage.MongoBucketStorage(psdb, { slot_name_prefix: configuration.slot_name_prefix }); + const bucketStorage = new storage.MongoBucketStorage(psdb, { + slot_name_prefix: configuration.slot_name_prefix + }); const active = await bucketStorage.getActiveSyncRulesContent(); if (active == null) { logger.info('No active instance to compact'); return; } - const p = bucketStorage.getInstance(active); + using p = bucketStorage.getInstance(active); logger.info('Performing compaction...'); await p.compact({ memoryLimitMB: COMPACT_MEMORY_LIMIT_MB }); logger.info('Successfully compacted storage.'); diff --git a/packages/service-core/src/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.ts b/packages/service-core/src/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.ts new file mode 100644 index 000000000..2bac37fcc --- /dev/null +++ b/packages/service-core/src/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.ts @@ -0,0 +1,37 @@ +import * as storage from '../../../storage/storage-index.js'; +import * as utils from '../../../util/util-index.js'; + +const INDEX_NAME = 'user_sync_rule_unique'; + +export const up = async (context: utils.MigrationContext) => { + const { runner_config } = context; + const config = await utils.loadConfig(runner_config); + const db = storage.createPowerSyncMongo(config.storage); + + try { + await db.custom_write_checkpoints.createIndex( + { + user_id: 1, + sync_rules_id: 1 + }, + { name: INDEX_NAME, unique: true } + ); + } finally { + await db.client.close(); + } +}; + +export const down = async (context: utils.MigrationContext) => { + const { runner_config } = context; + const config = await utils.loadConfig(runner_config); + + const db = storage.createPowerSyncMongo(config.storage); + + try { + if (await db.custom_write_checkpoints.indexExists(INDEX_NAME)) { + await db.custom_write_checkpoints.dropIndex(INDEX_NAME); + } + } finally { + await db.client.close(); + } +}; diff --git a/packages/service-core/src/replication/AbstractReplicationJob.ts b/packages/service-core/src/replication/AbstractReplicationJob.ts index 913146b83..dc27c2eda 100644 --- a/packages/service-core/src/replication/AbstractReplicationJob.ts +++ b/packages/service-core/src/replication/AbstractReplicationJob.ts @@ -1,7 +1,7 @@ -import * as storage from '../storage/storage-index.js'; -import { ErrorRateLimiter } from './ErrorRateLimiter.js'; import { container, logger } from '@powersync/lib-services-framework'; import winston from 'winston'; +import * as storage from '../storage/storage-index.js'; +import { ErrorRateLimiter } from './ErrorRateLimiter.js'; export interface AbstractReplicationJobOptions { id: string; diff --git a/packages/service-core/src/replication/AbstractReplicator.ts b/packages/service-core/src/replication/AbstractReplicator.ts index 6c5a2a934..fcc3fa0ec 100644 --- a/packages/service-core/src/replication/AbstractReplicator.ts +++ b/packages/service-core/src/replication/AbstractReplicator.ts @@ -1,10 +1,10 @@ +import { container, logger } from '@powersync/lib-services-framework'; import { hrtime } from 'node:process'; +import winston from 'winston'; import * as storage from '../storage/storage-index.js'; -import { container, logger } from '@powersync/lib-services-framework'; +import { StorageEngine } from '../storage/storage-index.js'; import { SyncRulesProvider } from '../util/config/sync-rules/sync-rules-provider.js'; -import winston from 'winston'; import { AbstractReplicationJob } from './AbstractReplicationJob.js'; -import { StorageEngine } from '../storage/storage-index.js'; import { ErrorRateLimiter } from './ErrorRateLimiter.js'; // 5 minutes @@ -192,6 +192,7 @@ export abstract class AbstractReplicator = new Map(); diff --git a/packages/service-core/src/replication/replication-index.ts b/packages/service-core/src/replication/replication-index.ts index 455ca913b..0b37534c9 100644 --- a/packages/service-core/src/replication/replication-index.ts +++ b/packages/service-core/src/replication/replication-index.ts @@ -1,5 +1,5 @@ -export * from './ErrorRateLimiter.js'; export * from './AbstractReplicationJob.js'; export * from './AbstractReplicator.js'; +export * from './ErrorRateLimiter.js'; export * from './ReplicationEngine.js'; export * from './ReplicationModule.js'; diff --git a/packages/service-core/src/routes/endpoints/checkpointing.ts b/packages/service-core/src/routes/endpoints/checkpointing.ts index c60c3b233..0cfd2dc12 100644 --- a/packages/service-core/src/routes/endpoints/checkpointing.ts +++ b/packages/service-core/src/routes/endpoints/checkpointing.ts @@ -1,5 +1,5 @@ -import * as t from 'ts-codec'; import { logger, router, schema } from '@powersync/lib-services-framework'; +import * as t from 'ts-codec'; import * as util from '../../util/util-index.js'; import { authUser } from '../auth.js'; @@ -63,7 +63,10 @@ export const writeCheckpoint2 = routeDefinition({ storageEngine: { activeBucketStorage } } = service_context; - const writeCheckpoint = await activeBucketStorage.createWriteCheckpoint(full_user_id, { '1': currentCheckpoint }); + const writeCheckpoint = await activeBucketStorage.createManagedWriteCheckpoint({ + user_id: full_user_id, + heads: { '1': currentCheckpoint } + }); logger.info(`Write checkpoint 2: ${JSON.stringify({ currentCheckpoint, id: String(full_user_id) })}`); return { diff --git a/packages/service-core/src/runner/teardown.ts b/packages/service-core/src/runner/teardown.ts index 583635642..b6b7bb5ac 100644 --- a/packages/service-core/src/runner/teardown.ts +++ b/packages/service-core/src/runner/teardown.ts @@ -4,11 +4,11 @@ // 2. Delete the storage import { container, logger } from '@powersync/lib-services-framework'; +import timers from 'timers/promises'; import * as modules from '../modules/modules-index.js'; -import * as system from '../system/system-index.js'; import * as storage from '../storage/storage-index.js'; +import * as system from '../system/system-index.js'; import * as utils from '../util/util-index.js'; -import timers from 'timers/promises'; export async function teardown(runnerConfig: utils.RunnerConfig) { try { @@ -51,7 +51,7 @@ async function terminateSyncRules(storageFactory: storage.BucketStorageFactory, // Mark the sync rules as terminated for (let syncRules of combinedSyncRules) { - const syncRulesStorage = storageFactory.getInstance(syncRules); + using syncRulesStorage = storageFactory.getInstance(syncRules); // The storage will be dropped at the end of the teardown, so we don't need to clear it here await syncRulesStorage.terminate({ clearStorage: false }); } diff --git a/packages/service-core/src/storage/BucketStorage.ts b/packages/service-core/src/storage/BucketStorage.ts index f2117f673..a7b8a716d 100644 --- a/packages/service-core/src/storage/BucketStorage.ts +++ b/packages/service-core/src/storage/BucketStorage.ts @@ -1,3 +1,4 @@ +import { DisposableListener, DisposableObserverClient } from '@powersync/lib-services-framework'; import { EvaluatedParameters, EvaluatedRow, @@ -8,11 +9,19 @@ import { ToastableSqliteRow } from '@powersync/service-sync-rules'; import * as util from '../util/util-index.js'; -import { SourceTable } from './SourceTable.js'; +import { ReplicationEventPayload } from './ReplicationEventPayload.js'; import { SourceEntityDescriptor } from './SourceEntity.js'; -import { ReplicaId } from './storage-index.js'; +import { SourceTable } from './SourceTable.js'; +import { BatchedCustomWriteCheckpointOptions, ReplicaId, WriteCheckpointAPI } from './storage-index.js'; + +export interface BucketStorageFactoryListener extends DisposableListener { + syncStorageCreated: (storage: SyncRulesBucketStorage) => void; + replicationEvent: (event: ReplicationEventPayload) => void; +} -export interface BucketStorageFactory { +export interface BucketStorageFactory + extends DisposableObserverClient, + WriteCheckpointAPI { /** * Update sync rules from configuration, if changed. */ @@ -81,10 +90,9 @@ export interface BucketStorageFactory { */ getActiveCheckpoint(): Promise; - createWriteCheckpoint(user_id: string, lsns: Record): Promise; - - lastWriteCheckpoint(user_id: string, lsn: string): Promise; - + /** + * Yields the latest user write checkpoint whenever the sync checkpoint updates. + */ watchWriteCheckpoint(user_id: string, signal: AbortSignal): AsyncIterable; /** @@ -194,7 +202,11 @@ export interface StartBatchOptions extends ParseSyncRulesOptions { zeroLSN: string; } -export interface SyncRulesBucketStorage { +export interface SyncRulesBucketStorageListener extends DisposableListener { + batchStarted: (batch: BucketStorageBatch) => void; +} + +export interface SyncRulesBucketStorage extends DisposableObserverClient { readonly group_id: number; readonly slot_name: string; @@ -293,7 +305,11 @@ export interface FlushedResult { flushed_op: string; } -export interface BucketStorageBatch { +export interface BucketBatchStorageListener extends DisposableListener { + replicationEvent: (payload: ReplicationEventPayload) => void; +} + +export interface BucketStorageBatch extends DisposableObserverClient { /** * Save an op, and potentially flush. * @@ -340,6 +356,11 @@ export interface BucketStorageBatch { keepalive(lsn: string): Promise; markSnapshotDone(tables: SourceTable[], no_checkpoint_before_lsn: string): Promise; + + /** + * Queues the creation of a custom Write Checkpoint. This will be persisted after operations are flushed. + */ + addCustomWriteCheckpoint(checkpoint: BatchedCustomWriteCheckpointOptions): void; } export interface SaveParameterData { @@ -357,6 +378,8 @@ export interface SaveBucketData { evaluated: EvaluatedRow[]; } +export type SaveOp = 'insert' | 'update' | 'delete'; + export type SaveOptions = SaveInsert | SaveUpdate | SaveDelete; export interface SaveInsert { diff --git a/packages/service-core/src/storage/MongoBucketStorage.ts b/packages/service-core/src/storage/MongoBucketStorage.ts index c3e59d0b7..c0254da71 100644 --- a/packages/service-core/src/storage/MongoBucketStorage.ts +++ b/packages/service-core/src/storage/MongoBucketStorage.ts @@ -8,11 +8,12 @@ import * as locks from '../locks/locks-index.js'; import * as sync from '../sync/sync-index.js'; import * as util from '../util/util-index.js'; -import { logger } from '@powersync/lib-services-framework'; +import { DisposableObserver, logger } from '@powersync/lib-services-framework'; import { v4 as uuid } from 'uuid'; import { ActiveCheckpoint, BucketStorageFactory, + BucketStorageFactoryListener, ParseSyncRulesOptions, PersistedSyncRules, PersistedSyncRulesContent, @@ -20,20 +21,36 @@ import { UpdateSyncRulesOptions, WriteCheckpoint } from './BucketStorage.js'; -import { MongoPersistedSyncRulesContent } from './mongo/MongoPersistedSyncRulesContent.js'; -import { MongoSyncBucketStorage } from './mongo/MongoSyncBucketStorage.js'; import { PowerSyncMongo, PowerSyncMongoOptions } from './mongo/db.js'; import { SyncRuleDocument, SyncRuleState } from './mongo/models.js'; +import { MongoPersistedSyncRulesContent } from './mongo/MongoPersistedSyncRulesContent.js'; +import { MongoSyncBucketStorage } from './mongo/MongoSyncBucketStorage.js'; +import { MongoWriteCheckpointAPI } from './mongo/MongoWriteCheckpointAPI.js'; import { generateSlotName } from './mongo/util.js'; +import { + CustomWriteCheckpointOptions, + DEFAULT_WRITE_CHECKPOINT_MODE, + LastWriteCheckpointFilters, + ManagedWriteCheckpointOptions, + WriteCheckpointAPI, + WriteCheckpointMode +} from './write-checkpoint.js'; export interface MongoBucketStorageOptions extends PowerSyncMongoOptions {} -export class MongoBucketStorage implements BucketStorageFactory { +export class MongoBucketStorage + extends DisposableObserver + implements BucketStorageFactory +{ private readonly client: mongo.MongoClient; private readonly session: mongo.ClientSession; // TODO: This is still Postgres specific and needs to be reworked public readonly slot_name_prefix: string; + readonly write_checkpoint_mode: WriteCheckpointMode; + + protected readonly writeCheckpointAPI: WriteCheckpointAPI; + private readonly storageCache = new LRUCache({ max: 3, fetchMethod: async (id) => { @@ -49,16 +66,31 @@ export class MongoBucketStorage implements BucketStorageFactory { } const rules = new MongoPersistedSyncRulesContent(this.db, doc2); return this.getInstance(rules); + }, + dispose: (storage) => { + storage[Symbol.dispose](); } }); public readonly db: PowerSyncMongo; - constructor(db: PowerSyncMongo, options: { slot_name_prefix: string }) { + constructor( + db: PowerSyncMongo, + options: { + slot_name_prefix: string; + write_checkpoint_mode?: WriteCheckpointMode; + } + ) { + super(); this.client = db.client; this.db = db; this.session = this.client.startSession(); this.slot_name_prefix = options.slot_name_prefix; + this.write_checkpoint_mode = options.write_checkpoint_mode ?? DEFAULT_WRITE_CHECKPOINT_MODE; + this.writeCheckpointAPI = new MongoWriteCheckpointAPI({ + db, + mode: this.write_checkpoint_mode + }); } getInstance(options: PersistedSyncRulesContent): MongoSyncBucketStorage { @@ -66,7 +98,17 @@ export class MongoBucketStorage implements BucketStorageFactory { if ((typeof id as any) == 'bigint') { id = Number(id); } - return new MongoSyncBucketStorage(this, id, options, slot_name); + const storage = new MongoSyncBucketStorage(this, id, options, slot_name); + this.iterateListeners((cb) => cb.syncStorageCreated?.(storage)); + storage.registerListener({ + batchStarted: (batch) => { + // This nested listener will be automatically disposed when the storage is disposed + batch.registerManagedListener(storage, { + replicationEvent: (payload) => this.iterateListeners((cb) => cb.replicationEvent?.(payload)) + }); + } + }); + return storage; } async configureSyncRules(sync_rules: string, options?: { lock?: boolean }) { @@ -257,30 +299,20 @@ export class MongoBucketStorage implements BucketStorageFactory { }); } - async createWriteCheckpoint(user_id: string, lsns: Record): Promise { - const doc = await this.db.write_checkpoints.findOneAndUpdate( - { - user_id: user_id - }, - { - $set: { - lsns: lsns - }, - $inc: { - client_id: 1n - } - }, - { upsert: true, returnDocument: 'after' } - ); - return doc!.client_id; + async batchCreateCustomWriteCheckpoints(checkpoints: CustomWriteCheckpointOptions[]): Promise { + return this.writeCheckpointAPI.batchCreateCustomWriteCheckpoints(checkpoints); } - async lastWriteCheckpoint(user_id: string, lsn: string): Promise { - const lastWriteCheckpoint = await this.db.write_checkpoints.findOne({ - user_id: user_id, - 'lsns.1': { $lte: lsn } - }); - return lastWriteCheckpoint?.client_id ?? null; + async createCustomWriteCheckpoint(options: CustomWriteCheckpointOptions): Promise { + return this.writeCheckpointAPI.createCustomWriteCheckpoint(options); + } + + async createManagedWriteCheckpoint(options: ManagedWriteCheckpointOptions): Promise { + return this.writeCheckpointAPI.createManagedWriteCheckpoint(options); + } + + async lastWriteCheckpoint(filters: LastWriteCheckpointFilters): Promise { + return this.writeCheckpointAPI.lastWriteCheckpoint(filters); } async getActiveCheckpoint(): Promise { @@ -496,8 +528,17 @@ export class MongoBucketStorage implements BucketStorageFactory { // What is important is: // 1. checkpoint (op_id) changes. // 2. write checkpoint changes for the specific user + const bucketStorage = await cp.getBucketStorage(); - const currentWriteCheckpoint = await this.lastWriteCheckpoint(user_id, lsn ?? ''); + const lsnFilters: Record = lsn ? { 1: lsn } : {}; + + const currentWriteCheckpoint = await this.lastWriteCheckpoint({ + user_id, + sync_rules_id: bucketStorage?.group_id, + heads: { + ...lsnFilters + } + }); if (currentWriteCheckpoint == lastWriteCheckpoint && checkpoint == lastCheckpoint) { // No change - wait for next one diff --git a/packages/service-core/src/storage/ReplicationEventPayload.ts b/packages/service-core/src/storage/ReplicationEventPayload.ts new file mode 100644 index 000000000..c2fe0aa84 --- /dev/null +++ b/packages/service-core/src/storage/ReplicationEventPayload.ts @@ -0,0 +1,16 @@ +import * as sync_rules from '@powersync/service-sync-rules'; +import { BucketStorageBatch, SaveOp } from './BucketStorage.js'; +import { SourceTable } from './SourceTable.js'; + +export type EventData = { + op: SaveOp; + before?: sync_rules.SqliteRow; + after?: sync_rules.SqliteRow; +}; + +export type ReplicationEventPayload = { + batch: BucketStorageBatch; + data: EventData; + event: sync_rules.SqlEventDescriptor; + table: SourceTable; +}; diff --git a/packages/service-core/src/storage/SourceTable.ts b/packages/service-core/src/storage/SourceTable.ts index 2f5364633..f514f9081 100644 --- a/packages/service-core/src/storage/SourceTable.ts +++ b/packages/service-core/src/storage/SourceTable.ts @@ -23,6 +23,15 @@ export class SourceTable { */ public syncParameters = true; + /** + * True if the table is used in sync rules for events. + * + * This value is resolved externally, and cached here. + * + * Defaults to true for tests. + */ + public syncEvent = true; + constructor( public readonly id: any, public readonly connectionTag: string, @@ -53,6 +62,6 @@ export class SourceTable { } get syncAny() { - return this.syncData || this.syncParameters; + return this.syncData || this.syncParameters || this.syncEvent; } } diff --git a/packages/service-core/src/storage/StorageEngine.ts b/packages/service-core/src/storage/StorageEngine.ts index bc4d23db4..bdafeb240 100644 --- a/packages/service-core/src/storage/StorageEngine.ts +++ b/packages/service-core/src/storage/StorageEngine.ts @@ -1,18 +1,31 @@ +import { DisposableListener, DisposableObserver, logger } from '@powersync/lib-services-framework'; import { ResolvedPowerSyncConfig } from '../util/util-index.js'; import { BucketStorageFactory } from './BucketStorage.js'; -import { BucketStorageProvider, ActiveStorage } from './StorageProvider.js'; -import { logger } from '@powersync/lib-services-framework'; +import { ActiveStorage, BucketStorageProvider, StorageSettings } from './StorageProvider.js'; +import { DEFAULT_WRITE_CHECKPOINT_MODE } from './write-checkpoint.js'; export type StorageEngineOptions = { configuration: ResolvedPowerSyncConfig; }; -export class StorageEngine { +export const DEFAULT_STORAGE_SETTINGS: StorageSettings = { + writeCheckpointMode: DEFAULT_WRITE_CHECKPOINT_MODE +}; + +export interface StorageEngineListener extends DisposableListener { + storageActivated: (storage: BucketStorageFactory) => void; +} + +export class StorageEngine extends DisposableObserver { // TODO: This will need to revisited when we actually support multiple storage providers. private storageProviders: Map = new Map(); private currentActiveStorage: ActiveStorage | null = null; + private _activeSettings: StorageSettings; - constructor(private options: StorageEngineOptions) {} + constructor(private options: StorageEngineOptions) { + super(); + this._activeSettings = DEFAULT_STORAGE_SETTINGS; + } get activeBucketStorage(): BucketStorageFactory { return this.activeStorage.storage; @@ -26,6 +39,20 @@ export class StorageEngine { return this.currentActiveStorage; } + get activeSettings(): StorageSettings { + return { ...this._activeSettings }; + } + + updateSettings(settings: Partial) { + if (this.currentActiveStorage) { + throw new Error(`Storage is already active, settings cannot be modified.`); + } + this._activeSettings = { + ...this._activeSettings, + ...settings + }; + } + /** * Register a provider which generates a {@link BucketStorageFactory} * given the matching config specified in the loaded {@link ResolvedPowerSyncConfig} @@ -38,8 +65,10 @@ export class StorageEngine { logger.info('Starting Storage Engine...'); const { configuration } = this.options; this.currentActiveStorage = await this.storageProviders.get(configuration.storage.type)!.getStorage({ - resolvedConfig: configuration + resolvedConfig: configuration, + ...this.activeSettings }); + this.iterateListeners((cb) => cb.storageActivated?.(this.activeBucketStorage)); logger.info(`Successfully activated storage: ${configuration.storage.type}.`); logger.info('Successfully started Storage Engine.'); } diff --git a/packages/service-core/src/storage/StorageProvider.ts b/packages/service-core/src/storage/StorageProvider.ts index 9e6078874..7c730fb4b 100644 --- a/packages/service-core/src/storage/StorageProvider.ts +++ b/packages/service-core/src/storage/StorageProvider.ts @@ -1,5 +1,6 @@ -import { BucketStorageFactory } from './BucketStorage.js'; import * as util from '../util/util-index.js'; +import { BucketStorageFactory } from './BucketStorage.js'; +import { WriteCheckpointMode } from './write-checkpoint.js'; export interface ActiveStorage { storage: BucketStorageFactory; @@ -11,7 +12,14 @@ export interface ActiveStorage { tearDown(): Promise; } -export interface GetStorageOptions { +/** + * Settings which can be modified by various modules in their initialization. + */ +export interface StorageSettings { + writeCheckpointMode: WriteCheckpointMode; +} + +export interface GetStorageOptions extends StorageSettings { // TODO: This should just be the storage config. Update once the slot name prefix coupling has been removed from the storage resolvedConfig: util.ResolvedPowerSyncConfig; } diff --git a/packages/service-core/src/storage/mongo/MongoBucketBatch.ts b/packages/service-core/src/storage/mongo/MongoBucketBatch.ts index 81c03e3e5..30f9121bf 100644 --- a/packages/service-core/src/storage/mongo/MongoBucketBatch.ts +++ b/packages/service-core/src/storage/mongo/MongoBucketBatch.ts @@ -1,14 +1,22 @@ -import { SqliteRow, SqlSyncRules } from '@powersync/service-sync-rules'; +import { SqlEventDescriptor, SqliteRow, SqlSyncRules } from '@powersync/service-sync-rules'; import * as bson from 'bson'; import * as mongo from 'mongodb'; -import { container, errors, logger } from '@powersync/lib-services-framework'; +import { container, DisposableObserver, errors, logger } from '@powersync/lib-services-framework'; import * as util from '../../util/util-index.js'; -import { BucketStorageBatch, FlushedResult, mergeToast, SaveOptions } from '../BucketStorage.js'; +import { + BucketBatchStorageListener, + BucketStorageBatch, + FlushedResult, + mergeToast, + SaveOptions +} from '../BucketStorage.js'; import { SourceTable } from '../SourceTable.js'; +import { CustomWriteCheckpointOptions } from '../write-checkpoint.js'; import { PowerSyncMongo } from './db.js'; -import { CurrentBucket, CurrentDataDocument, SourceKey } from './models.js'; +import { CurrentBucket, CurrentDataDocument, SourceKey, SyncRuleDocument } from './models.js'; import { MongoIdSequence } from './MongoIdSequence.js'; +import { batchCreateCustomWriteCheckpoints } from './MongoWriteCheckpointAPI.js'; import { cacheKey, OperationBatch, RecordOperation } from './OperationBatch.js'; import { PersistedBatch } from './PersistedBatch.js'; import { BSON_DESERIALIZE_OPTIONS, idPrefixFilter, replicaIdEquals, serializeLookup } from './util.js'; @@ -25,7 +33,7 @@ const MAX_ROW_SIZE = 15 * 1024 * 1024; // In the future, we can investigate allowing multiple replication streams operating independently. const replicationMutex = new util.Mutex(); -export class MongoBucketBatch implements BucketStorageBatch { +export class MongoBucketBatch extends DisposableObserver implements BucketStorageBatch { private readonly client: mongo.MongoClient; public readonly db: PowerSyncMongo; public readonly session: mongo.ClientSession; @@ -36,6 +44,7 @@ export class MongoBucketBatch implements BucketStorageBatch { private readonly slot_name: string; private batch: OperationBatch | null = null; + private write_checkpoint_batch: CustomWriteCheckpointOptions[] = []; /** * Last LSN received associated with a checkpoint. @@ -63,14 +72,22 @@ export class MongoBucketBatch implements BucketStorageBatch { last_checkpoint_lsn: string | null, no_checkpoint_before_lsn: string ) { - this.db = db; + super(); this.client = db.client; - this.sync_rules = sync_rules; + this.db = db; this.group_id = group_id; - this.slot_name = slot_name; - this.session = this.client.startSession(); this.last_checkpoint_lsn = last_checkpoint_lsn; this.no_checkpoint_before_lsn = no_checkpoint_before_lsn; + this.session = this.client.startSession(); + this.slot_name = slot_name; + this.sync_rules = sync_rules; + } + + addCustomWriteCheckpoint(checkpoint: CustomWriteCheckpointOptions): void { + this.write_checkpoint_batch.push({ + ...checkpoint, + sync_rules_id: this.group_id + }); } async flush(): Promise { @@ -83,6 +100,8 @@ export class MongoBucketBatch implements BucketStorageBatch { result = r; } } + await batchCreateCustomWriteCheckpoints(this.db, this.write_checkpoint_batch); + this.write_checkpoint_batch = []; return result; } @@ -528,8 +547,9 @@ export class MongoBucketBatch implements BucketStorageBatch { }); } - async abort() { + async [Symbol.asyncDispose]() { await this.session.endSession(); + super[Symbol.dispose](); } async commit(lsn: string): Promise { @@ -546,26 +566,29 @@ export class MongoBucketBatch implements BucketStorageBatch { return false; } + const now = new Date(); + const update: Partial = { + last_checkpoint_lsn: lsn, + last_checkpoint_ts: now, + last_keepalive_ts: now, + snapshot_done: true, + last_fatal_error: null + }; + if (this.persisted_op != null) { - const now = new Date(); - await this.db.sync_rules.updateOne( - { - _id: this.group_id - }, - { - $set: { - last_checkpoint: this.persisted_op, - last_checkpoint_lsn: lsn, - last_checkpoint_ts: now, - last_keepalive_ts: now, - snapshot_done: true, - last_fatal_error: null - } - }, - { session: this.session } - ); - this.persisted_op = null; + update.last_checkpoint = this.persisted_op; } + + await this.db.sync_rules.updateOne( + { + _id: this.group_id + }, + { + $set: update + }, + { session: this.session } + ); + this.persisted_op = null; this.last_checkpoint_lsn = lsn; return true; } @@ -606,6 +629,29 @@ export class MongoBucketBatch implements BucketStorageBatch { } async save(record: SaveOptions): Promise { + const { after, before, sourceTable, tag } = record; + for (const event of this.getTableEvents(sourceTable)) { + this.iterateListeners((cb) => + cb.replicationEvent?.({ + batch: this, + table: sourceTable, + data: { + op: tag, + after: after && util.isCompleteRow(after) ? after : undefined, + before: before && util.isCompleteRow(before) ? before : undefined + }, + event + }) + ); + } + + /** + * Return if the table is just an event table + */ + if (!sourceTable.syncData && !sourceTable.syncParameters) { + return null; + } + logger.debug(`Saving ${record.tag}:${record.before?.id}/${record.after?.id}`); this.batch ??= new OperationBatch(); @@ -754,6 +800,15 @@ export class MongoBucketBatch implements BucketStorageBatch { return copy; }); } + + /** + * Gets relevant {@link SqlEventDescriptor}s for the given {@link SourceTable} + */ + protected getTableEvents(table: SourceTable): SqlEventDescriptor[] { + return this.sync_rules.event_descriptors.filter((evt) => + [...evt.getSourceTables()].some((sourceTable) => sourceTable.matches(table)) + ); + } } export function currentBucketKey(b: CurrentBucket) { diff --git a/packages/service-core/src/storage/mongo/MongoStorageProvider.ts b/packages/service-core/src/storage/mongo/MongoStorageProvider.ts index e5af38922..ef16900eb 100644 --- a/packages/service-core/src/storage/mongo/MongoStorageProvider.ts +++ b/packages/service-core/src/storage/mongo/MongoStorageProvider.ts @@ -1,8 +1,8 @@ +import { logger } from '@powersync/lib-services-framework'; import * as db from '../../db/db-index.js'; import { MongoBucketStorage } from '../MongoBucketStorage.js'; -import { BucketStorageProvider, ActiveStorage, GetStorageOptions } from '../StorageProvider.js'; +import { ActiveStorage, BucketStorageProvider, GetStorageOptions } from '../StorageProvider.js'; import { PowerSyncMongo } from './db.js'; -import { logger } from '@powersync/lib-services-framework'; export class MongoStorageProvider implements BucketStorageProvider { get type() { @@ -19,7 +19,8 @@ export class MongoStorageProvider implements BucketStorageProvider { return { storage: new MongoBucketStorage(database, { // TODO currently need the entire resolved config due to this - slot_name_prefix: resolvedConfig.slot_name_prefix + slot_name_prefix: resolvedConfig.slot_name_prefix, + write_checkpoint_mode: options.writeCheckpointMode }), shutDown: () => client.close(), tearDown: () => { diff --git a/packages/service-core/src/storage/mongo/MongoSyncBucketStorage.ts b/packages/service-core/src/storage/mongo/MongoSyncBucketStorage.ts index 3844f5b22..71ab4a531 100644 --- a/packages/service-core/src/storage/mongo/MongoSyncBucketStorage.ts +++ b/packages/service-core/src/storage/mongo/MongoSyncBucketStorage.ts @@ -2,6 +2,7 @@ import { SqliteJsonRow, SqliteJsonValue, SqlSyncRules } from '@powersync/service import * as bson from 'bson'; import * as mongo from 'mongodb'; +import { DisposableObserver } from '@powersync/lib-services-framework'; import * as db from '../../db/db-index.js'; import * as util from '../../util/util-index.js'; import { @@ -12,13 +13,13 @@ import { DEFAULT_DOCUMENT_CHUNK_LIMIT_BYTES, FlushedResult, ParseSyncRulesOptions, - PersistedSyncRules, PersistedSyncRulesContent, ResolveTableOptions, ResolveTableResult, StartBatchOptions, SyncBucketDataBatch, SyncRulesBucketStorage, + SyncRulesBucketStorageListener, SyncRuleStatus, TerminateOptions } from '../BucketStorage.js'; @@ -31,7 +32,10 @@ import { MongoBucketBatch } from './MongoBucketBatch.js'; import { MongoCompactor } from './MongoCompactor.js'; import { BSON_DESERIALIZE_OPTIONS, idPrefixFilter, mapOpEntry, readSingleBatch, serializeLookup } from './util.js'; -export class MongoSyncBucketStorage implements SyncRulesBucketStorage { +export class MongoSyncBucketStorage + extends DisposableObserver + implements SyncRulesBucketStorage +{ private readonly db: PowerSyncMongo; private checksumCache = new ChecksumCache({ fetchChecksums: (batch) => { @@ -47,6 +51,7 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage { private readonly sync_rules: PersistedSyncRulesContent, public readonly slot_name: string ) { + super(); this.db = factory.db; } @@ -79,7 +84,7 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage { ); const checkpoint_lsn = doc?.last_checkpoint_lsn ?? null; - const batch = new MongoBucketBatch( + await using batch = new MongoBucketBatch( this.db, this.sync_rules.parsed(options).sync_rules, this.group_id, @@ -87,18 +92,14 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage { checkpoint_lsn, doc?.no_checkpoint_before ?? options.zeroLSN ); - try { - await callback(batch); - await batch.flush(); - await batch.abort(); - if (batch.last_flushed_op) { - return { flushed_op: String(batch.last_flushed_op) }; - } else { - return null; - } - } catch (e) { - await batch.abort(); - throw e; + this.iterateListeners((cb) => cb.batchStarted?.(batch)); + + await callback(batch); + await batch.flush(); + if (batch.last_flushed_op) { + return { flushed_op: String(batch.last_flushed_op) }; + } else { + return null; } } @@ -150,6 +151,7 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage { replicationColumns, doc.snapshot_done ?? true ); + sourceTable.syncEvent = options.sync_rules.tableTriggersEvent(sourceTable); sourceTable.syncData = options.sync_rules.tableSyncsData(sourceTable); sourceTable.syncParameters = options.sync_rules.tableSyncsParameters(sourceTable); diff --git a/packages/service-core/src/storage/mongo/MongoWriteCheckpointAPI.ts b/packages/service-core/src/storage/mongo/MongoWriteCheckpointAPI.ts new file mode 100644 index 000000000..230db3153 --- /dev/null +++ b/packages/service-core/src/storage/mongo/MongoWriteCheckpointAPI.ts @@ -0,0 +1,136 @@ +import * as framework from '@powersync/lib-services-framework'; +import { + CustomWriteCheckpointFilters, + CustomWriteCheckpointOptions, + LastWriteCheckpointFilters, + ManagedWriteCheckpointFilters, + ManagedWriteCheckpointOptions, + WriteCheckpointAPI, + WriteCheckpointMode +} from '../write-checkpoint.js'; +import { PowerSyncMongo } from './db.js'; + +export type MongoCheckpointAPIOptions = { + db: PowerSyncMongo; + mode: WriteCheckpointMode; +}; + +export class MongoWriteCheckpointAPI implements WriteCheckpointAPI { + readonly db: PowerSyncMongo; + readonly mode: WriteCheckpointMode; + + constructor(options: MongoCheckpointAPIOptions) { + this.db = options.db; + this.mode = options.mode; + } + + async batchCreateCustomWriteCheckpoints(checkpoints: CustomWriteCheckpointOptions[]): Promise { + return batchCreateCustomWriteCheckpoints(this.db, checkpoints); + } + + async createCustomWriteCheckpoint(options: CustomWriteCheckpointOptions): Promise { + if (this.mode !== WriteCheckpointMode.CUSTOM) { + throw new framework.errors.ValidationError( + `Creating a custom Write Checkpoint when the current Write Checkpoint mode is set to "${this.mode}"` + ); + } + + const { checkpoint, user_id, sync_rules_id } = options; + const doc = await this.db.custom_write_checkpoints.findOneAndUpdate( + { + user_id: user_id, + sync_rules_id + }, + { + $set: { + checkpoint + } + }, + { upsert: true, returnDocument: 'after' } + ); + return doc!.checkpoint; + } + + async createManagedWriteCheckpoint(checkpoint: ManagedWriteCheckpointOptions): Promise { + if (this.mode !== WriteCheckpointMode.MANAGED) { + throw new framework.errors.ValidationError( + `Creating a managed Write Checkpoint when the current Write Checkpoint mode is set to "${this.mode}"` + ); + } + + const { user_id, heads: lsns } = checkpoint; + const doc = await this.db.write_checkpoints.findOneAndUpdate( + { + user_id: user_id + }, + { + $set: { + lsns + }, + $inc: { + client_id: 1n + } + }, + { upsert: true, returnDocument: 'after' } + ); + return doc!.client_id; + } + + async lastWriteCheckpoint(filters: LastWriteCheckpointFilters): Promise { + switch (this.mode) { + case WriteCheckpointMode.CUSTOM: + if (false == 'sync_rules_id' in filters) { + throw new framework.errors.ValidationError(`Sync rules ID is required for custom Write Checkpoint filtering`); + } + return this.lastCustomWriteCheckpoint(filters); + case WriteCheckpointMode.MANAGED: + if (false == 'heads' in filters) { + throw new framework.errors.ValidationError( + `Replication HEAD is required for managed Write Checkpoint filtering` + ); + } + return this.lastManagedWriteCheckpoint(filters); + } + } + + protected async lastCustomWriteCheckpoint(filters: CustomWriteCheckpointFilters) { + const { user_id, sync_rules_id } = filters; + const lastWriteCheckpoint = await this.db.custom_write_checkpoints.findOne({ + user_id, + sync_rules_id + }); + return lastWriteCheckpoint?.checkpoint ?? null; + } + + protected async lastManagedWriteCheckpoint(filters: ManagedWriteCheckpointFilters) { + const { user_id } = filters; + const lastWriteCheckpoint = await this.db.write_checkpoints.findOne({ + user_id: user_id + }); + return lastWriteCheckpoint?.client_id ?? null; + } +} + +export async function batchCreateCustomWriteCheckpoints( + db: PowerSyncMongo, + checkpoints: CustomWriteCheckpointOptions[] +): Promise { + if (!checkpoints.length) { + return; + } + + await db.custom_write_checkpoints.bulkWrite( + checkpoints.map((checkpointOptions) => ({ + updateOne: { + filter: { user_id: checkpointOptions.user_id, sync_rules_id: checkpointOptions.sync_rules_id }, + update: { + $set: { + checkpoint: checkpointOptions.checkpoint, + sync_rules_id: checkpointOptions.sync_rules_id + } + }, + upsert: true + } + })) + ); +} diff --git a/packages/service-core/src/storage/mongo/db.ts b/packages/service-core/src/storage/mongo/db.ts index 1cc3f8471..dddfdf918 100644 --- a/packages/service-core/src/storage/mongo/db.ts +++ b/packages/service-core/src/storage/mongo/db.ts @@ -1,11 +1,13 @@ import * as mongo from 'mongodb'; +import { configFile } from '@powersync/service-types'; import * as db from '../../db/db-index.js'; import * as locks from '../../locks/locks-index.js'; import { BucketDataDocument, BucketParameterDocument, CurrentDataDocument, + CustomWriteCheckpointDocument, IdSequenceDocument, InstanceDocument, SourceTableDocument, @@ -13,7 +15,6 @@ import { WriteCheckpointDocument } from './models.js'; import { BSON_DESERIALIZE_OPTIONS } from './util.js'; -import { configFile } from '@powersync/service-types'; export interface PowerSyncMongoOptions { /** @@ -33,6 +34,7 @@ export class PowerSyncMongo { readonly op_id_sequence: mongo.Collection; readonly sync_rules: mongo.Collection; readonly source_tables: mongo.Collection; + readonly custom_write_checkpoints: mongo.Collection; readonly write_checkpoints: mongo.Collection; readonly instance: mongo.Collection; readonly locks: mongo.Collection; @@ -54,6 +56,7 @@ export class PowerSyncMongo { this.op_id_sequence = db.collection('op_id_sequence'); this.sync_rules = db.collection('sync_rules'); this.source_tables = db.collection('source_tables'); + this.custom_write_checkpoints = db.collection('custom_write_checkpoints'); this.write_checkpoints = db.collection('write_checkpoints'); this.instance = db.collection('instance'); this.locks = this.db.collection('locks'); diff --git a/packages/service-core/src/storage/mongo/models.ts b/packages/service-core/src/storage/mongo/models.ts index fa52a37da..a85886c4e 100644 --- a/packages/service-core/src/storage/mongo/models.ts +++ b/packages/service-core/src/storage/mongo/models.ts @@ -1,5 +1,5 @@ -import * as bson from 'bson'; import { SqliteJsonValue } from '@powersync/service-sync-rules'; +import * as bson from 'bson'; /** * Replica id uniquely identifying a row on the source database. @@ -159,6 +159,13 @@ export interface SyncRuleDocument { content: string; } +export interface CustomWriteCheckpointDocument { + _id: bson.ObjectId; + user_id: string; + checkpoint: bigint; + sync_rules_id: number; +} + export interface WriteCheckpointDocument { _id: bson.ObjectId; user_id: string; diff --git a/packages/service-core/src/storage/storage-index.ts b/packages/service-core/src/storage/storage-index.ts index 3c137b8d1..076248882 100644 --- a/packages/service-core/src/storage/storage-index.ts +++ b/packages/service-core/src/storage/storage-index.ts @@ -1,5 +1,6 @@ export * from './BucketStorage.js'; export * from './MongoBucketStorage.js'; +export * from './ReplicationEventPayload.js'; export * from './SourceEntity.js'; export * from './SourceTable.js'; export * from './StorageEngine.js'; @@ -16,3 +17,4 @@ export * from './mongo/MongoSyncRulesLock.js'; export * from './mongo/OperationBatch.js'; export * from './mongo/PersistedBatch.js'; export * from './mongo/util.js'; +export * from './write-checkpoint.js'; diff --git a/packages/service-core/src/storage/write-checkpoint.ts b/packages/service-core/src/storage/write-checkpoint.ts new file mode 100644 index 000000000..0b61fe0c1 --- /dev/null +++ b/packages/service-core/src/storage/write-checkpoint.ts @@ -0,0 +1,67 @@ +export enum WriteCheckpointMode { + /** + * Raw mappings of `user_id` to `write_checkpoint`s should + * be supplied for each set of sync rules. + */ + CUSTOM = 'manual', + /** + * Write checkpoints are stored as a mapping of `user_id` plus + * replication HEAD (lsn in Postgres) to an automatically generated + * incrementing `write_checkpoint` (stored as`client_id`). + */ + MANAGED = 'managed' +} + +export interface BaseWriteCheckpointIdentifier { + /** + * Identifier for User's account. + */ + user_id: string; +} + +export interface CustomWriteCheckpointFilters extends BaseWriteCheckpointIdentifier { + /** + * Sync rules which were active when this checkpoint was created. + */ + sync_rules_id: number; +} + +export interface CustomWriteCheckpointOptions extends CustomWriteCheckpointFilters { + /** + * A supplied incrementing Write Checkpoint number + */ + checkpoint: bigint; +} + +/** + * Options for creating a custom Write Checkpoint in a batch. + * A {@link BucketStorageBatch} is already associated with a Sync Rules instance. + * The `sync_rules_id` is not required here. + */ +export type BatchedCustomWriteCheckpointOptions = Omit; + +/** + * Managed Write Checkpoints are a mapping of User ID to replication HEAD + */ +export interface ManagedWriteCheckpointFilters extends BaseWriteCheckpointIdentifier { + /** + * Replication HEAD(s) at the creation of the checkpoint. + */ + heads: Record; +} + +export type ManagedWriteCheckpointOptions = ManagedWriteCheckpointFilters; + +export type LastWriteCheckpointFilters = CustomWriteCheckpointFilters | ManagedWriteCheckpointFilters; + +export interface WriteCheckpointAPI { + batchCreateCustomWriteCheckpoints(checkpoints: CustomWriteCheckpointOptions[]): Promise; + + createCustomWriteCheckpoint(checkpoint: CustomWriteCheckpointOptions): Promise; + + createManagedWriteCheckpoint(checkpoint: ManagedWriteCheckpointOptions): Promise; + + lastWriteCheckpoint(filters: LastWriteCheckpointFilters): Promise; +} + +export const DEFAULT_WRITE_CHECKPOINT_MODE = WriteCheckpointMode.MANAGED; diff --git a/packages/service-core/test/src/data_storage.test.ts b/packages/service-core/test/src/data_storage.test.ts index 103ff4b4d..8eceacf40 100644 --- a/packages/service-core/test/src/data_storage.test.ts +++ b/packages/service-core/test/src/data_storage.test.ts @@ -1,10 +1,6 @@ -import { - BucketDataBatchOptions, - ParseSyncRulesOptions, - PersistedSyncRulesContent, - StartBatchOptions -} from '@/storage/BucketStorage.js'; -import { RequestParameters, SqlSyncRules } from '@powersync/service-sync-rules'; +import { BucketDataBatchOptions } from '@/storage/BucketStorage.js'; +import { getUuidReplicaIdentityBson } from '@/util/util-index.js'; +import { RequestParameters } from '@powersync/service-sync-rules'; import { describe, expect, test } from 'vitest'; import { fromAsync, oneFromAsync } from './stream_utils.js'; import { @@ -16,10 +12,8 @@ import { PARSE_OPTIONS, rid, StorageFactory, - testRules, - ZERO_LSN + testRules } from './util.js'; -import { getUuidReplicaIdentityBson } from '@/util/util-index.js'; const TEST_TABLE = makeTestTable('test', ['id']); @@ -1406,4 +1400,42 @@ bucket_definitions: expect(getBatchMeta(batch3)).toEqual(null); }); + + test('batch should be disposed automatically', async () => { + const sync_rules = testRules(` + bucket_definitions: + global: + data: [] + `); + + const storage = (await factory()).getInstance(sync_rules); + + let isDisposed = false; + await storage.startBatch(BATCH_OPTIONS, async (batch) => { + batch.registerListener({ + disposed: () => { + isDisposed = true; + } + }); + }); + expect(isDisposed).true; + + isDisposed = false; + let errorCaught = false; + try { + await storage.startBatch(BATCH_OPTIONS, async (batch) => { + batch.registerListener({ + disposed: () => { + isDisposed = true; + } + }); + throw new Error(`Testing exceptions`); + }); + } catch (ex) { + errorCaught = true; + expect(ex.message.includes('Testing')).true; + } + expect(errorCaught).true; + expect(isDisposed).true; + }); } diff --git a/packages/service-core/test/src/util.ts b/packages/service-core/test/src/util.ts index 5acdd2f2e..cd8c06f2c 100644 --- a/packages/service-core/test/src/util.ts +++ b/packages/service-core/test/src/util.ts @@ -11,11 +11,10 @@ import { SourceTable } from '@/storage/SourceTable.js'; import { PowerSyncMongo } from '@/storage/mongo/db.js'; import { SyncBucketData } from '@/util/protocol-types.js'; import { getUuidReplicaIdentityBson, hashData } from '@/util/utils.js'; +import { SqlSyncRules } from '@powersync/service-sync-rules'; import * as bson from 'bson'; import * as mongo from 'mongodb'; import { env } from './env.js'; -import { SqlSyncRules } from '@powersync/service-sync-rules'; -import { ReplicaId } from '@/storage/storage-index.js'; // The metrics need to be initialised before they can be used await Metrics.initialise({ diff --git a/packages/sync-rules/.gitignore b/packages/sync-rules/.gitignore new file mode 100644 index 000000000..b73759d7b --- /dev/null +++ b/packages/sync-rules/.gitignore @@ -0,0 +1 @@ +schema/ \ No newline at end of file diff --git a/packages/sync-rules/package.json b/packages/sync-rules/package.json index de6e1f4de..ffe53c975 100644 --- a/packages/sync-rules/package.json +++ b/packages/sync-rules/package.json @@ -9,13 +9,16 @@ "access": "public" }, "files": [ - "dist/**/*" + "dist/**/*", + "schema/*" ], "type": "module", "scripts": { "clean": "rm -r ./dist && tsc -b --clean", "build": "tsc -b", "build:tests": "tsc -b test/tsconfig.json", + "compile:schema": "pnpm build && node scripts/compile-schema.js", + "postversion": "pnpm compile:schema", "test": "vitest" }, "dependencies": { diff --git a/packages/sync-rules/scripts/compile-schema.js b/packages/sync-rules/scripts/compile-schema.js new file mode 100644 index 000000000..267de50d5 --- /dev/null +++ b/packages/sync-rules/scripts/compile-schema.js @@ -0,0 +1,11 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { syncRulesSchema } from '../dist/json_schema.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const schemaDir = path.join(__dirname, '../schema'); + +fs.mkdirSync(schemaDir, { recursive: true }); + +fs.writeFileSync(path.join(schemaDir, 'sync_rules.json'), JSON.stringify(syncRulesSchema, null, '\t')); diff --git a/packages/sync-rules/src/BaseSqlDataQuery.ts b/packages/sync-rules/src/BaseSqlDataQuery.ts new file mode 100644 index 000000000..342314d9b --- /dev/null +++ b/packages/sync-rules/src/BaseSqlDataQuery.ts @@ -0,0 +1,125 @@ +import { SelectedColumn } from 'pgsql-ast-parser'; +import { SqlRuleError } from './errors.js'; +import { ColumnDefinition } from './ExpressionType.js'; +import { SourceTableInterface } from './SourceTableInterface.js'; +import { SqlTools } from './sql_filters.js'; +import { TablePattern } from './TablePattern.js'; +import { QueryParameters, QuerySchema, SourceSchema, SourceSchemaTable, SqliteJsonRow, SqliteRow } from './types.js'; +import { filterJsonRow } from './utils.js'; + +export interface RowValueExtractor { + extract(tables: QueryParameters, into: SqliteRow): void; + getTypes(schema: QuerySchema, into: Record): void; +} + +export class BaseSqlDataQuery { + sourceTable?: TablePattern; + table?: string; + sql?: string; + columns?: SelectedColumn[]; + extractors: RowValueExtractor[] = []; + descriptor_name?: string; + bucket_parameters?: string[]; + tools?: SqlTools; + + ruleId?: string; + + errors: SqlRuleError[] = []; + + constructor() {} + + applies(table: SourceTableInterface) { + return this.sourceTable?.matches(table); + } + + addSpecialParameters(table: SourceTableInterface, row: SqliteRow) { + if (this.sourceTable!.isWildcard) { + return { + ...row, + _table_suffix: this.sourceTable!.suffix(table.table) + }; + } else { + return row; + } + } + + getOutputName(sourceTable: string) { + if (this.isUnaliasedWildcard()) { + // Wildcard without alias - use source + return sourceTable; + } else { + return this.table!; + } + } + + isUnaliasedWildcard() { + return this.sourceTable!.isWildcard && this.table == this.sourceTable!.tablePattern; + } + + columnOutputNames(): string[] { + return this.columns!.map((c) => { + return this.tools!.getOutputName(c); + }); + } + + getColumnOutputs(schema: SourceSchema): { name: string; columns: ColumnDefinition[] }[] { + let result: { name: string; columns: ColumnDefinition[] }[] = []; + + if (this.isUnaliasedWildcard()) { + // Separate results + for (let schemaTable of schema.getTables(this.sourceTable!)) { + let output: Record = {}; + + this.getColumnOutputsFor(schemaTable, output); + + result.push({ + name: this.getOutputName(schemaTable.table), + columns: Object.values(output) + }); + } + } else { + // Merged results + let output: Record = {}; + for (let schemaTable of schema.getTables(this.sourceTable!)) { + this.getColumnOutputsFor(schemaTable, output); + } + result.push({ + name: this.table!, + columns: Object.values(output) + }); + } + + return result; + } + + protected transformRow(tables: QueryParameters): SqliteJsonRow { + let result: SqliteRow = {}; + for (let extractor of this.extractors) { + extractor.extract(tables, result); + } + return filterJsonRow(result); + } + + protected getColumnOutputsFor(schemaTable: SourceSchemaTable, output: Record) { + const querySchema: QuerySchema = { + getColumn: (table, column) => { + if (table == this.table!) { + return schemaTable.getColumn(column); + } else { + // TODO: bucket parameters? + return undefined; + } + }, + getColumns: (table) => { + if (table == this.table!) { + return schemaTable.getColumns(); + } else { + return []; + } + } + }; + for (let extractor of this.extractors) { + extractor.getTypes(querySchema, output); + } + } +} diff --git a/packages/sync-rules/src/SqlDataQuery.ts b/packages/sync-rules/src/SqlDataQuery.ts index 9f15d00db..6f082a96a 100644 --- a/packages/sync-rules/src/SqlDataQuery.ts +++ b/packages/sync-rules/src/SqlDataQuery.ts @@ -1,32 +1,21 @@ import { JSONBig } from '@powersync/service-jsonbig'; -import { parse, SelectedColumn } from 'pgsql-ast-parser'; +import { parse } from 'pgsql-ast-parser'; +import { BaseSqlDataQuery } from './BaseSqlDataQuery.js'; import { SqlRuleError } from './errors.js'; -import { ColumnDefinition, ExpressionType } from './ExpressionType.js'; +import { ExpressionType } from './ExpressionType.js'; import { SourceTableInterface } from './SourceTableInterface.js'; import { SqlTools } from './sql_filters.js'; import { castAsText } from './sql_functions.js'; import { checkUnsupportedFeatures, isClauseError } from './sql_support.js'; +import { SyncRulesOptions } from './SqlSyncRules.js'; import { TablePattern } from './TablePattern.js'; -import { - EvaluationResult, - ParameterMatchClause, - QueryParameters, - QuerySchema, - SourceSchema, - SourceSchemaTable, - SqliteJsonRow, - SqliteRow -} from './types.js'; -import { filterJsonRow, getBucketId, isSelectStatement } from './utils.js'; import { TableQuerySchema } from './TableQuerySchema.js'; -import { SyncRulesOptions } from './SqlSyncRules.js'; +import { EvaluationResult, ParameterMatchClause, QuerySchema, SqliteRow } from './types.js'; +import { getBucketId, isSelectStatement } from './utils.js'; -interface RowValueExtractor { - extract(tables: QueryParameters, into: SqliteRow): void; - getTypes(schema: QuerySchema, into: Record): void; -} +export class SqlDataQuery extends BaseSqlDataQuery { + filter?: ParameterMatchClause; -export class SqlDataQuery { static fromSql(descriptor_name: string, bucket_parameters: string[], sql: string, options: SyncRulesOptions) { const parsed = parse(sql, { locationTracking: true }); const rows = new SqlDataQuery(); @@ -174,50 +163,6 @@ export class SqlDataQuery { return rows; } - sourceTable?: TablePattern; - table?: string; - sql?: string; - columns?: SelectedColumn[]; - extractors: RowValueExtractor[] = []; - filter?: ParameterMatchClause; - descriptor_name?: string; - bucket_parameters?: string[]; - tools?: SqlTools; - - ruleId?: string; - - errors: SqlRuleError[] = []; - - constructor() {} - - applies(table: SourceTableInterface) { - return this.sourceTable?.matches(table); - } - - addSpecialParameters(table: SourceTableInterface, row: SqliteRow) { - if (this.sourceTable!.isWildcard) { - return { - ...row, - _table_suffix: this.sourceTable!.suffix(table.table) - }; - } else { - return row; - } - } - - getOutputName(sourceTable: string) { - if (this.isUnaliasedWildcard()) { - // Wildcard without alias - use source - return sourceTable; - } else { - return this.table!; - } - } - - isUnaliasedWildcard() { - return this.sourceTable!.isWildcard && this.table == this.sourceTable!.tablePattern; - } - evaluateRow(table: SourceTableInterface, row: SqliteRow): EvaluationResult[] { try { const tables = { [this.table!]: this.addSpecialParameters(table, row) }; @@ -252,71 +197,4 @@ export class SqlDataQuery { return [{ error: e.message ?? `Evaluating data query failed` }]; } } - - private transformRow(tables: QueryParameters): SqliteJsonRow { - let result: SqliteRow = {}; - for (let extractor of this.extractors) { - extractor.extract(tables, result); - } - return filterJsonRow(result); - } - - columnOutputNames(): string[] { - return this.columns!.map((c) => { - return this.tools!.getOutputName(c); - }); - } - - getColumnOutputs(schema: SourceSchema): { name: string; columns: ColumnDefinition[] }[] { - let result: { name: string; columns: ColumnDefinition[] }[] = []; - - if (this.isUnaliasedWildcard()) { - // Separate results - for (let schemaTable of schema.getTables(this.sourceTable!)) { - let output: Record = {}; - - this.getColumnOutputsFor(schemaTable, output); - - result.push({ - name: this.getOutputName(schemaTable.table), - columns: Object.values(output) - }); - } - } else { - // Merged results - let output: Record = {}; - for (let schemaTable of schema.getTables(this.sourceTable!)) { - this.getColumnOutputsFor(schemaTable, output); - } - result.push({ - name: this.table!, - columns: Object.values(output) - }); - } - - return result; - } - - private getColumnOutputsFor(schemaTable: SourceSchemaTable, output: Record) { - const querySchema: QuerySchema = { - getColumn: (table, column) => { - if (table == this.table!) { - return schemaTable.getColumn(column); - } else { - // TODO: bucket parameters? - return undefined; - } - }, - getColumns: (table) => { - if (table == this.table!) { - return schemaTable.getColumns(); - } else { - return []; - } - } - }; - for (let extractor of this.extractors) { - extractor.getTypes(querySchema, output); - } - } } diff --git a/packages/sync-rules/src/SqlSyncRules.ts b/packages/sync-rules/src/SqlSyncRules.ts index 10c0de3b4..ca5f05d85 100644 --- a/packages/sync-rules/src/SqlSyncRules.ts +++ b/packages/sync-rules/src/SqlSyncRules.ts @@ -1,5 +1,6 @@ -import { LineCounter, parseDocument, Scalar, YAMLMap, YAMLSeq } from 'yaml'; +import { isScalar, LineCounter, parseDocument, Scalar, YAMLMap, YAMLSeq } from 'yaml'; import { SqlRuleError, SyncRulesErrors, YamlError } from './errors.js'; +import { SqlEventDescriptor } from './events/SqlEventDescriptor.js'; import { IdSequence } from './IdSequence.js'; import { validateSyncRulesSchema } from './json_schema.js'; import { SourceTableInterface } from './SourceTableInterface.js'; @@ -39,6 +40,7 @@ export interface SyncRulesOptions { export class SqlSyncRules implements SyncRules { bucket_descriptors: SqlBucketDescriptor[] = []; + event_descriptors: SqlEventDescriptor[] = []; idSequence = new IdSequence(); content: string; @@ -145,6 +147,35 @@ export class SqlSyncRules implements SyncRules { rules.bucket_descriptors.push(descriptor); } + const eventMap = parsed.get('event_definitions') as YAMLMap; + for (const event of eventMap?.items ?? []) { + const { key, value } = event as { key: Scalar; value: YAMLSeq }; + + if (false == value instanceof YAMLMap) { + rules.errors.push(new YamlError(new Error(`Event definitions must be objects.`))); + continue; + } + + const payloads = value.get('payloads') as YAMLSeq; + if (false == payloads instanceof YAMLSeq) { + rules.errors.push(new YamlError(new Error(`Event definition payloads must be an array.`))); + continue; + } + + const eventDescriptor = new SqlEventDescriptor(key.toString(), rules.idSequence); + for (let item of payloads.items) { + if (!isScalar(item)) { + rules.errors.push(new YamlError(new Error(`Payload queries for events must be scalar.`))); + continue; + } + rules.withScalar(item, (q) => { + return eventDescriptor.addSourceQuery(q, options); + }); + } + + rules.event_descriptors.push(eventDescriptor); + } + // Validate that there are no additional properties. // Since these errors don't contain line numbers, do this last. const valid = validateSyncRulesSchema(parsed.toJSON()); @@ -290,18 +321,42 @@ export class SqlSyncRules implements SyncRules { } getSourceTables(): TablePattern[] { - let sourceTables = new Map(); - for (let bucket of this.bucket_descriptors) { - for (let r of bucket.getSourceTables()) { + const sourceTables = new Map(); + for (const bucket of this.bucket_descriptors) { + for (const r of bucket.getSourceTables()) { const key = `${r.connectionTag}.${r.schema}.${r.tablePattern}`; sourceTables.set(key, r); } } + + for (const event of this.event_descriptors) { + for (const r of event.getSourceTables()) { + const key = `${r.connectionTag}.${r.schema}.${r.tablePattern}`; + sourceTables.set(key, r); + } + } + return [...sourceTables.values()]; } + getEventTables(): TablePattern[] { + const eventTables = new Map(); + + for (const event of this.event_descriptors) { + for (const r of event.getSourceTables()) { + const key = `${r.connectionTag}.${r.schema}.${r.tablePattern}`; + eventTables.set(key, r); + } + } + return [...eventTables.values()]; + } + + tableTriggersEvent(table: SourceTableInterface): boolean { + return this.event_descriptors.some((bucket) => bucket.tableTriggersEvent(table)); + } + tableSyncsData(table: SourceTableInterface): boolean { - for (let bucket of this.bucket_descriptors) { + for (const bucket of this.bucket_descriptors) { if (bucket.tableSyncsData(table)) { return true; } diff --git a/packages/sync-rules/src/events/SqlEventDescriptor.ts b/packages/sync-rules/src/events/SqlEventDescriptor.ts new file mode 100644 index 000000000..a02cd42ef --- /dev/null +++ b/packages/sync-rules/src/events/SqlEventDescriptor.ts @@ -0,0 +1,65 @@ +import { SqlRuleError } from '../errors.js'; +import { IdSequence } from '../IdSequence.js'; +import { SourceTableInterface } from '../SourceTableInterface.js'; +import { QueryParseResult } from '../SqlBucketDescriptor.js'; +import { SyncRulesOptions } from '../SqlSyncRules.js'; +import { TablePattern } from '../TablePattern.js'; +import { EvaluateRowOptions } from '../types.js'; +import { EvaluatedEventRowWithErrors, SqlEventSourceQuery } from './SqlEventSourceQuery.js'; + +/** + * A sync rules event which is triggered from a SQL table change. + */ +export class SqlEventDescriptor { + name: string; + source_queries: SqlEventSourceQuery[] = []; + + constructor(name: string, public idSequence: IdSequence) { + this.name = name; + } + + addSourceQuery(sql: string, options: SyncRulesOptions): QueryParseResult { + const source = SqlEventSourceQuery.fromSql(this.name, sql, options); + + // Each source query should be for a unique table + const existingSourceQuery = this.source_queries.find((q) => q.table == source.table); + if (existingSourceQuery) { + return { + parsed: false, + errors: [new SqlRuleError('Each payload query should query a unique table', sql)] + }; + } + + source.ruleId = this.idSequence.nextId(); + this.source_queries.push(source); + + return { + parsed: true, + errors: source.errors + }; + } + + evaluateRowWithErrors(options: EvaluateRowOptions): EvaluatedEventRowWithErrors { + // There should only be 1 payload result per source query + const matchingQuery = this.source_queries.find((q) => q.applies(options.sourceTable)); + if (!matchingQuery) { + return { + errors: [{ error: `No marching source query found for table ${options.sourceTable.table}` }] + }; + } + + return matchingQuery.evaluateRowWithErrors(options.sourceTable, options.record); + } + + getSourceTables(): Set { + let result = new Set(); + for (let query of this.source_queries) { + result.add(query.sourceTable!); + } + return result; + } + + tableTriggersEvent(table: SourceTableInterface): boolean { + return this.source_queries.some((query) => query.applies(table)); + } +} diff --git a/packages/sync-rules/src/events/SqlEventSourceQuery.ts b/packages/sync-rules/src/events/SqlEventSourceQuery.ts new file mode 100644 index 000000000..c5ca1e1ab --- /dev/null +++ b/packages/sync-rules/src/events/SqlEventSourceQuery.ts @@ -0,0 +1,142 @@ +import { parse } from 'pgsql-ast-parser'; +import { BaseSqlDataQuery } from '../BaseSqlDataQuery.js'; +import { SqlRuleError } from '../errors.js'; +import { ExpressionType } from '../ExpressionType.js'; +import { SourceTableInterface } from '../SourceTableInterface.js'; +import { SqlTools } from '../sql_filters.js'; +import { checkUnsupportedFeatures, isClauseError } from '../sql_support.js'; +import { SyncRulesOptions } from '../SqlSyncRules.js'; +import { TablePattern } from '../TablePattern.js'; +import { TableQuerySchema } from '../TableQuerySchema.js'; +import { EvaluationError, QuerySchema, SqliteJsonRow, SqliteRow } from '../types.js'; +import { isSelectStatement } from '../utils.js'; + +export type EvaluatedEventSourceRow = { + data: SqliteJsonRow; + ruleId?: string; +}; + +export type EvaluatedEventRowWithErrors = { + result?: EvaluatedEventSourceRow; + errors: EvaluationError[]; +}; + +/** + * Defines how a Replicated Row is mapped to source parameters for events. + */ +export class SqlEventSourceQuery extends BaseSqlDataQuery { + static fromSql(descriptor_name: string, sql: string, options: SyncRulesOptions) { + const parsed = parse(sql, { locationTracking: true }); + const rows = new SqlEventSourceQuery(); + const schema = options.schema; + + if (parsed.length > 1) { + throw new SqlRuleError('Only a single SELECT statement is supported', sql, parsed[1]?._location); + } + const q = parsed[0]; + if (!isSelectStatement(q)) { + throw new SqlRuleError('Only SELECT statements are supported', sql, q._location); + } + + rows.errors.push(...checkUnsupportedFeatures(sql, q)); + + if (q.from == null || q.from.length != 1 || q.from[0].type != 'table') { + throw new SqlRuleError('Must SELECT from a single table', sql, q.from?.[0]._location); + } + + const tableRef = q.from?.[0].name; + if (tableRef?.name == null) { + throw new SqlRuleError('Must SELECT from a single table', sql, q.from?.[0]._location); + } + const alias: string = tableRef.alias ?? tableRef.name; + + const sourceTable = new TablePattern(tableRef.schema ?? options.defaultSchema, tableRef.name); + let querySchema: QuerySchema | undefined = undefined; + if (schema) { + const tables = schema.getTables(sourceTable); + if (tables.length == 0) { + const e = new SqlRuleError( + `Table ${sourceTable.schema}.${sourceTable.tablePattern} not found`, + sql, + q.from?.[0]?._location + ); + e.type = 'warning'; + + rows.errors.push(e); + } else { + querySchema = new TableQuerySchema(tables, alias); + } + } + + const tools = new SqlTools({ + table: alias, + parameter_tables: [], + value_tables: [alias], + sql, + schema: querySchema + }); + + rows.sourceTable = sourceTable; + rows.table = alias; + rows.sql = sql; + rows.descriptor_name = descriptor_name; + rows.columns = q.columns ?? []; + rows.tools = tools; + + for (let column of q.columns ?? []) { + const name = tools.getOutputName(column); + if (name != '*') { + const clause = tools.compileRowValueExtractor(column.expr); + if (isClauseError(clause)) { + // Error logged already + continue; + } + rows.extractors.push({ + extract: (tables, output) => { + output[name] = clause.evaluate(tables); + }, + getTypes(schema, into) { + const def = clause.getColumnDefinition(schema); + into[name] = { name, type: def?.type ?? ExpressionType.NONE, originalType: def?.originalType }; + } + }); + } else { + rows.extractors.push({ + extract: (tables, output) => { + const row = tables[alias]; + for (let key in row) { + if (key.startsWith('_')) { + continue; + } + output[key] ??= row[key]; + } + }, + getTypes(schema, into) { + for (let column of schema.getColumns(alias)) { + into[column.name] ??= column; + } + } + }); + } + } + rows.errors.push(...tools.errors); + return rows; + } + + evaluateRowWithErrors(table: SourceTableInterface, row: SqliteRow): EvaluatedEventRowWithErrors { + try { + const tables = { [this.table!]: this.addSpecialParameters(table, row) }; + + const data = this.transformRow(tables); + return { + result: { + data, + ruleId: this.ruleId + }, + errors: [] + }; + } catch (e) { + return { errors: [e.message ?? `Evaluating data query failed`] }; + } + } +} diff --git a/packages/sync-rules/src/index.ts b/packages/sync-rules/src/index.ts index d72a1e58c..877d52c37 100644 --- a/packages/sync-rules/src/index.ts +++ b/packages/sync-rules/src/index.ts @@ -1,20 +1,22 @@ +export * from './DartSchemaGenerator.js'; export * from './errors.js'; +export * from './events/SqlEventDescriptor.js'; +export * from './events/SqlEventSourceQuery.js'; +export * from './ExpressionType.js'; +export * from './generators.js'; export * from './IdSequence.js'; +export * from './JsLegacySchemaGenerator.js'; +export * from './json_schema.js'; +export * from './request_functions.js'; +export * from './SchemaGenerator.js'; export * from './SourceTableInterface.js'; export * from './sql_filters.js'; export * from './sql_functions.js'; +export * from './SqlDataQuery.js'; +export * from './SqlParameterQuery.js'; export * from './SqlSyncRules.js'; +export * from './StaticSchema.js'; export * from './TablePattern.js'; +export * from './TsSchemaGenerator.js'; export * from './types.js'; export * from './utils.js'; -export * from './SqlParameterQuery.js'; -export * from './json_schema.js'; -export * from './StaticSchema.js'; -export * from './ExpressionType.js'; -export * from './SchemaGenerator.js'; -export * from './DartSchemaGenerator.js'; -export * from './JsLegacySchemaGenerator.js'; -export * from './TsSchemaGenerator.js'; -export * from './generators.js'; -export * from './SqlDataQuery.js'; -export * from './request_functions.js'; diff --git a/packages/sync-rules/src/json_schema.ts b/packages/sync-rules/src/json_schema.ts index dfe614825..b2f9367a9 100644 --- a/packages/sync-rules/src/json_schema.ts +++ b/packages/sync-rules/src/json_schema.ts @@ -44,6 +44,35 @@ export const syncRulesSchema: ajvModule.Schema = { additionalProperties: false } } + }, + event_definitions: { + type: 'object', + description: 'Record of sync replication event definitions', + examples: [ + { + write_checkpoints: { + payloads: ['select user_id, client_id, checkpoint from checkpoints'] + } + } + ], + patternProperties: { + '.*': { + type: ['object'], + required: ['payloads'], + examples: [{ payloads: ['select user_id, client_id, checkpoint from checkpoints'] }], + properties: { + payloads: { + description: 'Queries which extract event payload fields from replicated table rows.', + type: 'array', + items: { + type: 'string' + } + }, + additionalProperties: false, + uniqueItems: true + } + } + } } }, required: ['bucket_definitions'], diff --git a/packages/sync-rules/src/sql_filters.ts b/packages/sync-rules/src/sql_filters.ts index 9313ffd28..5cf9961f3 100644 --- a/packages/sync-rules/src/sql_filters.ts +++ b/packages/sync-rules/src/sql_filters.ts @@ -1,7 +1,9 @@ -import { Expr, ExprRef, Name, NodeLocation, QName, QNameAliased, SelectedColumn, parse } from 'pgsql-ast-parser'; +import { JSONBig } from '@powersync/service-jsonbig'; +import { Expr, ExprRef, Name, NodeLocation, QName, QNameAliased, SelectedColumn } from 'pgsql-ast-parser'; import { nil } from 'pgsql-ast-parser/src/utils.js'; -import { ExpressionType, TYPE_NONE } from './ExpressionType.js'; +import { ExpressionType } from './ExpressionType.js'; import { SqlRuleError } from './errors.js'; +import { REQUEST_FUNCTIONS } from './request_functions.js'; import { BASIC_OPERATORS, OPERATOR_IN, @@ -13,6 +15,7 @@ import { SQL_FUNCTIONS, SqlFunction, castOperator, + getOperatorFunction, sqliteTypeOf } from './sql_functions.js'; import { @@ -20,7 +23,6 @@ import { SQLITE_TRUE, andFilters, compileStaticOperator, - getOperatorFunction, isClauseError, isParameterMatchClause, isParameterValueClause, @@ -44,8 +46,6 @@ import { TrueIfParametersMatch } from './types.js'; import { isJsonValue } from './utils.js'; -import { JSONBig } from '@powersync/service-jsonbig'; -import { REQUEST_FUNCTIONS } from './request_functions.js'; export const MATCH_CONST_FALSE: TrueIfParametersMatch = []; export const MATCH_CONST_TRUE: TrueIfParametersMatch = [{}]; diff --git a/packages/sync-rules/src/sql_functions.ts b/packages/sync-rules/src/sql_functions.ts index 715f1494f..ce419d49a 100644 --- a/packages/sync-rules/src/sql_functions.ts +++ b/packages/sync-rules/src/sql_functions.ts @@ -1,5 +1,5 @@ import { JSONBig } from '@powersync/service-jsonbig'; -import { getOperatorFunction, SQLITE_FALSE, SQLITE_TRUE, sqliteBool, sqliteNot } from './sql_support.js'; +import { SQLITE_FALSE, SQLITE_TRUE, sqliteBool, sqliteNot } from './sql_support.js'; import { SqliteValue } from './types.js'; import { jsonValueToSqlite } from './utils.js'; // Declares @syncpoint/wkx module @@ -44,6 +44,18 @@ export interface DocumentedSqlFunction extends SqlFunction { documentation?: string; } +export function getOperatorFunction(op: string): SqlFunction { + return { + debugName: `operator${op}`, + call(...args: SqliteValue[]) { + return evaluateOperator(op, args[0], args[1]); + }, + getReturnType(args) { + return getOperatorReturnType(op, args[0], args[1]); + } + }; +} + const upper: DocumentedSqlFunction = { debugName: 'upper', call(value: SqliteValue) { diff --git a/packages/sync-rules/src/sql_support.ts b/packages/sync-rules/src/sql_support.ts index e2b074c55..b64aacd4f 100644 --- a/packages/sync-rules/src/sql_support.ts +++ b/packages/sync-rules/src/sql_support.ts @@ -1,3 +1,8 @@ +import { SelectFromStatement } from 'pgsql-ast-parser'; +import { SqlRuleError } from './errors.js'; +import { ExpressionType } from './ExpressionType.js'; +import { MATCH_CONST_FALSE, MATCH_CONST_TRUE } from './sql_filters.js'; +import { evaluateOperator, getOperatorReturnType } from './sql_functions.js'; import { ClauseError, CompiledClause, @@ -6,16 +11,11 @@ import { ParameterMatchClause, ParameterValueClause, QueryParameters, - SqliteValue, RowValueClause, + SqliteValue, StaticValueClause, TrueIfParametersMatch } from './types.js'; -import { MATCH_CONST_FALSE, MATCH_CONST_TRUE } from './sql_filters.js'; -import { SqlFunction, evaluateOperator, getOperatorReturnType } from './sql_functions.js'; -import { SelectFromStatement } from 'pgsql-ast-parser'; -import { SqlRuleError } from './errors.js'; -import { ExpressionType } from './ExpressionType.js'; export function isParameterMatchClause(clause: CompiledClause): clause is ParameterMatchClause { return Array.isArray((clause as ParameterMatchClause).inputParameters); @@ -78,18 +78,6 @@ export function compileStaticOperator(op: string, left: RowValueClause, right: R }; } -export function getOperatorFunction(op: string): SqlFunction { - return { - debugName: `operator${op}`, - call(...args: SqliteValue[]) { - return evaluateOperator(op, args[0], args[1]); - }, - getReturnType(args) { - return getOperatorReturnType(op, args[0], args[1]); - } - }; -} - export function andFilters(a: CompiledClause, b: CompiledClause): CompiledClause { if (isRowValueClause(a) && isRowValueClause(b)) { // Optimization diff --git a/packages/sync-rules/test/src/sync_rules.test.ts b/packages/sync-rules/test/src/sync_rules.test.ts index 26ff3adb3..54d507440 100644 --- a/packages/sync-rules/test/src/sync_rules.test.ts +++ b/packages/sync-rules/test/src/sync_rules.test.ts @@ -1,12 +1,5 @@ import { describe, expect, test } from 'vitest'; -import { - DEFAULT_TAG, - DartSchemaGenerator, - JsLegacySchemaGenerator, - SqlSyncRules, - StaticSchema, - TsSchemaGenerator -} from '../../src/index.js'; +import { SqlSyncRules } from '../../src/index.js'; import { ASSETS, BASIC_SCHEMA, PARSE_OPTIONS, TestSourceTable, USERS, normalizeTokenParameters } from './util.js'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index beb4d92be..eac450a03 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,16 +19,16 @@ importers: version: 3.2.5 bson: specifier: ^6.6.0 - version: 6.7.0 + version: 6.8.0 concurrently: specifier: ^8.2.2 version: 8.2.2 inquirer: specifier: ^9.2.7 - version: 9.2.22 + version: 9.3.5 npm-check-updates: specifier: ^17.1.2 - version: 17.1.2 + version: 17.1.3 prettier: specifier: ^3.3.3 version: 3.3.3 @@ -52,19 +52,19 @@ importers: version: 5.6.2 ws: specifier: ^8.2.3 - version: 8.2.3 + version: 8.18.0 libs/lib-services: dependencies: ajv: specifier: ^8.12.0 - version: 8.14.0 + version: 8.16.0 better-ajv-errors: specifier: ^1.2.0 - version: 1.2.0(ajv@8.14.0) + version: 1.2.0(ajv@8.16.0) bson: specifier: ^6.6.0 - version: 6.7.0 + version: 6.8.0 dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -79,14 +79,14 @@ importers: version: 9.0.1 winston: specifier: ^3.13.0 - version: 3.13.0 + version: 3.13.1 zod: specifier: ^3.23.8 version: 3.23.8 devDependencies: '@types/lodash': specifier: ^4.17.5 - version: 4.17.5 + version: 4.17.6 '@types/uuid': specifier: ^9.0.4 version: 9.0.8 @@ -116,7 +116,7 @@ importers: version: link:../../packages/types jose: specifier: ^4.15.1 - version: 4.15.5 + version: 4.15.9 pgwire: specifier: github:kagis/pgwire#f1cb95f9a0f42a612bb5a6b67bb2eb793fc5fc87 version: https://codeload.github.com/kagis/pgwire/tar.gz/f1cb95f9a0f42a612bb5a6b67bb2eb793fc5fc87 @@ -138,7 +138,7 @@ importers: version: 5.6.2 vite-tsconfig-paths: specifier: ^4.3.2 - version: 4.3.2(typescript@5.6.2)(vite@5.2.11(@types/node@22.5.5)) + version: 4.3.2(typescript@5.6.2)(vite@5.3.3(@types/node@22.5.5)) vitest: specifier: ^2.1.1 version: 2.1.1(@types/node@22.5.5) @@ -183,7 +183,7 @@ importers: version: 9.0.1 ws: specifier: ^8.17.0 - version: 8.17.0 + version: 8.18.0 devDependencies: '@types/uuid': specifier: ^9.0.4 @@ -193,7 +193,7 @@ importers: version: 8.2.3 bson: specifier: ^6.6.0 - version: 6.7.0 + version: 6.8.0 rsocket-websocket-client: specifier: 1.0.0-alpha.3 version: 1.0.0-alpha.3 @@ -220,7 +220,7 @@ importers: version: 0.51.1(@opentelemetry/api@1.8.0) '@opentelemetry/resources': specifier: ^1.24.1 - version: 1.24.1(@opentelemetry/api@1.8.0) + version: 1.25.1(@opentelemetry/api@1.8.0) '@opentelemetry/sdk-metrics': specifier: 1.24.1 version: 1.24.1(@opentelemetry/api@1.8.0) @@ -247,7 +247,7 @@ importers: version: 0.5.0 bson: specifier: ^6.6.0 - version: 6.7.0 + version: 6.8.0 commander: specifier: ^12.0.0 version: 12.1.0 @@ -262,16 +262,16 @@ importers: version: 5.0.0 jose: specifier: ^4.15.1 - version: 4.15.5 + version: 4.15.9 lodash: specifier: ^4.17.21 version: 4.17.21 lru-cache: specifier: ^10.2.2 - version: 10.2.2 + version: 10.4.3 mongodb: specifier: ^6.7.0 - version: 6.7.0(socks@2.8.3) + version: 6.8.0(socks@2.8.3) node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -283,17 +283,17 @@ importers: version: 9.0.1 winston: specifier: ^3.13.0 - version: 3.13.0 + version: 3.13.1 yaml: specifier: ^2.3.2 - version: 2.4.2 + version: 2.4.5 devDependencies: '@types/async': specifier: ^3.2.24 version: 3.2.24 '@types/lodash': specifier: ^4.17.5 - version: 4.17.5 + version: 4.17.6 '@types/uuid': specifier: ^9.0.4 version: 9.0.8 @@ -308,7 +308,7 @@ importers: version: 5.6.2 vite-tsconfig-paths: specifier: ^4.3.2 - version: 4.3.2(typescript@5.6.2)(vite@5.2.11(@types/node@22.5.5)) + version: 4.3.2(typescript@5.6.2)(vite@5.3.3(@types/node@22.5.5)) vitest: specifier: ^2.1.1 version: 2.1.1(@types/node@22.5.5) @@ -323,13 +323,13 @@ importers: version: 0.5.2 ajv: specifier: ^8.12.0 - version: 8.14.0 + version: 8.16.0 pgsql-ast-parser: specifier: ^11.1.0 version: 11.2.0 yaml: specifier: ^2.3.1 - version: 2.4.2 + version: 2.4.5 devDependencies: '@types/node': specifier: ^22.5.5 @@ -387,13 +387,13 @@ importers: version: link:../packages/types '@sentry/node': specifier: ^8.9.2 - version: 8.9.2 + version: 8.17.0 async-mutex: specifier: ^0.5.0 version: 0.5.0 bson: specifier: ^6.6.0 - version: 6.7.0 + version: 6.8.0 commander: specifier: ^12.0.0 version: 12.1.0 @@ -411,13 +411,13 @@ importers: version: 5.0.0 jose: specifier: ^4.15.1 - version: 4.15.5 + version: 4.15.9 lru-cache: specifier: ^10.0.1 - version: 10.2.2 + version: 10.4.3 mongodb: specifier: ^6.7.0 - version: 6.7.0(socks@2.8.3) + version: 6.8.0(socks@2.8.3) node-fetch: specifier: ^3.3.2 version: 3.3.2 @@ -432,14 +432,14 @@ importers: version: 9.0.1 winston: specifier: ^3.13.0 - version: 3.13.0 + version: 3.13.1 yaml: specifier: ^2.3.2 - version: 2.4.2 + version: 2.4.5 devDependencies: '@sentry/types': specifier: ^8.9.2 - version: 8.9.2 + version: 8.17.0 '@types/uuid': specifier: ^9.0.4 version: 9.0.8 @@ -448,7 +448,7 @@ importers: version: 2.4.1 nodemon: specifier: ^3.0.1 - version: 3.1.1 + version: 3.1.4 npm-check-updates: specifier: ^16.14.4 version: 16.14.20 @@ -472,7 +472,7 @@ importers: version: 12.1.0 jose: specifier: ^4.15.1 - version: 4.15.5 + version: 4.15.9 yaml: specifier: ^2.5.0 version: 2.5.0 @@ -486,20 +486,20 @@ importers: packages: - '@babel/code-frame@7.24.6': - resolution: {integrity: sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==} + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.24.6': - resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.24.6': - resolution: {integrity: sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==} + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/runtime@7.24.6': - resolution: {integrity: sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==} + '@babel/runtime@7.24.8': + resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==} engines: {node: '>=6.9.0'} '@changesets/apply-release-plan@7.0.5': @@ -572,146 +572,146 @@ packages: '@dabh/diagnostics@2.0.3': resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] - '@fastify/ajv-compiler@3.5.0': - resolution: {integrity: sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==} + '@fastify/ajv-compiler@3.6.0': + resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} '@fastify/cors@8.4.1': resolution: {integrity: sha512-iYQJtrY3pFiDS5mo5zRaudzg2OcUdJ96PD6xfkKOOEilly5nnrFZx/W6Sce2T79xxlEn2qpU3t5+qS2phS369w==} @@ -732,8 +732,8 @@ packages: resolution: {integrity: sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==} engines: {node: '>=10.10.0'} - '@inquirer/figures@1.0.2': - resolution: {integrity: sha512-4F1MBwVr3c/m4bAUef6LgkvBfSjzwH+OfldgHqcuacWwSUetFebM2wi58WfG9uk1rR98U6GwLed4asLJbwdV5w==} + '@inquirer/figures@1.0.3': + resolution: {integrity: sha512-ErXXzENMH5pJt5/ssXV0DfWUZqly8nGzf0UcBV9xTnP+KyffE2mqyxIMBrZ8ijQck2nU0TQm40EQB53YreyWHw==} engines: {node: '>=18'} '@isaacs/cliui@8.0.2': @@ -744,9 +744,6 @@ packages: resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} @@ -756,10 +753,6 @@ packages: '@js-sdsl/ordered-set@4.4.2': resolution: {integrity: sha512-ieYQ8WlBPKYzEo81H3q0DFbd8WtFRXXABb4+vRCF0AO3WWtJZFxYvRGdipUXGrd6tlSySmqhcPuO3J6SCodCxg==} - '@ljharb/through@2.3.13': - resolution: {integrity: sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==} - engines: {node: '>= 0.4'} - '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -819,8 +812,8 @@ packages: resolution: {integrity: sha512-E3skn949Pk1z2XtXu/lxf6QAZpawuTM/IUEXcAzpiUkTd73Hmvw26FiN3cJuTmkpM5hZzHwkomVdtrh/n/zzwA==} engines: {node: '>=14'} - '@opentelemetry/api-logs@0.52.0': - resolution: {integrity: sha512-HxjD7xH9iAE4OyhNaaSec65i1H6QZYBWSwWkowFfsc5YAcDvJG30/J1sRKXEQqdmUcKTXEAnA66UciqZha/4+Q==} + '@opentelemetry/api-logs@0.52.1': + resolution: {integrity: sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==} engines: {node: '>=14'} '@opentelemetry/api@1.6.0': @@ -835,8 +828,8 @@ packages: resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@1.25.0': - resolution: {integrity: sha512-sBW313mnMyFg0cp/40BRzrZBWG+581s2j5gIsa5fgGadswyILk4mNFATsqrCOpAx945RDuZ2B7ThQLgor9OpfA==} + '@opentelemetry/context-async-hooks@1.25.1': + resolution: {integrity: sha512-UW/ge9zjvAEmRWVapOP0qyCvPulWU6cQxGxDbWEFfGOj1VBBZAuOqTo3X6yWmDTD3Xe15ysCZChHncr2xFMIfQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -853,8 +846,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.9.0' - '@opentelemetry/core@1.25.0': - resolution: {integrity: sha512-n0B3s8rrqGrasTgNkXLKXzN0fXo+6IYP7M5b7AMsrZM33f/y6DS6kJ0Btd7SespASWq8bgL3taLo0oe0vB52IQ==} + '@opentelemetry/core@1.25.1': + resolution: {integrity: sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -877,110 +870,104 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-connect@0.37.0': - resolution: {integrity: sha512-SeQktDIH5rNzjiEiazWiJAIXkmnLOnNV7wwHpahrqE0Ph+Z3heqMfxRtoMtbdJSIYLfcNZYO51AjxZ00IXufdw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-express@0.40.1': - resolution: {integrity: sha512-+RKMvVe2zw3kIXRup9c1jFu3T4d0fs5aKy015TpiMyoCKX1UMu3Z0lfgYtuyiSTANvg5hZnDbWmQmqSPj9VTvg==} + '@opentelemetry/instrumentation-connect@0.38.0': + resolution: {integrity: sha512-2/nRnx3pjYEmdPIaBwtgtSviTKHWnDZN3R+TkRUnhIVrvBKVcq+I5B2rtd6mr6Fe9cHlZ9Ojcuh7pkNh/xdWWg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-fastify@0.37.0': - resolution: {integrity: sha512-WRjwzNZgupSzbEYvo9s+QuHJRqZJjVdNxSEpGBwWK8RKLlHGwGVAu0gcc2gPamJWUJsGqPGvahAPWM18ZkWj6A==} + '@opentelemetry/instrumentation-express@0.41.0': + resolution: {integrity: sha512-/B7fbMdaf3SYe5f1P973tkqd6s7XZirjpfkoJ63E7nltU30qmlgm9tY5XwZOzAFI0rHS9tbrFI2HFPAvQUFe/A==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-graphql@0.41.0': - resolution: {integrity: sha512-R/gXeljgIhaRDKquVkKYT5QHPnFouM8ooyePZEP0kqyaVAedtR1V7NfAUJbxfTG5fBQa5wdmLjvu63+tzRXZCA==} + '@opentelemetry/instrumentation-fastify@0.38.0': + resolution: {integrity: sha512-HBVLpTSYpkQZ87/Df3N0gAw7VzYZV3n28THIBrJWfuqw3Or7UqdhnjeuMIPQ04BKk3aZc0cWn2naSQObbh5vXw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-hapi@0.39.0': - resolution: {integrity: sha512-ik2nA9Yj2s2ay+aNY+tJsKCsEx6Tsc2g/MK0iWBW5tibwrWKTy1pdVt5sB3kd5Gkimqj23UV5+FH2JFcQLeKug==} + '@opentelemetry/instrumentation-graphql@0.42.0': + resolution: {integrity: sha512-N8SOwoKL9KQSX7z3gOaw5UaTeVQcfDO1c21csVHnmnmGUoqsXbArK2B8VuwPWcv6/BC/i3io+xTo7QGRZ/z28Q==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-http@0.52.0': - resolution: {integrity: sha512-E6ywZuxTa4LnVXZGwL1oj3e2Eog1yIaNqa8KjKXoGkDNKte9/SjQnePXOmhQYI0A9nf0UyFbP9aKd+yHrkJXUA==} + '@opentelemetry/instrumentation-hapi@0.40.0': + resolution: {integrity: sha512-8U/w7Ifumtd2bSN1OLaSwAAFhb9FyqWUki3lMMB0ds+1+HdSxYBe9aspEJEgvxAqOkrQnVniAPTEGf1pGM7SOw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-ioredis@0.41.0': - resolution: {integrity: sha512-rxiLloU8VyeJGm5j2fZS8ShVdB82n7VNP8wTwfUQqDwRfHCnkzGr+buKoxuhGD91gtwJ91RHkjHA1Eg6RqsUTg==} + '@opentelemetry/instrumentation-http@0.52.1': + resolution: {integrity: sha512-dG/aevWhaP+7OLv4BQQSEKMJv8GyeOp3Wxl31NHqE8xo9/fYMfEljiZphUHIfyg4gnZ9swMyWjfOQs5GUQe54Q==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-koa@0.41.0': - resolution: {integrity: sha512-mbPnDt7ELvpM2S0vixYUsde7122lgegLOJQxx8iJQbB8YHal/xnTh9v7IfArSVzIDo+E+080hxZyUZD4boOWkw==} + '@opentelemetry/instrumentation-ioredis@0.42.0': + resolution: {integrity: sha512-P11H168EKvBB9TUSasNDOGJCSkpT44XgoM6d3gRIWAa9ghLpYhl0uRkS8//MqPzcJVHr3h3RmfXIpiYLjyIZTw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mongodb@0.45.0': - resolution: {integrity: sha512-xnZP9+ayeB1JJyNE9cIiwhOJTzNEsRhXVdLgfzmrs48Chhhk026mQdM5CITfyXSCfN73FGAIB8d91+pflJEfWQ==} + '@opentelemetry/instrumentation-koa@0.42.0': + resolution: {integrity: sha512-H1BEmnMhho8o8HuNRq5zEI4+SIHDIglNB7BPKohZyWG4fWNuR7yM4GTlR01Syq21vODAS7z5omblScJD/eZdKw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mongoose@0.39.0': - resolution: {integrity: sha512-J1r66A7zJklPPhMtrFOO7/Ud2p0Pv5u8+r23Cd1JUH6fYPmftNJVsLp2urAt6PHK4jVqpP/YegN8wzjJ2mZNPQ==} + '@opentelemetry/instrumentation-mongodb@0.46.0': + resolution: {integrity: sha512-VF/MicZ5UOBiXrqBslzwxhN7TVqzu1/LN/QDpkskqM0Zm0aZ4CVRbUygL8d7lrjLn15x5kGIe8VsSphMfPJzlA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mysql2@0.39.0': - resolution: {integrity: sha512-Iypuq2z6TCfriAXCIZjRq8GTFCKhQv5SpXbmI+e60rYdXw8NHtMH4NXcGF0eKTuoCsC59IYSTUvDQYDKReaszA==} + '@opentelemetry/instrumentation-mongoose@0.40.0': + resolution: {integrity: sha512-niRi5ZUnkgzRhIGMOozTyoZIvJKNJyhijQI4nF4iFSb+FUx2v5fngfR+8XLmdQAO7xmsD8E5vEGdDVYVtKbZew==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-mysql@0.39.0': - resolution: {integrity: sha512-8snHPh83rhrDf31v9Kq0Nf+ts8hdr7NguuszRqZomZBHgE0+UyXZSkXHAAFZoBPPRMGyM68uaFE5hVtFl+wOcA==} + '@opentelemetry/instrumentation-mysql2@0.40.0': + resolution: {integrity: sha512-0xfS1xcqUmY7WE1uWjlmI67Xg3QsSUlNT+AcXHeA4BDUPwZtWqF4ezIwLgpVZfHOnkAEheqGfNSWd1PIu3Wnfg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-nestjs-core@0.38.0': - resolution: {integrity: sha512-M381Df1dM8aqihZz2yK+ugvMFK5vlHG/835dc67Sx2hH4pQEQYDA2PpFPTgc9AYYOydQaj7ClFQunESimjXDgg==} + '@opentelemetry/instrumentation-mysql@0.40.0': + resolution: {integrity: sha512-d7ja8yizsOCNMYIJt5PH/fKZXjb/mS48zLROO4BzZTtDfhNCl2UM/9VIomP2qkGIFVouSJrGr/T00EzY7bPtKA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-pg@0.42.0': - resolution: {integrity: sha512-sjgcM8CswYy8zxHgXv4RAZ09DlYhQ+9TdlourUs63Df/ek5RrB1ZbjznqW7PB6c3TyJJmX6AVtPTjAsROovEjA==} + '@opentelemetry/instrumentation-nestjs-core@0.39.0': + resolution: {integrity: sha512-mewVhEXdikyvIZoMIUry8eb8l3HUjuQjSjVbmLVTt4NQi35tkpnHQrG9bTRBrl3403LoWZ2njMPJyg4l6HfKvA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-redis-4@0.40.0': - resolution: {integrity: sha512-0ieQYJb6yl35kXA75LQUPhHtGjtQU9L85KlWa7d4ohBbk/iQKZ3X3CFl5jC5vNMq/GGPB3+w3IxNvALlHtrp7A==} + '@opentelemetry/instrumentation-pg@0.43.0': + resolution: {integrity: sha512-og23KLyoxdnAeFs1UWqzSonuCkePUzCX30keSYigIzJe/6WSYA8rnEI5lobcxPEzg+GcU06J7jzokuEHbjVJNw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.43.0': - resolution: {integrity: sha512-S1uHE+sxaepgp+t8lvIDuRgyjJWisAb733198kwQTUc9ZtYQ2V2gmyCtR1x21ePGVLoMiX/NWY7WA290hwkjJQ==} + '@opentelemetry/instrumentation-redis-4@0.41.0': + resolution: {integrity: sha512-H7IfGTqW2reLXqput4yzAe8YpDC0fmVNal95GHMLOrS89W+qWUKIqxolSh63hJyfmwPSFwXASzj7wpSk8Az+Dg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.51.1': - resolution: {integrity: sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w==} + '@opentelemetry/instrumentation@0.46.0': + resolution: {integrity: sha512-a9TijXZZbk0vI5TGLZl+0kxyFfrXHhX6Svtz7Pp2/VBlCSKrazuULEyoJQrOknJyFWNMEmbbJgOciHCCpQcisw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.52.0': - resolution: {integrity: sha512-LPwSIrw+60cheWaXsfGL8stBap/AppKQJFE+qqRvzYrgttXFH2ofoIMxWadeqPTq4BYOXM/C7Bdh/T+B60xnlQ==} + '@opentelemetry/instrumentation@0.52.1': + resolution: {integrity: sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -1013,8 +1000,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.9.0' - '@opentelemetry/resources@1.25.0': - resolution: {integrity: sha512-iHjydPMYJ+Li1auveJCq2rp5U2h6Mhq8BidiyE0jfVlDTFyR1ny8AfJHfmFzJ/RAM8vT8L7T21kcmGybxZC7lQ==} + '@opentelemetry/resources@1.25.1': + resolution: {integrity: sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -1044,8 +1031,8 @@ packages: peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.9.0' - '@opentelemetry/sdk-trace-base@1.25.0': - resolution: {integrity: sha512-6+g2fiRQUG39guCsKVeY8ToeuUf3YUnPkN6DXRA1qDmFLprlLvZm9cS6+chgbW70cZJ406FTtSCDnJwxDC5sGQ==} + '@opentelemetry/sdk-trace-base@1.25.1': + resolution: {integrity: sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -1058,8 +1045,8 @@ packages: resolution: {integrity: sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw==} engines: {node: '>=14'} - '@opentelemetry/semantic-conventions@1.25.0': - resolution: {integrity: sha512-M+kkXKRAIAiAP6qYyesfrC5TOmDpDVtsxuGfPcqd9B/iBrac+E14jYwrgm0yZBUIbIP2OnqC3j+UgkXLm1vxUQ==} + '@opentelemetry/semantic-conventions@1.25.1': + resolution: {integrity: sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==} engines: {node: '>=14'} '@opentelemetry/sql-common@0.40.1': @@ -1084,113 +1071,113 @@ packages: resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} engines: {node: '>=12'} - '@prisma/instrumentation@5.15.0': - resolution: {integrity: sha512-fCWOOOajTKOUEp43gRmBqwt6oN9bPJcLiloi2OG/2ED0N5z62Cuza6FDrlm3SJHQAXYlXqLE0HLdEE5WcUkOzg==} + '@prisma/instrumentation@5.16.1': + resolution: {integrity: sha512-4m5gRFWnQb8s/yTyGbMZkL7A5uJgqOWcWJxapwcAD0T0kh5sGPEVSQl/zTQvE9aduXhFAxOtC3gO+R8Hb5xO1Q==} - '@rollup/rollup-android-arm-eabi@4.18.0': - resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} + '@rollup/rollup-android-arm-eabi@4.18.1': + resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.18.0': - resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} + '@rollup/rollup-android-arm64@4.18.1': + resolution: {integrity: sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.18.0': - resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} + '@rollup/rollup-darwin-arm64@4.18.1': + resolution: {integrity: sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.18.0': - resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} + '@rollup/rollup-darwin-x64@4.18.1': + resolution: {integrity: sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.18.0': - resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': + resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.18.0': - resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} + '@rollup/rollup-linux-arm-musleabihf@4.18.1': + resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.18.0': - resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} + '@rollup/rollup-linux-arm64-gnu@4.18.1': + resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.18.0': - resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} + '@rollup/rollup-linux-arm64-musl@4.18.1': + resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': - resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': + resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.18.0': - resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} + '@rollup/rollup-linux-riscv64-gnu@4.18.1': + resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.18.0': - resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} + '@rollup/rollup-linux-s390x-gnu@4.18.1': + resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.18.0': - resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} + '@rollup/rollup-linux-x64-gnu@4.18.1': + resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.18.0': - resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} + '@rollup/rollup-linux-x64-musl@4.18.1': + resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.18.0': - resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} + '@rollup/rollup-win32-arm64-msvc@4.18.1': + resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.18.0': - resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} + '@rollup/rollup-win32-ia32-msvc@4.18.1': + resolution: {integrity: sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.18.0': - resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} + '@rollup/rollup-win32-x64-msvc@4.18.1': + resolution: {integrity: sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==} cpu: [x64] os: [win32] - '@sentry/core@8.9.2': - resolution: {integrity: sha512-ixm8NISFlPlEo3FjSaqmq4nnd13BRHoafwJ5MG+okCz6BKGZ1SexEggP42/QpGvDprUUHnfncG6WUMgcarr1zA==} + '@sentry/core@8.17.0': + resolution: {integrity: sha512-s62O0Re6WcvaVbH1IEeAWmj/ca8UhaRoFaDnc5TR68reOycBrgnqCNq3qHxBsELOA6NJowoK+T29DDGs9QVXhQ==} engines: {node: '>=14.18'} - '@sentry/node@8.9.2': - resolution: {integrity: sha512-Q+JBpR4yx3eUyyhwgugucfRtPg65gYvzJGEmjzcnDJXJqX8ms4HPpNv9o2Om7A4014JxIibUdrQ+p5idcT7SZA==} + '@sentry/node@8.17.0': + resolution: {integrity: sha512-HJ7B/zlpGMOIN+TnLzp6gbOpOzTk3Co19N39Y17T9MrR+5Z4eHdgEKWORFyE0Wy2KYKkVRwJ5zZJbfldc0EsEA==} engines: {node: '>=14.18'} - '@sentry/opentelemetry@8.9.2': - resolution: {integrity: sha512-Q6SHDQhrsBPcMi7ejqVdNTkt6SCTIhpGsFN8QR7daH3uvM0X2O7ciCuO9gRNRTEkflEINV4SBZEjANYH7BkRAg==} + '@sentry/opentelemetry@8.17.0': + resolution: {integrity: sha512-SKHfvHECIs7kqcXVRypXC6bQ7AQ4TTILamamZS5Ro1FP+i+yT8qEIoVWljoFZUIyO4J42mAP98THa1lCPK4BXA==} engines: {node: '>=14.18'} peerDependencies: '@opentelemetry/api': ^1.9.0 - '@opentelemetry/core': ^1.25.0 - '@opentelemetry/instrumentation': ^0.52.0 - '@opentelemetry/sdk-trace-base': ^1.25.0 - '@opentelemetry/semantic-conventions': ^1.25.0 + '@opentelemetry/core': ^1.25.1 + '@opentelemetry/instrumentation': ^0.52.1 + '@opentelemetry/sdk-trace-base': ^1.25.1 + '@opentelemetry/semantic-conventions': ^1.25.1 - '@sentry/types@8.9.2': - resolution: {integrity: sha512-+LFOyQGl+zk5SZRGZD2MEURf7i5RHgP/mt3s85Rza+vz8M211WJ0YsjkIGUJFSY842nged5QLx4JysLaBlLymg==} + '@sentry/types@8.17.0': + resolution: {integrity: sha512-v0nI0+ajiGTijhF1W/ryn2+zFVFr6VPn6lao3W4qKj9MlltIHa4/uuGzTaiCFwoPw7g5bZ1Q09SStpDXVMkz2A==} engines: {node: '>=14.18'} - '@sentry/utils@8.9.2': - resolution: {integrity: sha512-A4srR9mEBFdVXwSEKjQ94msUbVkMr8JeFiEj9ouOFORw/Y/ux/WV2bWVD/ZI9wq0TcTNK8L1wBgU8UMS5lIq3A==} + '@sentry/utils@8.17.0': + resolution: {integrity: sha512-HHtAPLOlvzhwgfYzxtuPnLUoGRMtMrFvopkii74zmx/1ZD4VN4PYPB2E5KFf3c18pTovw+kxF0ux6VrGiyAHsw==} engines: {node: '>=14.18'} '@sigstore/bundle@1.1.0': @@ -1244,62 +1231,20 @@ packages: resolution: {integrity: sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - '@types/accepts@1.3.7': - resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} - '@types/async@3.2.24': resolution: {integrity: sha512-8iHVLHsCCOBKjCF2KwFe0p9Z3rfM9mL+sSP8btyR5vTjJRAqpBYD28/ZLgXPf0pjG1VxOvtCV/BgXkQbpSe8Hw==} - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - '@types/connect@3.4.36': resolution: {integrity: sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==} - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/content-disposition@0.5.8': - resolution: {integrity: sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==} - - '@types/cookies@0.9.0': - resolution: {integrity: sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==} - '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/express-serve-static-core@4.19.1': - resolution: {integrity: sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==} - - '@types/express@4.17.21': - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} - - '@types/http-assert@1.5.5': - resolution: {integrity: sha512-4+tE/lwdAahgZT1g30Jkdm9PzFRde0xwxBNUyRsCitRvCQB90iuA2uJYdUnhnANRcqGXaWOGY4FEoxeElNAK2g==} - '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} - '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - - '@types/keygrip@1.0.6': - resolution: {integrity: sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==} - - '@types/koa-compose@3.2.8': - resolution: {integrity: sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==} - - '@types/koa@2.14.0': - resolution: {integrity: sha512-DTDUyznHGNHAl+wd1n0z1jxNajduyTh8R53xoewuerdBzGo6Ogj6F2299BFtrexJw4NtgjsI5SMPCmV9gZwGXA==} - - '@types/koa__router@12.0.3': - resolution: {integrity: sha512-5YUJVv6NwM1z7m6FuYpKfNLTZ932Z6EF6xy2BbtpJSyn13DKNQEkXVffFVSnJHxvwwWh2SAeumpjAYUELqgjyw==} - - '@types/lodash@4.17.5': - resolution: {integrity: sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==} - - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/lodash@4.17.6': + resolution: {integrity: sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==} '@types/mysql@2.15.22': resolution: {integrity: sha512-wK1pzsJVVAjYCSZWQoWHziQZbNggXFDUEIGf54g4ZM/ERuP86uGdWeKZWMYlqTPMZfHJJvLPyogXGvCOg87yLQ==} @@ -1322,26 +1267,14 @@ packages: '@types/pg@8.6.1': resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} - '@types/qs@6.9.15': - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} - - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/semver-utils@1.1.3': resolution: {integrity: sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==} '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - - '@types/serve-static@1.15.7': - resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} - - '@types/shimmer@1.0.5': - resolution: {integrity: sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==} + '@types/shimmer@1.2.0': + resolution: {integrity: sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==} '@types/strip-bom@3.0.0': resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} @@ -1414,12 +1347,12 @@ packages: peerDependencies: acorn: ^8 - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} engines: {node: '>=0.4.0'} hasBin: true @@ -1451,8 +1384,8 @@ packages: ajv: optional: true - ajv@8.14.0: - resolution: {integrity: sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==} + ajv@8.16.0: + resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -1564,8 +1497,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - bson@6.7.0: - resolution: {integrity: sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==} + bson@6.8.0: + resolution: {integrity: sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==} engines: {node: '>=16.20.1'} buffer-from@1.1.2: @@ -1597,10 +1530,6 @@ packages: resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} - camelcase@7.0.1: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} @@ -1773,8 +1702,8 @@ packages: date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1810,10 +1739,6 @@ packages: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} @@ -1872,16 +1797,8 @@ packages: err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} hasBin: true @@ -1939,8 +1856,8 @@ packages: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} - fast-json-stringify@5.16.0: - resolution: {integrity: sha512-A4bg6E15QrkuVO3f0SwIASgzMzR6XC4qTyTqhf3hYXy0iazbAdZKwkE+ox4WgzKyzM6ygvbdq3r134UjOaaAnA==} + fast-json-stringify@5.16.1: + resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} fast-memoize@2.5.2: resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} @@ -1952,8 +1869,8 @@ packages: resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} engines: {node: '>=6'} - fast-uri@2.3.0: - resolution: {integrity: sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw==} + fast-uri@2.4.0: + resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} fastify-plugin@4.5.1: resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} @@ -1990,8 +1907,8 @@ packages: fn.name@1.1.0: resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} form-data-encoder@2.1.4: @@ -2052,10 +1969,6 @@ packages: get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} - get-stdin@8.0.0: resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} engines: {node: '>=10'} @@ -2068,9 +1981,8 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob@10.4.1: - resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} - engines: {node: '>=16 || 14 >=14.18'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true glob@7.2.3: @@ -2093,9 +2005,6 @@ packages: globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - got@12.6.1: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} @@ -2114,17 +2023,6 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} - - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - has-unicode@2.0.1: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} @@ -2187,14 +2085,11 @@ packages: resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} - import-in-the-middle@1.4.2: - resolution: {integrity: sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==} + import-in-the-middle@1.7.1: + resolution: {integrity: sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==} - import-in-the-middle@1.7.4: - resolution: {integrity: sha512-Lk+qzWmiQuRPPulGQeK5qq0v32k2bHnWrRPFgqyvhw7Kkov5L6MOLOIU3pcWeujc9W4q54Cp3Q2WV16eQkc7Bg==} - - import-in-the-middle@1.8.0: - resolution: {integrity: sha512-/xQjze8szLNnJ5rvHSzn+dcVXqCAU6Plbk4P24U/jwPmg1wy7IIp9OjKIO5tYue8GSPhDpPDiApQjvBUmWwhsQ==} + import-in-the-middle@1.9.0: + resolution: {integrity: sha512-Ng1SJINJDBzyUEkx9Mj32XD8G0TQCUb5TMoL9V91CTn6F3wYZLygLuhNFrv0cNMBZaeptnL1zecV6XrIdHJ+xQ==} import-lazy@4.0.0: resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} @@ -2229,8 +2124,8 @@ packages: resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - inquirer@9.2.22: - resolution: {integrity: sha512-SqLLa/Oe5rZUagTR9z+Zd6izyatHglbmbvVofo1KzuVB54YHleWzeHNLoR7FOICGOeQSqeLh1cordb3MzhGcEw==} + inquirer@9.3.5: + resolution: {integrity: sha512-SVRCRovA7KaT6nqWB2mCNpTvU4cuZ0hOXo5KPyiyOcNNUIZwq/JKtvXuDJNaxfuJKabBYRu1ecHze0YEwDYoRQ==} engines: {node: '>=18'} ip-address@9.0.5: @@ -2256,8 +2151,9 @@ packages: resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} hasBin: true - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.14.0: + resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} + engines: {node: '>= 0.4'} is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} @@ -2333,15 +2229,14 @@ packages: ix@5.0.0: resolution: {integrity: sha512-6LyyrHnvNrSy5pKtW/KA+KKusHrB223aBJCJlIGPN7QBfDkEEtNrAkAz9lLLShIcdJntq6BiPCHuKaCM/9wwXw==} - jackspeak@3.1.2: - resolution: {integrity: sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==} - engines: {node: '>=14'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - jose@4.15.5: - resolution: {integrity: sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==} + jose@4.15.9: + resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2434,8 +2329,8 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} - logform@2.6.0: - resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==} + logform@2.6.1: + resolution: {integrity: sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==} engines: {node: '>= 12.0.0'} lossless-json@2.0.11: @@ -2448,9 +2343,8 @@ packages: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lru-cache@10.2.2: - resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} - engines: {node: 14 || >=16.14} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -2506,8 +2400,8 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: @@ -2570,8 +2464,8 @@ packages: mongodb-connection-string-url@3.0.1: resolution: {integrity: sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==} - mongodb@6.7.0: - resolution: {integrity: sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==} + mongodb@6.8.0: + resolution: {integrity: sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==} engines: {node: '>=16.20.1'} peerDependencies: '@aws-sdk/credential-providers': ^3.188.0 @@ -2643,8 +2537,8 @@ packages: engines: {node: ^12.13 || ^14.13 || >=16} hasBin: true - nodemon@3.1.1: - resolution: {integrity: sha512-k43xGaDtaDIcufn0Fc6fTtsdKSkV/hQzoQFigNH//GaKta28yoKVYXCnV+KXRqfT/YzsFaQU9VdeEG+HEyxr6A==} + nodemon@3.1.4: + resolution: {integrity: sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==} engines: {node: '>=10'} hasBin: true @@ -2677,8 +2571,8 @@ packages: engines: {node: '>=14.14'} hasBin: true - npm-check-updates@17.1.2: - resolution: {integrity: sha512-k3osAbCNXIXqC7QAuF2uRHsKtTUS50KhOW1VAojRHlLdZRh/5EYfduvnVPGDWsbQXFakbSrSbWDdV8qIvDSUtA==} + npm-check-updates@17.1.3: + resolution: {integrity: sha512-4uDLBWPuDHT5KLieIJ20FoAB8yqJejmupI42wPyfObgQOBbPAikQSwT73afDwREvhuxYrRDqlRvxTMSfvO+L8A==} engines: {node: ^18.18.0 || >=20.0.0, npm: '>=8.12.1'} hasBin: true @@ -2732,9 +2626,11 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - opentelemetry-instrumentation-fetch-node@1.2.0: - resolution: {integrity: sha512-aiSt/4ubOTyb1N5C2ZbGrBvaJOXIZhZvpRPYuUVxQJe27wJZqf/o65iPrqgLcgfeOLaQ8cS2Q+762jrYvniTrA==} + opentelemetry-instrumentation-fetch-node@1.2.3: + resolution: {integrity: sha512-Qb11T7KvoCevMaSeuamcLsAD+pZnavkhDnlVL0kRozfhl42dKG5Q3anUklAFKJZjY3twLR+BnRa6DlwwkIE/+A==} engines: {node: '>18.0.0'} + peerDependencies: + '@opentelemetry/api': ^1.6.0 ora@5.4.1: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} @@ -2783,6 +2679,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + package-json@8.1.1: resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} engines: {node: '>=14.16'} @@ -2795,9 +2694,9 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true - parse-github-url@1.0.2: - resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==} - engines: {node: '>=0.10.0'} + parse-github-url@1.0.3: + resolution: {integrity: sha512-tfalY5/4SqGaV/GIGzWyHnFjlpTPTNpENR9Ea2lLldSJ8EWXMsvacWucqY3m3I4YPtas15IxTLQVQ5NSYXPrww==} + engines: {node: '>= 0.10'} hasBin: true path-exists@4.0.0: @@ -2876,8 +2775,8 @@ packages: resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} hasBin: true - postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + postcss@8.4.39: + resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -3090,8 +2989,8 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.3.1: - resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} @@ -3103,13 +3002,13 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rimraf@5.0.7: - resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} - engines: {node: '>=14.18'} + rimraf@5.0.9: + resolution: {integrity: sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==} + engines: {node: 14 >=14.20 || 16 >=16.20 || >=18} hasBin: true - rollup@4.18.0: - resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} + rollup@4.18.1: + resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3166,10 +3065,6 @@ packages: set-cookie-parser@2.6.0: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -3396,8 +3291,8 @@ packages: resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} engines: {node: '>=14.0.0'} - tinyspy@3.0.0: - resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} tmp@0.0.33: @@ -3463,8 +3358,8 @@ packages: peerDependencies: typescript: '*' - tsconfck@3.0.3: - resolution: {integrity: sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==} + tsconfck@3.1.1: + resolution: {integrity: sha512-00eoI6WY57SvZEVjm13stEVE90VkEdJAFGgpFLTsZbJyW/LwFQ7uQxJHWpZ2hzSWgCPKc9AnBnNP+0X7o3hAmQ==} engines: {node: ^18 || >=20} hasBin: true peerDependencies: @@ -3476,8 +3371,8 @@ packages: tsconfig@7.0.0: resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} tuf-js@1.1.7: resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==} @@ -3578,8 +3473,8 @@ packages: vite: optional: true - vite@5.2.11: - resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} + vite@5.3.3: + resolution: {integrity: sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -3672,12 +3567,12 @@ packages: resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} engines: {node: '>=12'} - winston-transport@4.7.0: - resolution: {integrity: sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==} + winston-transport@4.7.1: + resolution: {integrity: sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==} engines: {node: '>= 12.0.0'} - winston@3.13.0: - resolution: {integrity: sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==} + winston@3.13.1: + resolution: {integrity: sha512-SvZit7VFNvXRzbqGHsv5KSmgbEYR5EiQfDAL9gxYkRqa934Hnk++zze0wANKtMHcy/gI4W/3xmSDwlhf865WGw==} engines: {node: '>= 12.0.0'} wrap-ansi@6.2.0: @@ -3698,8 +3593,8 @@ packages: write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} - ws@8.17.0: - resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -3710,18 +3605,6 @@ packages: utf-8-validate: optional: true - ws@8.2.3: - resolution: {integrity: sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - xdg-basedir@5.1.0: resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} engines: {node: '>=12'} @@ -3740,8 +3623,8 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml@2.4.2: - resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} + yaml@2.4.5: + resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} engines: {node: '>= 14'} hasBin: true @@ -3774,26 +3657,30 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} snapshots: - '@babel/code-frame@7.24.6': + '@babel/code-frame@7.24.7': dependencies: - '@babel/highlight': 7.24.6 + '@babel/highlight': 7.24.7 picocolors: 1.0.1 - '@babel/helper-validator-identifier@7.24.6': {} + '@babel/helper-validator-identifier@7.24.7': {} - '@babel/highlight@7.24.6': + '@babel/highlight@7.24.7': dependencies: - '@babel/helper-validator-identifier': 7.24.6 + '@babel/helper-validator-identifier': 7.24.7 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.0.1 - '@babel/runtime@7.24.6': + '@babel/runtime@7.24.8': dependencies: regenerator-runtime: 0.14.1 @@ -3956,80 +3843,80 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 - '@esbuild/aix-ppc64@0.20.2': + '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/android-arm64@0.20.2': + '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm@0.20.2': + '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-x64@0.20.2': + '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.20.2': + '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-x64@0.20.2': + '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.20.2': + '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.20.2': + '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/linux-arm64@0.20.2': + '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm@0.20.2': + '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-ia32@0.20.2': + '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-loong64@0.20.2': + '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-mips64el@0.20.2': + '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-ppc64@0.20.2': + '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.20.2': + '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-s390x@0.20.2': + '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-x64@0.20.2': + '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.20.2': + '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.20.2': + '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.20.2': + '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/win32-arm64@0.20.2': + '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-ia32@0.20.2': + '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-x64@0.20.2': + '@esbuild/win32-x64@0.21.5': optional: true - '@fastify/ajv-compiler@3.5.0': + '@fastify/ajv-compiler@3.6.0': dependencies: - ajv: 8.14.0 - ajv-formats: 2.1.1(ajv@8.14.0) - fast-uri: 2.3.0 + ajv: 8.16.0 + ajv-formats: 2.1.1(ajv@8.16.0) + fast-uri: 2.4.0 '@fastify/cors@8.4.1': dependencies: @@ -4040,7 +3927,7 @@ snapshots: '@fastify/fast-json-stringify-compiler@4.3.0': dependencies: - fast-json-stringify: 5.16.0 + fast-json-stringify: 5.16.1 '@fastify/merge-json-schemas@0.1.1': dependencies: @@ -4050,7 +3937,7 @@ snapshots: '@humanwhocodes/momoa@2.0.4': {} - '@inquirer/figures@1.0.2': {} + '@inquirer/figures@1.0.3': {} '@isaacs/cliui@8.0.2': dependencies: @@ -4063,31 +3950,25 @@ snapshots: '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.4.15': {} - '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@js-sdsl/ordered-set@4.4.2': {} - '@ljharb/through@2.3.13': - dependencies: - call-bind: 1.0.7 - '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.24.8 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.24.8 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -4163,9 +4044,9 @@ snapshots: dependencies: '@opentelemetry/api': 1.8.0 - '@opentelemetry/api-logs@0.52.0': + '@opentelemetry/api-logs@0.52.1': dependencies: - '@opentelemetry/api': 1.8.0 + '@opentelemetry/api': 1.6.0 '@opentelemetry/api@1.6.0': {} @@ -4173,7 +4054,7 @@ snapshots: '@opentelemetry/api@1.9.0': {} - '@opentelemetry/context-async-hooks@1.25.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/context-async-hooks@1.25.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -4197,15 +4078,15 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.24.1 - '@opentelemetry/core@1.25.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/core@1.25.1(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/semantic-conventions': 1.25.1 - '@opentelemetry/core@1.25.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/semantic-conventions': 1.25.1 '@opentelemetry/exporter-metrics-otlp-http@0.51.1(@opentelemetry/api@1.8.0)': dependencies: @@ -4230,149 +4111,147 @@ snapshots: '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) '@opentelemetry/sdk-metrics': 1.24.1(@opentelemetry/api@1.8.0) - '@opentelemetry/instrumentation-connect@0.37.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-connect@0.38.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@types/connect': 3.4.36 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-express@0.40.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-express@0.41.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-fastify@0.37.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-fastify@0.38.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-graphql@0.41.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-graphql@0.42.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-hapi@0.39.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-hapi@0.40.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-http@0.52.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-http@0.52.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 semver: 7.6.2 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-ioredis@0.41.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-ioredis@0.42.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-koa@0.41.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-koa@0.42.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 - '@types/koa': 2.14.0 - '@types/koa__router': 12.0.3 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongodb@0.45.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mongodb@0.46.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': 1.24.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongoose@0.39.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mongoose@0.40.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql2@0.39.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mysql2@0.40.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql@0.39.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-mysql@0.40.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@types/mysql': 2.15.22 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-nestjs-core@0.38.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-nestjs-core@0.39.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-pg@0.42.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-pg@0.43.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@opentelemetry/sql-common': 0.40.1(@opentelemetry/api@1.9.0) '@types/pg': 8.6.1 '@types/pg-pool': 2.0.4 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-redis-4@0.40.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-redis-4@0.41.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.36.2 - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.43.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation@0.46.0(@opentelemetry/api@1.9.0)': dependencies: - '@opentelemetry/api': 1.8.0 - '@types/shimmer': 1.0.5 - import-in-the-middle: 1.4.2 + '@opentelemetry/api': 1.9.0 + '@types/shimmer': 1.2.0 + import-in-the-middle: 1.7.1 require-in-the-middle: 7.3.0 semver: 7.6.2 shimmer: 1.2.1 @@ -4380,24 +4259,24 @@ snapshots: - supports-color optional: true - '@opentelemetry/instrumentation@0.51.1(@opentelemetry/api@1.8.0)': + '@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 - '@opentelemetry/api-logs': 0.51.1 - '@types/shimmer': 1.0.5 - import-in-the-middle: 1.7.4 + '@opentelemetry/api-logs': 0.52.1 + '@types/shimmer': 1.2.0 + import-in-the-middle: 1.9.0 require-in-the-middle: 7.3.0 semver: 7.6.2 shimmer: 1.2.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.52.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.52.0 - '@types/shimmer': 1.0.5 - import-in-the-middle: 1.8.0 + '@opentelemetry/api-logs': 0.52.1 + '@types/shimmer': 1.2.0 + import-in-the-middle: 1.9.0 require-in-the-middle: 7.3.0 semver: 7.6.2 shimmer: 1.2.1 @@ -4445,17 +4324,17 @@ snapshots: '@opentelemetry/core': 1.24.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.24.1 - '@opentelemetry/resources@1.25.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/resources@1.25.1(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.25.1 - '@opentelemetry/resources@1.25.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/resources@1.25.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@opentelemetry/sdk-logs@0.51.1(@opentelemetry/api-logs@0.51.1)(@opentelemetry/api@1.8.0)': dependencies: @@ -4499,30 +4378,30 @@ snapshots: '@opentelemetry/resources': 1.24.1(@opentelemetry/api@1.8.0) '@opentelemetry/semantic-conventions': 1.24.1 - '@opentelemetry/sdk-trace-base@1.25.0(@opentelemetry/api@1.8.0)': + '@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.8.0) - '@opentelemetry/resources': 1.25.0(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.8.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.25.1 - '@opentelemetry/sdk-trace-base@1.25.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 '@opentelemetry/semantic-conventions@1.17.0': {} '@opentelemetry/semantic-conventions@1.24.1': {} - '@opentelemetry/semantic-conventions@1.25.0': {} + '@opentelemetry/semantic-conventions@1.25.1': {} '@opentelemetry/sql-common@0.40.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) '@pkgjs/parseargs@0.11.0': optional: true @@ -4539,117 +4418,117 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 - '@prisma/instrumentation@5.15.0': + '@prisma/instrumentation@5.16.1': dependencies: '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.51.1(@opentelemetry/api@1.8.0) - '@opentelemetry/sdk-trace-base': 1.25.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.8.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.8.0) transitivePeerDependencies: - supports-color - '@rollup/rollup-android-arm-eabi@4.18.0': + '@rollup/rollup-android-arm-eabi@4.18.1': optional: true - '@rollup/rollup-android-arm64@4.18.0': + '@rollup/rollup-android-arm64@4.18.1': optional: true - '@rollup/rollup-darwin-arm64@4.18.0': + '@rollup/rollup-darwin-arm64@4.18.1': optional: true - '@rollup/rollup-darwin-x64@4.18.0': + '@rollup/rollup-darwin-x64@4.18.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.18.0': + '@rollup/rollup-linux-arm-musleabihf@4.18.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.18.0': + '@rollup/rollup-linux-arm64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.18.0': + '@rollup/rollup-linux-arm64-musl@4.18.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.18.0': + '@rollup/rollup-linux-riscv64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.18.0': + '@rollup/rollup-linux-s390x-gnu@4.18.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.18.0': + '@rollup/rollup-linux-x64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-x64-musl@4.18.0': + '@rollup/rollup-linux-x64-musl@4.18.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.18.0': + '@rollup/rollup-win32-arm64-msvc@4.18.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.18.0': + '@rollup/rollup-win32-ia32-msvc@4.18.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.18.0': + '@rollup/rollup-win32-x64-msvc@4.18.1': optional: true - '@sentry/core@8.9.2': + '@sentry/core@8.17.0': dependencies: - '@sentry/types': 8.9.2 - '@sentry/utils': 8.9.2 + '@sentry/types': 8.17.0 + '@sentry/utils': 8.17.0 - '@sentry/node@8.9.2': + '@sentry/node@8.17.0': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-connect': 0.37.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-express': 0.40.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-fastify': 0.37.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-graphql': 0.41.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-hapi': 0.39.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-http': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-ioredis': 0.41.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-koa': 0.41.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongodb': 0.45.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mongoose': 0.39.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql': 0.39.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-mysql2': 0.39.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-nestjs-core': 0.38.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-pg': 0.42.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-redis-4': 0.40.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 - '@prisma/instrumentation': 5.15.0 - '@sentry/core': 8.9.2 - '@sentry/opentelemetry': 8.9.2(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.0) - '@sentry/types': 8.9.2 - '@sentry/utils': 8.9.2 + '@opentelemetry/context-async-hooks': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-connect': 0.38.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-express': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fastify': 0.38.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-graphql': 0.42.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-hapi': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-http': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-ioredis': 0.42.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-koa': 0.42.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongodb': 0.46.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongoose': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql2': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-nestjs-core': 0.39.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pg': 0.43.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-redis-4': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@prisma/instrumentation': 5.16.1 + '@sentry/core': 8.17.0 + '@sentry/opentelemetry': 8.17.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.6.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.6.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.6.0))(@opentelemetry/semantic-conventions@1.25.1) + '@sentry/types': 8.17.0 + '@sentry/utils': 8.17.0 optionalDependencies: - opentelemetry-instrumentation-fetch-node: 1.2.0 + opentelemetry-instrumentation-fetch-node: 1.2.3(@opentelemetry/api@1.9.0) transitivePeerDependencies: - supports-color - '@sentry/opentelemetry@8.9.2(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.0)': + '@sentry/opentelemetry@8.17.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.6.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.6.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.6.0))(@opentelemetry/semantic-conventions@1.25.1)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.52.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.25.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.25.0 - '@sentry/core': 8.9.2 - '@sentry/types': 8.9.2 - '@sentry/utils': 8.9.2 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@sentry/core': 8.17.0 + '@sentry/types': 8.17.0 + '@sentry/utils': 8.17.0 - '@sentry/types@8.9.2': {} + '@sentry/types@8.17.0': {} - '@sentry/utils@8.9.2': + '@sentry/utils@8.17.0': dependencies: - '@sentry/types': 8.9.2 + '@sentry/types': 8.17.0 '@sigstore/bundle@1.1.0': dependencies: @@ -4697,82 +4576,19 @@ snapshots: '@tufjs/models@1.0.4': dependencies: '@tufjs/canonical-json': 1.0.0 - minimatch: 9.0.4 - - '@types/accepts@1.3.7': - dependencies: - '@types/node': 22.5.5 + minimatch: 9.0.5 '@types/async@3.2.24': {} - '@types/body-parser@1.19.5': - dependencies: - '@types/connect': 3.4.38 - '@types/node': 22.5.5 - '@types/connect@3.4.36': dependencies: '@types/node': 22.5.5 - '@types/connect@3.4.38': - dependencies: - '@types/node': 22.5.5 - - '@types/content-disposition@0.5.8': {} - - '@types/cookies@0.9.0': - dependencies: - '@types/connect': 3.4.38 - '@types/express': 4.17.21 - '@types/keygrip': 1.0.6 - '@types/node': 22.5.5 - '@types/estree@1.0.5': {} - '@types/express-serve-static-core@4.19.1': - dependencies: - '@types/node': 22.5.5 - '@types/qs': 6.9.15 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - - '@types/express@4.17.21': - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.19.1 - '@types/qs': 6.9.15 - '@types/serve-static': 1.15.7 - - '@types/http-assert@1.5.5': {} - '@types/http-cache-semantics@4.0.4': {} - '@types/http-errors@2.0.4': {} - - '@types/keygrip@1.0.6': {} - - '@types/koa-compose@3.2.8': - dependencies: - '@types/koa': 2.14.0 - - '@types/koa@2.14.0': - dependencies: - '@types/accepts': 1.3.7 - '@types/content-disposition': 0.5.8 - '@types/cookies': 0.9.0 - '@types/http-assert': 1.5.5 - '@types/http-errors': 2.0.4 - '@types/keygrip': 1.0.6 - '@types/koa-compose': 3.2.8 - '@types/node': 22.5.5 - - '@types/koa__router@12.0.3': - dependencies: - '@types/koa': 2.14.0 - - '@types/lodash@4.17.5': {} - - '@types/mime@1.3.5': {} + '@types/lodash@4.17.6': {} '@types/mysql@2.15.22': dependencies: @@ -4798,26 +4614,11 @@ snapshots: pg-protocol: 1.6.1 pg-types: 2.2.0 - '@types/qs@6.9.15': {} - - '@types/range-parser@1.2.7': {} - '@types/semver-utils@1.1.3': {} '@types/semver@7.5.8': {} - '@types/send@0.17.4': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 22.5.5 - - '@types/serve-static@1.15.7': - dependencies: - '@types/http-errors': 2.0.4 - '@types/node': 22.5.5 - '@types/send': 0.17.4 - - '@types/shimmer@1.0.5': {} + '@types/shimmer@1.2.0': {} '@types/strip-bom@3.0.0': {} @@ -4844,13 +4645,13 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.2.11(@types/node@22.5.5))': + '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.3.3(@types/node@22.5.5))': dependencies: '@vitest/spy': 2.1.1 estree-walker: 3.0.3 magic-string: 0.30.11 optionalDependencies: - vite: 5.2.11(@types/node@22.5.5) + vite: 5.3.3(@types/node@22.5.5) '@vitest/pretty-format@2.1.1': dependencies: @@ -4869,7 +4670,7 @@ snapshots: '@vitest/spy@2.1.1': dependencies: - tinyspy: 3.0.0 + tinyspy: 3.0.2 '@vitest/utils@2.1.1': dependencies: @@ -4885,22 +4686,24 @@ snapshots: abstract-logging@2.0.1: {} - acorn-import-assertions@1.9.0(acorn@8.11.3): + acorn-import-assertions@1.9.0(acorn@8.12.1): dependencies: - acorn: 8.11.3 + acorn: 8.12.1 optional: true - acorn-import-attributes@1.9.5(acorn@8.11.3): + acorn-import-attributes@1.9.5(acorn@8.12.1): dependencies: - acorn: 8.11.3 + acorn: 8.12.1 - acorn-walk@8.3.2: {} + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 - acorn@8.11.3: {} + acorn@8.12.1: {} agent-base@6.0.2: dependencies: - debug: 4.3.7 + debug: 4.3.5(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -4913,15 +4716,15 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ajv-formats@2.1.1(ajv@8.14.0): + ajv-formats@2.1.1(ajv@8.16.0): optionalDependencies: - ajv: 8.14.0 + ajv: 8.16.0 - ajv-formats@3.0.1(ajv@8.14.0): + ajv-formats@3.0.1(ajv@8.16.0): optionalDependencies: - ajv: 8.14.0 + ajv: 8.16.0 - ajv@8.14.0: + ajv@8.16.0: dependencies: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 @@ -4978,7 +4781,7 @@ snapshots: async-mutex@0.5.0: dependencies: - tslib: 2.6.2 + tslib: 2.6.3 async@3.2.5: {} @@ -4993,11 +4796,11 @@ snapshots: base64-js@1.5.1: {} - better-ajv-errors@1.2.0(ajv@8.14.0): + better-ajv-errors@1.2.0(ajv@8.16.0): dependencies: - '@babel/code-frame': 7.24.6 + '@babel/code-frame': 7.24.7 '@humanwhocodes/momoa': 2.0.4 - ajv: 8.14.0 + ajv: 8.16.0 chalk: 4.1.2 jsonpointer: 5.0.1 leven: 3.1.0 @@ -5038,7 +4841,7 @@ snapshots: dependencies: fill-range: 7.1.1 - bson@6.7.0: {} + bson@6.8.0: {} buffer-from@1.1.2: {} @@ -5081,7 +4884,7 @@ snapshots: dependencies: '@npmcli/fs': 3.1.1 fs-minipass: 3.0.3 - glob: 10.4.1 + glob: 10.4.5 lru-cache: 7.18.3 minipass: 7.1.2 minipass-collect: 1.0.2 @@ -5104,14 +4907,6 @@ snapshots: normalize-url: 8.0.1 responselike: 3.0.0 - call-bind@1.0.7: - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - set-function-length: 1.2.2 - camelcase@7.0.1: {} chai@5.1.1: @@ -5294,11 +5089,11 @@ snapshots: date-fns@2.30.0: dependencies: - '@babel/runtime': 7.24.6 + '@babel/runtime': 7.24.8 date-fns@3.6.0: {} - debug@4.3.4(supports-color@5.5.0): + debug@4.3.5(supports-color@5.5.0): dependencies: ms: 2.1.2 optionalDependencies: @@ -5322,12 +5117,6 @@ snapshots: defer-to-connect@2.0.1: {} - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - gopd: 1.0.1 - delegates@1.0.0: {} detect-indent@6.1.0: {} @@ -5374,37 +5163,31 @@ snapshots: err-code@2.0.3: {} - es-define-property@1.0.0: - dependencies: - get-intrinsic: 1.2.4 - - es-errors@1.3.0: {} - - esbuild@0.20.2: + esbuild@0.21.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 escalade@3.1.2: {} @@ -5456,15 +5239,15 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.7 - fast-json-stringify@5.16.0: + fast-json-stringify@5.16.1: dependencies: '@fastify/merge-json-schemas': 0.1.1 - ajv: 8.14.0 - ajv-formats: 3.0.1(ajv@8.14.0) + ajv: 8.16.0 + ajv-formats: 3.0.1(ajv@8.16.0) fast-deep-equal: 3.1.3 - fast-uri: 2.3.0 + fast-uri: 2.4.0 json-schema-ref-resolver: 1.0.1 - rfdc: 1.3.1 + rfdc: 1.4.1 fast-memoize@2.5.2: {} @@ -5474,25 +5257,25 @@ snapshots: fast-redact@3.5.0: {} - fast-uri@2.3.0: {} + fast-uri@2.4.0: {} fastify-plugin@4.5.1: {} fastify@4.23.2: dependencies: - '@fastify/ajv-compiler': 3.5.0 + '@fastify/ajv-compiler': 3.6.0 '@fastify/error': 3.4.1 '@fastify/fast-json-stringify-compiler': 4.3.0 abstract-logging: 2.0.1 avvio: 8.3.2 fast-content-type-parse: 1.1.0 - fast-json-stringify: 5.16.0 + fast-json-stringify: 5.16.1 find-my-way: 7.7.0 light-my-request: 5.13.0 pino: 8.21.0 process-warning: 2.3.2 proxy-addr: 2.0.7 - rfdc: 1.3.1 + rfdc: 1.4.1 secure-json-parse: 2.7.0 semver: 7.6.2 toad-cache: 3.7.0 @@ -5530,7 +5313,7 @@ snapshots: fn.name@1.1.0: {} - foreground-child@3.1.1: + foreground-child@3.2.1: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 @@ -5589,14 +5372,6 @@ snapshots: get-func-name@2.0.2: {} - get-intrinsic@1.2.4: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 - hasown: 2.0.2 - get-stdin@8.0.0: {} get-stream@6.0.1: {} @@ -5605,12 +5380,13 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.4.1: + glob@10.4.5: dependencies: - foreground-child: 3.1.1 - jackspeak: 3.1.2 - minimatch: 9.0.4 + foreground-child: 3.2.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 minipass: 7.1.2 + package-json-from-dist: 1.0.0 path-scurry: 1.11.1 glob@7.2.3: @@ -5645,10 +5421,6 @@ snapshots: globrex@0.1.2: {} - gopd@1.0.1: - dependencies: - get-intrinsic: 1.2.4 - got@12.6.1: dependencies: '@sindresorhus/is': 5.6.0 @@ -5671,14 +5443,6 @@ snapshots: has-flag@4.0.0: {} - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.0 - - has-proto@1.0.3: {} - - has-symbols@1.0.3: {} - has-unicode@2.0.1: {} has-yarn@3.0.0: {} @@ -5701,7 +5465,7 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.7 + debug: 4.3.5(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -5713,7 +5477,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.7 + debug: 4.3.5(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -5738,29 +5502,22 @@ snapshots: ignore-walk@6.0.5: dependencies: - minimatch: 9.0.4 + minimatch: 9.0.5 ignore@5.3.1: {} - import-in-the-middle@1.4.2: + import-in-the-middle@1.7.1: dependencies: - acorn: 8.11.3 - acorn-import-assertions: 1.9.0(acorn@8.11.3) + acorn: 8.12.1 + acorn-import-assertions: 1.9.0(acorn@8.12.1) cjs-module-lexer: 1.3.1 module-details-from-path: 1.0.3 optional: true - import-in-the-middle@1.7.4: + import-in-the-middle@1.9.0: dependencies: - acorn: 8.11.3 - acorn-import-attributes: 1.9.5(acorn@8.11.3) - cjs-module-lexer: 1.3.1 - module-details-from-path: 1.0.3 - - import-in-the-middle@1.8.0: - dependencies: - acorn: 8.11.3 - acorn-import-attributes: 1.9.5(acorn@8.11.3) + acorn: 8.12.1 + acorn-import-attributes: 1.9.5(acorn@8.12.1) cjs-module-lexer: 1.3.1 module-details-from-path: 1.0.3 @@ -5785,16 +5542,12 @@ snapshots: ini@4.1.3: {} - inquirer@9.2.22: + inquirer@9.3.5: dependencies: - '@inquirer/figures': 1.0.2 - '@ljharb/through': 2.3.13 + '@inquirer/figures': 1.0.3 ansi-escapes: 4.3.2 - chalk: 5.3.0 - cli-cursor: 3.1.0 cli-width: 4.1.0 external-editor: 3.1.0 - lodash: 4.17.21 mute-stream: 1.0.0 ora: 5.4.1 run-async: 3.0.0 @@ -5802,6 +5555,7 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 ip-address@9.0.5: dependencies: @@ -5822,7 +5576,7 @@ snapshots: dependencies: ci-info: 3.9.0 - is-core-module@2.13.1: + is-core-module@2.14.0: dependencies: hasown: 2.0.2 @@ -5874,9 +5628,9 @@ snapshots: ix@5.0.0: dependencies: '@types/node': 13.13.52 - tslib: 2.6.2 + tslib: 2.6.3 - jackspeak@3.1.2: + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: @@ -5884,7 +5638,7 @@ snapshots: jju@1.4.0: {} - jose@4.15.5: {} + jose@4.15.9: {} js-tokens@4.0.0: {} @@ -5964,7 +5718,7 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 - logform@2.6.0: + logform@2.6.1: dependencies: '@colors/colors': 1.6.0 '@types/triple-beam': 1.3.5 @@ -5981,7 +5735,7 @@ snapshots: lowercase-keys@3.0.0: {} - lru-cache@10.2.2: {} + lru-cache@10.4.3: {} lru-cache@4.1.5: dependencies: @@ -6063,7 +5817,7 @@ snapshots: dependencies: brace-expansion: 2.0.1 - minimatch@9.0.4: + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -6132,10 +5886,10 @@ snapshots: '@types/whatwg-url': 11.0.5 whatwg-url: 13.0.0 - mongodb@6.7.0(socks@2.8.3): + mongodb@6.8.0(socks@2.8.3): dependencies: '@mongodb-js/saslprep': 1.1.7 - bson: 6.7.0 + bson: 6.8.0 mongodb-connection-string-url: 3.0.1 optionalDependencies: socks: 2.8.3 @@ -6188,10 +5942,10 @@ snapshots: - bluebird - supports-color - nodemon@3.1.1: + nodemon@3.1.4: dependencies: chokidar: 3.6.0 - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.5(supports-color@5.5.0) ignore-by-default: 1.0.1 minimatch: 3.1.2 pstree.remy: 1.1.8 @@ -6213,7 +5967,7 @@ snapshots: normalize-package-data@5.0.0: dependencies: hosted-git-info: 6.1.1 - is-core-module: 2.13.1 + is-core-module: 2.14.0 semver: 7.6.2 validate-npm-package-license: 3.0.4 @@ -6243,15 +5997,15 @@ snapshots: jsonlines: 0.1.1 lodash: 4.17.21 make-fetch-happen: 11.1.1 - minimatch: 9.0.4 + minimatch: 9.0.5 p-map: 4.0.0 pacote: 15.2.0 - parse-github-url: 1.0.2 + parse-github-url: 1.0.3 progress: 2.0.3 prompts-ncu: 3.0.0 rc-config-loader: 4.1.3 remote-git-tags: 3.0.0 - rimraf: 5.0.7 + rimraf: 5.0.9 semver: 7.6.2 semver-utils: 1.1.4 source-map-support: 0.5.21 @@ -6264,7 +6018,7 @@ snapshots: - bluebird - supports-color - npm-check-updates@17.1.2: {} + npm-check-updates@17.1.3: {} npm-install-checks@6.3.0: dependencies: @@ -6327,11 +6081,11 @@ snapshots: dependencies: mimic-fn: 2.1.0 - opentelemetry-instrumentation-fetch-node@1.2.0: + opentelemetry-instrumentation-fetch-node@1.2.3(@opentelemetry/api@1.9.0): dependencies: - '@opentelemetry/api': 1.8.0 - '@opentelemetry/instrumentation': 0.43.0(@opentelemetry/api@1.8.0) - '@opentelemetry/semantic-conventions': 1.25.0 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.46.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 transitivePeerDependencies: - supports-color optional: true @@ -6382,6 +6136,8 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.0: {} + package-json@8.1.1: dependencies: got: 12.6.1 @@ -6415,7 +6171,7 @@ snapshots: - bluebird - supports-color - parse-github-url@1.0.2: {} + parse-github-url@1.0.3: {} path-exists@4.0.0: {} @@ -6427,7 +6183,7 @@ snapshots: path-scurry@1.11.1: dependencies: - lru-cache: 10.2.2 + lru-cache: 10.4.3 minipass: 7.1.2 path-type@4.0.0: {} @@ -6488,7 +6244,7 @@ snapshots: sonic-boom: 3.8.1 thread-stream: 2.7.0 - postcss@8.4.38: + postcss@8.4.39: dependencies: nanoid: 3.3.7 picocolors: 1.0.1 @@ -6568,7 +6324,7 @@ snapshots: rc-config-loader@4.1.3: dependencies: - debug: 4.3.4(supports-color@5.5.0) + debug: 4.3.5(supports-color@5.5.0) js-yaml: 4.1.0 json5: 2.2.3 require-from-string: 2.0.2 @@ -6589,7 +6345,7 @@ snapshots: read-package-json@6.0.4: dependencies: - glob: 10.4.1 + glob: 10.4.5 json-parse-even-better-errors: 3.0.2 normalize-package-data: 5.0.0 npm-normalize-package-bin: 3.0.1 @@ -6656,7 +6412,7 @@ snapshots: require-in-the-middle@7.3.0: dependencies: - debug: 4.3.7 + debug: 4.3.5(supports-color@5.5.0) module-details-from-path: 1.0.3 resolve: 1.22.8 transitivePeerDependencies: @@ -6668,7 +6424,7 @@ snapshots: resolve@1.22.8: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.14.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 @@ -6689,7 +6445,7 @@ snapshots: reusify@1.0.4: {} - rfdc@1.3.1: {} + rfdc@1.4.1: {} rimraf@2.7.1: dependencies: @@ -6699,30 +6455,30 @@ snapshots: dependencies: glob: 7.2.3 - rimraf@5.0.7: + rimraf@5.0.9: dependencies: - glob: 10.4.1 + glob: 10.4.5 - rollup@4.18.0: + rollup@4.18.1: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.18.0 - '@rollup/rollup-android-arm64': 4.18.0 - '@rollup/rollup-darwin-arm64': 4.18.0 - '@rollup/rollup-darwin-x64': 4.18.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 - '@rollup/rollup-linux-arm-musleabihf': 4.18.0 - '@rollup/rollup-linux-arm64-gnu': 4.18.0 - '@rollup/rollup-linux-arm64-musl': 4.18.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 - '@rollup/rollup-linux-riscv64-gnu': 4.18.0 - '@rollup/rollup-linux-s390x-gnu': 4.18.0 - '@rollup/rollup-linux-x64-gnu': 4.18.0 - '@rollup/rollup-linux-x64-musl': 4.18.0 - '@rollup/rollup-win32-arm64-msvc': 4.18.0 - '@rollup/rollup-win32-ia32-msvc': 4.18.0 - '@rollup/rollup-win32-x64-msvc': 4.18.0 + '@rollup/rollup-android-arm-eabi': 4.18.1 + '@rollup/rollup-android-arm64': 4.18.1 + '@rollup/rollup-darwin-arm64': 4.18.1 + '@rollup/rollup-darwin-x64': 4.18.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.1 + '@rollup/rollup-linux-arm-musleabihf': 4.18.1 + '@rollup/rollup-linux-arm64-gnu': 4.18.1 + '@rollup/rollup-linux-arm64-musl': 4.18.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.1 + '@rollup/rollup-linux-riscv64-gnu': 4.18.1 + '@rollup/rollup-linux-s390x-gnu': 4.18.1 + '@rollup/rollup-linux-x64-gnu': 4.18.1 + '@rollup/rollup-linux-x64-musl': 4.18.1 + '@rollup/rollup-win32-arm64-msvc': 4.18.1 + '@rollup/rollup-win32-ia32-msvc': 4.18.1 + '@rollup/rollup-win32-x64-msvc': 4.18.1 fsevents: 2.3.3 rsocket-core@1.0.0-alpha.3: {} @@ -6739,7 +6495,7 @@ snapshots: rxjs@7.8.1: dependencies: - tslib: 2.6.2 + tslib: 2.6.3 safe-buffer@5.1.2: {} @@ -6767,15 +6523,6 @@ snapshots: set-cookie-parser@2.6.0: {} - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-property-descriptors: 1.0.2 - shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 @@ -6825,7 +6572,7 @@ snapshots: socks-proxy-agent@7.0.0: dependencies: agent-base: 6.0.2 - debug: 4.3.7 + debug: 4.3.5(supports-color@5.5.0) socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -6989,7 +6736,7 @@ snapshots: tinyrainbow@1.2.0: {} - tinyspy@3.0.0: {} + tinyspy@3.0.2: {} tmp@0.0.33: dependencies: @@ -7039,8 +6786,8 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 22.5.5 - acorn: 8.11.3 - acorn-walk: 8.3.2 + acorn: 8.12.1 + acorn-walk: 8.3.3 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 @@ -7057,7 +6804,7 @@ snapshots: string-argv: 0.3.2 typescript: 5.6.2 - tsconfck@3.0.3(typescript@5.6.2): + tsconfck@3.1.1(typescript@5.6.2): optionalDependencies: typescript: 5.6.2 @@ -7068,12 +6815,12 @@ snapshots: strip-bom: 3.0.0 strip-json-comments: 2.0.1 - tslib@2.6.2: {} + tslib@2.6.3: {} tuf-js@1.1.7: dependencies: '@tufjs/models': 1.0.4 - debug: 4.3.7 + debug: 4.3.5(supports-color@5.5.0) make-fetch-happen: 11.1.1 transitivePeerDependencies: - supports-color @@ -7159,7 +6906,7 @@ snapshots: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.2.11(@types/node@22.5.5) + vite: 5.3.3(@types/node@22.5.5) transitivePeerDependencies: - '@types/node' - less @@ -7170,22 +6917,22 @@ snapshots: - supports-color - terser - vite-tsconfig-paths@4.3.2(typescript@5.6.2)(vite@5.2.11(@types/node@22.5.5)): + vite-tsconfig-paths@4.3.2(typescript@5.6.2)(vite@5.3.3(@types/node@22.5.5)): dependencies: - debug: 4.3.7 + debug: 4.3.5(supports-color@5.5.0) globrex: 0.1.2 - tsconfck: 3.0.3(typescript@5.6.2) + tsconfck: 3.1.1(typescript@5.6.2) optionalDependencies: - vite: 5.2.11(@types/node@22.5.5) + vite: 5.3.3(@types/node@22.5.5) transitivePeerDependencies: - supports-color - typescript - vite@5.2.11(@types/node@22.5.5): + vite@5.3.3(@types/node@22.5.5): dependencies: - esbuild: 0.20.2 - postcss: 8.4.38 - rollup: 4.18.0 + esbuild: 0.21.5 + postcss: 8.4.39 + rollup: 4.18.1 optionalDependencies: '@types/node': 22.5.5 fsevents: 2.3.3 @@ -7193,7 +6940,7 @@ snapshots: vitest@2.1.1(@types/node@22.5.5): dependencies: '@vitest/expect': 2.1.1 - '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(vite@5.2.11(@types/node@22.5.5)) + '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(vite@5.3.3(@types/node@22.5.5)) '@vitest/pretty-format': 2.1.1 '@vitest/runner': 2.1.1 '@vitest/snapshot': 2.1.1 @@ -7208,7 +6955,7 @@ snapshots: tinyexec: 0.3.0 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.2.11(@types/node@22.5.5) + vite: 5.3.3(@types/node@22.5.5) vite-node: 2.1.1(@types/node@22.5.5) why-is-node-running: 2.3.0 optionalDependencies: @@ -7261,25 +7008,25 @@ snapshots: dependencies: string-width: 5.1.2 - winston-transport@4.7.0: + winston-transport@4.7.1: dependencies: - logform: 2.6.0 + logform: 2.6.1 readable-stream: 3.6.2 triple-beam: 1.4.1 - winston@3.13.0: + winston@3.13.1: dependencies: '@colors/colors': 1.6.0 '@dabh/diagnostics': 2.0.3 async: 3.2.5 is-stream: 2.0.1 - logform: 2.6.0 + logform: 2.6.1 one-time: 1.0.0 readable-stream: 3.6.2 safe-stable-stringify: 2.4.3 stack-trace: 0.0.10 triple-beam: 1.4.1 - winston-transport: 4.7.0 + winston-transport: 4.7.1 wrap-ansi@6.2.0: dependencies: @@ -7308,9 +7055,7 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 - ws@8.17.0: {} - - ws@8.2.3: {} + ws@8.18.0: {} xdg-basedir@5.1.0: {} @@ -7322,7 +7067,7 @@ snapshots: yallist@4.0.0: {} - yaml@2.4.2: {} + yaml@2.4.5: {} yaml@2.5.0: {} @@ -7354,4 +7099,6 @@ snapshots: yocto-queue@0.1.0: {} + yoctocolors-cjs@2.1.2: {} + zod@3.23.8: {} diff --git a/service/src/runners/server.ts b/service/src/runners/server.ts index c91c507be..28939464b 100644 --- a/service/src/runners/server.ts +++ b/service/src/runners/server.ts @@ -78,6 +78,7 @@ export async function startServer(runnerConfig: core.utils.RunnerConfig) { await moduleManager.initialize(serviceContext); logger.info('Starting service...'); + await serviceContext.lifeCycleEngine.start(); logger.info('Service started.');