diff --git a/Makefile b/Makefile
index 01f437b8..4f9b56d6 100644
--- a/Makefile
+++ b/Makefile
@@ -41,11 +41,11 @@ phpunit-integration: vendor
.PHONY: phpunit-integration-postgres
phpunit-integration-postgres: vendor ## run phpunit integration tests on postgres
- DB_URL="pdo-pgsql://postgres:postgres@localhost:5432/eventstore?charset=utf8" vendor/bin/phpunit --testsuite=integration
+ DB_URL="pdo-pgsql://postgres:postgres@127.0.0.1:5432/eventstore?charset=utf8" vendor/bin/phpunit --testsuite=integration
.PHONY: phpunit-integration-mysql
phpunit-integration-mysql: vendor ## run phpunit integration tests on mysql
- DB_URL="pdo-mysql://root@localhost:3306/eventstore?charset=utf8" vendor/bin/phpunit --testsuite=integration
+ DB_URL="pdo-mysql://root@127.0.0.1:3306/eventstore?charset=utf8" vendor/bin/phpunit --testsuite=integration
.PHONY: phpunit-unit
phpunit-unit: vendor ## run phpunit unit tests
diff --git a/baseline.xml b/baseline.xml
index 7504e13d..2e51abc6 100644
--- a/baseline.xml
+++ b/baseline.xml
@@ -95,6 +95,12 @@
+
+
+
+
+
+
diff --git a/composer.lock b/composer.lock
index 9ab3b46d..d2d175e4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -2438,16 +2438,16 @@
},
{
"name": "amphp/parallel",
- "version": "v2.3.1",
+ "version": "v2.3.2",
"source": {
"type": "git",
"url": "https://github.com/amphp/parallel.git",
- "reference": "5113111de02796a782f5d90767455e7391cca190"
+ "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/amphp/parallel/zipball/5113111de02796a782f5d90767455e7391cca190",
- "reference": "5113111de02796a782f5d90767455e7391cca190",
+ "url": "https://api.github.com/repos/amphp/parallel/zipball/321b45ae771d9c33a068186b24117e3cd1c48dce",
+ "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce",
"shasum": ""
},
"require": {
@@ -2510,7 +2510,7 @@
],
"support": {
"issues": "https://github.com/amphp/parallel/issues",
- "source": "https://github.com/amphp/parallel/tree/v2.3.1"
+ "source": "https://github.com/amphp/parallel/tree/v2.3.2"
},
"funding": [
{
@@ -2518,7 +2518,7 @@
"type": "github"
}
],
- "time": "2024-12-21T01:56:09+00:00"
+ "time": "2025-08-27T21:55:40+00:00"
},
{
"name": "amphp/parser",
@@ -4607,16 +4607,16 @@
},
{
"name": "justinrainbow/json-schema",
- "version": "6.5.0",
+ "version": "6.5.1",
"source": {
"type": "git",
"url": "https://github.com/jsonrainbow/json-schema.git",
- "reference": "3916d662058b47fddb07c0c2ec57eb027b9ba21d"
+ "reference": "b5ab21e431594897e5bb86343c01f140ba862c26"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/3916d662058b47fddb07c0c2ec57eb027b9ba21d",
- "reference": "3916d662058b47fddb07c0c2ec57eb027b9ba21d",
+ "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/b5ab21e431594897e5bb86343c01f140ba862c26",
+ "reference": "b5ab21e431594897e5bb86343c01f140ba862c26",
"shasum": ""
},
"require": {
@@ -4676,9 +4676,9 @@
],
"support": {
"issues": "https://github.com/jsonrainbow/json-schema/issues",
- "source": "https://github.com/jsonrainbow/json-schema/tree/6.5.0"
+ "source": "https://github.com/jsonrainbow/json-schema/tree/6.5.1"
},
- "time": "2025-08-29T08:51:57+00:00"
+ "time": "2025-08-29T10:58:11+00:00"
},
{
"name": "kelunik/certificate",
@@ -6187,16 +6187,16 @@
},
{
"name": "phpstan/phpdoc-parser",
- "version": "2.2.0",
+ "version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8"
+ "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b9e61a61e39e02dd90944e9115241c7f7e76bfd8",
- "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
+ "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
"shasum": ""
},
"require": {
@@ -6228,9 +6228,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.2.0"
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
},
- "time": "2025-07-13T07:04:09+00:00"
+ "time": "2025-08-30T15:50:23+00:00"
},
{
"name": "phpstan/phpstan",
@@ -8195,32 +8195,32 @@
},
{
"name": "slevomat/coding-standard",
- "version": "8.20.0",
+ "version": "8.21.1",
"source": {
"type": "git",
"url": "https://github.com/slevomat/coding-standard.git",
- "reference": "b4f9f02edd4e6a586777f0cabe8d05574323f3eb"
+ "reference": "2b801e950ae1cceb30bb3c0373141f553c99d3c3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b4f9f02edd4e6a586777f0cabe8d05574323f3eb",
- "reference": "b4f9f02edd4e6a586777f0cabe8d05574323f3eb",
+ "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/2b801e950ae1cceb30bb3c0373141f553c99d3c3",
+ "reference": "2b801e950ae1cceb30bb3c0373141f553c99d3c3",
"shasum": ""
},
"require": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.1.2",
"php": "^7.4 || ^8.0",
- "phpstan/phpdoc-parser": "^2.2.0",
+ "phpstan/phpdoc-parser": "^2.3.0",
"squizlabs/php_codesniffer": "^3.13.2"
},
"require-dev": {
"phing/phing": "3.0.1|3.1.0",
"php-parallel-lint/php-parallel-lint": "1.4.0",
- "phpstan/phpstan": "2.1.19",
+ "phpstan/phpstan": "2.1.22",
"phpstan/phpstan-deprecation-rules": "2.0.3",
"phpstan/phpstan-phpunit": "2.0.7",
"phpstan/phpstan-strict-rules": "2.0.6",
- "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.27|12.2.7"
+ "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.27|12.3.7"
},
"type": "phpcodesniffer-standard",
"extra": {
@@ -8244,7 +8244,7 @@
],
"support": {
"issues": "https://github.com/slevomat/coding-standard/issues",
- "source": "https://github.com/slevomat/coding-standard/tree/8.20.0"
+ "source": "https://github.com/slevomat/coding-standard/tree/8.21.1"
},
"funding": [
{
@@ -8256,7 +8256,7 @@
"type": "tidelift"
}
],
- "time": "2025-07-26T15:35:10+00:00"
+ "time": "2025-08-31T13:32:28+00:00"
},
{
"name": "spatie/array-to-xml",
diff --git a/src/Cryptography/DoctrineCipherKeyStore.php b/src/Cryptography/DoctrineCipherKeyStore.php
index 2bfb00da..fdd4c850 100644
--- a/src/Cryptography/DoctrineCipherKeyStore.php
+++ b/src/Cryptography/DoctrineCipherKeyStore.php
@@ -6,6 +6,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Schema;
+use Patchlevel\EventSourcing\Schema\DoctrineHelper;
use Patchlevel\EventSourcing\Schema\DoctrineSchemaConfigurator;
use Patchlevel\Hydrator\Cryptography\Cipher\CipherKey;
use Patchlevel\Hydrator\Cryptography\Store\CipherKeyNotExists;
@@ -80,7 +81,7 @@ public function remove(string $id): void
public function configureSchema(Schema $schema, Connection $connection): void
{
- if ($connection !== $this->connection) {
+ if (!DoctrineHelper::sameDatabase($this->connection, $connection)) {
return;
}
diff --git a/src/Schema/DoctrineHelper.php b/src/Schema/DoctrineHelper.php
new file mode 100644
index 00000000..889c9cf6
--- /dev/null
+++ b/src/Schema/DoctrineHelper.php
@@ -0,0 +1,44 @@
+getParams() === $connectionB->getParams()) {
+ return true;
+ }
+
+ $checkTable = 'same_db_check_' . bin2hex(random_bytes(7));
+ $connectionA->executeStatement(sprintf('CREATE TABLE %s (id INTEGER NOT NULL)', $checkTable));
+
+ try {
+ $connectionB->executeStatement(sprintf('DROP TABLE %s', $checkTable));
+ } catch (Throwable) {
+ // ignore
+ }
+
+ try {
+ $connectionA->executeStatement(sprintf('DROP TABLE %s', $checkTable));
+
+ return false;
+ } catch (TableNotFoundException) {
+ return true;
+ }
+ }
+}
diff --git a/src/Store/DoctrineDbalStore.php b/src/Store/DoctrineDbalStore.php
index 76c775bd..902d6c41 100644
--- a/src/Store/DoctrineDbalStore.php
+++ b/src/Store/DoctrineDbalStore.php
@@ -21,6 +21,7 @@
use Patchlevel\EventSourcing\Message\Message;
use Patchlevel\EventSourcing\Message\Serializer\DefaultHeadersSerializer;
use Patchlevel\EventSourcing\Message\Serializer\HeadersSerializer;
+use Patchlevel\EventSourcing\Schema\DoctrineHelper;
use Patchlevel\EventSourcing\Schema\DoctrineSchemaConfigurator;
use Patchlevel\EventSourcing\Serializer\EventSerializer;
use Patchlevel\EventSourcing\Store\Criteria\AggregateIdCriterion;
@@ -314,7 +315,7 @@ public function transactional(Closure $function): void
public function configureSchema(Schema $schema, Connection $connection): void
{
- if ($this->connection !== $connection) {
+ if (!DoctrineHelper::sameDatabase($this->connection, $connection)) {
return;
}
diff --git a/src/Store/StreamDoctrineDbalStore.php b/src/Store/StreamDoctrineDbalStore.php
index 69ef4b9e..83a24a24 100644
--- a/src/Store/StreamDoctrineDbalStore.php
+++ b/src/Store/StreamDoctrineDbalStore.php
@@ -21,6 +21,7 @@
use Patchlevel\EventSourcing\Message\Message;
use Patchlevel\EventSourcing\Message\Serializer\DefaultHeadersSerializer;
use Patchlevel\EventSourcing\Message\Serializer\HeadersSerializer;
+use Patchlevel\EventSourcing\Schema\DoctrineHelper;
use Patchlevel\EventSourcing\Schema\DoctrineSchemaConfigurator;
use Patchlevel\EventSourcing\Serializer\EventSerializer;
use Patchlevel\EventSourcing\Store\Criteria\ArchivedCriterion;
@@ -396,7 +397,7 @@ public function archive(Criteria|null $criteria = null): void
public function configureSchema(Schema $schema, Connection $connection): void
{
- if ($this->connection !== $connection) {
+ if (!DoctrineHelper::sameDatabase($this->connection, $connection)) {
return;
}
diff --git a/src/Subscription/Store/DoctrineSubscriptionStore.php b/src/Subscription/Store/DoctrineSubscriptionStore.php
index 08cde34d..424f1cce 100644
--- a/src/Subscription/Store/DoctrineSubscriptionStore.php
+++ b/src/Subscription/Store/DoctrineSubscriptionStore.php
@@ -15,6 +15,7 @@
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Patchlevel\EventSourcing\Clock\SystemClock;
+use Patchlevel\EventSourcing\Schema\DoctrineHelper;
use Patchlevel\EventSourcing\Schema\DoctrineSchemaConfigurator;
use Patchlevel\EventSourcing\Subscription\RunMode;
use Patchlevel\EventSourcing\Subscription\Status;
@@ -208,6 +209,10 @@ public function inLock(Closure $closure): mixed
public function configureSchema(Schema $schema, Connection $connection): void
{
+ if (!DoctrineHelper::sameDatabase($this->connection, $connection)) {
+ return;
+ }
+
$table = $schema->createTable($this->tableName);
$table->addColumn('id', Types::STRING)
diff --git a/tests/DbalManager.php b/tests/DbalManager.php
index c4a39af7..240e5c21 100644
--- a/tests/DbalManager.php
+++ b/tests/DbalManager.php
@@ -7,6 +7,7 @@
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
use Doctrine\DBAL\DriverManager;
+use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Tools\DsnParser;
use Patchlevel\EventSourcing\Console\DoctrineHelper;
use RuntimeException;
@@ -45,6 +46,14 @@ public static function createConnection(string $dbName = self::DEFAULT_DB_NAME):
$databases = $schemaManager->listDatabases();
if (in_array($dbName, $databases, true)) {
+ if ($tempConnection->getDatabasePlatform() instanceof PostgreSQLPlatform) {
+ $tempConnection->executeStatement("
+ SELECT pg_terminate_backend(pid)
+ FROM pg_stat_activity
+ WHERE datname = '{$dbName}';
+ ");
+ }
+
$schemaManager->dropDatabase($dbName);
}
diff --git a/tests/Integration/Store/DoctrineDbalStoreTest.php b/tests/Integration/Store/DoctrineDbalStoreTest.php
index 3eee96ad..04511fc7 100644
--- a/tests/Integration/Store/DoctrineDbalStoreTest.php
+++ b/tests/Integration/Store/DoctrineDbalStoreTest.php
@@ -6,6 +6,7 @@
use DateTimeImmutable;
use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Schema\Schema;
use Patchlevel\EventSourcing\Aggregate\AggregateHeader;
use Patchlevel\EventSourcing\Message\Message;
use Patchlevel\EventSourcing\Schema\DoctrineSchemaDirector;
@@ -224,4 +225,38 @@ public function testLoad(): void
$stream?->close();
}
}
+
+ public function testConfigureSchemaSameDatabase(): void
+ {
+ $connection = DbalManager::createConnection();
+ $otherConnection = DbalManager::createConnection();
+
+ $store = new DoctrineDbalStore(
+ $connection,
+ DefaultEventSerializer::createFromPaths([__DIR__ . '/Events']),
+ );
+
+ $schema = new Schema();
+
+ $store->configureSchema($schema, $otherConnection);
+
+ self::assertTrue($schema->hasTable('eventstore'));
+ }
+
+ public function testConfigureSchemaNotSameDatabase(): void
+ {
+ $connection = DbalManager::createConnection();
+ $otherConnection = DbalManager::createConnection('other');
+
+ $store = new DoctrineDbalStore(
+ $connection,
+ DefaultEventSerializer::createFromPaths([__DIR__ . '/Events']),
+ );
+
+ $schema = new Schema();
+
+ $store->configureSchema($schema, $otherConnection);
+
+ self::assertFalse($schema->hasTable('eventstore'));
+ }
}
diff --git a/tests/Integration/Store/StreamDoctrineDbalStoreTest.php b/tests/Integration/Store/StreamDoctrineDbalStoreTest.php
index 9d22d7b5..9b83b285 100644
--- a/tests/Integration/Store/StreamDoctrineDbalStoreTest.php
+++ b/tests/Integration/Store/StreamDoctrineDbalStoreTest.php
@@ -6,6 +6,7 @@
use DateTimeImmutable;
use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Schema\Schema;
use Patchlevel\EventSourcing\Clock\FrozenClock;
use Patchlevel\EventSourcing\Message\Message;
use Patchlevel\EventSourcing\Schema\DoctrineSchemaDirector;
@@ -538,4 +539,40 @@ public function testRemove(): void
self::assertEquals(['foo'], $streams);
}
+
+ public function testConfigureSchemaSameDatabase(): void
+ {
+ $connection = DbalManager::createConnection();
+ $otherConnection = DbalManager::createConnection();
+
+ $store = new StreamDoctrineDbalStore(
+ $connection,
+ DefaultEventSerializer::createFromPaths([__DIR__ . '/Events']),
+ clock: $this->clock,
+ );
+
+ $schema = new Schema();
+
+ $store->configureSchema($schema, $otherConnection);
+
+ self::assertTrue($schema->hasTable('event_store'));
+ }
+
+ public function testConfigureSchemaNotSameDatabase(): void
+ {
+ $connection = DbalManager::createConnection();
+ $otherConnection = DbalManager::createConnection('other');
+
+ $store = new StreamDoctrineDbalStore(
+ $connection,
+ DefaultEventSerializer::createFromPaths([__DIR__ . '/Events']),
+ clock: $this->clock,
+ );
+
+ $schema = new Schema();
+
+ $store->configureSchema($schema, $otherConnection);
+
+ self::assertFalse($schema->hasTable('event_store'));
+ }
}
diff --git a/tests/Unit/Store/DoctrineDbalStoreTest.php b/tests/Unit/Store/DoctrineDbalStoreTest.php
index b6807935..0d968ff5 100644
--- a/tests/Unit/Store/DoctrineDbalStoreTest.php
+++ b/tests/Unit/Store/DoctrineDbalStoreTest.php
@@ -1375,9 +1375,11 @@ public function testWait(): void
$doctrineDbalStore->wait(100);
}
- public function testConfigureSchemaWithDifferentConnections(): void
+ public function testConfigureSchemaWithDifferentDatabase(): void
{
$connection = $this->createMock(Connection::class);
+ $connection->expects($this->once())->method('getParams')->willReturn(['dbname' => 'db']);
+
$eventSerializer = $this->createMock(EventSerializer::class);
$headersSerializer = $this->createMock(HeadersSerializer::class);
@@ -1386,8 +1388,12 @@ public function testConfigureSchemaWithDifferentConnections(): void
$eventSerializer,
$headersSerializer,
);
+
+ $differentConnection = $this->createMock(Connection::class);
+ $differentConnection->expects($this->once())->method('getParams')->willReturn(['dbname' => 'db2']);
+
$schema = new Schema();
- $doctrineDbalStore->configureSchema($schema, $this->createMock(Connection::class));
+ $doctrineDbalStore->configureSchema($schema, $differentConnection);
self::assertEquals(new Schema(), $schema);
}
diff --git a/tests/Unit/Store/StreamDoctrineDbalStoreTest.php b/tests/Unit/Store/StreamDoctrineDbalStoreTest.php
index 1e9d472a..c78414c2 100644
--- a/tests/Unit/Store/StreamDoctrineDbalStoreTest.php
+++ b/tests/Unit/Store/StreamDoctrineDbalStoreTest.php
@@ -1404,9 +1404,11 @@ public function testWait(): void
$doctrineDbalStore->wait(100);
}
- public function testConfigureSchemaWithDifferentConnections(): void
+ public function testConfigureSchemaWithDifferentDatabase(): void
{
$connection = $this->createMock(Connection::class);
+ $connection->expects($this->once())->method('getParams')->willReturn(['dbname' => 'db']);
+
$eventSerializer = $this->createMock(EventSerializer::class);
$headersSerializer = $this->createMock(HeadersSerializer::class);
@@ -1415,8 +1417,12 @@ public function testConfigureSchemaWithDifferentConnections(): void
$eventSerializer,
$headersSerializer,
);
+
+ $differentConnection = $this->createMock(Connection::class);
+ $connection->expects($this->once())->method('getParams')->willReturn(['dbname' => 'db2']);
+
$schema = new Schema();
- $doctrineDbalStore->configureSchema($schema, $this->createMock(Connection::class));
+ $doctrineDbalStore->configureSchema($schema, $differentConnection);
self::assertEquals(new Schema(), $schema);
}
diff --git a/tools/composer.lock b/tools/composer.lock
index 9c5bb13d..b03d5be3 100644
--- a/tools/composer.lock
+++ b/tools/composer.lock
@@ -866,16 +866,16 @@
},
{
"name": "justinrainbow/json-schema",
- "version": "6.5.0",
+ "version": "6.5.1",
"source": {
"type": "git",
"url": "https://github.com/jsonrainbow/json-schema.git",
- "reference": "3916d662058b47fddb07c0c2ec57eb027b9ba21d"
+ "reference": "b5ab21e431594897e5bb86343c01f140ba862c26"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/3916d662058b47fddb07c0c2ec57eb027b9ba21d",
- "reference": "3916d662058b47fddb07c0c2ec57eb027b9ba21d",
+ "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/b5ab21e431594897e5bb86343c01f140ba862c26",
+ "reference": "b5ab21e431594897e5bb86343c01f140ba862c26",
"shasum": ""
},
"require": {
@@ -935,9 +935,9 @@
],
"support": {
"issues": "https://github.com/jsonrainbow/json-schema/issues",
- "source": "https://github.com/jsonrainbow/json-schema/tree/6.5.0"
+ "source": "https://github.com/jsonrainbow/json-schema/tree/6.5.1"
},
- "time": "2025-08-29T08:51:57+00:00"
+ "time": "2025-08-29T10:58:11+00:00"
},
{
"name": "marc-mabe/php-enum",
@@ -1517,22 +1517,22 @@
},
{
"name": "roave/better-reflection",
- "version": "6.60.0",
+ "version": "6.61.0",
"source": {
"type": "git",
"url": "https://github.com/Roave/BetterReflection.git",
- "reference": "53dd01710b5c705b1b570a1820bd65e70529ebc7"
+ "reference": "d0c9955a6cce8dfefe379b6ea53a26488dc1feb6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/BetterReflection/zipball/53dd01710b5c705b1b570a1820bd65e70529ebc7",
- "reference": "53dd01710b5c705b1b570a1820bd65e70529ebc7",
+ "url": "https://api.github.com/repos/Roave/BetterReflection/zipball/d0c9955a6cce8dfefe379b6ea53a26488dc1feb6",
+ "reference": "d0c9955a6cce8dfefe379b6ea53a26488dc1feb6",
"shasum": ""
},
"require": {
"ext-json": "*",
"jetbrains/phpstorm-stubs": "2024.3",
- "nikic/php-parser": "^5.6.0",
+ "nikic/php-parser": "^5.6.1",
"php": "~8.2.0 || ~8.3.2 || ~8.4.1 || ~8.5.0"
},
"conflict": {
@@ -1540,7 +1540,7 @@
},
"require-dev": {
"phpbench/phpbench": "^1.4.1",
- "phpunit/phpunit": "^11.5.28"
+ "phpunit/phpunit": "^11.5.35"
},
"suggest": {
"composer/composer": "Required to use the ComposerSourceLocator"
@@ -1580,9 +1580,9 @@
"description": "Better Reflection - an improved code reflection API",
"support": {
"issues": "https://github.com/Roave/BetterReflection/issues",
- "source": "https://github.com/Roave/BetterReflection/tree/6.60.0"
+ "source": "https://github.com/Roave/BetterReflection/tree/6.61.0"
},
- "time": "2025-08-21T11:08:59+00:00"
+ "time": "2025-09-02T20:05:51+00:00"
},
{
"name": "seld/jsonlint",