diff --git a/.github/workflows/cluster-faces-test.yml b/.github/workflows/cluster-faces-test.yml index 24404c066..be626e7f8 100644 --- a/.github/workflows/cluster-faces-test.yml +++ b/.github/workflows/cluster-faces-test.yml @@ -161,8 +161,10 @@ jobs: - name: Set config run: | - ./occ config:app:set --value ${{ matrix.pure-js-mode }} recognize tensorflow.purejs + ./occ config:app:set --lazy --value ${{ matrix.pure-js-mode }} recognize tensorflow.purejs ./occ config:app:set --value true recognize faces.enabled + # Don't force API key usage to allow tests to run + ./occ config:app:set --value false recognize require_api_key # only use one core. GH actions has 2 ./occ config:app:set --value 1 recognize tensorflow.cores diff --git a/.github/workflows/files-scan-test.yml b/.github/workflows/files-scan-test.yml index 35bd12427..cfae8dd55 100644 --- a/.github/workflows/files-scan-test.yml +++ b/.github/workflows/files-scan-test.yml @@ -133,7 +133,7 @@ jobs: - name: Set imagenet.enabled and concurrency.enabled run: | ./occ config:app:set --value true recognize imagenet.enabled - ./occ config:app:set --value true recognize concurrency.enabled + ./occ config:app:set --lazy --value true recognize concurrency.enabled - name: Run scan env: diff --git a/.github/workflows/full-run-test.yml b/.github/workflows/full-run-test.yml index 776de7840..6aca00ff0 100644 --- a/.github/workflows/full-run-test.yml +++ b/.github/workflows/full-run-test.yml @@ -155,7 +155,7 @@ jobs: - name: Set pure-js mode run: | - ./occ config:app:set --value ${{ matrix.pure-js-mode }} recognize tensorflow.purejs + ./occ config:app:set --lazy --value ${{ matrix.pure-js-mode }} recognize tensorflow.purejs - name: Set imagenet.enabled run: | diff --git a/lib/Classifiers/Audio/MusicnnClassifier.php b/lib/Classifiers/Audio/MusicnnClassifier.php index e1bf329cf..de5dba13f 100644 --- a/lib/Classifiers/Audio/MusicnnClassifier.php +++ b/lib/Classifiers/Audio/MusicnnClassifier.php @@ -31,7 +31,7 @@ public function __construct(Logger $logger, IAppConfig $config, TagManager $tagM #[Override] public function classify(array $queueFiles): void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { $timeout = self::AUDIO_PUREJS_TIMEOUT; } else { $timeout = self::AUDIO_TIMEOUT; @@ -43,8 +43,8 @@ public function classify(array $queueFiles): void { */ foreach ($classifierProcess as $queueFile => $results) { $this->tagManager->assignTags($queueFile->getFileId(), $results); - $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true'); - $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time()); + $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true', lazy: true); + $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time(), lazy: true); } } } diff --git a/lib/Classifiers/Classifier.php b/lib/Classifiers/Classifier.php index 43c0162ce..f50ff70be 100644 --- a/lib/Classifiers/Classifier.php +++ b/lib/Classifiers/Classifier.php @@ -159,15 +159,15 @@ public function classifyFiles(string $model, array $queueFiles, int $timeout): \ $this->logger->debug('Classifying '.var_export($paths, true)); $command = [ - $this->config->getAppValueString('node_binary'), + $this->config->getAppValueString('node_binary', lazy: true), dirname(__DIR__, 2) . '/src/classifier_'.$model.'.js', '-' ]; - if (trim($this->config->getAppValueString('nice_binary', '')) !== '') { + if (trim($this->config->getAppValueString('nice_binary', '', lazy: true)) !== '') { $command = [ - $this->config->getAppValueString('nice_binary'), - "-" . $this->config->getAppValueString('nice_value', '0'), + $this->config->getAppValueString('nice_binary', lazy: true), + "-" . $this->config->getAppValueString('nice_value', '0', lazy: true), ...$command, ]; } @@ -179,7 +179,7 @@ public function classifyFiles(string $model, array $queueFiles, int $timeout): \ if ($this->config->getAppValueString('tensorflow.gpu', 'false') === 'true') { $env['RECOGNIZE_GPU'] = 'true'; } - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { $env['RECOGNIZE_PUREJS'] = 'true'; } // Set cores diff --git a/lib/Classifiers/Images/ClusteringFaceClassifier.php b/lib/Classifiers/Images/ClusteringFaceClassifier.php index b69bb0c7a..81eff74a6 100644 --- a/lib/Classifiers/Images/ClusteringFaceClassifier.php +++ b/lib/Classifiers/Images/ClusteringFaceClassifier.php @@ -64,7 +64,7 @@ private function getUsersWithFileAccess(Node $node): array { #[Override] public function classify(array $queueFiles): void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { $timeout = self::IMAGE_PUREJS_TIMEOUT; } else { $timeout = self::IMAGE_TIMEOUT; @@ -134,8 +134,8 @@ public function classify(array $queueFiles): void { $this->logger->debug('scheduling ClusterFacesJob for user ' . $userId); $this->jobList->add(ClusterFacesJob::class, ['userId' => $userId]); } - $this->config->setAppValueString(self::MODEL_NAME . '.status', 'true'); - $this->config->setAppValueString(self::MODEL_NAME . '.lastFile', (string)time()); + $this->config->setAppValueString(self::MODEL_NAME . '.status', 'true', lazy: true); + $this->config->setAppValueString(self::MODEL_NAME . '.lastFile', (string)time(), lazy: true); } } $this->logger->debug('face classifier end'); diff --git a/lib/Classifiers/Images/ImagenetClassifier.php b/lib/Classifiers/Images/ImagenetClassifier.php index a69d99ce3..576c0546d 100644 --- a/lib/Classifiers/Images/ImagenetClassifier.php +++ b/lib/Classifiers/Images/ImagenetClassifier.php @@ -33,7 +33,7 @@ public function __construct(Logger $logger, IAppConfig $config, TagManager $tagM #[Override] public function classify(array $queueFiles): void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { $timeout = self::IMAGE_PUREJS_TIMEOUT; } else { $timeout = self::IMAGE_TIMEOUT; @@ -47,8 +47,8 @@ public function classify(array $queueFiles): void { $landmarkTags = array_filter($results, static function ($tagName) { return in_array($tagName, LandmarksClassifier::PRECONDITION_TAGS); }); - $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true'); - $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time()); + $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true', lazy: true); + $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time(), lazy: true); if (count($landmarkTags) > 0) { try { diff --git a/lib/Classifiers/Images/LandmarksClassifier.php b/lib/Classifiers/Images/LandmarksClassifier.php index 9bda84039..adcf60ad8 100644 --- a/lib/Classifiers/Images/LandmarksClassifier.php +++ b/lib/Classifiers/Images/LandmarksClassifier.php @@ -33,7 +33,7 @@ public function __construct(Logger $logger, IAppConfig $config, TagManager $tagM #[Override] public function classify(array $queueFiles): void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { $timeout = self::IMAGE_PUREJS_TIMEOUT; } else { $timeout = self::IMAGE_TIMEOUT; @@ -44,8 +44,8 @@ public function classify(array $queueFiles): void { /** @var list $results */ foreach ($classifierProcess as $queueFile => $results) { $this->tagManager->assignTags($queueFile->getFileId(), $results); - $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true'); - $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time()); + $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true', lazy: true); + $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time(), lazy: true); } } } diff --git a/lib/Classifiers/Video/MovinetClassifier.php b/lib/Classifiers/Video/MovinetClassifier.php index ad6f986da..5f9b6a602 100644 --- a/lib/Classifiers/Video/MovinetClassifier.php +++ b/lib/Classifiers/Video/MovinetClassifier.php @@ -31,7 +31,7 @@ public function __construct(Logger $logger, IAppConfig $config, TagManager $tagM #[Override] public function classify(array $queueFiles): void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { throw new Exception('Movinet does not support WASM mode'); } else { $timeout = self::VIDEO_TIMEOUT; @@ -42,8 +42,8 @@ public function classify(array $queueFiles): void { /** @var list $results */ foreach ($classifierProcess as $queueFile => $results) { $this->tagManager->assignTags($queueFile->getFileId(), $results); - $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true'); - $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time()); + $this->config->setAppValueString(self::MODEL_NAME.'.status', 'true', lazy: true); + $this->config->setAppValueString(self::MODEL_NAME.'.lastFile', (string)time(), lazy: true); } } } diff --git a/lib/Controller/AdminController.php b/lib/Controller/AdminController.php index a266c0dd9..72c51c8b1 100644 --- a/lib/Controller/AdminController.php +++ b/lib/Controller/AdminController.php @@ -177,17 +177,17 @@ public function musl(): JSONResponse { public function nice(): JSONResponse { /* use nice binary from settings if available */ - if ($this->config->getAppValueString('nice_binary', '') !== '') { - $nice_path = $this->config->getAppValueString('nice_binary'); + if ($this->config->getAppValueString('nice_binary', '', lazy: true) !== '') { + $nice_path = $this->config->getAppValueString('nice_binary', lazy: true); } else { /* returns the path to the nice binary or false if not found */ $nice_path = $this->binaryFinder->findBinaryPath('nice'); } if ($nice_path !== false) { - $this->config->setAppValueString('nice_binary', $nice_path); + $this->config->setAppValueString('nice_binary', $nice_path, lazy: true); } else { - $this->config->setAppValueString('nice_binary', ''); + $this->config->setAppValueString('nice_binary', '', lazy: true); return new JSONResponse(['nice' => false]); } diff --git a/lib/Dav/Faces/PropFindPlugin.php b/lib/Dav/Faces/PropFindPlugin.php index 0c56f1f18..d5e615e3c 100644 --- a/lib/Dav/Faces/PropFindPlugin.php +++ b/lib/Dav/Faces/PropFindPlugin.php @@ -15,6 +15,7 @@ use OCA\Recognize\Db\FaceDetectionWithTitle; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\Exception; use OCP\Files\DavUtil; @@ -47,6 +48,7 @@ public function __construct( private ICrypto $crypto, private LoggerInterface $logger, private ITimeFactory $timeFactory, + private IAppConfig $appConfig, ) { } @@ -130,6 +132,9 @@ public function beforeMethod(RequestInterface $request, ResponseInterface $respo if (!str_starts_with($request->getPath(), 'recognize')) { return; } + if ($this->appConfig->getAppValueString('require_api_key', 'true') !== 'true') { + return; + } $key = $request->getHeader('X-Recognize-Api-Key'); if ($key === null) { throw new Forbidden('You must provide a valid X-Recognize-Api-Key'); diff --git a/lib/Migration/InstallDeps.php b/lib/Migration/InstallDeps.php index 914fcda7d..ed8ed084e 100644 --- a/lib/Migration/InstallDeps.php +++ b/lib/Migration/InstallDeps.php @@ -74,7 +74,7 @@ public function getName(): string { public function run(IOutput $output): void { try { - $existingBinary = $this->config->getAppValueString('node_binary', ''); + $existingBinary = $this->config->getAppValueString('node_binary', '', lazy: true); if ($existingBinary !== '') { $version = $this->testBinary($existingBinary); if ($version === null) { @@ -86,7 +86,7 @@ public function run(IOutput $output): void { $this->setBinariesPermissions(); - $binaryPath = $this->config->getAppValueString('node_binary', ''); + $binaryPath = $this->config->getAppValueString('node_binary', '', lazy: true); $this->runTfjsInstall($binaryPath); $this->runFfmpegInstall($binaryPath); @@ -102,17 +102,17 @@ public function run(IOutput $output): void { protected function setNiceBinaryPath() : void { /* use nice binary from settings if available */ - if ($this->config->getAppValueString('nice_binary', '') !== '') { - $nice_path = $this->config->getAppValueString('nice_binary'); + if ($this->config->getAppValueString('nice_binary', '', lazy: true) !== '') { + $nice_path = $this->config->getAppValueString('nice_binary', lazy: true); } else { /* returns the path to the nice binary or false if not found */ $nice_path = $this->binaryFinder->findBinaryPath('nice'); } if ($nice_path !== false) { - $this->config->setAppValueString('nice_binary', $nice_path); + $this->config->setAppValueString('nice_binary', $nice_path, lazy: true); } else { - $this->config->setAppValueString('nice_binary', ''); + $this->config->setAppValueString('nice_binary', '', lazy: true); } } @@ -155,12 +155,12 @@ protected function installNodeBinary(IOutput $output) : void { } // Write the app config - $this->config->setAppValueString('node_binary', $binaryPath); + $this->config->setAppValueString('node_binary', $binaryPath, lazy: true); $supportsAVX = $this->isAVXSupported(); if ($isARM || $isMusl || !$supportsAVX) { $output->info('Enabling purejs mode (isMusl='.$isMusl.', isARM='.$isARM.', supportsAVX='.$supportsAVX.')'); - $this->config->setAppValueString('tensorflow.purejs', 'true'); + $this->config->setAppValueString('tensorflow.purejs', 'true', lazy: true); } } @@ -238,17 +238,17 @@ protected function runFfmpegInstall(string $nodeBinary): void { protected function setFfmpegBinaryPath() : void { /* use nice binary from settings if available */ - if ($this->config->getAppValueString('ffmpeg_binary', '') !== '') { - $ffmpeg_path = $this->config->getAppValueString('ffmpeg_binary'); + if ($this->config->getAppValueString('ffmpeg_binary', '', lazy: true) !== '') { + $ffmpeg_path = $this->config->getAppValueString('ffmpeg_binary', lazy: true); } else { /* returns the path to the nice binary or false if not found */ $ffmpeg_path = $this->binaryFinder->findBinaryPath('ffmpeg'); } if ($ffmpeg_path !== false) { - $this->config->setAppValueString('ffmpeg_binary', $ffmpeg_path); + $this->config->setAppValueString('ffmpeg_binary', $ffmpeg_path, lazy: true); } else { - $this->config->setAppValueString('ffmpeg_binary', __DIR__ . '/../../node_modules/ffmpeg-static/ffmpeg'); + $this->config->setAppValueString('ffmpeg_binary', __DIR__ . '/../../node_modules/ffmpeg-static/ffmpeg', lazy: true); } } diff --git a/lib/Migration/Version011000002Date20260129094821.php b/lib/Migration/Version011000002Date20260129094821.php new file mode 100644 index 000000000..b00e03d6c --- /dev/null +++ b/lib/Migration/Version011000002Date20260129094821.php @@ -0,0 +1,32 @@ +appConfig->hasAppKey($settingsKey, lazy: false)) { + $value = $this->appConfig->getAppValueString($settingsKey); + $this->appConfig->deleteAppValue($settingsKey); + $this->appConfig->setAppValueString($settingsKey, $value, lazy: true); + } + } + } +} diff --git a/lib/Service/SettingsService.php b/lib/Service/SettingsService.php index 66b9f44da..93c6eac2f 100644 --- a/lib/Service/SettingsService.php +++ b/lib/Service/SettingsService.php @@ -63,6 +63,31 @@ final class SettingsService { 'movinet.batchSize' => '5', 'musicnn.batchSize' => '20', ]; + public const LAZY_SETTINGS = [ + 'tensorflow.purejs', + 'node_binary', + 'nice_binary', + 'nice_value', + 'ffmpeg_binary', + 'clusterFaces.status', + 'faces.status', + 'imagenet.status', + 'landmarks.status', + 'movinet.status', + 'musicnn.status', + 'faces.lastFile', + 'imagenet.lastFile', + 'landmarks.lastFile', + 'movinet.lastFile', + 'musicnn.lastFile', + 'clusterFaces.lastRun', + 'faces.batchSize', + 'imagenet.batchSize', + 'landmarks.batchSize', + 'movinet.batchSize', + 'musicnn.batchSize', + 'concurrency.enabled' + ]; private IAppConfig $config; private IJobList $jobList; @@ -80,7 +105,11 @@ public function getSetting(string $key): string { if (strpos($key, 'batchSize') !== false) { return $this->config->getAppValueString($key, $this->getSetting('tensorflow.purejs') === 'false' ? self::DEFAULTS[$key] : self::PUREJS_DEFAULTS[$key]); } - return $this->config->getAppValueString($key, self::DEFAULTS[$key]); + $lazy = false; + if (in_array($key, self::LAZY_SETTINGS, true)) { + $lazy = true; + } + return $this->config->getAppValueString($key, self::DEFAULTS[$key], lazy: $lazy); } /** @@ -115,7 +144,11 @@ public function setSetting(string $key, string $value): void { break; } } - $this->config->setAppValueString($key, $value); + $lazy = false; + if (in_array($key, self::LAZY_SETTINGS, true)) { + $lazy = true; + } + $this->config->setAppValueString($key, $value, lazy: $lazy); } /** diff --git a/tests/ClassifierTest.php b/tests/ClassifierTest.php index 330c65aff..d549df67f 100644 --- a/tests/ClassifierTest.php +++ b/tests/ClassifierTest.php @@ -395,7 +395,7 @@ public function testImagenetPipeline(string $ignoreFileName) : void { } public function testLandmarksPipeline() : void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { // landmarks will fail with purejs/WASM mode, sadly, because we use a worse imagenet model in WASM mode self::markTestSkipped(); } @@ -582,7 +582,7 @@ public function testFacesPipeline() : void { * @throws \Psr\Container\NotFoundExceptionInterface */ public function testMovinetPipeline(string $ignoreFileName) : void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { // Cannot run musicnn with purejs/WASM mode self::markTestSkipped(); } @@ -664,7 +664,7 @@ public function testMovinetPipeline(string $ignoreFileName) : void { * @throws \Psr\Container\NotFoundExceptionInterface */ public function testMusicnnPipeline(string $ignoreFileName) : void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true') { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true') { // Cannot run musicnn with purejs/WASM mode self::markTestSkipped(); } @@ -736,7 +736,7 @@ public function testMusicnnPipeline(string $ignoreFileName) : void { * @throws \OCP\Files\NotPermittedException */ public function testClassifier($file, $model, $tag) : void { - if ($this->config->getAppValueString('tensorflow.purejs', 'false') === 'true' && in_array($model, ['movinet', 'musicnn'])) { + if ($this->config->getAppValueString('tensorflow.purejs', 'false', lazy: true) === 'true' && in_array($model, ['movinet', 'musicnn'])) { // Cannot run musicnn/movinet with purejs/WASM mode self::markTestSkipped(); } diff --git a/vendor-bin/php-cs-fixer/composer.lock b/vendor-bin/php-cs-fixer/composer.lock index ca256f972..9d16cd3ca 100644 --- a/vendor-bin/php-cs-fixer/composer.lock +++ b/vendor-bin/php-cs-fixer/composer.lock @@ -402,16 +402,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.92.3", + "version": "v3.93.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8" + "reference": "b3546ab487c0762c39f308dc1ec0ea2c461fc21a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8", - "reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/b3546ab487c0762c39f308dc1ec0ea2c461fc21a", + "reference": "b3546ab487c0762c39f308dc1ec0ea2c461fc21a", "shasum": "" }, "require": { @@ -443,17 +443,17 @@ }, "require-dev": { "facile-it/paraunit": "^1.3.1 || ^2.7", - "infection/infection": "^0.31.0", - "justinrainbow/json-schema": "^6.5", - "keradus/cli-executor": "^2.2", + "infection/infection": "^0.32", + "justinrainbow/json-schema": "^6.6", + "keradus/cli-executor": "^2.3", "mikey179/vfsstream": "^1.6.12", "php-coveralls/php-coveralls": "^2.9", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", - "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34", + "phpunit/phpunit": "^9.6.31 || ^10.5.60 || ^11.5.48", "symfony/polyfill-php85": "^1.33", - "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2 || ^8.0", - "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2 || ^8.0" + "symfony/var-dumper": "^5.4.48 || ^6.4.26 || ^7.4.0 || ^8.0", + "symfony/yaml": "^5.4.45 || ^6.4.30 || ^7.4.1 || ^8.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -494,7 +494,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.3" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.93.1" }, "funding": [ { @@ -502,7 +502,7 @@ "type": "github" } ], - "time": "2025-12-18T10:45:02+00:00" + "time": "2026-01-28T23:50:50+00:00" }, { "name": "nextcloud/coding-standard", @@ -772,16 +772,16 @@ }, { "name": "react/child-process", - "version": "v0.6.6", + "version": "v0.6.7", "source": { "type": "git", "url": "https://github.com/reactphp/child-process.git", - "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", - "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/970f0e71945556422ee4570ccbabaedc3cf04ad3", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3", "shasum": "" }, "require": { @@ -835,7 +835,7 @@ ], "support": { "issues": "https://github.com/reactphp/child-process/issues", - "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + "source": "https://github.com/reactphp/child-process/tree/v0.6.7" }, "funding": [ { @@ -843,7 +843,7 @@ "type": "open_collective" } ], - "time": "2025-01-01T16:37:48+00:00" + "time": "2025-12-23T15:25:20+00:00" }, { "name": "react/dns", @@ -1293,16 +1293,16 @@ }, { "name": "symfony/console", - "version": "v8.0.1", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "fcb73f69d655b48fcb894a262f074218df08bd58" + "reference": "ace03c4cf9805080ff40cbeec69fca180c339a3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fcb73f69d655b48fcb894a262f074218df08bd58", - "reference": "fcb73f69d655b48fcb894a262f074218df08bd58", + "url": "https://api.github.com/repos/symfony/console/zipball/ace03c4cf9805080ff40cbeec69fca180c339a3b", + "reference": "ace03c4cf9805080ff40cbeec69fca180c339a3b", "shasum": "" }, "require": { @@ -1359,7 +1359,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v8.0.1" + "source": "https://github.com/symfony/console/tree/v8.0.4" }, "funding": [ { @@ -1379,7 +1379,7 @@ "type": "tidelift" } ], - "time": "2025-12-05T15:25:33+00:00" + "time": "2026-01-13T13:06:50+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1450,16 +1450,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v8.0.0", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "573f95783a2ec6e38752979db139f09fec033f03" + "reference": "99301401da182b6cfaa4700dbe9987bb75474b47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/573f95783a2ec6e38752979db139f09fec033f03", - "reference": "573f95783a2ec6e38752979db139f09fec033f03", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47", + "reference": "99301401da182b6cfaa4700dbe9987bb75474b47", "shasum": "" }, "require": { @@ -1511,7 +1511,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.4" }, "funding": [ { @@ -1531,7 +1531,7 @@ "type": "tidelift" } ], - "time": "2025-10-30T14:17:19+00:00" + "time": "2026-01-05T11:45:55+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -1681,16 +1681,16 @@ }, { "name": "symfony/finder", - "version": "v8.0.0", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "7598dd5770580fa3517ec83e8da0c9b9e01f4291" + "reference": "8bd576e97c67d45941365bf824e18dc8538e6eb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7598dd5770580fa3517ec83e8da0c9b9e01f4291", - "reference": "7598dd5770580fa3517ec83e8da0c9b9e01f4291", + "url": "https://api.github.com/repos/symfony/finder/zipball/8bd576e97c67d45941365bf824e18dc8538e6eb0", + "reference": "8bd576e97c67d45941365bf824e18dc8538e6eb0", "shasum": "" }, "require": { @@ -1725,7 +1725,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v8.0.0" + "source": "https://github.com/symfony/finder/tree/v8.0.5" }, "funding": [ { @@ -1745,7 +1745,7 @@ "type": "tidelift" } ], - "time": "2025-11-05T14:36:47+00:00" + "time": "2026-01-26T15:08:38+00:00" }, { "name": "symfony/options-resolver", @@ -2399,16 +2399,16 @@ }, { "name": "symfony/process", - "version": "v8.0.0", + "version": "v8.0.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "a0a750500c4ce900d69ba4e9faf16f82c10ee149" + "reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/a0a750500c4ce900d69ba4e9faf16f82c10ee149", - "reference": "a0a750500c4ce900d69ba4e9faf16f82c10ee149", + "url": "https://api.github.com/repos/symfony/process/zipball/b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674", + "reference": "b5f3aa6762e33fd95efbaa2ec4f4bc9fdd16d674", "shasum": "" }, "require": { @@ -2440,7 +2440,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v8.0.0" + "source": "https://github.com/symfony/process/tree/v8.0.5" }, "funding": [ { @@ -2460,7 +2460,7 @@ "type": "tidelift" } ], - "time": "2025-10-16T16:25:44+00:00" + "time": "2026-01-26T15:08:38+00:00" }, { "name": "symfony/service-contracts", @@ -2617,16 +2617,16 @@ }, { "name": "symfony/string", - "version": "v8.0.1", + "version": "v8.0.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc" + "reference": "758b372d6882506821ed666032e43020c4f57194" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc", - "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc", + "url": "https://api.github.com/repos/symfony/string/zipball/758b372d6882506821ed666032e43020c4f57194", + "reference": "758b372d6882506821ed666032e43020c4f57194", "shasum": "" }, "require": { @@ -2683,7 +2683,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.0.1" + "source": "https://github.com/symfony/string/tree/v8.0.4" }, "funding": [ { @@ -2703,7 +2703,7 @@ "type": "tidelift" } ], - "time": "2025-12-01T09:13:36+00:00" + "time": "2026-01-12T12:37:40+00:00" } ], "packages-dev": [], diff --git a/vendor-bin/php-scoper/composer.lock b/vendor-bin/php-scoper/composer.lock index 520170e05..9a25b52fd 100644 --- a/vendor-bin/php-scoper/composer.lock +++ b/vendor-bin/php-scoper/composer.lock @@ -491,16 +491,16 @@ }, { "name": "symfony/console", - "version": "v6.4.30", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e" + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1b2813049506b39eb3d7e64aff033fd5ca26c97e", - "reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e", + "url": "https://api.github.com/repos/symfony/console/zipball/0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", "shasum": "" }, "require": { @@ -565,7 +565,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.30" + "source": "https://github.com/symfony/console/tree/v6.4.32" }, "funding": [ { @@ -585,7 +585,7 @@ "type": "tidelift" } ], - "time": "2025-12-05T13:47:41+00:00" + "time": "2026-01-13T08:45:59+00:00" }, { "name": "symfony/deprecation-contracts", @@ -802,16 +802,16 @@ }, { "name": "symfony/finder", - "version": "v6.4.27", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a1b6aa435d2fba50793b994a839c32b6064f063b" + "reference": "24965ca011dac87431729640feef8bcf7b5523e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a1b6aa435d2fba50793b994a839c32b6064f063b", - "reference": "a1b6aa435d2fba50793b994a839c32b6064f063b", + "url": "https://api.github.com/repos/symfony/finder/zipball/24965ca011dac87431729640feef8bcf7b5523e0", + "reference": "24965ca011dac87431729640feef8bcf7b5523e0", "shasum": "" }, "require": { @@ -846,7 +846,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.27" + "source": "https://github.com/symfony/finder/tree/v6.4.33" }, "funding": [ { @@ -866,7 +866,7 @@ "type": "tidelift" } ], - "time": "2025-10-15T18:32:00+00:00" + "time": "2026-01-26T13:03:48+00:00" }, { "name": "symfony/polyfill-ctype", diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock index 550588c6a..b30d392b4 100644 --- a/vendor-bin/phpunit/composer.lock +++ b/vendor-bin/phpunit/composer.lock @@ -9,30 +9,29 @@ "packages-dev": [ { "name": "doctrine/instantiator", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", - "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/23da848e1a2308728fe5fdddabf4be17ff9720c7", + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.4" }, "require-dev": { - "doctrine/coding-standard": "^11", + "doctrine/coding-standard": "^14", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^9.5.27", - "vimeo/psalm": "^5.4" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5.58" }, "type": "library", "autoload": { @@ -59,7 +58,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + "source": "https://github.com/doctrine/instantiator/tree/2.1.0" }, "funding": [ { @@ -75,7 +74,7 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:23:10+00:00" + "time": "2026-01-05T06:47:08+00:00" }, { "name": "myclabs/deep-copy", @@ -634,16 +633,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.31", + "version": "9.6.34", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "945d0b7f346a084ce5549e95289962972c4272e5" + "reference": "b36f02317466907a230d3aa1d34467041271ef4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/945d0b7f346a084ce5549e95289962972c4272e5", - "reference": "945d0b7f346a084ce5549e95289962972c4272e5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a", + "reference": "b36f02317466907a230d3aa1d34467041271ef4a", "shasum": "" }, "require": { @@ -665,7 +664,7 @@ "phpunit/php-timer": "^5.0.3", "sebastian/cli-parser": "^1.0.2", "sebastian/code-unit": "^1.0.8", - "sebastian/comparator": "^4.0.9", + "sebastian/comparator": "^4.0.10", "sebastian/diff": "^4.0.6", "sebastian/environment": "^5.1.5", "sebastian/exporter": "^4.0.8", @@ -717,7 +716,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.31" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34" }, "funding": [ { @@ -741,7 +740,7 @@ "type": "tidelift" } ], - "time": "2025-12-06T07:45:52+00:00" + "time": "2026-01-27T05:45:00+00:00" }, { "name": "sebastian/cli-parser", @@ -912,16 +911,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.9", + "version": "4.0.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5" + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5", - "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d", + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d", "shasum": "" }, "require": { @@ -974,7 +973,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10" }, "funding": [ { @@ -994,7 +993,7 @@ "type": "tidelift" } ], - "time": "2025-08-10T06:51:50+00:00" + "time": "2026-01-24T09:22:56+00:00" }, { "name": "sebastian/complexity", diff --git a/vendor-bin/psalm/composer.lock b/vendor-bin/psalm/composer.lock index 2c723e318..fad56c621 100644 --- a/vendor-bin/psalm/composer.lock +++ b/vendor-bin/psalm/composer.lock @@ -1038,22 +1038,22 @@ }, { "name": "danog/advanced-json-rpc", - "version": "v3.2.2", + "version": "v3.2.3", "source": { "type": "git", "url": "https://github.com/danog/php-advanced-json-rpc.git", - "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb" + "reference": "ae703ea7b4811797a10590b6078de05b3b33dd91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/danog/php-advanced-json-rpc/zipball/aadb1c4068a88c3d0530cfe324b067920661efcb", - "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb", + "url": "https://api.github.com/repos/danog/php-advanced-json-rpc/zipball/ae703ea7b4811797a10590b6078de05b3b33dd91", + "reference": "ae703ea7b4811797a10590b6078de05b3b33dd91", "shasum": "" }, "require": { "netresearch/jsonmapper": "^5", "php": ">=8.1", - "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0 || ^6" }, "replace": { "felixfbecker/php-advanced-json-rpc": "^3" @@ -1084,9 +1084,9 @@ "description": "A more advanced JSONRPC implementation", "support": { "issues": "https://github.com/danog/php-advanced-json-rpc/issues", - "source": "https://github.com/danog/php-advanced-json-rpc/tree/v3.2.2" + "source": "https://github.com/danog/php-advanced-json-rpc/tree/v3.2.3" }, - "time": "2025-02-14T10:55:15+00:00" + "time": "2026-01-12T21:07:10+00:00" }, { "name": "daverandom/libdns", @@ -1394,20 +1394,20 @@ }, { "name": "league/uri", - "version": "7.7.0", + "version": "7.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807" + "reference": "4436c6ec8d458e4244448b069cc572d088230b76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/8d587cddee53490f9b82bf203d3a9aa7ea4f9807", - "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/4436c6ec8d458e4244448b069cc572d088230b76", + "reference": "4436c6ec8d458e4244448b069cc572d088230b76", "shasum": "" }, "require": { - "league/uri-interfaces": "^7.7", + "league/uri-interfaces": "^7.8", "php": "^8.1", "psr/http-factory": "^1" }, @@ -1421,11 +1421,11 @@ "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", "ext-uri": "to use the PHP native URI class", - "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", - "league/uri-components": "Needed to easily manipulate URI objects components", - "league/uri-polyfill": "Needed to backport the PHP URI extension for older versions of PHP", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", "php-64bit": "to improve IPV4 host parsing", - "rowbot/url": "to handle WHATWG URL", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", @@ -1480,7 +1480,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.7.0" + "source": "https://github.com/thephpleague/uri/tree/7.8.0" }, "funding": [ { @@ -1488,20 +1488,20 @@ "type": "github" } ], - "time": "2025-12-07T16:02:06+00:00" + "time": "2026-01-14T17:24:56+00:00" }, { "name": "league/uri-interfaces", - "version": "7.7.0", + "version": "7.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c" + "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/62ccc1a0435e1c54e10ee6022df28d6c04c2946c", - "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/c5c5cd056110fc8afaba29fa6b72a43ced42acd4", + "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4", "shasum": "" }, "require": { @@ -1514,7 +1514,7 @@ "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", "php-64bit": "to improve IPV4 host parsing", - "rowbot/url": "to handle WHATWG URL", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", @@ -1564,7 +1564,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.7.0" + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.0" }, "funding": [ { @@ -1572,7 +1572,7 @@ "type": "github" } ], - "time": "2025-12-07T16:03:21+00:00" + "time": "2026-01-15T06:54:53+00:00" }, { "name": "netresearch/jsonmapper", @@ -1738,16 +1738,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.5", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761" + "reference": "2f5cbed597cb261d1ea458f3da3a9ad32e670b1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/90614c73d3800e187615e2dd236ad0e2a01bf761", - "reference": "90614c73d3800e187615e2dd236ad0e2a01bf761", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/2f5cbed597cb261d1ea458f3da3a9ad32e670b1e", + "reference": "2f5cbed597cb261d1ea458f3da3a9ad32e670b1e", "shasum": "" }, "require": { @@ -1755,9 +1755,9 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", - "webmozart/assert": "^1.9.1" + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", + "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { "mockery/mockery": "~1.3.5 || ~1.6.0", @@ -1766,7 +1766,8 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, "type": "library", "extra": { @@ -1796,44 +1797,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.5" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.1" }, - "time": "2025-11-27T19:50:05+00:00" + "time": "2026-01-20T15:30:42+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.12.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -1854,22 +1855,22 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, - "time": "2025-11-21T15:09:14+00:00" + "time": "2026-01-06T21:53:42+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "2.3.0", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", "shasum": "" }, "require": { @@ -1901,9 +1902,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" }, - "time": "2025-08-30T15:50:23+00:00" + "time": "2026-01-25T14:56:51+00:00" }, { "name": "psr/container", @@ -2325,16 +2326,16 @@ }, { "name": "symfony/console", - "version": "v6.4.30", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e" + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1b2813049506b39eb3d7e64aff033fd5ca26c97e", - "reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e", + "url": "https://api.github.com/repos/symfony/console/zipball/0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", "shasum": "" }, "require": { @@ -2399,7 +2400,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.30" + "source": "https://github.com/symfony/console/tree/v6.4.32" }, "funding": [ { @@ -2419,7 +2420,7 @@ "type": "tidelift" } ], - "time": "2025-12-05T13:47:41+00:00" + "time": "2026-01-13T08:45:59+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2975,16 +2976,16 @@ }, { "name": "symfony/process", - "version": "v6.4.26", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "48bad913268c8cafabbf7034b39c8bb24fbc5ab8" + "reference": "c46e854e79b52d07666e43924a20cb6dc546644e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/48bad913268c8cafabbf7034b39c8bb24fbc5ab8", - "reference": "48bad913268c8cafabbf7034b39c8bb24fbc5ab8", + "url": "https://api.github.com/repos/symfony/process/zipball/c46e854e79b52d07666e43924a20cb6dc546644e", + "reference": "c46e854e79b52d07666e43924a20cb6dc546644e", "shasum": "" }, "require": { @@ -3016,7 +3017,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.26" + "source": "https://github.com/symfony/process/tree/v6.4.33" }, "funding": [ { @@ -3036,7 +3037,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T09:57:09+00:00" + "time": "2026-01-23T16:02:12+00:00" }, { "name": "symfony/service-contracts", @@ -3127,16 +3128,16 @@ }, { "name": "symfony/string", - "version": "v7.4.0", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003" + "reference": "1c4b10461bf2ec27537b5f36105337262f5f5d6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d50e862cb0a0e0886f73ca1f31b865efbb795003", - "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003", + "url": "https://api.github.com/repos/symfony/string/zipball/1c4b10461bf2ec27537b5f36105337262f5f5d6f", + "reference": "1c4b10461bf2ec27537b5f36105337262f5f5d6f", "shasum": "" }, "require": { @@ -3194,7 +3195,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.0" + "source": "https://github.com/symfony/string/tree/v7.4.4" }, "funding": [ { @@ -3214,20 +3215,20 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-01-12T10:54:30+00:00" }, { "name": "vimeo/psalm", - "version": "6.14.2", + "version": "6.14.3", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "bbd217fc98c0daa0a13aea2a7f119d03ba3fc9a0" + "reference": "d0b040a91f280f071c1abcb1b77ce3822058725a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/bbd217fc98c0daa0a13aea2a7f119d03ba3fc9a0", - "reference": "bbd217fc98c0daa0a13aea2a7f119d03ba3fc9a0", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/d0b040a91f280f071c1abcb1b77ce3822058725a", + "reference": "d0b040a91f280f071c1abcb1b77ce3822058725a", "shasum": "" }, "require": { @@ -3253,8 +3254,8 @@ "php": "~8.1.31 || ~8.2.27 || ~8.3.16 || ~8.4.3 || ~8.5.0", "sebastian/diff": "^4.0 || ^5.0 || ^6.0 || ^7.0", "spatie/array-to-xml": "^2.17.0 || ^3.0", - "symfony/console": "^6.0 || ^7.0", - "symfony/filesystem": "~6.3.12 || ~6.4.3 || ^7.0.3", + "symfony/console": "^6.0 || ^7.0 || ^8.0", + "symfony/filesystem": "~6.3.12 || ~6.4.3 || ^7.0.3 || ^8.0", "symfony/polyfill-php84": "^1.31.0" }, "provide": { @@ -3276,7 +3277,7 @@ "psalm/plugin-phpunit": "^0.19", "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^6.0 || ^7.0" + "symfony/process": "^6.0 || ^7.0 || ^8.0" }, "suggest": { "ext-curl": "In order to send data to shepherd", @@ -3332,27 +3333,27 @@ "issues": "https://github.com/vimeo/psalm/issues", "source": "https://github.com/vimeo/psalm" }, - "time": "2025-12-11T08:58:52+00:00" + "time": "2025-12-23T15:36:48+00:00" }, { "name": "webmozart/assert", - "version": "1.12.1", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + "reference": "ce6a2f100c404b2d32a1dd1270f9b59ad4f57649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/ce6a2f100c404b2d32a1dd1270f9b59ad4f57649", + "reference": "ce6a2f100c404b2d32a1dd1270f9b59ad4f57649", "shasum": "" }, "require": { "ext-ctype": "*", "ext-date": "*", "ext-filter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.2" }, "suggest": { "ext-intl": "", @@ -3362,7 +3363,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10-dev" + "dev-feature/2-0": "2.0-dev" } }, "autoload": { @@ -3378,6 +3379,10 @@ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", @@ -3388,9 +3393,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.12.1" + "source": "https://github.com/webmozarts/assert/tree/2.1.2" }, - "time": "2025-10-29T15:56:20+00:00" + "time": "2026-01-13T14:02:24+00:00" } ], "packages-dev": [ @@ -3400,16 +3405,16 @@ "source": { "type": "git", "url": "https://github.com/nextcloud-deps/ocp.git", - "reference": "4a157cd2b3b339cc2529de578bddc1d2e4b77507" + "reference": "a101733a740e3264643b76f6489515cb27c43c99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/4a157cd2b3b339cc2529de578bddc1d2e4b77507", - "reference": "4a157cd2b3b339cc2529de578bddc1d2e4b77507", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/a101733a740e3264643b76f6489515cb27c43c99", + "reference": "a101733a740e3264643b76f6489515cb27c43c99", "shasum": "" }, "require": { - "php": "~8.1 || ~8.2 || ~8.3 || ~8.4", + "php": "~8.1 || ~8.2 || ~8.3 || ~8.4 || ~8.5", "psr/clock": "^1.0", "psr/container": "^2.0.2", "psr/event-dispatcher": "^1.0", @@ -3419,7 +3424,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "33.0.0-dev" + "dev-master": "34.0.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -3441,7 +3446,7 @@ "issues": "https://github.com/nextcloud-deps/ocp/issues", "source": "https://github.com/nextcloud-deps/ocp/tree/master" }, - "time": "2025-12-19T00:55:34+00:00" + "time": "2026-01-29T01:05:54+00:00" }, { "name": "psr/clock", @@ -3815,16 +3820,16 @@ }, { "name": "sabre/vobject", - "version": "4.5.7", + "version": "4.5.8", "source": { "type": "git", "url": "https://github.com/sabre-io/vobject.git", - "reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c" + "reference": "d554eb24d64232922e1eab5896cc2f84b3b9ffb1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/vobject/zipball/ff22611a53782e90c97be0d0bc4a5f98a5c0a12c", - "reference": "ff22611a53782e90c97be0d0bc4a5f98a5c0a12c", + "url": "https://api.github.com/repos/sabre-io/vobject/zipball/d554eb24d64232922e1eab5896cc2f84b3b9ffb1", + "reference": "d554eb24d64232922e1eab5896cc2f84b3b9ffb1", "shasum": "" }, "require": { @@ -3915,7 +3920,7 @@ "issues": "https://github.com/sabre-io/vobject/issues", "source": "https://github.com/fruux/sabre-vobject" }, - "time": "2025-04-17T09:22:48+00:00" + "time": "2026-01-12T10:45:19+00:00" }, { "name": "sabre/xml",