diff --git a/meet-ce/backend/src/migrations/README.md b/meet-ce/backend/src/migrations/README.md index fadf16ab..5447feff 100644 --- a/meet-ce/backend/src/migrations/README.md +++ b/meet-ce/backend/src/migrations/README.md @@ -21,7 +21,6 @@ The schema migration system enables safe evolution of MongoDB document structure - ✅ **HA-safe** (distributed locking prevents concurrent migrations) - ✅ **Batch processing** (efficient handling of large collections) - ✅ **Progress tracking** (migrations stored in `MeetMigration` collection) -- ✅ **Version validation** (optional runtime checks in repositories) --- @@ -47,7 +46,6 @@ Each document includes a `schemaVersion` field: ``` src/ ├── migrations/ -│ ├── base-migration.ts # Base class for migrations │ ├── migration-registry.ts # Central registry of all collections │ ├── room-migrations.ts # Room-specific migrations │ ├── recording-migrations.ts # Recording-specific migrations @@ -59,13 +57,24 @@ src/ └── migration.model.ts # Migration types and interfaces ``` -**Note**: All migration types and interfaces (`ISchemaMigration`, `MigrationContext`, `MigrationResult`, `SchemaVersion`, `CollectionMigrationRegistry`) are defined in `src/models/migration.model.ts` for better code organization. - --- ## Adding New Migrations -### Step 1: Update Schema Version in Configuration +### Step 1: Update TypeScript Interface + +Update the domain interface to include new fields or changes: + +```typescript +// typings/src/room.ts +export interface MeetRoom extends MeetRoomOptions { + roomId: string; + // ... existing fields ... + maxParticipants: number; // New field +} +``` + +### Step 2: Update Schema Version in Configuration In `src/config/internal-config.ts`, increment the version constant: @@ -78,89 +87,48 @@ export const INTERNAL_CONFIG = { }; ``` -### Step 2: Create Migration Class +### Step 3: Update Moongose Schema + +Update the Mongoose schema to reflect the changes (new fields, etc.): ```typescript -import { BaseSchemaMigration } from './base-migration.js'; -import { MeetRoomDocument } from '../repositories/schemas/room.schema.js'; -import { MigrationContext } from '../models/migration.model.js'; -import { Model } from 'mongoose'; - -class RoomMigrationV1ToV2 extends BaseSchemaMigration { - fromVersion = 1; - toVersion = 2; - description = 'Add maxParticipants field with default value of 100'; - - protected async transform(document: MeetRoomDocument): Promise> { - // Return fields to update (schemaVersion is handled automatically) - return { - maxParticipants: 100 - }; - } - - // Optional: Add validation before migration runs - async validate(model: Model, context: MigrationContext): Promise { - // Check prerequisites, data integrity, etc. - return true; - } -} -``` - -### Step 3: Register Migration - -Add the migration instance to the migrations array in `room-migrations.ts`: - -```typescript -import { ISchemaMigration } from '../models/migration.model.js'; -import { MeetRoomDocument } from '../repositories/schemas/room.schema.js'; - -export const roomMigrations: ISchemaMigration[] = [ - new RoomMigrationV1ToV2() - // Future migrations will be added here -]; -``` - -### Step 4: Update Schema Definition - -Update the Mongoose schema default version in `internal-config.ts`: - -```typescript -// config/internal-config.ts -export const INTERNAL_CONFIG = { - // ... other config - ROOM_SCHEMA_VERSION: 2 // Updated from 1 - // ... -}; -``` - -If adding new required fields, update the Mongoose schema: - -```typescript -// repositories/schemas/room.schema.ts -import { INTERNAL_CONFIG } from '../../config/internal-config.js'; - +// models/mongoose-schemas/room.schema.ts const MeetRoomSchema = new Schema({ - schemaVersion: { - type: Number, - required: true, - default: INTERNAL_CONFIG.ROOM_SCHEMA_VERSION // Uses config value (2) - }, // ... existing fields ... maxParticipants: { type: Number, required: true, default: 100 } // New field }); ``` -### Step 5: Update TypeScript Interface - -Update the domain interface to include new fields: +### Step 4: Create Migration Definition ```typescript -// typings/src/room.ts -export interface MeetRoom extends MeetRoomOptions { - roomId: string; - // ... existing fields ... - maxParticipants: number; // New field -} +import { SchemaTransform, generateSchemaMigrationName } from '../models/migration.model.js'; +import { MeetRoomDocument } from '../models/mongoose-schemas/room.schema.js'; + +const roomMigrationV1ToV2Name = generateSchemaMigrationName('MeetRoom', 1, 2); + +const roomMigrationV1ToV2Transform: SchemaTransform = () => ({ + $set: { + maxParticipants: 100 + } +}); +``` + +`transform` must return MongoDB update operators, so it can express any kind of change: + +- `$set` to add/modify values +- `$unset` to remove properties +- `$rename` to rename fields +- Any other supported update operator + +### Step 5: Register Migration + +Add the migration to the map initialization in `room-migrations.ts`: + +```typescript +export const roomMigrations: SchemaMigrationMap = new Map([ + [roomMigrationV1ToV2Name, roomMigrationV1ToV2Transform] +]); ``` ### Step 6: Test Migration @@ -187,7 +155,6 @@ Each migration is tracked in the `MeetMigration` collection: "fromVersion": 1, "toVersion": 2, "migratedCount": 1523, - "skippedCount": 0, "failedCount": 0, "durationMs": 123000 } diff --git a/meet-ce/backend/src/migrations/api-key-migrations.ts b/meet-ce/backend/src/migrations/api-key-migrations.ts index eec68ae6..3b0db16b 100644 --- a/meet-ce/backend/src/migrations/api-key-migrations.ts +++ b/meet-ce/backend/src/migrations/api-key-migrations.ts @@ -1,24 +1,20 @@ -import { ISchemaMigration } from '../models/migration.model.js'; +import { SchemaMigrationMap } from '../models/migration.model.js'; import { MeetApiKeyDocument } from '../models/mongoose-schemas/api-key.schema.js'; /** - * All migrations for the MeetApiKey collection in chronological order. - * Add new migrations to this array as the schema evolves. + * Schema migrations for MeetApiKey. + * Key format: schema_{collection}_v{from}_to_v{to} * - * Example migration (when needed in the future): + * Example: * - * class ApiKeyMigrationV1ToV2 extends BaseSchemaMigration { - * fromVersion = 1; - * toVersion = 2; - * description = 'Add expirationDate field for API key expiration'; + * const apiKeyMigrationV1ToV2Name = generateSchemaMigrationName('MeetApiKey', 1, 2); * - * protected async transform(document: MeetApiKeyDocument): Promise> { - * return { - * expirationDate: undefined // No expiration for existing keys - * }; - * } - * } + * const apiKeyMigrationV1ToV2Transform: SchemaTransform = () => ({ + * $set: { + * expirationDate: undefined + * } + * }); */ -export const apiKeyMigrations: ISchemaMigration[] = [ - // Migrations will be added here as the schema evolves -]; +export const apiKeyMigrations: SchemaMigrationMap = new Map([ + // [apiKeyMigrationV1ToV2Name, apiKeyMigrationV1ToV2Transform] +]); diff --git a/meet-ce/backend/src/migrations/base-migration.ts b/meet-ce/backend/src/migrations/base-migration.ts deleted file mode 100644 index 69794eb4..00000000 --- a/meet-ce/backend/src/migrations/base-migration.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Model } from 'mongoose'; -import { ISchemaMigration, MigrationContext, MigrationResult, SchemaVersion } from '../models/migration.model.js'; - -/** - * Base class for schema migrations providing common functionality. - * Extend this class to implement specific migrations for collections. - */ -export abstract class BaseSchemaMigration implements ISchemaMigration { - abstract fromVersion: SchemaVersion; - abstract toVersion: SchemaVersion; - abstract description: string; - - /** - * Default batch size for processing documents. - * Can be overridden in subclasses for collections with large documents. - */ - protected readonly defaultBatchSize = 50; - - /** - * Executes the migration in batches. - * Processes all documents at fromVersion and upgrades them to toVersion. - */ - async execute(model: Model, context: MigrationContext): Promise { - const startTime = Date.now(); - const batchSize = context.batchSize || this.defaultBatchSize; - let migratedCount = 0; - const skippedCount = 0; - let failedCount = 0; - - context.logger.info( - `Starting schema migration: ${this.description} (v${this.fromVersion} -> v${this.toVersion})` - ); - - try { - // Find all documents at the source version - const totalDocs = await model.countDocuments({ schemaVersion: this.fromVersion }).exec(); - - if (totalDocs === 0) { - context.logger.info('No documents to migrate'); - return { - migratedCount: 0, - skippedCount: 0, - failedCount: 0, - durationMs: Date.now() - startTime - }; - } - - context.logger.info(`Found ${totalDocs} documents to migrate`); - - // Process documents in batches - let processedCount = 0; - - while (processedCount < totalDocs) { - const documents = await model.find({ schemaVersion: this.fromVersion }).limit(batchSize).exec(); - - if (documents.length === 0) { - break; - } - - // Transform and update each document - for (const doc of documents) { - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const updates = await this.transform(doc as any); - - // Update the document with new fields and version - await model - .updateOne( - { _id: doc._id }, - { - $set: { - ...updates, - schemaVersion: this.toVersion - } - } - ) - .exec(); - - migratedCount++; - } catch (error) { - failedCount++; - context.logger.warn(`Failed to migrate document ${doc._id}:`, error); - } - } - - processedCount += documents.length; - context.logger.debug(`Processed ${processedCount}/${totalDocs} documents`); - } - - const durationMs = Date.now() - startTime; - context.logger.info( - `Migration completed: ${migratedCount} migrated, ${failedCount} failed (${durationMs}ms)` - ); - - return { - migratedCount, - skippedCount, - failedCount, - durationMs - }; - } catch (error) { - context.logger.error('Migration failed:', error); - throw error; - } - } - - /** - * Transform a single document from source version to target version. - * Override this method to implement the specific transformation logic. - * - * @param document - The document to transform - * @returns Object with fields to update (excluding schemaVersion which is handled automatically) - */ - protected abstract transform(document: TDocument): Promise>; - - /** - * Optional validation before running migration. - * Default implementation always returns true. - */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - async validate(_model: Model, _context: MigrationContext): Promise { - return true; - } -} diff --git a/meet-ce/backend/src/migrations/global-config-migrations.ts b/meet-ce/backend/src/migrations/global-config-migrations.ts index d261d8ef..f474aaec 100644 --- a/meet-ce/backend/src/migrations/global-config-migrations.ts +++ b/meet-ce/backend/src/migrations/global-config-migrations.ts @@ -1,27 +1,20 @@ -import { ISchemaMigration } from '../models/migration.model.js'; +import { SchemaMigrationMap } from '../models/migration.model.js'; import { MeetGlobalConfigDocument } from '../models/mongoose-schemas/global-config.schema.js'; /** - * All migrations for the MeetGlobalConfig collection in chronological order. - * Add new migrations to this array as the schema evolves. + * Schema migrations for MeetGlobalConfig. + * Key format: schema_{collection}_v{from}_to_v{to} * - * Example migration (when needed in the future): + * Example: * - * class GlobalConfigMigrationV1ToV2 extends BaseSchemaMigration { - * fromVersion = 1; - * toVersion = 2; - * description = 'Add new branding configuration section'; + * const globalConfigMigrationV1ToV2Name = generateSchemaMigrationName('MeetGlobalConfig', 1, 2); * - * protected async transform(document: MeetGlobalConfigDocument): Promise> { - * return { - * brandingConfig: { - * logoUrl: '', - * companyName: 'OpenVidu Meet' - * } - * }; - * } - * } + * const globalConfigMigrationV1ToV2Transform: SchemaTransform = () => ({ + * $set: { + * newField: 'default-value' + * } + * }); */ -export const globalConfigMigrations: ISchemaMigration[] = [ - // Migrations will be added here as the schema evolves -]; +export const globalConfigMigrations: SchemaMigrationMap = new Map([ + // [globalConfigMigrationV1ToV2Name, globalConfigMigrationV1ToV2Transform] +]); diff --git a/meet-ce/backend/src/migrations/index.ts b/meet-ce/backend/src/migrations/index.ts new file mode 100644 index 00000000..089f70e5 --- /dev/null +++ b/meet-ce/backend/src/migrations/index.ts @@ -0,0 +1,6 @@ +export * from './api-key-migrations.js'; +export * from './global-config-migrations.js'; +export * from './migration-registry.js'; +export * from './recording-migrations.js'; +export * from './room-migrations.js'; +export * from './user-migrations.js'; diff --git a/meet-ce/backend/src/migrations/migration-registry.ts b/meet-ce/backend/src/migrations/migration-registry.ts index 90dcebc7..302aecae 100644 --- a/meet-ce/backend/src/migrations/migration-registry.ts +++ b/meet-ce/backend/src/migrations/migration-registry.ts @@ -1,13 +1,22 @@ import { INTERNAL_CONFIG } from '../config/internal-config.js'; -import { CollectionMigrationRegistry } from '../models/migration.model.js'; -import { meetApiKeyCollectionName, MeetApiKeyModel } from '../models/mongoose-schemas/api-key.schema.js'; +import { CollectionMigrationRegistry, SchemaMigratableDocument } from '../models/migration.model.js'; +import { + meetApiKeyCollectionName, + MeetApiKeyDocument, + MeetApiKeyModel +} from '../models/mongoose-schemas/api-key.schema.js'; import { meetGlobalConfigCollectionName, + MeetGlobalConfigDocument, MeetGlobalConfigModel } from '../models/mongoose-schemas/global-config.schema.js'; -import { meetRecordingCollectionName, MeetRecordingModel } from '../models/mongoose-schemas/recording.schema.js'; -import { meetRoomCollectionName, MeetRoomModel } from '../models/mongoose-schemas/room.schema.js'; -import { meetUserCollectionName, MeetUserModel } from '../models/mongoose-schemas/user.schema.js'; +import { + meetRecordingCollectionName, + MeetRecordingDocument, + MeetRecordingModel +} from '../models/mongoose-schemas/recording.schema.js'; +import { meetRoomCollectionName, MeetRoomDocument, MeetRoomModel } from '../models/mongoose-schemas/room.schema.js'; +import { meetUserCollectionName, MeetUserDocument, MeetUserModel } from '../models/mongoose-schemas/user.schema.js'; import { apiKeyMigrations } from './api-key-migrations.js'; import { globalConfigMigrations } from './global-config-migrations.js'; import { recordingMigrations } from './recording-migrations.js'; @@ -16,12 +25,18 @@ import { userMigrations } from './user-migrations.js'; /** * Central registry of all collection migrations. - * Defines the current version and migration path for each collection. + * Defines the current version and migration map for each collection. * * Order matters: collections should be listed in dependency order. * For example, if recordings depend on rooms, rooms should come first. */ -export const migrationRegistry: CollectionMigrationRegistry[] = [ +const migrationRegistry: [ + CollectionMigrationRegistry, + CollectionMigrationRegistry, + CollectionMigrationRegistry, + CollectionMigrationRegistry, + CollectionMigrationRegistry +] = [ // GlobalConfig - no dependencies, can run first { collectionName: meetGlobalConfigCollectionName, @@ -59,3 +74,10 @@ export const migrationRegistry: CollectionMigrationRegistry[] = [ migrations: recordingMigrations } ]; + +/** + * Homogeneous runtime view of the migration registry. + * Used by migration execution code that iterates over all collections. + */ +export const runtimeMigrationRegistry = + migrationRegistry as unknown as CollectionMigrationRegistry[]; diff --git a/meet-ce/backend/src/migrations/recording-migrations.ts b/meet-ce/backend/src/migrations/recording-migrations.ts index 8bbd683a..a0f0891d 100644 --- a/meet-ce/backend/src/migrations/recording-migrations.ts +++ b/meet-ce/backend/src/migrations/recording-migrations.ts @@ -1,24 +1,20 @@ -import { ISchemaMigration } from '../models/migration.model.js'; +import { SchemaMigrationMap } from '../models/migration.model.js'; import { MeetRecordingDocument } from '../models/mongoose-schemas/recording.schema.js'; /** - * All migrations for the MeetRecording collection in chronological order. - * Add new migrations to this array as the schema evolves. + * Schema migrations for MeetRecording. + * Key format: schema_{collection}_v{from}_to_v{to} * - * Example migration (when needed in the future): + * Example: * - * class RecordingMigrationV1ToV2 extends BaseSchemaMigration { - * fromVersion = 1; - * toVersion = 2; - * description = 'Add new optional field "quality" for recording quality tracking'; + * const recordingMigrationV1ToV2Name = generateSchemaMigrationName('MeetRecording', 1, 2); * - * protected async transform(document: MeetRecordingDocument): Promise> { - * return { - * quality: 'standard' // Default quality for existing recordings - * }; - * } - * } + * const recordingMigrationV1ToV2Transform: SchemaTransform = () => ({ + * $set: { + * quality: 'standard' + * } + * }); */ -export const recordingMigrations: ISchemaMigration[] = [ - // Migrations will be added here as the schema evolves -]; +export const recordingMigrations: SchemaMigrationMap = new Map([ + // [recordingMigrationV1ToV2Name, recordingMigrationV1ToV2Transform] +]); diff --git a/meet-ce/backend/src/migrations/room-migrations.ts b/meet-ce/backend/src/migrations/room-migrations.ts index b696452b..4690ea2f 100644 --- a/meet-ce/backend/src/migrations/room-migrations.ts +++ b/meet-ce/backend/src/migrations/room-migrations.ts @@ -1,26 +1,20 @@ -import { ISchemaMigration } from '../models/migration.model.js'; +import { SchemaMigrationMap } from '../models/migration.model.js'; import { MeetRoomDocument } from '../models/mongoose-schemas/room.schema.js'; /** - * All migrations for the MeetRoom collection in chronological order. - * Add new migrations to this array as the schema evolves. + * Schema migrations for MeetRoom. + * Key format: schema_{collection}_v{from}_to_v{to} * - * Example migration (when needed in the future): + * Example: * - * class RoomMigrationV1ToV2 extends BaseSchemaMigration { - * fromVersion = 1; - * toVersion = 2; - * description = 'Add new required field "maxParticipants" with default value'; + * const roomMigrationV1ToV2Name = generateSchemaMigrationName('MeetRoom', 1, 2); * - * protected async transform(document: MeetRoomDocument): Promise> { - * return { - * maxParticipants: 100 // Add default value for existing rooms - * }; - * } - * } + * const roomMigrationV1ToV2Transform: SchemaTransform = () => ({ + * $set: { + * maxParticipants: 100 + * } + * }); */ -export const roomMigrations: ISchemaMigration[] = [ - // Migrations will be added here as the schema evolves - // Example: new RoomMigrationV1ToV2(), - // Example: new RoomMigrationV2ToV3(), -]; +export const roomMigrations: SchemaMigrationMap = new Map([ + // [roomMigrationV1ToV2Name, roomMigrationV1ToV2Transform] +]); diff --git a/meet-ce/backend/src/migrations/user-migrations.ts b/meet-ce/backend/src/migrations/user-migrations.ts index d7449b87..464f87b1 100644 --- a/meet-ce/backend/src/migrations/user-migrations.ts +++ b/meet-ce/backend/src/migrations/user-migrations.ts @@ -1,24 +1,20 @@ -import { ISchemaMigration } from '../models/migration.model.js'; +import { SchemaMigrationMap } from '../models/migration.model.js'; import { MeetUserDocument } from '../models/mongoose-schemas/user.schema.js'; /** - * All migrations for the MeetUser collection in chronological order. - * Add new migrations to this array as the schema evolves. + * Schema migrations for MeetUser. + * Key format: schema_{collection}_v{from}_to_v{to} * - * Example migration (when needed in the future): + * Example: * - * class UserMigrationV1ToV2 extends BaseSchemaMigration { - * fromVersion = 1; - * toVersion = 2; - * description = 'Add email field for user notifications'; + * const userMigrationV1ToV2Name = generateSchemaMigrationName('MeetUser', 1, 2); * - * protected async transform(document: MeetUserDocument): Promise> { - * return { - * email: undefined // Email will be optional initially - * }; - * } - * } + * const userMigrationV1ToV2Transform: SchemaTransform = () => ({ + * $set: { + * email: undefined + * } + * }); */ -export const userMigrations: ISchemaMigration[] = [ - // Migrations will be added here as the schema evolves -]; +export const userMigrations: SchemaMigrationMap = new Map([ + // [userMigrationV1ToV2Name, userMigrationV1ToV2Transform] +]); diff --git a/meet-ce/backend/src/models/migration.model.ts b/meet-ce/backend/src/models/migration.model.ts index 28515487..f22e52b9 100644 --- a/meet-ce/backend/src/models/migration.model.ts +++ b/meet-ce/backend/src/models/migration.model.ts @@ -1,5 +1,4 @@ -import { Model } from 'mongoose'; -import { LoggerService } from '../services/logger.service.js'; +import { Document, Model, UpdateQuery } from 'mongoose'; /** * Interface representing a migration document in MongoDB. @@ -58,19 +57,11 @@ export enum MigrationStatus { } /** - * Enum defining all possible migration names in the system. - * Each migration should have a unique identifier. - * * Schema migrations follow the pattern: schema_{collection}_v{from}_to_v{to} * Example: 'schema_room_v1_to_v2', 'schema_recording_v2_to_v3' */ -export enum MigrationName { - /** - * Migration from legacy storage (S3, ABS, GCS) to MongoDB. - * Includes: GlobalConfig, Users, ApiKeys, Rooms, and Recordings. - */ - LEGACY_STORAGE_TO_MONGODB = 'legacy_storage_to_mongodb' -} +export type SchemaMigrationName = `schema_${string}_v${number}_to_v${number}`; +export type MigrationName = SchemaMigrationName; /** * Generates a migration name for schema version upgrades. @@ -83,12 +74,49 @@ export enum MigrationName { * @example * generateSchemaMigrationName('MeetRoom', 1, 2) // Returns: 'schema_room_v1_to_v2' */ -export function generateSchemaMigrationName(collectionName: string, fromVersion: number, toVersion: number): string { +export function generateSchemaMigrationName( + collectionName: string, + fromVersion: number, + toVersion: number +): SchemaMigrationName { // Convert collection name to lowercase and remove 'Meet' prefix const simpleName = collectionName.replace(/^Meet/, '').toLowerCase(); return `schema_${simpleName}_v${fromVersion}_to_v${toVersion}`; } +/** + * Checks whether a string matches the schema migration naming convention. + */ +export function isSchemaMigrationName(name: string): name is SchemaMigrationName { + return /^schema_[a-z0-9_]+_v\d+_to_v\d+$/.test(name); +} + +/** + * Parses a schema migration name and extracts entity and versions. + */ +export function parseSchemaMigrationName( + name: string +): { collectionName: string; fromVersion: SchemaVersion; toVersion: SchemaVersion } | null { + const match = /^schema_([a-z0-9_]+)_v(\d+)_to_v(\d+)$/.exec(name); + + if (!match) { + return null; + } + + return { + collectionName: match[1], + fromVersion: Number(match[2]), + toVersion: Number(match[3]) + }; +} + +/** + * Base document shape required for schema migrations. + */ +export interface SchemaMigratableDocument extends Document { + schemaVersion?: number; +} + /** * Represents a schema version number. * Versions start at 1 and increment sequentially. @@ -96,14 +124,49 @@ export function generateSchemaMigrationName(collectionName: string, fromVersion: export type SchemaVersion = number; /** - * Context provided to migration functions. - * Contains utilities and services needed during migration. + * MongoDB update operations generated by a migration transform. + * Supports full update operators like $set, $unset, $rename, etc. */ -export interface MigrationContext { - /** Logger service for tracking migration progress */ - logger: LoggerService; - /** Batch size for processing documents (default: 50) */ - batchSize?: number; +export type MigrationUpdate = UpdateQuery; + +/** + * Function that transforms a document and returns a MongoDB update operation. + */ +export type SchemaTransform = ( + document: TDocument +) => MigrationUpdate; + +/** + * Map of schema migration names to transform functions. + */ +export type SchemaMigrationMap = Map< + SchemaMigrationName, + SchemaTransform +>; + +/** + * Resolved migration step ready to be executed. + */ +export interface SchemaMigrationStep { + name: SchemaMigrationName; + fromVersion: SchemaVersion; + toVersion: SchemaVersion; + transform: SchemaTransform; +} + +/** + * Registry entry for a collection's migrations. + * Groups all migrations for a specific collection. + */ +export interface CollectionMigrationRegistry { + /** Name of the collection */ + collectionName: string; + /** Mongoose model for the collection */ + model: Model; + /** Current schema version expected by the application */ + currentVersion: SchemaVersion; + /** Map of migration names to their transform functions */ + migrations: SchemaMigrationMap; } /** @@ -113,60 +176,8 @@ export interface MigrationContext { export interface MigrationResult { /** Number of documents successfully migrated */ migratedCount: number; - /** Number of documents skipped (already at target version) */ - skippedCount: number; /** Number of documents that failed migration */ failedCount: number; /** Total time taken in milliseconds */ durationMs: number; } - -/** - * Interface for a single schema migration handler. - * Each migration transforms documents from one version to the next. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export interface ISchemaMigration { - /** The source schema version this migration upgrades from */ - fromVersion: SchemaVersion; - /** The target schema version this migration upgrades to */ - toVersion: SchemaVersion; - /** Short description of what this migration does */ - description: string; - - /** - * Executes the migration on a batch of documents. - * Should update documents using MongoDB bulk operations for efficiency. - * - * @param model - Mongoose model for the collection - * @param context - Migration context with logger and configuration - * @returns Migration result with statistics - */ - execute(model: Model, context: MigrationContext): Promise; - - /** - * Optional validation to check if migration is safe to run. - * Can verify prerequisites or data integrity before migration starts. - * - * @param model - Mongoose model for the collection - * @param context - Migration context with logger and configuration - * @returns true if migration can proceed, false otherwise - */ - validate?(model: Model, context: MigrationContext): Promise; -} - -/** - * Registry entry for a collection's migrations. - * Groups all migrations for a specific collection. - */ -export interface CollectionMigrationRegistry { - /** Name of the collection */ - collectionName: string; - /** Mongoose model for the collection */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - model: Model; - /** Current schema version expected by the application */ - currentVersion: SchemaVersion; - /** Array of migrations in chronological order */ - migrations: ISchemaMigration[]; -} diff --git a/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts index 89578726..8c15ea28 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/migration.schema.ts @@ -1,5 +1,5 @@ import { Document, model, Schema } from 'mongoose'; -import { MeetMigration, MigrationName, MigrationStatus } from '../migration.model.js'; +import { isSchemaMigrationName, MeetMigration, MigrationStatus } from '../migration.model.js'; /** * Mongoose Document interface for MeetMigration. @@ -16,7 +16,10 @@ const MigrationSchema = new Schema( name: { type: String, required: true, - enum: Object.values(MigrationName) + validate: { + validator: (value: string) => isSchemaMigrationName(value), + message: 'Invalid migration name format' + } }, status: { type: String, diff --git a/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts b/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts index 60b3af81..566822bf 100644 --- a/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts +++ b/meet-ce/backend/src/models/mongoose-schemas/room.schema.ts @@ -1,6 +1,5 @@ import { MeetRecordingAccess, - MeetRecordingEncodingPreset, MeetRecordingLayout, MeetRoom, MeetRoomDeletionPolicyWithMeeting, @@ -54,34 +53,16 @@ const MeetRecordingConfigSchema = new Schema( layout: { type: String, enum: Object.values(MeetRecordingLayout), - required: true, - default: MeetRecordingLayout.GRID + required: true }, encoding: { type: Schema.Types.Mixed, - required: false, - encoding: { - type: Schema.Types.Mixed, - required: true, - default: MeetRecordingEncodingPreset.H264_720P_30, - validate: { - validator: (value: any) => { - if (!value) return true; - - if (typeof value === 'string') return true; - - if (typeof value === 'object') return value.video || value.audio; - - return false; - }, - message: 'Encoding must be a preset string or options object' - } - } + required: true }, allowAccessTo: { type: String, enum: Object.values(MeetRecordingAccess), - required: false + required: true } }, { _id: false } @@ -120,8 +101,7 @@ const MeetE2EEConfigSchema = new Schema( { enabled: { type: Boolean, - required: true, - default: false + required: true } }, { _id: false } @@ -134,8 +114,7 @@ const MeetCaptionsConfigSchema = new Schema( { enabled: { type: Boolean, - required: true, - default: true + required: true } }, { _id: false } @@ -215,13 +194,11 @@ const MeetRoomConfigSchema = new Schema( }, e2ee: { type: MeetE2EEConfigSchema, - required: true, - default: { enabled: false } + required: true }, captions: { type: MeetCaptionsConfigSchema, - required: true, - default: { enabled: false } + required: true } }, { _id: false } @@ -273,14 +250,12 @@ const MeetRoomSchema = new Schema( status: { type: String, enum: Object.values(MeetRoomStatus), - required: true, - default: MeetRoomStatus.OPEN + required: true }, meetingEndAction: { type: String, enum: Object.values(MeetingEndAction), - required: true, - default: MeetingEndAction.NONE + required: true } }, { diff --git a/meet-ce/backend/src/repositories/migration.repository.ts b/meet-ce/backend/src/repositories/migration.repository.ts index 22e6144f..80f88801 100644 --- a/meet-ce/backend/src/repositories/migration.repository.ts +++ b/meet-ce/backend/src/repositories/migration.repository.ts @@ -95,7 +95,7 @@ export class MigrationRepository extends BaseRepository { - const documents = await this.findAll(); - return documents; - } - - /** - * Get a specific migration by name. - * - * @param name - The name of the migration - * @returns The migration document or null if not found - */ - async getMigration(name: MigrationName): Promise { - const document = await this.findOne({ name }); - return document ? this.toDomain(document) : null; - } - /** * Check if a migration has been completed successfully. * diff --git a/meet-ce/backend/src/server.ts b/meet-ce/backend/src/server.ts index 5e6f2da5..1fefb73b 100644 --- a/meet-ce/backend/src/server.ts +++ b/meet-ce/backend/src/server.ts @@ -85,7 +85,9 @@ const createApp = () => { if (process.env.NODE_ENV === 'development') { // Serve internal API docs only in development mode appRouter.use(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/docs`, (_req: Request, res: Response) => - res.type('html').send(getOpenApiHtmlWithBasePath(internalApiHtmlFilePath, INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1)) + res + .type('html') + .send(getOpenApiHtmlWithBasePath(internalApiHtmlFilePath, INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1)) ); } @@ -137,7 +139,9 @@ const startServer = (app: express.Application) => { console.log( 'REST API Docs: ', - chalk.cyanBright(`http://localhost:${MEET_ENV.SERVER_PORT}${basePathDisplay}${INTERNAL_CONFIG.API_BASE_PATH_V1}/docs`) + chalk.cyanBright( + `http://localhost:${MEET_ENV.SERVER_PORT}${basePathDisplay}${INTERNAL_CONFIG.API_BASE_PATH_V1}/docs` + ) ); logEnvVars(); }); @@ -164,8 +168,8 @@ const isMainModule = (): boolean => { if (isMainModule()) { registerDependencies(); const app = createApp(); - startServer(app); await initializeEagerServices(); + startServer(app); } export { createApp, registerDependencies }; diff --git a/meet-ce/backend/src/services/migration.service.ts b/meet-ce/backend/src/services/migration.service.ts index f0a8a780..a0be8e75 100644 --- a/meet-ce/backend/src/services/migration.service.ts +++ b/meet-ce/backend/src/services/migration.service.ts @@ -2,13 +2,15 @@ import { inject, injectable } from 'inversify'; import { Model } from 'mongoose'; import ms from 'ms'; import { MeetLock } from '../helpers/redis.helper.js'; -import { migrationRegistry } from '../migrations/migration-registry.js'; +import { runtimeMigrationRegistry } from '../migrations/migration-registry.js'; import { CollectionMigrationRegistry, generateSchemaMigrationName, - ISchemaMigration, - MigrationContext, - MigrationName + MigrationResult, + MigrationUpdate, + SchemaMigratableDocument, + SchemaMigrationStep, + SchemaVersion } from '../models/migration.model.js'; import { ApiKeyRepository } from '../repositories/api-key.repository.js'; import { GlobalConfigRepository } from '../repositories/global-config.repository.js'; @@ -73,133 +75,19 @@ export class MigrationService { /** * Runs all schema migrations to upgrade document structures to the latest version. * Processes each collection in the registry and executes pending migrations. - * - * Schema migrations run after data migrations and upgrade existing documents - * to match the current schema version expected by the application. */ protected async runSchemaMigrations(): Promise { this.logger.info('Running schema migrations...'); try { let totalMigrated = 0; - let totalSkipped = 0; // Process each collection in the registry - for (const registry of migrationRegistry) { - this.logger.info(`Checking schema version for collection: ${registry.collectionName}`); - - // Get the current version of documents in the collection - const currentVersionInDb = await this.getCurrentSchemaVersion(registry.model); - - if (currentVersionInDb === null) { - this.logger.info(`No documents found in ${registry.collectionName}, skipping migration`); - continue; - } - - if (currentVersionInDb === registry.currentVersion) { - this.logger.info( - `Collection ${registry.collectionName} is already at version ${registry.currentVersion}` - ); - continue; - } - - if (currentVersionInDb > registry.currentVersion) { - this.logger.warn( - `Collection ${registry.collectionName} has version ${currentVersionInDb} ` + - `but application expects ${registry.currentVersion}. ` + - `This may indicate a downgrade or inconsistent deployment.` - ); - continue; - } - - // Find migrations needed to upgrade from current to target version - const neededMigrations = this.findNeededMigrations( - registry, - currentVersionInDb, - registry.currentVersion - ); - - if (neededMigrations.length === 0) { - this.logger.info(`No migrations needed for ${registry.collectionName}`); - continue; - } - - this.logger.info( - `Found ${neededMigrations.length} migrations for ${registry.collectionName} ` + - `(v${currentVersionInDb} -> v${registry.currentVersion})` - ); - - // Execute each migration in sequence - for (const migration of neededMigrations) { - const migrationName = generateSchemaMigrationName( - registry.collectionName, - migration.fromVersion, - migration.toVersion - ); - - // Check if this specific migration was already completed - const isCompleted = await this.migrationRepository.isCompleted(migrationName as MigrationName); - - if (isCompleted) { - this.logger.info(`Migration ${migrationName} already completed, skipping`); - continue; - } - - // Mark migration as started - await this.migrationRepository.markAsStarted(migrationName as MigrationName); - - try { - const migrationContext: MigrationContext = { - logger: this.logger, - batchSize: 50 // Default batch size - }; - - // Validate migration if validation method is provided - if (migration.validate) { - const isValid = await migration.validate(registry.model, migrationContext); - - if (!isValid) { - throw new Error(`Validation failed for migration ${migrationName}`); - } - } - - // Execute the migration - this.logger.info(`Executing migration: ${migration.description}`); - const result = await migration.execute(registry.model, migrationContext); - - // Track statistics - totalMigrated += result.migratedCount; - totalSkipped += result.skippedCount; - - // Mark migration as completed with metadata - const metadata: Record = { - collectionName: registry.collectionName, - fromVersion: migration.fromVersion, - toVersion: migration.toVersion, - migratedCount: result.migratedCount, - skippedCount: result.skippedCount, - failedCount: result.failedCount, - durationMs: result.durationMs - }; - - await this.migrationRepository.markAsCompleted(migrationName as MigrationName, metadata); - - this.logger.info( - `Migration ${migrationName} completed: ${result.migratedCount} migrated, ` + - `${result.failedCount} failed (${result.durationMs}ms)` - ); - } catch (error) { - // Mark migration as failed - const errorMessage = error instanceof Error ? error.message : String(error); - await this.migrationRepository.markAsFailed(migrationName as MigrationName, errorMessage); - throw error; - } - } + for (const registry of runtimeMigrationRegistry) { + totalMigrated += await this.migrateCollectionSchemas(registry); } - this.logger.info( - `Schema migrations completed successfully: ${totalMigrated} documents migrated, ${totalSkipped} skipped` - ); + this.logger.info(`Schema migrations completed successfully: ${totalMigrated} documents migrated`); } catch (error) { this.logger.error('Error running schema migrations:', error); throw error; @@ -207,17 +95,238 @@ export class MigrationService { } /** - * Gets the current schema version of documents in a collection. - * Samples the database to determine the version. + * Migrates documents in a collection through all required schema versions to reach the current version. + * + * @param registry - The collection migration registry containing migration steps and model + * @returns Number of documents migrated in this collection + */ + protected async migrateCollectionSchemas( + registry: CollectionMigrationRegistry + ): Promise { + this.logger.info(`Checking schema version for collection: ${registry.collectionName}`); + + const minVersionInDb = await this.getMinSchemaVersion(registry.model); + + if (minVersionInDb === null) { + this.logger.info(`No documents found in ${registry.collectionName}, skipping migration`); + return 0; + } + + const maxVersionInDb = await this.getMaxSchemaVersion(registry.model); + + if (maxVersionInDb && maxVersionInDb > registry.currentVersion) { + throw new Error( + `Collection ${registry.collectionName} has schemaVersion ${maxVersionInDb}, ` + + `which is higher than expected ${registry.currentVersion}. ` + + 'Startup aborted to prevent inconsistent schema handling.' + ); + } + + if (minVersionInDb === registry.currentVersion) { + this.logger.info(`Collection ${registry.collectionName} is already at version ${registry.currentVersion}`); + return 0; + } + + const migrationSteps = this.getRequiredMigrationSteps(registry, minVersionInDb); + let collectionMigrated = 0; + + for (const migrationStep of migrationSteps) { + collectionMigrated += await this.executeCollectionMigrationStep(registry, migrationStep); + } + + return collectionMigrated; + } + + /** + * Gets the required migration steps to upgrade from the current version in the database to the target version. + * Validates that there are no missing migration steps in the chain. + * + * @param registry - The collection migration registry + * @param minVersionInDb - The minimum schema version currently present in the database + * @returns Array of migration steps that need to be executed in order + */ + protected getRequiredMigrationSteps( + registry: CollectionMigrationRegistry, + minVersionInDb: SchemaVersion + ): SchemaMigrationStep[] { + const migrationSteps = this.findSchemaMigrationSteps(registry, minVersionInDb, registry.currentVersion); + + if (migrationSteps.length === 0) { + throw new Error( + `No migration steps found for ${registry.collectionName} ` + + `(v${minVersionInDb} -> v${registry.currentVersion}). Startup aborted.` + ); + } + + this.logger.info( + `Found ${migrationSteps.length} migration steps for ${registry.collectionName} ` + + `(v${minVersionInDb} -> v${registry.currentVersion})` + ); + + return migrationSteps; + } + + /** + * Executes a single migration step for a collection, applying the transform to all documents at the fromVersion. + * Handles marking the migration as started, completed, or failed in the migration repository. + * + * @param registry - The collection migration registry + * @param migrationStep - The specific migration step to execute + * @returns Number of documents migrated in this step + */ + protected async executeCollectionMigrationStep( + registry: CollectionMigrationRegistry, + migrationStep: SchemaMigrationStep + ): Promise { + const pendingBefore = await this.countDocumentsAtSchemaVersion(registry.model, migrationStep.fromVersion); + + if (pendingBefore === 0) { + this.logger.info(`Migration ${migrationStep.name} has no pending documents, skipping execution`); + return 0; + } + + const isCompleted = await this.migrationRepository.isCompleted(migrationStep.name); + + if (isCompleted) { + this.logger.warn( + `Migration ${migrationStep.name} is marked as completed but still has ${pendingBefore} pending ` + + `documents at schemaVersion ${migrationStep.fromVersion}. Re-running migration step.` + ); + } + + await this.migrationRepository.markAsStarted(migrationStep.name); + + try { + this.logger.info(`Executing migration: ${migrationStep.name}`); + const result = await this.runSchemaMigrationStep(migrationStep, registry.model); + const pendingAfter = await this.countDocumentsAtSchemaVersion(registry.model, migrationStep.fromVersion); + + const metadata: Record = { + collectionName: registry.collectionName, + fromVersion: migrationStep.fromVersion, + toVersion: migrationStep.toVersion, + migratedCount: result.migratedCount, + failedCount: result.failedCount, + pendingBefore, + pendingAfter, + durationMs: result.durationMs + }; + + if (result.failedCount > 0 || pendingAfter > 0) { + const failureReason = + `Migration ${migrationStep.name} did not complete successfully. ` + + `failedCount=${result.failedCount}, pendingAfter=${pendingAfter}`; + + await this.migrationRepository.markAsFailed(migrationStep.name, failureReason); + throw new Error(failureReason); + } + + await this.migrationRepository.markAsCompleted(migrationStep.name, metadata); + + this.logger.info( + `Migration ${migrationStep.name} completed: ${result.migratedCount} documents migrated (${result.durationMs}ms)` + ); + + return result.migratedCount; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + await this.migrationRepository.markAsFailed(migrationStep.name, errorMessage); + throw error; + } + } + + /** + * Executes a single schema migration step on all documents that match the fromVersion. + * Applies the transform function to each document and updates it to the toVersion. + * + * @param migrationStep - The migration step to execute + * @param model - Mongoose model for the collection being migrated + * @param batchSize - Number of documents to process in each batch. Default is 50. + * @returns Migration result with statistics about the execution + */ + protected async runSchemaMigrationStep( + migrationStep: SchemaMigrationStep, + model: Model, + batchSize = 50 + ): Promise { + const startTime = Date.now(); + let migratedCount = 0; + let failedCount = 0; + + const versionFilter = { schemaVersion: migrationStep.fromVersion }; + const totalDocs = await model.countDocuments(versionFilter).exec(); + + if (totalDocs === 0) { + return { + migratedCount, + failedCount, + durationMs: Date.now() - startTime + }; + } + + let processedCount = 0; + let lastProcessedId: TDocument['_id'] | null = null; + let hasMoreDocuments = true; + + while (hasMoreDocuments) { + const batchFilter = + lastProcessedId === null + ? versionFilter + : { + ...versionFilter, + _id: { $gt: lastProcessedId } + }; + const documents = await model.find(batchFilter).sort({ _id: 1 }).limit(batchSize).exec(); + + if (documents.length === 0) { + break; + } + + const batchResults = await Promise.allSettled( + documents.map(async (doc) => { + const transformedUpdate = migrationStep.transform(doc); + const update = this.appendSchemaVersionUpdate(transformedUpdate, migrationStep.toVersion); + await model.updateOne({ _id: doc._id }, update).exec(); + return String(doc._id); + }) + ); + + for (let i = 0; i < batchResults.length; i++) { + const batchResult = batchResults[i]; + + if (batchResult.status === 'fulfilled') { + migratedCount++; + continue; + } + + failedCount++; + this.logger.warn(`Failed to migrate document ${String(documents[i]._id)}:`, batchResult.reason); + } + + processedCount += documents.length; + lastProcessedId = documents[documents.length - 1]._id; + hasMoreDocuments = documents.length === batchSize; + this.logger.debug(`Processed ${processedCount}/${totalDocs} documents`); + } + + return { + migratedCount, + failedCount, + durationMs: Date.now() - startTime + }; + } + + /** + * Gets the minimum schema version present in the collection to detect the oldest pending version of documents. * * @param model - Mongoose model for the collection * @returns Current version or null if collection is empty */ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - protected async getCurrentSchemaVersion(model: Model): Promise { + protected async getMinSchemaVersion( + model: Model + ): Promise { try { - // Get a sample document to check its version - const sampleDoc = await model.findOne({}).select('schemaVersion').exec(); + const sampleDoc = await model.findOne({}).sort({ schemaVersion: 1 }).select('schemaVersion').exec(); if (!sampleDoc) { return null; // Collection is empty @@ -232,39 +341,107 @@ export class MigrationService { } /** - * Finds the migrations needed to upgrade from one version to another. + * Gets the maximum schema version present in the collection to detect if there are any documents above expected version. + * + * @param model - Mongoose model for the collection + * @returns Maximum version or null if collection is empty + */ + protected async getMaxSchemaVersion( + model: Model + ): Promise { + try { + const sampleDoc = await model.findOne({}).sort({ schemaVersion: -1 }).select('schemaVersion').exec(); + + if (!sampleDoc) { + return null; // Collection is empty + } + + return sampleDoc.schemaVersion ?? 1; + } catch (error) { + this.logger.error('Error getting max schema version:', error); + throw error; + } + } + + /** + * Counts how many documents are at a specific schema version. + * + * @param model - Mongoose model for the collection + * @param schemaVersion - Schema version to count + * @returns Number of documents at the specified schema version + */ + protected async countDocumentsAtSchemaVersion( + model: Model, + schemaVersion: SchemaVersion + ): Promise { + return model.countDocuments({ schemaVersion }).exec(); + } + + /** + * Finds the schema migration steps needed to upgrade from one version to another. * Returns migrations in the correct order to apply. * * @param registry - Collection migration registry * @param fromVersion - Current version in database * @param toVersion - Target version from application - * @returns Array of migrations to execute in order + * @returns Array of schema migration steps to execute in order */ - protected findNeededMigrations( - registry: CollectionMigrationRegistry, - fromVersion: number, - toVersion: number - ): ISchemaMigration[] { - const needed: ISchemaMigration[] = []; + protected findSchemaMigrationSteps( + registry: CollectionMigrationRegistry, + fromVersion: SchemaVersion, + toVersion: SchemaVersion + ): SchemaMigrationStep[] { + const needed: SchemaMigrationStep[] = []; // Build a chain of migrations from fromVersion to toVersion let currentVersion = fromVersion; while (currentVersion < toVersion) { - const nextMigration = registry.migrations.find((m) => m.fromVersion === currentVersion); + const nextVersion = currentVersion + 1; + const expectedMigrationName = generateSchemaMigrationName( + registry.collectionName, + currentVersion, + nextVersion + ); + const transform = registry.migrations.get(expectedMigrationName); - if (!nextMigration) { - this.logger.warn( - `No migration found from version ${currentVersion} for ${registry.collectionName}. ` + - `Migration chain is incomplete.` + if (!transform) { + throw new Error( + `No migration found from version ${currentVersion} to ${nextVersion} for ` + + `${registry.collectionName}. Migration chain is incomplete.` ); - break; } - needed.push(nextMigration); - currentVersion = nextMigration.toVersion; + needed.push({ + name: expectedMigrationName, + fromVersion: currentVersion, + toVersion: nextVersion, + transform + }); + currentVersion = nextVersion; } return needed; } + + /** + * Appends a schemaVersion update to the migration update operation. + * Ensures that migrated documents are marked with the new version. + * + * @param update - Original migration update operation + * @param toVersion - Target schema version to set + * @returns Updated migration operation with schemaVersion set + */ + protected appendSchemaVersionUpdate( + update: MigrationUpdate, + toVersion: SchemaVersion + ): MigrationUpdate { + return { + ...update, + $set: { + ...(update.$set ?? {}), + schemaVersion: toVersion + } + }; + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0e533e13..76bdc1bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -306,7 +306,7 @@ importers: devDependencies: '@angular-builders/custom-webpack': specifier: 20.0.0 - version: 20.0.0(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2) + version: 20.0.0(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.5.1)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2) '@angular-devkit/build-angular': specifier: 20.3.13 version: 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(tsx@4.20.6)(typescript@5.9.2) @@ -504,6 +504,359 @@ importers: specifier: 5.9.3 version: 5.9.3 + meet-pro/backend: + dependencies: + '@aws-sdk/client-s3': + specifier: 3.846.0 + version: 3.846.0 + '@azure/storage-blob': + specifier: 12.27.0 + version: 12.27.0 + '@google-cloud/storage': + specifier: 7.17.1 + version: 7.17.1(encoding@0.1.13) + '@openvidu-meet-pro/typings': + specifier: workspace:* + version: link:../typings + '@openvidu-meet/backend': + specifier: workspace:* + version: link:../../meet-ce/backend + '@sesamecare-oss/redlock': + specifier: 1.4.0 + version: 1.4.0(ioredis@5.6.1) + archiver: + specifier: 7.0.1 + version: 7.0.1 + bcrypt: + specifier: 5.1.1 + version: 5.1.1(encoding@0.1.13) + body-parser: + specifier: 2.2.0 + version: 2.2.0 + chalk: + specifier: 5.6.2 + version: 5.6.2 + cookie-parser: + specifier: 1.4.7 + version: 1.4.7 + cors: + specifier: 2.8.5 + version: 2.8.5 + cron: + specifier: 4.3.3 + version: 4.3.3 + dotenv: + specifier: 16.6.1 + version: 16.6.1 + express: + specifier: 4.21.2 + version: 4.21.2 + express-rate-limit: + specifier: 7.5.1 + version: 7.5.1(express@4.21.2) + inversify: + specifier: 6.2.2 + version: 6.2.2(reflect-metadata@0.2.2) + ioredis: + specifier: 5.6.1 + version: 5.6.1 + jwt-decode: + specifier: 4.0.0 + version: 4.0.0 + livekit-server-sdk: + specifier: 2.13.1 + version: 2.13.1 + ms: + specifier: 2.1.3 + version: 2.1.3 + uid: + specifier: 2.0.2 + version: 2.0.2 + winston: + specifier: 3.18.3 + version: 3.18.3 + yamljs: + specifier: 0.3.0 + version: 0.3.0 + zod: + specifier: 3.25.76 + version: 3.25.76 + devDependencies: + '@types/archiver': + specifier: 6.0.3 + version: 6.0.3 + '@types/bcrypt': + specifier: 5.0.2 + version: 5.0.2 + '@types/cookie-parser': + specifier: 1.4.9 + version: 1.4.9(@types/express@4.17.23) + '@types/cors': + specifier: 2.8.19 + version: 2.8.19 + '@types/express': + specifier: 4.17.23 + version: 4.17.23 + '@types/jest': + specifier: 29.5.14 + version: 29.5.14 + '@types/ms': + specifier: 2.1.0 + version: 2.1.0 + '@types/node': + specifier: 22.16.4 + version: 22.16.4 + '@types/supertest': + specifier: 6.0.3 + version: 6.0.3 + '@types/unzipper': + specifier: 0.10.11 + version: 0.10.11 + '@types/validator': + specifier: 13.15.2 + version: 13.15.2 + '@types/yamljs': + specifier: 0.2.34 + version: 0.2.34 + '@typescript-eslint/eslint-plugin': + specifier: 6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': + specifier: 6.21.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.9.2) + cross-env: + specifier: 7.0.3 + version: 7.0.3 + eslint: + specifier: 8.57.1 + version: 8.57.1 + eslint-config-prettier: + specifier: 9.1.0 + version: 9.1.0(eslint@8.57.1) + jest: + specifier: 29.7.0 + version: 29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + jest-fetch-mock: + specifier: 3.0.3 + version: 3.0.3(encoding@0.1.13) + jest-junit: + specifier: 16.0.0 + version: 16.0.0 + nodemon: + specifier: 3.1.10 + version: 3.1.10 + openapi-generate-html: + specifier: 0.5.3 + version: 0.5.3(@types/node@22.16.4) + prettier: + specifier: 3.6.2 + version: 3.6.2 + supertest: + specifier: 7.1.3 + version: 7.1.3 + ts-jest: + specifier: 29.4.0 + version: 29.4.0(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)))(typescript@5.9.2) + ts-jest-resolver: + specifier: 2.0.1 + version: 2.0.1 + tsx: + specifier: 4.20.3 + version: 4.20.3 + typescript: + specifier: 5.9.2 + version: 5.9.2 + unzipper: + specifier: 0.12.3 + version: 0.12.3 + + meet-pro/frontend: + dependencies: + '@angular/animations': + specifier: 20.3.15 + version: 20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/cdk': + specifier: 20.2.14 + version: 20.2.14(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/common': + specifier: 20.3.15 + version: 20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/compiler': + specifier: 20.3.15 + version: 20.3.15 + '@angular/core': + specifier: 20.3.15 + version: 20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/forms': + specifier: 20.3.15 + version: 20.3.15(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + '@angular/material': + specifier: 20.2.14 + version: 20.2.14(2a2c27b5f9f3f8b334e74e3c717f4ace) + '@angular/platform-browser': + specifier: 20.3.15 + version: 20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/platform-browser-dynamic': + specifier: 20.3.15 + version: 20.3.15(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))) + '@angular/router': + specifier: 20.3.15 + version: 20.3.15(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + '@livekit/track-processors': + specifier: 0.7.0 + version: 0.7.0(@types/dom-mediacapture-transform@0.1.11)(livekit-client@2.16.1(@types/dom-mediacapture-record@1.0.22)) + '@openvidu-meet/shared-components': + specifier: workspace:* + version: link:../../meet-ce/frontend/projects/shared-meet-components + '@openvidu-meet/typings': + specifier: workspace:* + version: link:../../meet-ce/typings + autolinker: + specifier: 4.1.5 + version: 4.1.5 + core-js: + specifier: 3.45.1 + version: 3.45.1 + jwt-decode: + specifier: 4.0.0 + version: 4.0.0 + livekit-client: + specifier: 2.16.1 + version: 2.16.1(@types/dom-mediacapture-record@1.0.22) + openvidu-components-angular: + specifier: workspace:* + version: link:../../../openvidu/openvidu-components-angular/projects/openvidu-components-angular + rxjs: + specifier: 7.8.2 + version: 7.8.2 + tslib: + specifier: 2.8.1 + version: 2.8.1 + unique-names-generator: + specifier: 4.7.1 + version: 4.7.1 + zone.js: + specifier: 0.15.1 + version: 0.15.1 + devDependencies: + '@angular-builders/custom-webpack': + specifier: 20.0.0 + version: 20.0.0(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.43.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2) + '@angular-devkit/build-angular': + specifier: 20.3.13 + version: 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(tsx@4.20.6)(typescript@5.9.2) + '@angular-eslint/builder': + specifier: 20.3.0 + version: 20.3.0(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2) + '@angular-eslint/eslint-plugin': + specifier: 20.3.0 + version: 20.3.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@angular-eslint/eslint-plugin-template': + specifier: 20.3.0 + version: 20.3.0(@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.50.0)(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@angular-eslint/schematics': + specifier: 20.3.0 + version: 20.3.0(@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.50.0)(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2) + '@angular-eslint/template-parser': + specifier: 20.3.0 + version: 20.3.0(eslint@8.57.1)(typescript@5.9.2) + '@angular/cli': + specifier: 20.3.13 + version: 20.3.13(@types/node@22.18.13)(chokidar@4.0.3) + '@angular/compiler-cli': + specifier: 20.3.15 + version: 20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2) + '@types/chai': + specifier: 4.3.20 + version: 4.3.20 + '@types/fluent-ffmpeg': + specifier: 2.1.27 + version: 2.1.27 + '@types/jasmine': + specifier: 5.1.9 + version: 5.1.9 + '@types/mocha': + specifier: 9.1.1 + version: 9.1.1 + '@types/node': + specifier: 22.18.13 + version: 22.18.13 + '@types/pixelmatch': + specifier: 5.2.6 + version: 5.2.6 + '@types/pngjs': + specifier: 6.0.5 + version: 6.0.5 + '@typescript-eslint/eslint-plugin': + specifier: 8.46.4 + version: 8.46.4(@typescript-eslint/parser@8.46.4(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/parser': + specifier: 8.46.4 + version: 8.46.4(eslint@8.57.1)(typescript@5.9.2) + chai: + specifier: 4.5.0 + version: 4.5.0 + chromedriver: + specifier: 141.0.6 + version: 141.0.6 + cross-env: + specifier: 7.0.3 + version: 7.0.3 + eslint: + specifier: 8.57.1 + version: 8.57.1 + eslint-config-prettier: + specifier: 9.1.2 + version: 9.1.2(eslint@8.57.1) + fluent-ffmpeg: + specifier: 2.1.3 + version: 2.1.3 + jasmine-core: + specifier: 5.6.0 + version: 5.6.0 + jasmine-spec-reporter: + specifier: 7.0.0 + version: 7.0.0 + karma: + specifier: 6.4.4 + version: 6.4.4 + karma-chrome-launcher: + specifier: 3.2.0 + version: 3.2.0 + karma-coverage: + specifier: 2.2.1 + version: 2.2.1 + karma-jasmine: + specifier: 5.1.0 + version: 5.1.0(karma@6.4.4) + karma-jasmine-html-reporter: + specifier: 2.1.0 + version: 2.1.0(jasmine-core@5.6.0)(karma-jasmine@5.1.0(karma@6.4.4))(karma@6.4.4) + mocha: + specifier: 10.7.3 + version: 10.7.3 + ng-packagr: + specifier: 20.3.2 + version: 20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2) + prettier: + specifier: 3.3.3 + version: 3.3.3 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@types/node@22.18.13)(typescript@5.9.2) + typescript: + specifier: 5.9.2 + version: 5.9.2 + + meet-pro/typings: + devDependencies: + '@openvidu-meet/typings': + specifier: workspace:* + version: link:../../meet-ce/typings + typescript: + specifier: 5.9.2 + version: 5.9.2 + testapp: dependencies: '@openvidu-meet/typings': @@ -696,15 +1049,33 @@ packages: resolution: {integrity: sha512-hdMKY4rUTko8xqeWYGnwwDYDomkeOoLsYsP6SdaHWK7hpGvzWsT6Q/aIv8J8NrCYkLu+M+5nLiKOooweUZu3GQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} + '@angular-eslint/builder@20.3.0': + resolution: {integrity: sha512-3XpWLdh+/K4+r0ChkKW00SXWyBA7ShMpE+Pt1XUmIu4srJgGRnt8e+kC4Syi+s2t5QS7PjlwRaelB1KfSMXZ5A==} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + '@angular-eslint/builder@20.7.0': resolution: {integrity: sha512-qgf4Cfs1z0VsVpzF/OnxDRvBp60OIzeCsp4mzlckWYVniKo19EPIN6kFDol5eTAIOMPgiBQlMIwgQMHgocXEig==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '*' + '@angular-eslint/bundled-angular-compiler@20.3.0': + resolution: {integrity: sha512-QwuNnmRNr/uNj89TxknPbGcs5snX1w7RoJJPNAsfb2QGcHzUTQovS8hqm9kaDZdpUJDPP7jt7B6F0+EjrPAXRA==} + '@angular-eslint/bundled-angular-compiler@20.7.0': resolution: {integrity: sha512-9KPz24YoiL0SvTtTX6sd1zmysU5cKOCcmpEiXkCoO3L2oYZGlVxmMT4hfSaHMt8qmfvV2KzQMoR6DZM84BwRzQ==} + '@angular-eslint/eslint-plugin-template@20.3.0': + resolution: {integrity: sha512-WMJDJfybOLCiN4QrOyrLl+Zt5F+A/xoDYMWTdn+LgACheLs2tguVQiwf+oCgHnHGcsTsulPYlRHldKBGZMgs4w==} + peerDependencies: + '@angular-eslint/template-parser': 20.3.0 + '@typescript-eslint/types': ^7.11.0 || ^8.0.0 + '@typescript-eslint/utils': ^7.11.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + '@angular-eslint/eslint-plugin-template@20.7.0': resolution: {integrity: sha512-WFmvW2vBR6ExsSKEaActQTteyw6ikWyuJau9XmWEPFd+2eusEt/+wO21ybjDn3uc5FTp1IcdhfYy+U5OdDjH5w==} peerDependencies: @@ -714,6 +1085,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '*' + '@angular-eslint/eslint-plugin@20.3.0': + resolution: {integrity: sha512-7ghzGTiExrgTetDQ6IPP5uXSa94Xhtzp2VHCIa58EcUb7oMv06HWZ1Uss3xgFmACsLpN+vayKJIdFiboqaGVRA==} + peerDependencies: + '@typescript-eslint/utils': ^7.11.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + '@angular-eslint/eslint-plugin@20.7.0': resolution: {integrity: sha512-aHH2YTiaonojsKN+y2z4IMugCwdsH/dYIjYBig6kfoSPyf9rGK4zx+gnNGq/pGRjF3bOYrmFgIviYpQVb80inQ==} peerDependencies: @@ -721,15 +1099,31 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '*' + '@angular-eslint/schematics@20.3.0': + resolution: {integrity: sha512-4n92tHKIJm1PP+FjhnmO7AMpvKdRIoF+YgF38oUU7aMJqfZ3RXIhazMMxw2u3VU1MisKH766KSll++c4LgarVA==} + '@angular-eslint/schematics@20.7.0': resolution: {integrity: sha512-S0onfRipDUIL6gFGTFjiWwUDhi42XYrBoi3kJ3wBbKBeIgYv9SP1ppTKDD4ZoDaDU9cQE8nToX7iPn9ifMw6eQ==} + '@angular-eslint/template-parser@20.3.0': + resolution: {integrity: sha512-gB564h/kZ7siWvgHDETU++sk5e25qFfVaizLaa6KoBEYFP6dOCiedz15LTcA0TsXp0rGu6Z6zkl291iSM1qzDA==} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + '@angular-eslint/template-parser@20.7.0': resolution: {integrity: sha512-CVskZnF38IIxVVlKWi1VCz7YH/gHMJu2IY9bD1AVoBBGIe0xA4FRXJkW2Y+EDs9vQqZTkZZljhK5gL65Ro1PeQ==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '*' + '@angular-eslint/utils@20.3.0': + resolution: {integrity: sha512-7XOQeNXgyhznDwoP1TwPrCMq/uXKJHQgCVPFREkJGKbNf/jzNldB7iV1eqpBzUQIPEQFgfcDG67dexpMAq3N4g==} + peerDependencies: + '@typescript-eslint/utils': ^7.11.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + '@angular-eslint/utils@20.7.0': resolution: {integrity: sha512-B6EJHbsk2W/lnS3kS/gm56VGvX735419z/DzgbRDcOvqMGMLwD1ILzv5OTEcL1rzpnB0AHW+IxOu6y/aCzSNUA==} peerDependencies: @@ -2052,6 +2446,10 @@ packages: resolution: {integrity: sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==} engines: {node: '>=14'} + '@google-cloud/storage@7.17.1': + resolution: {integrity: sha512-2FMQbpU7qK+OtBPaegC6n+XevgZksobUGo6mGKnXNmeZpvLiAo1gTAE3oTKsrMGDV4VtL8Zzpono0YsK/Q7Iqg==} + engines: {node: '>=14'} + '@google-cloud/storage@7.17.3': resolution: {integrity: sha512-gOnCAbFgAYKRozywLsxagdevTF7Gm+2Ncz5u5CQAuOv/2VCa0rdGJWvJFDOftPx1tc+q8TXiC2pEJfFKu+yeMQ==} engines: {node: '>=14'} @@ -3351,6 +3749,9 @@ packages: resolution: {integrity: sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==} engines: {node: ^18.17.0 || >=20.5.0} + '@types/archiver@6.0.3': + resolution: {integrity: sha512-a6wUll6k3zX6qs5KlxIggs1P1JcYJaTCx2gnlr+f0S1yd2DoaEwoIK10HmBaLnZwWneBz+JBm0dwcZu0zECBcQ==} + '@types/archiver@6.0.4': resolution: {integrity: sha512-ULdQpARQ3sz9WH4nb98mJDYA0ft2A8C4f4fovvUcFwINa1cgGjY36JCAYuP5YypRq4mco1lJp1/7jEMS2oR0Hg==} @@ -3425,12 +3826,18 @@ packages: '@types/express-serve-static-core@5.1.0': resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} + '@types/express@4.17.23': + resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} + '@types/express@4.17.25': resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} '@types/express@5.0.6': resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} + '@types/fluent-ffmpeg@2.1.27': + resolution: {integrity: sha512-QiDWjihpUhriISNoBi2hJBRUUmoj/BMTYcfz+F+ZM9hHWBYABFAE6hjP/TbCZC0GWwlpa3FzvHH9RzFeRusZ7A==} + '@types/fluent-ffmpeg@2.1.28': resolution: {integrity: sha512-5ovxsDwBcPfJ+eYs1I/ZpcYCnkce7pvH9AHSvrZllAp1ZPpTRDZAFjF3TRFbukxSgIYTTNYePbS0rKUmaxVbXw==} @@ -3455,6 +3862,9 @@ packages: '@types/jasmine@5.1.13': resolution: {integrity: sha512-MYCcDkruFc92LeYZux5BC0dmqo2jk+M5UIZ4/oFnAPCXN9mCcQhLyj7F3/Za7rocVyt5YRr1MmqJqFlvQ9LVcg==} + '@types/jasmine@5.1.9': + resolution: {integrity: sha512-8t4HtkW4wxiPVedMpeZ63n3vlWxEIquo/zc1Tm8ElU+SqVV7+D3Na2PWaJUp179AzTragMWVwkMv7mvty0NfyQ==} + '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} @@ -3497,6 +3907,9 @@ packages: '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} + '@types/node@22.16.4': + resolution: {integrity: sha512-PYRhNtZdm2wH/NT2k/oAJ6/f2VD2N2Dag0lGlx2vWgMSJXGNmlce5MiTQzoWAiIJtso30mjnfQCOKVH+kAQC/g==} + '@types/node@22.16.5': resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==} @@ -4606,6 +5019,9 @@ packages: core-js-compat@3.47.0: resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} + core-js@3.45.1: + resolution: {integrity: sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==} + core-js@3.47.0: resolution: {integrity: sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==} @@ -4642,6 +5058,10 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + cron@4.3.3: + resolution: {integrity: sha512-B/CJj5yL3sjtlun6RtYHvoSB26EmQ2NUmhq9ZiJSyKIM4K/fqfh9aelDFlIayD2YMeFZqWLi9hHV+c+pq2Djkw==} + engines: {node: '>=18.x'} + cron@4.3.5: resolution: {integrity: sha512-hKPP7fq1+OfyCqoePkKfVq7tNAdFwiQORr4lZUHwrf0tebC65fYEeWgOrXOL6prn1/fegGOdTfrM6e34PJfksg==} engines: {node: '>=18.x'} @@ -5160,6 +5580,12 @@ packages: peerDependencies: eslint: '>=6.0.0' + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + eslint-config-prettier@9.1.2: resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} hasBin: true @@ -5235,6 +5661,10 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@9.0.0: resolution: {integrity: sha512-+Yh0LeQKq+mW/tQArNj67tljR3L1HajDTQPuZOEwC00oBdoIDQrr89yBgjAlzAwRrY/5zDkM3v99iGHwz9y0dw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -5646,16 +6076,17 @@ packages: glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} @@ -6584,6 +7015,10 @@ packages: peerDependencies: '@types/dom-mediacapture-record': ^1 + livekit-server-sdk@2.13.1: + resolution: {integrity: sha512-k4qFvqjHUR0s9lMMueZ1CMDLw/IngOmL/wsh/zq0+6bIg3rMzns9s3ECOf7XuT56esEuu8LGlrw0+inL86QiqQ==} + engines: {node: '>=18'} + livekit-server-sdk@2.13.3: resolution: {integrity: sha512-ItSQ2gE1oz/Ev9mfBRdAw+P05rt/BaYRkldggKz0+3rh/Yt0ag0BLID3VrgCVFVRAQ2YEJKcJJyj5p4epIJ8QA==} engines: {node: '>=18'} @@ -8428,10 +8863,12 @@ packages: tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me tar@7.5.2: resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} engines: {node: '>=18'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me tcp-port-used@1.0.2: resolution: {integrity: sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==} @@ -8651,6 +9088,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.20.3: + resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==} + engines: {node: '>=18.0.0'} + hasBin: true + tsx@4.20.6: resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} engines: {node: '>=18.0.0'} @@ -9298,13 +9740,66 @@ snapshots: - chokidar - typescript - '@angular-builders/custom-webpack@20.0.0(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2)': + '@angular-builders/custom-webpack@20.0.0(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.43.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2)': dependencies: '@angular-builders/common': 4.0.0(@types/node@22.18.13)(chokidar@4.0.3)(typescript@5.9.2) '@angular-devkit/architect': 0.2003.13(chokidar@4.0.3) '@angular-devkit/build-angular': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(tsx@4.20.6)(typescript@5.9.2) '@angular-devkit/core': 20.3.13(chokidar@4.0.3) - '@angular/build': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2) + '@angular/build': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.43.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2) + '@angular/compiler-cli': 20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2) + lodash: 4.17.21 + webpack-merge: 6.0.1 + transitivePeerDependencies: + - '@angular/compiler' + - '@angular/core' + - '@angular/localize' + - '@angular/platform-browser' + - '@angular/platform-server' + - '@angular/service-worker' + - '@angular/ssr' + - '@rspack/core' + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - '@web/test-runner' + - browser-sync + - bufferutil + - chokidar + - debug + - html-webpack-plugin + - jest + - jest-environment-jsdom + - jiti + - karma + - less + - lightningcss + - ng-packagr + - node-sass + - postcss + - protractor + - sass-embedded + - stylus + - sugarss + - supports-color + - tailwindcss + - terser + - tslib + - tsx + - typescript + - uglify-js + - utf-8-validate + - vitest + - webpack-cli + - yaml + + '@angular-builders/custom-webpack@20.0.0(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(less@4.5.1)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2)': + dependencies: + '@angular-builders/common': 4.0.0(@types/node@22.18.13)(chokidar@4.0.3)(typescript@5.9.2) + '@angular-devkit/architect': 0.2003.13(chokidar@4.0.3) + '@angular-devkit/build-angular': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(browser-sync@3.0.4)(chokidar@4.0.3)(jest-environment-jsdom@29.7.0)(jest@29.7.0(@types/node@22.18.13)(ts-node@10.9.2(@types/node@22.18.13)(typescript@5.9.2)))(jiti@1.21.7)(karma@6.4.4)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(tsx@4.20.6)(typescript@5.9.2) + '@angular-devkit/core': 20.3.13(chokidar@4.0.3) + '@angular/build': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.5.1)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2) '@angular/compiler-cli': 20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2) lodash: 4.17.21 webpack-merge: 6.0.1 @@ -9362,7 +9857,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.13(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.2003.13(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2))(webpack@5.101.2) + '@angular-devkit/build-webpack': 0.2003.13(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)))(webpack@5.101.2(esbuild@0.25.9)) '@angular-devkit/core': 20.3.13(chokidar@4.0.3) '@angular/build': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.43.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2) '@angular/compiler-cli': 20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2) @@ -9376,13 +9871,13 @@ snapshots: '@babel/preset-env': 7.28.3(@babel/core@7.28.3) '@babel/runtime': 7.28.3 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2) + '@ngtools/webpack': 20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9)) ansi-colors: 4.1.3 autoprefixer: 10.4.21(postcss@8.5.6) - babel-loader: 10.0.0(@babel/core@7.28.3)(webpack@5.101.2) + babel-loader: 10.0.0(@babel/core@7.28.3)(webpack@5.101.2(esbuild@0.25.9)) browserslist: 4.28.1 - copy-webpack-plugin: 13.0.1(webpack@5.101.2) - css-loader: 7.1.2(webpack@5.101.2) + copy-webpack-plugin: 13.0.1(webpack@5.101.2(esbuild@0.25.9)) + css-loader: 7.1.2(webpack@5.101.2(esbuild@0.25.9)) esbuild-wasm: 0.25.9 fast-glob: 3.3.3 http-proxy-middleware: 3.0.5 @@ -9390,32 +9885,32 @@ snapshots: jsonc-parser: 3.3.1 karma-source-map-support: 1.4.0 less: 4.4.0 - less-loader: 12.3.0(less@4.4.0)(webpack@5.101.2) - license-webpack-plugin: 4.0.2(webpack@5.101.2) + less-loader: 12.3.0(less@4.4.0)(webpack@5.101.2(esbuild@0.25.9)) + license-webpack-plugin: 4.0.2(webpack@5.101.2(esbuild@0.25.9)) loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.4(webpack@5.101.2) + mini-css-extract-plugin: 2.9.4(webpack@5.101.2(esbuild@0.25.9)) open: 10.2.0 ora: 8.2.0 picomatch: 4.0.3 piscina: 5.1.3 postcss: 8.5.6 - postcss-loader: 8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2) + postcss-loader: 8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9)) resolve-url-loader: 5.0.0 rxjs: 7.8.2 sass: 1.90.0 - sass-loader: 16.0.5(sass@1.90.0)(webpack@5.101.2) + sass-loader: 16.0.5(sass@1.90.0)(webpack@5.101.2(esbuild@0.25.9)) semver: 7.7.2 - source-map-loader: 5.0.0(webpack@5.101.2) + source-map-loader: 5.0.0(webpack@5.101.2(esbuild@0.25.9)) source-map-support: 0.5.21 terser: 5.43.1 tree-kill: 1.2.2 tslib: 2.8.1 typescript: 5.9.2 webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-middleware: 7.4.2(webpack@5.101.2) - webpack-dev-server: 5.2.2(webpack@5.101.2) + webpack-dev-middleware: 7.4.2(webpack@5.101.2(esbuild@0.25.9)) + webpack-dev-server: 5.2.2(webpack@5.101.2(esbuild@0.25.9)) webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.101.2) + webpack-subresource-integrity: 5.1.0(webpack@5.101.2(esbuild@0.25.9)) optionalDependencies: '@angular/core': 20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1) '@angular/platform-browser': 20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)) @@ -9448,12 +9943,12 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-webpack@0.2003.13(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2))(webpack@5.101.2)': + '@angular-devkit/build-webpack@0.2003.13(chokidar@4.0.3)(webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)))(webpack@5.101.2(esbuild@0.25.9))': dependencies: '@angular-devkit/architect': 0.2003.13(chokidar@4.0.3) rxjs: 7.8.2 webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-server: 5.2.2(webpack@5.101.2) + webpack-dev-server: 5.2.2(webpack@5.101.2(esbuild@0.25.9)) transitivePeerDependencies: - chokidar @@ -9478,6 +9973,15 @@ snapshots: transitivePeerDependencies: - chokidar + '@angular-eslint/builder@20.3.0(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2)': + dependencies: + '@angular-devkit/architect': 0.2003.13(chokidar@4.0.3) + '@angular-devkit/core': 20.3.13(chokidar@4.0.3) + eslint: 8.57.1 + typescript: 5.9.2 + transitivePeerDependencies: + - chokidar + '@angular-eslint/builder@20.7.0(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@angular-devkit/architect': 0.2003.13(chokidar@4.0.3) @@ -9487,8 +9991,22 @@ snapshots: transitivePeerDependencies: - chokidar + '@angular-eslint/bundled-angular-compiler@20.3.0': {} + '@angular-eslint/bundled-angular-compiler@20.7.0': {} + '@angular-eslint/eslint-plugin-template@20.3.0(@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.50.0)(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': + dependencies: + '@angular-eslint/bundled-angular-compiler': 20.3.0 + '@angular-eslint/template-parser': 20.3.0(eslint@8.57.1)(typescript@5.9.2) + '@angular-eslint/utils': 20.3.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/utils': 8.50.0(eslint@8.57.1)(typescript@5.9.2) + aria-query: 5.3.2 + axobject-query: 4.1.0 + eslint: 8.57.1 + typescript: 5.9.2 + '@angular-eslint/eslint-plugin-template@20.7.0(@angular-eslint/template-parser@20.7.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.50.0)(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@angular-eslint/bundled-angular-compiler': 20.7.0 @@ -9501,6 +10019,15 @@ snapshots: eslint: 8.57.1 typescript: 5.9.2 + '@angular-eslint/eslint-plugin@20.3.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': + dependencies: + '@angular-eslint/bundled-angular-compiler': 20.3.0 + '@angular-eslint/utils': 20.3.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@typescript-eslint/utils': 8.50.0(eslint@8.57.1)(typescript@5.9.2) + eslint: 8.57.1 + ts-api-utils: 2.1.0(typescript@5.9.2) + typescript: 5.9.2 + '@angular-eslint/eslint-plugin@20.7.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@angular-eslint/bundled-angular-compiler': 20.7.0 @@ -9510,6 +10037,23 @@ snapshots: ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 + '@angular-eslint/schematics@20.3.0(@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.50.0)(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2)': + dependencies: + '@angular-devkit/core': 20.3.13(chokidar@4.0.3) + '@angular-devkit/schematics': 20.3.13(chokidar@4.0.3) + '@angular-eslint/eslint-plugin': 20.3.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + '@angular-eslint/eslint-plugin-template': 20.3.0(@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.50.0)(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2) + ignore: 7.0.5 + semver: 7.7.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - '@angular-eslint/template-parser' + - '@typescript-eslint/types' + - '@typescript-eslint/utils' + - chokidar + - eslint + - typescript + '@angular-eslint/schematics@20.7.0(@angular-eslint/template-parser@20.7.0(eslint@8.57.1)(typescript@5.9.2))(@typescript-eslint/types@8.50.0)(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(chokidar@4.0.3)(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@angular-devkit/core': 20.3.13(chokidar@4.0.3) @@ -9527,6 +10071,13 @@ snapshots: - eslint - typescript + '@angular-eslint/template-parser@20.3.0(eslint@8.57.1)(typescript@5.9.2)': + dependencies: + '@angular-eslint/bundled-angular-compiler': 20.3.0 + eslint: 8.57.1 + eslint-scope: 8.4.0 + typescript: 5.9.2 + '@angular-eslint/template-parser@20.7.0(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@angular-eslint/bundled-angular-compiler': 20.7.0 @@ -9534,6 +10085,13 @@ snapshots: eslint-scope: 9.0.0 typescript: 5.9.2 + '@angular-eslint/utils@20.3.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': + dependencies: + '@angular-eslint/bundled-angular-compiler': 20.3.0 + '@typescript-eslint/utils': 8.50.0(eslint@8.57.1)(typescript@5.9.2) + eslint: 8.57.1 + typescript: 5.9.2 + '@angular-eslint/utils@20.7.0(@typescript-eslint/utils@8.50.0(eslint@8.57.1)(typescript@5.9.2))(eslint@8.57.1)(typescript@5.9.2)': dependencies: '@angular-eslint/bundled-angular-compiler': 20.7.0 @@ -9556,7 +10114,7 @@ snapshots: '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 '@inquirer/confirm': 5.1.14(@types/node@22.18.13) - '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6)) + '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.6)) beasties: 0.3.5 browserslist: 4.28.1 esbuild: 0.25.9 @@ -9599,7 +10157,7 @@ snapshots: - tsx - yaml - '@angular/build@20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.4.0)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2)': + '@angular/build@20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(@angular/compiler@20.3.15)(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@22.18.13)(chokidar@4.0.3)(jiti@1.21.7)(karma@6.4.4)(less@4.5.1)(ng-packagr@20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2))(postcss@8.5.6)(terser@5.44.1)(tslib@2.8.1)(tsx@4.20.6)(typescript@5.9.2)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.13(chokidar@4.0.3) @@ -9609,7 +10167,7 @@ snapshots: '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 '@inquirer/confirm': 5.1.14(@types/node@22.18.13) - '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6)) + '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.5.1)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6)) beasties: 0.3.5 browserslist: 4.28.1 esbuild: 0.25.9 @@ -9629,13 +10187,13 @@ snapshots: tinyglobby: 0.2.14 tslib: 2.8.1 typescript: 5.9.2 - vite: 7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6) + vite: 7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.5.1)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6) watchpack: 2.4.4 optionalDependencies: '@angular/core': 20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1) '@angular/platform-browser': 20.3.15(@angular/animations@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@20.3.15(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.15(@angular/compiler@20.3.15)(rxjs@7.8.2)(zone.js@0.15.1)) karma: 6.4.4 - less: 4.4.0 + less: 4.5.1 lmdb: 3.4.2 ng-packagr: 20.3.2(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(tslib@2.8.1)(typescript@5.9.2) postcss: 8.5.6 @@ -10344,7 +10902,7 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.3 + '@babel/generator': 7.28.5 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) '@babel/helpers': 7.28.4 @@ -11332,6 +11890,27 @@ snapshots: '@google-cloud/promisify@4.0.0': {} + '@google-cloud/storage@7.17.1(encoding@0.1.13)': + dependencies: + '@google-cloud/paginator': 5.0.2 + '@google-cloud/projectify': 4.0.0 + '@google-cloud/promisify': 4.0.0 + abort-controller: 3.0.0 + async-retry: 1.3.3 + duplexify: 4.1.3 + fast-xml-parser: 4.5.3 + gaxios: 6.7.1(encoding@0.1.13) + google-auth-library: 9.15.1(encoding@0.1.13) + html-entities: 2.6.0 + mime: 3.0.0 + p-limit: 3.1.0 + retry-request: 7.0.2(encoding@0.1.13) + teeny-request: 9.0.0(encoding@0.1.13) + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + - supports-color + '@google-cloud/storage@7.17.3(encoding@0.1.13)': dependencies: '@google-cloud/paginator': 5.0.2 @@ -11383,6 +11962,16 @@ snapshots: '@inquirer/ansi@1.0.2': {} + '@inquirer/checkbox@4.3.2(@types/node@22.16.4)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.16.4) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/checkbox@4.3.2(@types/node@22.16.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -11410,6 +11999,13 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/confirm@5.1.21(@types/node@22.16.4)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/confirm@5.1.21(@types/node@22.16.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@22.16.5) @@ -11424,6 +12020,19 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/core@10.3.2(@types/node@22.16.4)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.16.4) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/core@10.3.2(@types/node@22.16.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -11450,6 +12059,14 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/editor@4.2.23(@types/node@22.16.4)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/external-editor': 1.0.3(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/editor@4.2.23(@types/node@22.16.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@22.16.5) @@ -11466,6 +12083,14 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/expand@4.0.23(@types/node@22.16.4)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/expand@4.0.23(@types/node@22.16.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@22.16.5) @@ -11482,6 +12107,13 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/external-editor@1.0.3(@types/node@22.16.4)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.1 + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/external-editor@1.0.3(@types/node@22.16.5)': dependencies: chardet: 2.1.1 @@ -11498,6 +12130,13 @@ snapshots: '@inquirer/figures@1.0.15': {} + '@inquirer/input@4.3.1(@types/node@22.16.4)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/input@4.3.1(@types/node@22.16.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@22.16.5) @@ -11512,6 +12151,13 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/number@3.0.23(@types/node@22.16.4)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/number@3.0.23(@types/node@22.16.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@22.16.5) @@ -11526,6 +12172,14 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/password@4.0.23(@types/node@22.16.4)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/password@4.0.23(@types/node@22.16.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -11542,6 +12196,21 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/prompts@7.10.1(@types/node@22.16.4)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@22.16.4) + '@inquirer/confirm': 5.1.21(@types/node@22.16.4) + '@inquirer/editor': 4.2.23(@types/node@22.16.4) + '@inquirer/expand': 4.0.23(@types/node@22.16.4) + '@inquirer/input': 4.3.1(@types/node@22.16.4) + '@inquirer/number': 3.0.23(@types/node@22.16.4) + '@inquirer/password': 4.0.23(@types/node@22.16.4) + '@inquirer/rawlist': 4.1.11(@types/node@22.16.4) + '@inquirer/search': 3.2.2(@types/node@22.16.4) + '@inquirer/select': 4.4.2(@types/node@22.16.4) + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/prompts@7.10.1(@types/node@22.16.5)': dependencies: '@inquirer/checkbox': 4.3.2(@types/node@22.16.5) @@ -11572,6 +12241,14 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/rawlist@4.1.11(@types/node@22.16.4)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/rawlist@4.1.11(@types/node@22.16.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@22.16.5) @@ -11588,6 +12265,15 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/search@3.2.2(@types/node@22.16.4)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.16.4) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/search@3.2.2(@types/node@22.16.5)': dependencies: '@inquirer/core': 10.3.2(@types/node@22.16.5) @@ -11606,6 +12292,16 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/select@4.4.2(@types/node@22.16.4)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@22.16.4) + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/select@4.4.2(@types/node@22.16.5)': dependencies: '@inquirer/ansi': 1.0.2 @@ -11626,6 +12322,10 @@ snapshots: optionalDependencies: '@types/node': 22.18.13 + '@inquirer/type@3.0.10(@types/node@22.16.4)': + optionalDependencies: + '@types/node': 22.16.4 + '@inquirer/type@3.0.10(@types/node@22.16.5)': optionalDependencies: '@types/node': 22.16.5 @@ -11687,6 +12387,41 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.3 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2))': dependencies: '@jest/console': 29.7.0 @@ -12155,7 +12890,7 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@ngtools/webpack@20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2)': + '@ngtools/webpack@20.3.13(@angular/compiler-cli@20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2))(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9))': dependencies: '@angular/compiler-cli': 20.3.15(@angular/compiler@20.3.15)(typescript@5.9.2) typescript: 5.9.2 @@ -12914,6 +13649,10 @@ snapshots: '@tufjs/canonical-json': 2.0.0 minimatch: 9.0.5 + '@types/archiver@6.0.3': + dependencies: + '@types/readdir-glob': 1.1.5 + '@types/archiver@6.0.4': dependencies: '@types/readdir-glob': 1.1.5 @@ -12958,13 +13697,17 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 4.19.7 + '@types/express-serve-static-core': 5.1.0 '@types/node': 22.19.3 '@types/connect@3.4.38': dependencies: '@types/node': 22.19.3 + '@types/cookie-parser@1.4.9(@types/express@4.17.23)': + dependencies: + '@types/express': 4.17.23 + '@types/cookie-parser@1.4.9(@types/express@4.17.25)': dependencies: '@types/express': 4.17.25 @@ -13011,6 +13754,13 @@ snapshots: '@types/range-parser': 1.2.7 '@types/send': 1.2.1 + '@types/express@4.17.23': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.7 + '@types/qs': 6.14.0 + '@types/serve-static': 2.2.0 + '@types/express@4.17.25': dependencies: '@types/body-parser': 1.19.6 @@ -13024,6 +13774,10 @@ snapshots: '@types/express-serve-static-core': 5.1.0 '@types/serve-static': 2.2.0 + '@types/fluent-ffmpeg@2.1.27': + dependencies: + '@types/node': 22.19.3 + '@types/fluent-ffmpeg@2.1.28': dependencies: '@types/node': 22.19.3 @@ -13050,6 +13804,8 @@ snapshots: '@types/jasmine@5.1.13': {} + '@types/jasmine@5.1.9': {} + '@types/jest@29.5.14': dependencies: expect: 29.7.0 @@ -13091,6 +13847,10 @@ snapshots: dependencies: '@types/node': 22.19.3 + '@types/node@22.16.4': + dependencies: + undici-types: 6.21.0 + '@types/node@22.16.5': dependencies: undici-types: 6.21.0 @@ -13542,9 +14302,13 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6))': + '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.6))': dependencies: - vite: 7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6) + vite: 7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.43.1)(tsx@4.20.6) + + '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.5.1)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6))': + dependencies: + vite: 7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.5.1)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6) '@webassemblyjs/ast@1.14.1': dependencies: @@ -13918,7 +14682,7 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@10.0.0(@babel/core@7.28.3)(webpack@5.101.2): + babel-loader@10.0.0(@babel/core@7.28.3)(webpack@5.101.2(esbuild@0.25.9)): dependencies: '@babel/core': 7.28.3 find-up: 5.0.0 @@ -14524,7 +15288,7 @@ snapshots: dependencies: is-what: 3.14.1 - copy-webpack-plugin@13.0.1(webpack@5.101.2): + copy-webpack-plugin@13.0.1(webpack@5.101.2(esbuild@0.25.9)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 @@ -14537,6 +15301,8 @@ snapshots: dependencies: browserslist: 4.28.1 + core-js@3.45.1: {} + core-js@3.47.0: {} core-util-is@1.0.3: {} @@ -14562,6 +15328,21 @@ snapshots: crc-32: 1.2.2 readable-stream: 4.7.0 + create-jest@29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-jest@29.7.0(@types/node@22.16.5)(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)): dependencies: '@jest/types': 29.6.3 @@ -14610,6 +15391,11 @@ snapshots: create-require@1.1.1: {} + cron@4.3.3: + dependencies: + '@types/luxon': 3.7.1 + luxon: 3.7.2 + cron@4.3.5: dependencies: '@types/luxon': 3.7.1 @@ -14635,7 +15421,7 @@ snapshots: dependencies: postcss: 8.5.6 - css-loader@7.1.2(webpack@5.101.2): + css-loader@7.1.2(webpack@5.101.2(esbuild@0.25.9)): dependencies: icss-utils: 5.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -14644,7 +15430,7 @@ snapshots: postcss-modules-scope: 3.2.1(postcss@8.5.6) postcss-modules-values: 4.0.0(postcss@8.5.6) postcss-value-parser: 4.2.0 - semver: 7.7.2 + semver: 7.7.3 optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) @@ -15227,6 +16013,10 @@ snapshots: eslint: 8.57.1 semver: 7.7.3 + eslint-config-prettier@9.1.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-config-prettier@9.1.2(eslint@8.57.1): dependencies: eslint: 8.57.1 @@ -15321,6 +16111,11 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-scope@9.0.0: dependencies: esrecurse: 4.3.0 @@ -16179,6 +16974,18 @@ snapshots: dependencies: tslib: 2.8.1 + inquirer@12.11.1(@types/node@22.16.4): + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/core': 10.3.2(@types/node@22.16.4) + '@inquirer/prompts': 7.10.1(@types/node@22.16.4) + '@inquirer/type': 3.0.10(@types/node@22.16.4) + mute-stream: 2.0.0 + run-async: 4.0.6 + rxjs: 7.8.2 + optionalDependencies: + '@types/node': 22.16.4 + inquirer@12.11.1(@types/node@22.16.5): dependencies: '@inquirer/ansi': 1.0.2 @@ -16439,11 +17246,11 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.5 '@babel/parser': 7.28.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.7.2 + semver: 7.7.3 transitivePeerDependencies: - supports-color @@ -16518,6 +17325,25 @@ snapshots: - babel-plugin-macros - supports-color + jest-cli@29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-cli@29.7.0(@types/node@22.16.5)(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)) @@ -16576,6 +17402,37 @@ snapshots: - supports-color - ts-node + jest-config@29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)): + dependencies: + '@babel/core': 7.28.5 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.16.4 + ts-node: 10.9.2(@types/node@22.16.4)(typescript@5.9.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@29.7.0(@types/node@22.16.5)(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)): dependencies: '@babel/core': 7.28.5 @@ -16639,6 +17496,37 @@ snapshots: - supports-color optional: true + jest-config@29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)): + dependencies: + '@babel/core': 7.28.5 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.19.3 + ts-node: 10.9.2(@types/node@22.16.4)(typescript@5.9.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@29.7.0(@types/node@22.19.3)(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)): dependencies: '@babel/core': 7.28.5 @@ -16983,6 +17871,18 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 + jest@29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest@29.7.0(@types/node@22.16.5)(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)) @@ -17218,7 +18118,7 @@ snapshots: dependencies: readable-stream: 2.3.8 - less-loader@12.3.0(less@4.4.0)(webpack@5.101.2): + less-loader@12.3.0(less@4.4.0)(webpack@5.101.2(esbuild@0.25.9)): dependencies: less: 4.4.0 optionalDependencies: @@ -17259,7 +18159,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.101.2): + license-webpack-plugin@4.0.2(webpack@5.101.2(esbuild@0.25.9)): dependencies: webpack-sources: 3.3.3 optionalDependencies: @@ -17294,6 +18194,13 @@ snapshots: typed-emitter: 2.1.0 webrtc-adapter: 9.0.3 + livekit-server-sdk@2.13.1: + dependencies: + '@bufbuild/protobuf': 1.10.1 + '@livekit/protocol': 1.43.4 + camelcase-keys: 9.1.3 + jose: 5.10.0 + livekit-server-sdk@2.13.3: dependencies: '@bufbuild/protobuf': 1.10.1 @@ -17511,7 +18418,7 @@ snapshots: mimic-function@5.0.1: {} - mini-css-extract-plugin@2.9.4(webpack@5.101.2): + mini-css-extract-plugin@2.9.4(webpack@5.101.2(esbuild@0.25.9)): dependencies: schema-utils: 4.3.3 tapable: 2.3.0 @@ -17830,7 +18737,7 @@ snapshots: dependencies: hosted-git-info: 9.0.2 proc-log: 5.0.0 - semver: 7.7.2 + semver: 7.7.3 validate-npm-package-name: 6.0.2 npm-packlist@10.0.3: @@ -17945,6 +18852,17 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 + openapi-generate-html@0.5.3(@types/node@22.16.4): + dependencies: + '@apidevtools/json-schema-ref-parser': 13.0.5 + commander: 12.1.0 + ejs: 3.1.10 + fast-safe-stringify: 2.1.1 + inquirer: 12.11.1(@types/node@22.16.4) + js-yaml: 4.1.1 + transitivePeerDependencies: + - '@types/node' + openapi-generate-html@0.5.3(@types/node@22.16.5): dependencies: '@apidevtools/json-schema-ref-parser': 13.0.5 @@ -18221,12 +19139,12 @@ snapshots: postcss: 8.5.6 ts-node: 10.9.2(@types/node@22.19.3)(typescript@5.9.3) - postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2): + postcss-loader@8.1.1(postcss@8.5.6)(typescript@5.9.2)(webpack@5.101.2(esbuild@0.25.9)): dependencies: cosmiconfig: 9.0.0(typescript@5.9.2) jiti: 1.21.7 postcss: 8.5.6 - semver: 7.7.2 + semver: 7.7.3 optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) transitivePeerDependencies: @@ -18813,7 +19731,7 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@16.0.5(sass@1.90.0)(webpack@5.101.2): + sass-loader@16.0.5(sass@1.90.0)(webpack@5.101.2(esbuild@0.25.9)): dependencies: neo-async: 2.6.2 optionalDependencies: @@ -19136,7 +20054,7 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.101.2): + source-map-loader@5.0.0(webpack@5.101.2(esbuild@0.25.9)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 @@ -19435,7 +20353,7 @@ snapshots: - encoding - supports-color - terser-webpack-plugin@5.3.16(esbuild@0.25.9)(webpack@5.101.2): + terser-webpack-plugin@5.3.16(esbuild@0.25.9)(webpack@5.101.2(esbuild@0.25.9)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -19566,6 +20484,26 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.28.5) + ts-jest@29.4.0(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)))(typescript@5.9.2): + dependencies: + bs-logger: 0.2.6 + ejs: 3.1.10 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@22.16.4)(ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.3 + type-fest: 4.41.0 + typescript: 5.9.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.28.5 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.5) + jest-util: 29.7.0 + ts-jest@29.4.0(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.16.5)(ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2)))(typescript@5.9.2): dependencies: bs-logger: 0.2.6 @@ -19604,6 +20542,25 @@ snapshots: - '@swc/wasm' - '@types/node' + ts-node@10.9.2(@types/node@22.16.4)(typescript@5.9.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.16.4 + acorn: 8.15.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.9.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + ts-node@10.9.2(@types/node@22.16.5)(typescript@5.9.2): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -19681,6 +20638,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.20.3: + dependencies: + esbuild: 0.25.12 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + tsx@4.20.6: dependencies: esbuild: 0.25.12 @@ -19877,7 +20841,7 @@ snapshots: terser: 5.43.1 tsx: 4.20.6 - vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.4.0)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6): + vite@7.1.11(@types/node@22.18.13)(jiti@1.21.7)(less@4.5.1)(sass@1.90.0)(terser@5.44.1)(tsx@4.20.6): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -19889,7 +20853,7 @@ snapshots: '@types/node': 22.18.13 fsevents: 2.3.3 jiti: 1.21.7 - less: 4.4.0 + less: 4.5.1 sass: 1.90.0 terser: 5.44.1 tsx: 4.20.6 @@ -19930,7 +20894,7 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-dev-middleware@7.4.2(webpack@5.101.2): + webpack-dev-middleware@7.4.2(webpack@5.101.2(esbuild@0.25.9)): dependencies: colorette: 2.0.20 memfs: 4.51.1 @@ -19941,7 +20905,7 @@ snapshots: optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) - webpack-dev-server@5.2.2(webpack@5.101.2): + webpack-dev-server@5.2.2(webpack@5.101.2(esbuild@0.25.9)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -19969,7 +20933,7 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.101.2) + webpack-dev-middleware: 7.4.2(webpack@5.101.2(esbuild@0.25.9)) ws: 8.18.3 optionalDependencies: webpack: 5.101.2(esbuild@0.25.9) @@ -19987,7 +20951,7 @@ snapshots: webpack-sources@3.3.3: {} - webpack-subresource-integrity@5.1.0(webpack@5.101.2): + webpack-subresource-integrity@5.1.0(webpack@5.101.2(esbuild@0.25.9)): dependencies: typed-assert: 1.0.9 webpack: 5.101.2(esbuild@0.25.9) @@ -20016,7 +20980,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(esbuild@0.25.9)(webpack@5.101.2) + terser-webpack-plugin: 5.3.16(esbuild@0.25.9)(webpack@5.101.2(esbuild@0.25.9)) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: