diff --git a/.editorconfig b/.editorconfig
index eb17208..ce36d20 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,12 +5,21 @@ charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
-
-[*.{md,json}]
-indent_style = space
indent_size = 4
+indent_style = space
+
+[*.md]
+indent_size = 2
+tab_width = 2
+trim_trailing_whitespace = false
+
+[*.json]
+indent_size = 2
+tab_width = 2
+
+[*.{yml,yaml}]
+indent_size = 2
+tab_width = 2
[*.php]
-indent_style = space
-indent_size = 4
max_line_length = 120
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 8982a87..fe5a2be 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,64 +2,142 @@ name: Continuous Integration
on:
push:
- branches: [main]
+ branches:
+ - main
+ paths-ignore:
+ - "**.md"
+ - "renovate.json"
+ - ".github/ISSUE_TEMPLATE/**"
+ - ".github/workflows/release.yml"
+
pull_request:
+ paths-ignore:
+ - "**.md"
+ - "renovate.json"
+ - ".github/ISSUE_TEMPLATE/**"
+ - ".github/workflows/release.yml"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
- static-analysis:
+ coding-standards:
+ name: Coding Standards
runs-on: ubuntu-latest
+
steps:
- - uses: actions/checkout@v6
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
show-progress: false
- - uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
with:
- php-version: '8.4'
+ php-version: 'latest'
tools: composer
- extensions: xdebug
- - uses: actions/cache@v4
+ coverage: none
+
+ - name: Composer Install
+ uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1
+
+ - name: Check Syntax
+ run: composer dev:lint:syntax
+
+ - name: Check Code Style
+ run: composer dev:lint:style
+
+ static-analysis:
+ name: Static Analysis
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
- path: |
- vendor
- ~/.composer/cache
- key: composer-${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
- restore-keys: composer-${{ runner.os }}-
- - run: composer install --quiet --no-ansi --no-interaction --no-progress --prefer-dist
- - run: composer normalize --dry-run
- - run: composer validate
- - run: composer phpstan -- --ansi
- - run: composer psalm
+ fetch-depth: 0
+ show-progress: false
- unit-tests:
- needs: [static-analysis]
+ - name: Setup PHP
+ uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
+ with:
+ php-version: 'latest'
+ tools: composer
+ coverage: none
+
+ - name: Composer Install
+ uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1
+
+ - name: Run Static Analysis
+ run: composer dev:analyze:phpstan
+
+ code-coverage:
+ name: Code Coverage
+ needs: [coding-standards, static-analysis]
runs-on: ubuntu-latest
+
steps:
- - uses: actions/checkout@v6
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
show-progress: false
- - uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
with:
- php-version: '8.4'
+ php-version: 'latest'
tools: composer
+ extensions: gmp
coverage: xdebug
- - uses: actions/cache@v4
- with:
- path: |
- vendor
- ~/.composer/cache
- key: composer-${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
- restore-keys: composer-${{ runner.os }}-
- - run: composer install --quiet --no-ansi --no-interaction --no-progress --prefer-dist
- - run: composer normalize --dry-run
- - run: composer validate
- - run: vendor/bin/phpunit || true
- - uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9
+
+ - name: Composer Install
+ uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1
+
+ - name: Run Tests with Coverage
+ run: composer dev:test:coverage:ci
+
+ - name: Upload to SonarCloud
+ uses: SonarSource/sonarqube-scan-action@a31c9398be7ace6bbfaf30c0bd5d415f843d45e9 # 7.0.0
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+
+ unit-tests:
+ name: Unit Tests
+ needs: [coding-standards, static-analysis]
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php-version: ['8.2', '8.3', '8.4', '8.5']
+ os: [ubuntu-latest, windows-latest]
+
+ steps:
+ - name: Configure Git for Windows
+ if: ${{ matrix.os == 'windows-latest' }}
+ run: |
+ git config --system core.autocrlf false
+ git config --system core.eol lf
+
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+ with:
+ fetch-depth: 0
+ show-progress: false
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
+ with:
+ php-version: ${{ matrix.php-version }}
+ tools: composer
+ extensions: gmp
+ coverage: none
+
+ - name: Composer Install
+ uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1
+
+ - name: Run Unit Tests
+ run: composer dev:test:unit
diff --git a/.gitignore b/.gitignore
index 08e8db6..0b2b1ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,131 @@
-# PhpStorm
-/.idea/
+##### Operating Systems
-# Composer
-/vendor
+# macOS
+.DS_Store
+.AppleDouble
+.LSOverride
+._*
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+# Linux
+*~
+.fuse_hidden*
+.directory
+.Trash-*
+.nfs*
+
+# Windows
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+*.stackdump
+[Dd]esktop.ini
+$RECYCLE.BIN/
+*.lnk
+
+##### IDEs and Editors
+
+# JetBrains (PhpStorm, IntelliJ, etc.)
+.idea/
+*.iws
+out/
+atlassian-ide-plugin.xml
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Visual Studio Code
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+.history/
+
+# Vim
+[._]*.s[a-v][a-z]
+!*.svg
+[._]*.sw[a-p]
+[._]s[a-rt-v][a-z]
+[._]ss[a-gi-z]
+[._]sw[a-p]
+Session.vim
+Sessionx.vim
+.netrwhist
+tags
+[._]*.un~
+
+# Emacs
+*~
+\#*\#
+/.emacs.desktop
+/.emacs.desktop.lock
+*.elc
+auto-save-list
+tramp
+.\#*
+.org-id-locations
+*_archive
+
+# Sublime Text
+*.tmlanguage.cache
+*.tmPreferences.cache
+*.stTheme.cache
+*.sublime-workspace
+sftp-config.json
+sftp-config-alt*.json
+
+##### Backup Files
+*.bak
+*.gho
+*.ori
+*.orig
+*.tmp
+
+##### Composer
+composer.phar
+/vendor/
+composer.lock
+
+##### PHP Testing & Analysis
# PHPUnit
-/.phpunit.cache
+.phpunit.cache/
.phpunit.result.cache
+phpunit.xml
+
+# Coverage Reports
+coverage/
+build/
+*.coverage
+clover.xml
+coverage.xml
+coverage.clover
+phpunit-coverage.xml
+
+# PHPStan
+.phpstan.cache/
+.phpstan/
+phpstan.neon.dist
+
+# PHP-CS-Fixer / CodeSniffer
+.php-cs-fixer.cache
+.php_cs.cache
+/wpcs/*
+
+# Psalm
+.psalm/
+psalm.xml
diff --git a/captainhook.json b/captainhook.json
index f81134d..c7b30a5 100644
--- a/captainhook.json
+++ b/captainhook.json
@@ -9,7 +9,11 @@
},
"pre-push": {
"enabled": false,
- "actions": []
+ "actions": [
+ {
+ "action": "composer test"
+ }
+ ]
},
"pre-commit": {
"enabled": true,
@@ -41,13 +45,30 @@
]
},
{
- "action": "composer phpstan"
- },
- {
- "action": "composer psalm"
+ "action": "composer dev:lint:syntax -- {$STAGED_FILES|of-type:php}",
+ "conditions": [
+ {
+ "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\OfType",
+ "args": [
+ [
+ "php"
+ ]
+ ]
+ }
+ ]
},
{
- "action": "XDEBUG_MODE=coverage vendor/bin/phpunit"
+ "action": "composer dev:lint:style -- {$STAGED_FILES|of-type:php}",
+ "conditions": [
+ {
+ "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\OfType",
+ "args": [
+ [
+ "php"
+ ]
+ ]
+ }
+ ]
}
]
},
@@ -69,8 +90,7 @@
"exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\Any",
"args": [
[
- "composer.json",
- "composer.lock"
+ "composer.json"
]
]
}
@@ -88,8 +108,7 @@
"exec": "\\CaptainHook\\App\\Hook\\Condition\\FileChanged\\Any",
"args": [
[
- "composer.json",
- "composer.lock"
+ "composer.json"
]
]
}
@@ -105,4 +124,4 @@
"enabled": false,
"actions": []
}
-}
\ No newline at end of file
+}
diff --git a/composer.json b/composer.json
index 0272925..1254e0e 100644
--- a/composer.json
+++ b/composer.json
@@ -14,23 +14,26 @@
}
],
"require": {
- "php": "^8.1",
+ "php": "^8.2",
"markrogoyski/math-php": "^2.11",
"symfony/polyfill-php83": "^1.32"
},
"require-dev": {
- "ext-ctype": "*",
- "captainhook/captainhook-phar": "^5.23",
+ "captainhook/captainhook": "^5.27",
"captainhook/hook-installer": "^1.0",
+ "captainhook/plugin-composer": "^5.3",
+ "dealerdirect/phpcodesniffer-composer-installer": "^1.2",
"ergebnis/composer-normalize": "^2.29",
+ "php-parallel-lint/php-parallel-lint": "^1.4",
+ "phpbench/phpbench": "^1.4",
"phpstan/phpstan": "^1.9",
"phpunit/phpunit": "^10.5",
"ramsey/conventional-commits": "^1.5",
- "squizlabs/php_codesniffer": "^4.0",
- "vimeo/psalm": "^6.0"
+ "slevomat/coding-standard": "^8.25",
+ "squizlabs/php_codesniffer": "^4.0"
},
"suggest": {
- "ext-gmp": "Allows for quicker Base16 to Base36 conversion"
+ "ext-gmp": "Enables faster math with arbitrary precision integers using GMP."
},
"minimum-stability": "dev",
"prefer-stable": true,
@@ -44,13 +47,15 @@
},
"autoload-dev": {
"psr-4": {
- "Visus\\Cuid2\\Test\\": "tests/"
+ "Visus\\Cuid2\\Test\\": "tests/",
+ "Visus\\Cuid2\\Test\\Benchmark\\": "tests/benchmark"
}
},
"config": {
"allow-plugins": {
- "captainhook/captainhook-phar": true,
"captainhook/hook-installer": true,
+ "captainhook/plugin-composer": true,
+ "dealerdirect/phpcodesniffer-composer-installer": true,
"ergebnis/composer-normalize": true
}
},
@@ -60,9 +65,30 @@
}
},
"scripts": {
- "phpstan": [
- "phpstan analyse -c phpstan.neon --no-progress --memory-limit=1G"
+ "dev:analyze": [
+ "@dev:analyze:phpstan"
],
- "psalm": "psalm --show-info=false --config=psalm.xml"
+ "dev:analyze:phpstan": [
+ "phpstan analyse -c phpstan.neon --ansi --memory-limit=1G"
+ ],
+ "dev:benchmark": "phpbench run tests/benchmark/ --report=default",
+ "dev:build:clean": "git clean -fX build/",
+ "dev:lint": [
+ "@dev:lint:syntax",
+ "@dev:lint:style"
+ ],
+ "dev:lint:fix": "phpcbf --cache=build/cache/phpcs.cache",
+ "dev:lint:style": "phpcs --cache=build/cache/phpcs.cache --colors",
+ "dev:lint:syntax": "parallel-lint --colors src/ tests/",
+ "dev:test": [
+ "@dev:lint",
+ "@dev:benchmark",
+ "@dev:analyze",
+ "@dev:test:unit"
+ ],
+ "dev:test:coverage:ci": "@php -d 'xdebug.mode=coverage' vendor/bin/phpunit --colors=always --coverage-clover build/coverage/xml/clover.xml --log-junit build/coverage/xml/execution.xml",
+ "dev:test:coverage:html": "@php -d 'xdebug.mode=coverage' vendor/bin/phpunit --colors=always --coverage-html build/coverage/html",
+ "dev:test:unit": "phpunit --colors=always --no-coverage",
+ "test": "@dev:test"
}
}
diff --git a/composer.lock b/composer.lock
deleted file mode 100644
index 14e06b3..0000000
--- a/composer.lock
+++ /dev/null
@@ -1,7539 +0,0 @@
-{
- "_readme": [
- "This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
- "This file is @generated automatically"
- ],
- "content-hash": "09dd9083c36ff0b88cdefdf1c704f7a0",
- "packages": [
- {
- "name": "markrogoyski/math-php",
- "version": "v2.13.0",
- "source": {
- "type": "git",
- "url": "https://github.com/markrogoyski/math-php.git",
- "reference": "c064e80bfc4039b812f6b29bacebb07dfb5a049f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/markrogoyski/math-php/zipball/c064e80bfc4039b812f6b29bacebb07dfb5a049f",
- "reference": "c064e80bfc4039b812f6b29bacebb07dfb5a049f",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "php": ">=7.2.0"
- },
- "require-dev": {
- "php-coveralls/php-coveralls": "^2.0",
- "php-parallel-lint/php-parallel-lint": "^1.2",
- "phploc/phploc": "*",
- "phpmd/phpmd": "^2.6",
- "phpstan/phpstan": "^1.10",
- "phpunit/phpunit": "^8.5",
- "squizlabs/php_codesniffer": "3.*"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "MathPHP\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mark Rogoyski",
- "email": "mark@rogoyski.com",
- "homepage": "https://github.com/markrogoyski",
- "role": "Lead developer"
- },
- {
- "name": "Kevin Nowaczyk",
- "homepage": "https://github.com/Beakerboy",
- "role": "Developer"
- },
- {
- "name": "MathPHP Community of Contributors",
- "homepage": "https://github.com/markrogoyski/math-php/graphs/contributors"
- }
- ],
- "description": "Math Library for PHP. Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra",
- "homepage": "https://github.com/markrogoyski/math-php/",
- "keywords": [
- "algebra",
- "combinatorics",
- "distributions",
- "linear algebra",
- "math",
- "mathematics",
- "matrix",
- "numerical analysis",
- "probability",
- "regressions",
- "statistics"
- ],
- "support": {
- "issues": "https://github.com/markrogoyski/math-php/issues",
- "source": "https://github.com/markrogoyski/math-php/tree/v2.13.0"
- },
- "time": "2025-10-24T05:40:38+00:00"
- },
- {
- "name": "symfony/polyfill-php83",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php83.git",
- "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5",
- "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php83\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-07-08T02:45:35+00:00"
- }
- ],
- "packages-dev": [
- {
- "name": "amphp/amp",
- "version": "v3.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/amp.git",
- "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/amp/zipball/fa0ab33a6f47a82929c38d03ca47ebb71086a93f",
- "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1",
- "revolt/event-loop": "^1 || ^0.2"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "phpunit/phpunit": "^9",
- "psalm/phar": "5.23.1"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php",
- "src/Future/functions.php",
- "src/Internal/functions.php"
- ],
- "psr-4": {
- "Amp\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Bob Weinand",
- "email": "bobwei9@hotmail.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- },
- {
- "name": "Daniel Lowrey",
- "email": "rdlowrey@php.net"
- }
- ],
- "description": "A non-blocking concurrency framework for PHP applications.",
- "homepage": "https://amphp.org/amp",
- "keywords": [
- "async",
- "asynchronous",
- "awaitable",
- "concurrency",
- "event",
- "event-loop",
- "future",
- "non-blocking",
- "promise"
- ],
- "support": {
- "issues": "https://github.com/amphp/amp/issues",
- "source": "https://github.com/amphp/amp/tree/v3.1.1"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2025-08-27T21:42:00+00:00"
- },
- {
- "name": "amphp/byte-stream",
- "version": "v2.1.2",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/byte-stream.git",
- "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/byte-stream/zipball/55a6bd071aec26fa2a3e002618c20c35e3df1b46",
- "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/parser": "^1.1",
- "amphp/pipeline": "^1",
- "amphp/serialization": "^1",
- "amphp/sync": "^2",
- "php": ">=8.1",
- "revolt/event-loop": "^1 || ^0.2.3"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "5.22.1"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php",
- "src/Internal/functions.php"
- ],
- "psr-4": {
- "Amp\\ByteStream\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "A stream abstraction to make working with non-blocking I/O simple.",
- "homepage": "https://amphp.org/byte-stream",
- "keywords": [
- "amp",
- "amphp",
- "async",
- "io",
- "non-blocking",
- "stream"
- ],
- "support": {
- "issues": "https://github.com/amphp/byte-stream/issues",
- "source": "https://github.com/amphp/byte-stream/tree/v2.1.2"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2025-03-16T17:10:27+00:00"
- },
- {
- "name": "amphp/cache",
- "version": "v2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/cache.git",
- "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/cache/zipball/46912e387e6aa94933b61ea1ead9cf7540b7797c",
- "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/serialization": "^1",
- "amphp/sync": "^2",
- "php": ">=8.1",
- "revolt/event-loop": "^1 || ^0.2"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "^5.4"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Amp\\Cache\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- },
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Daniel Lowrey",
- "email": "rdlowrey@php.net"
- }
- ],
- "description": "A fiber-aware cache API based on Amp and Revolt.",
- "homepage": "https://amphp.org/cache",
- "support": {
- "issues": "https://github.com/amphp/cache/issues",
- "source": "https://github.com/amphp/cache/tree/v2.0.1"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2024-04-19T03:38:06+00:00"
- },
- {
- "name": "amphp/dns",
- "version": "v2.4.0",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/dns.git",
- "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/dns/zipball/78eb3db5fc69bf2fc0cb503c4fcba667bc223c71",
- "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/byte-stream": "^2",
- "amphp/cache": "^2",
- "amphp/parser": "^1",
- "amphp/process": "^2",
- "daverandom/libdns": "^2.0.2",
- "ext-filter": "*",
- "ext-json": "*",
- "php": ">=8.1",
- "revolt/event-loop": "^1 || ^0.2"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "5.20"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php"
- ],
- "psr-4": {
- "Amp\\Dns\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Chris Wright",
- "email": "addr@daverandom.com"
- },
- {
- "name": "Daniel Lowrey",
- "email": "rdlowrey@php.net"
- },
- {
- "name": "Bob Weinand",
- "email": "bobwei9@hotmail.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- },
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- }
- ],
- "description": "Async DNS resolution for Amp.",
- "homepage": "https://github.com/amphp/dns",
- "keywords": [
- "amp",
- "amphp",
- "async",
- "client",
- "dns",
- "resolve"
- ],
- "support": {
- "issues": "https://github.com/amphp/dns/issues",
- "source": "https://github.com/amphp/dns/tree/v2.4.0"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2025-01-19T15:43:40+00:00"
- },
- {
- "name": "amphp/parallel",
- "version": "v2.3.2",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/parallel.git",
- "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/parallel/zipball/321b45ae771d9c33a068186b24117e3cd1c48dce",
- "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/byte-stream": "^2",
- "amphp/cache": "^2",
- "amphp/parser": "^1",
- "amphp/pipeline": "^1",
- "amphp/process": "^2",
- "amphp/serialization": "^1",
- "amphp/socket": "^2",
- "amphp/sync": "^2",
- "php": ">=8.1",
- "revolt/event-loop": "^1"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "^5.18"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/Context/functions.php",
- "src/Context/Internal/functions.php",
- "src/Ipc/functions.php",
- "src/Worker/functions.php"
- ],
- "psr-4": {
- "Amp\\Parallel\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- },
- {
- "name": "Stephen Coakley",
- "email": "me@stephencoakley.com"
- }
- ],
- "description": "Parallel processing component for Amp.",
- "homepage": "https://github.com/amphp/parallel",
- "keywords": [
- "async",
- "asynchronous",
- "concurrent",
- "multi-processing",
- "multi-threading"
- ],
- "support": {
- "issues": "https://github.com/amphp/parallel/issues",
- "source": "https://github.com/amphp/parallel/tree/v2.3.2"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2025-08-27T21:55:40+00:00"
- },
- {
- "name": "amphp/parser",
- "version": "v1.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/parser.git",
- "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/parser/zipball/3cf1f8b32a0171d4b1bed93d25617637a77cded7",
- "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7",
- "shasum": ""
- },
- "require": {
- "php": ">=7.4"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "phpunit/phpunit": "^9",
- "psalm/phar": "^5.4"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Amp\\Parser\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "A generator parser to make streaming parsers simple.",
- "homepage": "https://github.com/amphp/parser",
- "keywords": [
- "async",
- "non-blocking",
- "parser",
- "stream"
- ],
- "support": {
- "issues": "https://github.com/amphp/parser/issues",
- "source": "https://github.com/amphp/parser/tree/v1.1.1"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2024-03-21T19:16:53+00:00"
- },
- {
- "name": "amphp/pipeline",
- "version": "v1.2.3",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/pipeline.git",
- "reference": "7b52598c2e9105ebcddf247fc523161581930367"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/pipeline/zipball/7b52598c2e9105ebcddf247fc523161581930367",
- "reference": "7b52598c2e9105ebcddf247fc523161581930367",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "php": ">=8.1",
- "revolt/event-loop": "^1"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "^5.18"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Amp\\Pipeline\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "Asynchronous iterators and operators.",
- "homepage": "https://amphp.org/pipeline",
- "keywords": [
- "amp",
- "amphp",
- "async",
- "io",
- "iterator",
- "non-blocking"
- ],
- "support": {
- "issues": "https://github.com/amphp/pipeline/issues",
- "source": "https://github.com/amphp/pipeline/tree/v1.2.3"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2025-03-16T16:33:53+00:00"
- },
- {
- "name": "amphp/process",
- "version": "v2.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/process.git",
- "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/process/zipball/52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d",
- "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/byte-stream": "^2",
- "amphp/sync": "^2",
- "php": ">=8.1",
- "revolt/event-loop": "^1 || ^0.2"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "^5.4"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php"
- ],
- "psr-4": {
- "Amp\\Process\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bob Weinand",
- "email": "bobwei9@hotmail.com"
- },
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "A fiber-aware process manager based on Amp and Revolt.",
- "homepage": "https://amphp.org/process",
- "support": {
- "issues": "https://github.com/amphp/process/issues",
- "source": "https://github.com/amphp/process/tree/v2.0.3"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2024-04-19T03:13:44+00:00"
- },
- {
- "name": "amphp/serialization",
- "version": "v1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/serialization.git",
- "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/serialization/zipball/693e77b2fb0b266c3c7d622317f881de44ae94a1",
- "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "dev-master",
- "phpunit/phpunit": "^9 || ^8 || ^7"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php"
- ],
- "psr-4": {
- "Amp\\Serialization\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "Serialization tools for IPC and data storage in PHP.",
- "homepage": "https://github.com/amphp/serialization",
- "keywords": [
- "async",
- "asynchronous",
- "serialization",
- "serialize"
- ],
- "support": {
- "issues": "https://github.com/amphp/serialization/issues",
- "source": "https://github.com/amphp/serialization/tree/master"
- },
- "time": "2020-03-25T21:39:07+00:00"
- },
- {
- "name": "amphp/socket",
- "version": "v2.3.1",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/socket.git",
- "reference": "58e0422221825b79681b72c50c47a930be7bf1e1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/socket/zipball/58e0422221825b79681b72c50c47a930be7bf1e1",
- "reference": "58e0422221825b79681b72c50c47a930be7bf1e1",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/byte-stream": "^2",
- "amphp/dns": "^2",
- "ext-openssl": "*",
- "kelunik/certificate": "^1.1",
- "league/uri": "^6.5 | ^7",
- "league/uri-interfaces": "^2.3 | ^7",
- "php": ">=8.1",
- "revolt/event-loop": "^1 || ^0.2"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "amphp/process": "^2",
- "phpunit/phpunit": "^9",
- "psalm/phar": "5.20"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php",
- "src/Internal/functions.php",
- "src/SocketAddress/functions.php"
- ],
- "psr-4": {
- "Amp\\Socket\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Daniel Lowrey",
- "email": "rdlowrey@gmail.com"
- },
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.",
- "homepage": "https://github.com/amphp/socket",
- "keywords": [
- "amp",
- "async",
- "encryption",
- "non-blocking",
- "sockets",
- "tcp",
- "tls"
- ],
- "support": {
- "issues": "https://github.com/amphp/socket/issues",
- "source": "https://github.com/amphp/socket/tree/v2.3.1"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2024-04-21T14:33:03+00:00"
- },
- {
- "name": "amphp/sync",
- "version": "v2.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/amphp/sync.git",
- "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/amphp/sync/zipball/217097b785130d77cfcc58ff583cf26cd1770bf1",
- "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/pipeline": "^1",
- "amphp/serialization": "^1",
- "php": ">=8.1",
- "revolt/event-loop": "^1 || ^0.2"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "amphp/phpunit-util": "^3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "5.23"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php"
- ],
- "psr-4": {
- "Amp\\Sync\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- },
- {
- "name": "Stephen Coakley",
- "email": "me@stephencoakley.com"
- }
- ],
- "description": "Non-blocking synchronization primitives for PHP based on Amp and Revolt.",
- "homepage": "https://github.com/amphp/sync",
- "keywords": [
- "async",
- "asynchronous",
- "mutex",
- "semaphore",
- "synchronization"
- ],
- "support": {
- "issues": "https://github.com/amphp/sync/issues",
- "source": "https://github.com/amphp/sync/tree/v2.3.0"
- },
- "funding": [
- {
- "url": "https://github.com/amphp",
- "type": "github"
- }
- ],
- "time": "2024-08-03T19:31:26+00:00"
- },
- {
- "name": "captainhook/captainhook-phar",
- "version": "5.27.3",
- "source": {
- "type": "git",
- "url": "https://github.com/captainhook-git/captainhook-phar.git",
- "reference": "a5dbcd8d20b3dcdb1cbd6948d0d3a058453b3d6a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/captainhook-git/captainhook-phar/zipball/a5dbcd8d20b3dcdb1cbd6948d0d3a058453b3d6a",
- "reference": "a5dbcd8d20b3dcdb1cbd6948d0d3a058453b3d6a",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.1||^2.0",
- "ext-json": "*",
- "ext-spl": "*",
- "phar-io/composer-distributor": "^1.0.1",
- "php": ">=8.0"
- },
- "require-dev": {
- "composer/composer": "^1.1 || ^2.0"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "CaptainHook\\Composer\\Plugin"
- },
- "autoload": {
- "psr-4": {
- "CaptainHook\\Composer\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Sebastian Feldmann",
- "email": "sf@sebastian-feldmann.info"
- }
- ],
- "description": "PHP git hook manager",
- "homepage": "https://github.com/captainhook-git/captainhook",
- "keywords": [
- "commit-msg",
- "git",
- "hooks",
- "post-merge",
- "pre-commit",
- "pre-push",
- "prepare-commit-msg"
- ],
- "support": {
- "issues": "https://github.com/captainhook-git/captainhook/issues",
- "source": "https://github.com/captainhook-git/captainhook-phar/tree/5.27.3"
- },
- "funding": [
- {
- "url": "https://github.com/sponsors/sebastianfeldmann",
- "type": "github"
- }
- ],
- "time": "2025-04-08T07:07:48+00:00"
- },
- {
- "name": "captainhook/hook-installer",
- "version": "1.0.4",
- "source": {
- "type": "git",
- "url": "https://github.com/captainhook-git/hook-installer.git",
- "reference": "fb3c45f6204b08baba999f4ffc4ae707bf684e8b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/captainhook-git/hook-installer/zipball/fb3c45f6204b08baba999f4ffc4ae707bf684e8b",
- "reference": "fb3c45f6204b08baba999f4ffc4ae707bf684e8b",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.1|^2.0",
- "php": ">=8.0"
- },
- "require-dev": {
- "composer/composer": "*"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "CaptainHook\\HookInstaller\\ComposerPlugin"
- },
- "autoload": {
- "psr-4": {
- "CaptainHook\\HookInstaller\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Sebastian Feldmann",
- "email": "sf@sebastian-feldmann.info"
- }
- ],
- "description": "Composer Plugin that makes everyone activate the CaptainHook git hooks locally",
- "support": {
- "issues": "https://github.com/captainhook-git/hook-installer/issues",
- "source": "https://github.com/captainhook-git/hook-installer/tree/1.0.4"
- },
- "time": "2025-04-08T07:12:26+00:00"
- },
- {
- "name": "composer/ca-bundle",
- "version": "1.5.8",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/ca-bundle.git",
- "reference": "719026bb30813accb68271fee7e39552a58e9f65"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/719026bb30813accb68271fee7e39552a58e9f65",
- "reference": "719026bb30813accb68271fee7e39552a58e9f65",
- "shasum": ""
- },
- "require": {
- "ext-openssl": "*",
- "ext-pcre": "*",
- "php": "^7.2 || ^8.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.10",
- "phpunit/phpunit": "^8 || ^9",
- "psr/log": "^1.0 || ^2.0 || ^3.0",
- "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\CaBundle\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
- "keywords": [
- "cabundle",
- "cacert",
- "certificate",
- "ssl",
- "tls"
- ],
- "support": {
- "irc": "irc://irc.freenode.org/composer",
- "issues": "https://github.com/composer/ca-bundle/issues",
- "source": "https://github.com/composer/ca-bundle/tree/1.5.8"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- }
- ],
- "time": "2025-08-20T18:49:47+00:00"
- },
- {
- "name": "composer/class-map-generator",
- "version": "1.6.2",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/class-map-generator.git",
- "reference": "ba9f089655d4cdd64e762a6044f411ccdaec0076"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/class-map-generator/zipball/ba9f089655d4cdd64e762a6044f411ccdaec0076",
- "reference": "ba9f089655d4cdd64e762a6044f411ccdaec0076",
- "shasum": ""
- },
- "require": {
- "composer/pcre": "^2.1 || ^3.1",
- "php": "^7.2 || ^8.0",
- "symfony/finder": "^4.4 || ^5.3 || ^6 || ^7"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.12 || ^2",
- "phpstan/phpstan-deprecation-rules": "^1 || ^2",
- "phpstan/phpstan-phpunit": "^1 || ^2",
- "phpstan/phpstan-strict-rules": "^1.1 || ^2",
- "phpunit/phpunit": "^8",
- "symfony/filesystem": "^5.4 || ^6"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\ClassMapGenerator\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "https://seld.be"
- }
- ],
- "description": "Utilities to scan PHP code and generate class maps.",
- "keywords": [
- "classmap"
- ],
- "support": {
- "issues": "https://github.com/composer/class-map-generator/issues",
- "source": "https://github.com/composer/class-map-generator/tree/1.6.2"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- }
- ],
- "time": "2025-08-20T18:52:43+00:00"
- },
- {
- "name": "composer/composer",
- "version": "2.8.12",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/composer.git",
- "reference": "3e38919bc9a2c3c026f2151b5e56d04084ce8f0b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/composer/zipball/3e38919bc9a2c3c026f2151b5e56d04084ce8f0b",
- "reference": "3e38919bc9a2c3c026f2151b5e56d04084ce8f0b",
- "shasum": ""
- },
- "require": {
- "composer/ca-bundle": "^1.5",
- "composer/class-map-generator": "^1.4.0",
- "composer/metadata-minifier": "^1.0",
- "composer/pcre": "^2.2 || ^3.2",
- "composer/semver": "^3.3",
- "composer/spdx-licenses": "^1.5.7",
- "composer/xdebug-handler": "^2.0.2 || ^3.0.3",
- "justinrainbow/json-schema": "^6.5.1",
- "php": "^7.2.5 || ^8.0",
- "psr/log": "^1.0 || ^2.0 || ^3.0",
- "react/promise": "^3.3",
- "seld/jsonlint": "^1.4",
- "seld/phar-utils": "^1.2",
- "seld/signal-handler": "^2.0",
- "symfony/console": "^5.4.47 || ^6.4.25 || ^7.1.10",
- "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.1.10",
- "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.1.10",
- "symfony/polyfill-php73": "^1.24",
- "symfony/polyfill-php80": "^1.24",
- "symfony/polyfill-php81": "^1.24",
- "symfony/process": "^5.4.47 || ^6.4.25 || ^7.1.10"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.11.8",
- "phpstan/phpstan-deprecation-rules": "^1.2.0",
- "phpstan/phpstan-phpunit": "^1.4.0",
- "phpstan/phpstan-strict-rules": "^1.6.0",
- "phpstan/phpstan-symfony": "^1.4.0",
- "symfony/phpunit-bridge": "^6.4.25 || ^7.3.3"
- },
- "suggest": {
- "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
- "ext-zip": "Enabling the zip extension allows you to unzip archives",
- "ext-zlib": "Allow gzip compression of HTTP requests"
- },
- "bin": [
- "bin/composer"
- ],
- "type": "library",
- "extra": {
- "phpstan": {
- "includes": [
- "phpstan/rules.neon"
- ]
- },
- "branch-alias": {
- "dev-main": "2.8-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\": "src/Composer/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "https://www.naderman.de"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "https://seld.be"
- }
- ],
- "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
- "homepage": "https://getcomposer.org/",
- "keywords": [
- "autoload",
- "dependency",
- "package"
- ],
- "support": {
- "irc": "ircs://irc.libera.chat:6697/composer",
- "issues": "https://github.com/composer/composer/issues",
- "security": "https://github.com/composer/composer/security/policy",
- "source": "https://github.com/composer/composer/tree/2.8.12"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- }
- ],
- "time": "2025-09-19T11:41:59+00:00"
- },
- {
- "name": "composer/metadata-minifier",
- "version": "1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/metadata-minifier.git",
- "reference": "c549d23829536f0d0e984aaabbf02af91f443207"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/metadata-minifier/zipball/c549d23829536f0d0e984aaabbf02af91f443207",
- "reference": "c549d23829536f0d0e984aaabbf02af91f443207",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "composer/composer": "^2",
- "phpstan/phpstan": "^0.12.55",
- "symfony/phpunit-bridge": "^4.2 || ^5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\MetadataMinifier\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "Small utility library that handles metadata minification and expansion.",
- "keywords": [
- "composer",
- "compression"
- ],
- "support": {
- "issues": "https://github.com/composer/metadata-minifier/issues",
- "source": "https://github.com/composer/metadata-minifier/tree/1.0.0"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2021-04-07T13:37:33+00:00"
- },
- {
- "name": "composer/pcre",
- "version": "3.3.2",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/pcre.git",
- "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
- "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e",
- "shasum": ""
- },
- "require": {
- "php": "^7.4 || ^8.0"
- },
- "conflict": {
- "phpstan/phpstan": "<1.11.10"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.12 || ^2",
- "phpstan/phpstan-strict-rules": "^1 || ^2",
- "phpunit/phpunit": "^8 || ^9"
- },
- "type": "library",
- "extra": {
- "phpstan": {
- "includes": [
- "extension.neon"
- ]
- },
- "branch-alias": {
- "dev-main": "3.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\Pcre\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
- "keywords": [
- "PCRE",
- "preg",
- "regex",
- "regular expression"
- ],
- "support": {
- "issues": "https://github.com/composer/pcre/issues",
- "source": "https://github.com/composer/pcre/tree/3.3.2"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2024-11-12T16:29:46+00:00"
- },
- {
- "name": "composer/semver",
- "version": "3.4.4",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/semver.git",
- "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
- "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.11",
- "symfony/phpunit-bridge": "^3 || ^7"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\Semver\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "http://www.naderman.de"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- },
- {
- "name": "Rob Bast",
- "email": "rob.bast@gmail.com",
- "homepage": "http://robbast.nl"
- }
- ],
- "description": "Semver library that offers utilities, version constraint parsing and validation.",
- "keywords": [
- "semantic",
- "semver",
- "validation",
- "versioning"
- ],
- "support": {
- "irc": "ircs://irc.libera.chat:6697/composer",
- "issues": "https://github.com/composer/semver/issues",
- "source": "https://github.com/composer/semver/tree/3.4.4"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- }
- ],
- "time": "2025-08-20T19:15:30+00:00"
- },
- {
- "name": "composer/spdx-licenses",
- "version": "1.5.9",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/spdx-licenses.git",
- "reference": "edf364cefe8c43501e21e88110aac10b284c3c9f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/edf364cefe8c43501e21e88110aac10b284c3c9f",
- "reference": "edf364cefe8c43501e21e88110aac10b284c3c9f",
- "shasum": ""
- },
- "require": {
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.11",
- "symfony/phpunit-bridge": "^3 || ^7"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\Spdx\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nils Adermann",
- "email": "naderman@naderman.de",
- "homepage": "http://www.naderman.de"
- },
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- },
- {
- "name": "Rob Bast",
- "email": "rob.bast@gmail.com",
- "homepage": "http://robbast.nl"
- }
- ],
- "description": "SPDX licenses list and validation library.",
- "keywords": [
- "license",
- "spdx",
- "validator"
- ],
- "support": {
- "irc": "ircs://irc.libera.chat:6697/composer",
- "issues": "https://github.com/composer/spdx-licenses/issues",
- "source": "https://github.com/composer/spdx-licenses/tree/1.5.9"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2025-05-12T21:07:07+00:00"
- },
- {
- "name": "composer/xdebug-handler",
- "version": "3.0.5",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/xdebug-handler.git",
- "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
- "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
- "shasum": ""
- },
- "require": {
- "composer/pcre": "^1 || ^2 || ^3",
- "php": "^7.2.5 || ^8.0",
- "psr/log": "^1 || ^2 || ^3"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.0",
- "phpstan/phpstan-strict-rules": "^1.1",
- "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Composer\\XdebugHandler\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "John Stevenson",
- "email": "john-stevenson@blueyonder.co.uk"
- }
- ],
- "description": "Restarts a process without Xdebug.",
- "keywords": [
- "Xdebug",
- "performance"
- ],
- "support": {
- "irc": "ircs://irc.libera.chat:6697/composer",
- "issues": "https://github.com/composer/xdebug-handler/issues",
- "source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
- },
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://github.com/composer",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
- "time": "2024-05-06T16:37:16+00:00"
- },
- {
- "name": "danog/advanced-json-rpc",
- "version": "v3.2.2",
- "source": {
- "type": "git",
- "url": "https://github.com/danog/php-advanced-json-rpc.git",
- "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/danog/php-advanced-json-rpc/zipball/aadb1c4068a88c3d0530cfe324b067920661efcb",
- "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb",
- "shasum": ""
- },
- "require": {
- "netresearch/jsonmapper": "^5",
- "php": ">=8.1",
- "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0"
- },
- "replace": {
- "felixfbecker/php-advanced-json-rpc": "^3"
- },
- "require-dev": {
- "phpunit/phpunit": "^9"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "AdvancedJsonRpc\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "ISC"
- ],
- "authors": [
- {
- "name": "Felix Becker",
- "email": "felix.b@outlook.com"
- },
- {
- "name": "Daniil Gentili",
- "email": "daniil@daniil.it"
- }
- ],
- "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"
- },
- "time": "2025-02-14T10:55:15+00:00"
- },
- {
- "name": "daverandom/libdns",
- "version": "v2.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/DaveRandom/LibDNS.git",
- "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a",
- "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a",
- "shasum": ""
- },
- "require": {
- "ext-ctype": "*",
- "php": ">=7.1"
- },
- "suggest": {
- "ext-intl": "Required for IDN support"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php"
- ],
- "psr-4": {
- "LibDNS\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "DNS protocol implementation written in pure PHP",
- "keywords": [
- "dns"
- ],
- "support": {
- "issues": "https://github.com/DaveRandom/LibDNS/issues",
- "source": "https://github.com/DaveRandom/LibDNS/tree/v2.1.0"
- },
- "time": "2024-04-12T12:12:48+00:00"
- },
- {
- "name": "dnoegel/php-xdg-base-dir",
- "version": "v0.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
- "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
- "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "require-dev": {
- "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "XdgBaseDir\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "implementation of xdg base directory specification for php",
- "support": {
- "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues",
- "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1"
- },
- "time": "2019-12-04T15:06:13+00:00"
- },
- {
- "name": "doctrine/deprecations",
- "version": "1.1.5",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/deprecations.git",
- "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
- "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
- "shasum": ""
- },
- "require": {
- "php": "^7.1 || ^8.0"
- },
- "conflict": {
- "phpunit/phpunit": "<=7.5 || >=13"
- },
- "require-dev": {
- "doctrine/coding-standard": "^9 || ^12 || ^13",
- "phpstan/phpstan": "1.4.10 || 2.1.11",
- "phpstan/phpstan-phpunit": "^1.0 || ^2",
- "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12",
- "psr/log": "^1 || ^2 || ^3"
- },
- "suggest": {
- "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Doctrine\\Deprecations\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
- "homepage": "https://www.doctrine-project.org/",
- "support": {
- "issues": "https://github.com/doctrine/deprecations/issues",
- "source": "https://github.com/doctrine/deprecations/tree/1.1.5"
- },
- "time": "2025-04-07T20:06:18+00:00"
- },
- {
- "name": "ergebnis/composer-normalize",
- "version": "2.48.2",
- "source": {
- "type": "git",
- "url": "https://github.com/ergebnis/composer-normalize.git",
- "reference": "86dc9731b8320f49e9be9ad6d8e4de9b8b0e9b8b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/86dc9731b8320f49e9be9ad6d8e4de9b8b0e9b8b",
- "reference": "86dc9731b8320f49e9be9ad6d8e4de9b8b0e9b8b",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^2.0.0",
- "ergebnis/json": "^1.4.0",
- "ergebnis/json-normalizer": "^4.9.0",
- "ergebnis/json-printer": "^3.7.0",
- "ext-json": "*",
- "justinrainbow/json-schema": "^5.2.12 || ^6.0.0",
- "localheinz/diff": "^1.3.0",
- "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
- },
- "require-dev": {
- "composer/composer": "^2.8.3",
- "ergebnis/license": "^2.7.0",
- "ergebnis/php-cs-fixer-config": "^6.53.0",
- "ergebnis/phpstan-rules": "^2.11.0",
- "ergebnis/phpunit-slow-test-detector": "^2.20.0",
- "fakerphp/faker": "^1.24.1",
- "infection/infection": "~0.26.6",
- "phpstan/extension-installer": "^1.4.3",
- "phpstan/phpstan": "^2.1.17",
- "phpstan/phpstan-deprecation-rules": "^2.0.3",
- "phpstan/phpstan-phpunit": "^2.0.7",
- "phpstan/phpstan-strict-rules": "^2.0.6",
- "phpunit/phpunit": "^9.6.20",
- "rector/rector": "^2.1.4",
- "symfony/filesystem": "^5.4.41"
- },
- "type": "composer-plugin",
- "extra": {
- "class": "Ergebnis\\Composer\\Normalize\\NormalizePlugin",
- "branch-alias": {
- "dev-main": "2.49-dev"
- },
- "plugin-optional": true,
- "composer-normalize": {
- "indent-size": 2,
- "indent-style": "space"
- }
- },
- "autoload": {
- "psr-4": {
- "Ergebnis\\Composer\\Normalize\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Andreas Möller",
- "email": "am@localheinz.com",
- "homepage": "https://localheinz.com"
- }
- ],
- "description": "Provides a composer plugin for normalizing composer.json.",
- "homepage": "https://github.com/ergebnis/composer-normalize",
- "keywords": [
- "composer",
- "normalize",
- "normalizer",
- "plugin"
- ],
- "support": {
- "issues": "https://github.com/ergebnis/composer-normalize/issues",
- "security": "https://github.com/ergebnis/composer-normalize/blob/main/.github/SECURITY.md",
- "source": "https://github.com/ergebnis/composer-normalize"
- },
- "time": "2025-09-06T11:42:34+00:00"
- },
- {
- "name": "ergebnis/json",
- "version": "1.6.0",
- "source": {
- "type": "git",
- "url": "https://github.com/ergebnis/json.git",
- "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ergebnis/json/zipball/7b56d2b5d9e897e75b43e2e753075a0904c921b1",
- "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
- },
- "require-dev": {
- "ergebnis/composer-normalize": "^2.44.0",
- "ergebnis/data-provider": "^3.3.0",
- "ergebnis/license": "^2.5.0",
- "ergebnis/php-cs-fixer-config": "^6.37.0",
- "ergebnis/phpstan-rules": "^2.11.0",
- "ergebnis/phpunit-slow-test-detector": "^2.16.1",
- "fakerphp/faker": "^1.24.0",
- "infection/infection": "~0.26.6",
- "phpstan/extension-installer": "^1.4.3",
- "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.24",
- "rector/rector": "^2.1.4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.7-dev"
- },
- "composer-normalize": {
- "indent-size": 2,
- "indent-style": "space"
- }
- },
- "autoload": {
- "psr-4": {
- "Ergebnis\\Json\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Andreas Möller",
- "email": "am@localheinz.com",
- "homepage": "https://localheinz.com"
- }
- ],
- "description": "Provides a Json value object for representing a valid JSON string.",
- "homepage": "https://github.com/ergebnis/json",
- "keywords": [
- "json"
- ],
- "support": {
- "issues": "https://github.com/ergebnis/json/issues",
- "security": "https://github.com/ergebnis/json/blob/main/.github/SECURITY.md",
- "source": "https://github.com/ergebnis/json"
- },
- "time": "2025-09-06T09:08:45+00:00"
- },
- {
- "name": "ergebnis/json-normalizer",
- "version": "4.10.1",
- "source": {
- "type": "git",
- "url": "https://github.com/ergebnis/json-normalizer.git",
- "reference": "77961faf2c651c3f05977b53c6c68e8434febf62"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/77961faf2c651c3f05977b53c6c68e8434febf62",
- "reference": "77961faf2c651c3f05977b53c6c68e8434febf62",
- "shasum": ""
- },
- "require": {
- "ergebnis/json": "^1.2.0",
- "ergebnis/json-pointer": "^3.4.0",
- "ergebnis/json-printer": "^3.5.0",
- "ergebnis/json-schema-validator": "^4.2.0",
- "ext-json": "*",
- "justinrainbow/json-schema": "^5.2.12 || ^6.0.0",
- "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
- },
- "require-dev": {
- "composer/semver": "^3.4.3",
- "ergebnis/composer-normalize": "^2.44.0",
- "ergebnis/data-provider": "^3.3.0",
- "ergebnis/license": "^2.5.0",
- "ergebnis/php-cs-fixer-config": "^6.37.0",
- "ergebnis/phpunit-slow-test-detector": "^2.16.1",
- "fakerphp/faker": "^1.24.0",
- "infection/infection": "~0.26.6",
- "phpstan/extension-installer": "^1.4.3",
- "phpstan/phpstan": "^1.12.10",
- "phpstan/phpstan-deprecation-rules": "^1.2.1",
- "phpstan/phpstan-phpunit": "^1.4.0",
- "phpstan/phpstan-strict-rules": "^1.6.1",
- "phpunit/phpunit": "^9.6.19",
- "rector/rector": "^1.2.10"
- },
- "suggest": {
- "composer/semver": "If you want to use ComposerJsonNormalizer or VersionConstraintNormalizer"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "4.11-dev"
- },
- "composer-normalize": {
- "indent-size": 2,
- "indent-style": "space"
- }
- },
- "autoload": {
- "psr-4": {
- "Ergebnis\\Json\\Normalizer\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Andreas Möller",
- "email": "am@localheinz.com",
- "homepage": "https://localheinz.com"
- }
- ],
- "description": "Provides generic and vendor-specific normalizers for normalizing JSON documents.",
- "homepage": "https://github.com/ergebnis/json-normalizer",
- "keywords": [
- "json",
- "normalizer"
- ],
- "support": {
- "issues": "https://github.com/ergebnis/json-normalizer/issues",
- "security": "https://github.com/ergebnis/json-normalizer/blob/main/.github/SECURITY.md",
- "source": "https://github.com/ergebnis/json-normalizer"
- },
- "time": "2025-09-06T09:18:13+00:00"
- },
- {
- "name": "ergebnis/json-pointer",
- "version": "3.7.1",
- "source": {
- "type": "git",
- "url": "https://github.com/ergebnis/json-pointer.git",
- "reference": "43bef355184e9542635e35dd2705910a3df4c236"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ergebnis/json-pointer/zipball/43bef355184e9542635e35dd2705910a3df4c236",
- "reference": "43bef355184e9542635e35dd2705910a3df4c236",
- "shasum": ""
- },
- "require": {
- "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
- },
- "require-dev": {
- "ergebnis/composer-normalize": "^2.43.0",
- "ergebnis/data-provider": "^3.2.0",
- "ergebnis/license": "^2.4.0",
- "ergebnis/php-cs-fixer-config": "^6.32.0",
- "ergebnis/phpunit-slow-test-detector": "^2.15.0",
- "fakerphp/faker": "^1.23.1",
- "infection/infection": "~0.26.6",
- "phpstan/extension-installer": "^1.4.3",
- "phpstan/phpstan": "^1.12.10",
- "phpstan/phpstan-deprecation-rules": "^1.2.1",
- "phpstan/phpstan-phpunit": "^1.4.0",
- "phpstan/phpstan-strict-rules": "^1.6.1",
- "phpunit/phpunit": "^9.6.19",
- "rector/rector": "^1.2.10"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.8-dev"
- },
- "composer-normalize": {
- "indent-size": 2,
- "indent-style": "space"
- }
- },
- "autoload": {
- "psr-4": {
- "Ergebnis\\Json\\Pointer\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Andreas Möller",
- "email": "am@localheinz.com",
- "homepage": "https://localheinz.com"
- }
- ],
- "description": "Provides an abstraction of a JSON pointer.",
- "homepage": "https://github.com/ergebnis/json-pointer",
- "keywords": [
- "RFC6901",
- "json",
- "pointer"
- ],
- "support": {
- "issues": "https://github.com/ergebnis/json-pointer/issues",
- "security": "https://github.com/ergebnis/json-pointer/blob/main/.github/SECURITY.md",
- "source": "https://github.com/ergebnis/json-pointer"
- },
- "time": "2025-09-06T09:28:19+00:00"
- },
- {
- "name": "ergebnis/json-printer",
- "version": "3.8.1",
- "source": {
- "type": "git",
- "url": "https://github.com/ergebnis/json-printer.git",
- "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/211d73fc7ec6daf98568ee6ed6e6d133dee8503e",
- "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "ext-mbstring": "*",
- "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
- },
- "require-dev": {
- "ergebnis/composer-normalize": "^2.44.0",
- "ergebnis/data-provider": "^3.3.0",
- "ergebnis/license": "^2.5.0",
- "ergebnis/php-cs-fixer-config": "^6.37.0",
- "ergebnis/phpunit-slow-test-detector": "^2.16.1",
- "fakerphp/faker": "^1.24.0",
- "infection/infection": "~0.26.6",
- "phpstan/extension-installer": "^1.4.3",
- "phpstan/phpstan": "^1.12.10",
- "phpstan/phpstan-deprecation-rules": "^1.2.1",
- "phpstan/phpstan-phpunit": "^1.4.1",
- "phpstan/phpstan-strict-rules": "^1.6.1",
- "phpunit/phpunit": "^9.6.21",
- "rector/rector": "^1.2.10"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.9-dev"
- },
- "composer-normalize": {
- "indent-size": 2,
- "indent-style": "space"
- }
- },
- "autoload": {
- "psr-4": {
- "Ergebnis\\Json\\Printer\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Andreas Möller",
- "email": "am@localheinz.com",
- "homepage": "https://localheinz.com"
- }
- ],
- "description": "Provides a JSON printer, allowing for flexible indentation.",
- "homepage": "https://github.com/ergebnis/json-printer",
- "keywords": [
- "formatter",
- "json",
- "printer"
- ],
- "support": {
- "issues": "https://github.com/ergebnis/json-printer/issues",
- "security": "https://github.com/ergebnis/json-printer/blob/main/.github/SECURITY.md",
- "source": "https://github.com/ergebnis/json-printer"
- },
- "time": "2025-09-06T09:59:26+00:00"
- },
- {
- "name": "ergebnis/json-schema-validator",
- "version": "4.5.1",
- "source": {
- "type": "git",
- "url": "https://github.com/ergebnis/json-schema-validator.git",
- "reference": "b739527a480a9e3651360ad351ea77e7e9019df2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/b739527a480a9e3651360ad351ea77e7e9019df2",
- "reference": "b739527a480a9e3651360ad351ea77e7e9019df2",
- "shasum": ""
- },
- "require": {
- "ergebnis/json": "^1.2.0",
- "ergebnis/json-pointer": "^3.4.0",
- "ext-json": "*",
- "justinrainbow/json-schema": "^5.2.12 || ^6.0.0",
- "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
- },
- "require-dev": {
- "ergebnis/composer-normalize": "^2.44.0",
- "ergebnis/data-provider": "^3.3.0",
- "ergebnis/license": "^2.5.0",
- "ergebnis/php-cs-fixer-config": "^6.37.0",
- "ergebnis/phpunit-slow-test-detector": "^2.16.1",
- "fakerphp/faker": "^1.24.0",
- "infection/infection": "~0.26.6",
- "phpstan/extension-installer": "^1.4.3",
- "phpstan/phpstan": "^1.12.10",
- "phpstan/phpstan-deprecation-rules": "^1.2.1",
- "phpstan/phpstan-phpunit": "^1.4.0",
- "phpstan/phpstan-strict-rules": "^1.6.1",
- "phpunit/phpunit": "^9.6.20",
- "rector/rector": "^1.2.10"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "4.6-dev"
- },
- "composer-normalize": {
- "indent-size": 2,
- "indent-style": "space"
- }
- },
- "autoload": {
- "psr-4": {
- "Ergebnis\\Json\\SchemaValidator\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Andreas Möller",
- "email": "am@localheinz.com",
- "homepage": "https://localheinz.com"
- }
- ],
- "description": "Provides a JSON schema validator, building on top of justinrainbow/json-schema.",
- "homepage": "https://github.com/ergebnis/json-schema-validator",
- "keywords": [
- "json",
- "schema",
- "validator"
- ],
- "support": {
- "issues": "https://github.com/ergebnis/json-schema-validator/issues",
- "security": "https://github.com/ergebnis/json-schema-validator/blob/main/.github/SECURITY.md",
- "source": "https://github.com/ergebnis/json-schema-validator"
- },
- "time": "2025-09-06T11:37:35+00:00"
- },
- {
- "name": "felixfbecker/language-server-protocol",
- "version": "v1.5.3",
- "source": {
- "type": "git",
- "url": "https://github.com/felixfbecker/php-language-server-protocol.git",
- "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/a9e113dbc7d849e35b8776da39edaf4313b7b6c9",
- "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "require-dev": {
- "phpstan/phpstan": "*",
- "squizlabs/php_codesniffer": "^3.1",
- "vimeo/psalm": "^4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "LanguageServerProtocol\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "ISC"
- ],
- "authors": [
- {
- "name": "Felix Becker",
- "email": "felix.b@outlook.com"
- }
- ],
- "description": "PHP classes for the Language Server Protocol",
- "keywords": [
- "language",
- "microsoft",
- "php",
- "server"
- ],
- "support": {
- "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues",
- "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.3"
- },
- "time": "2024-04-30T00:40:11+00:00"
- },
- {
- "name": "fidry/cpu-core-counter",
- "version": "1.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/theofidry/cpu-core-counter.git",
- "reference": "db9508f7b1474469d9d3c53b86f817e344732678"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678",
- "reference": "db9508f7b1474469d9d3c53b86f817e344732678",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "require-dev": {
- "fidry/makefile": "^0.2.0",
- "fidry/php-cs-fixer-config": "^1.1.2",
- "phpstan/extension-installer": "^1.2.0",
- "phpstan/phpstan": "^2.0",
- "phpstan/phpstan-deprecation-rules": "^2.0.0",
- "phpstan/phpstan-phpunit": "^2.0",
- "phpstan/phpstan-strict-rules": "^2.0",
- "phpunit/phpunit": "^8.5.31 || ^9.5.26",
- "webmozarts/strict-phpunit": "^7.5"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Fidry\\CpuCoreCounter\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Théo FIDRY",
- "email": "theo.fidry@gmail.com"
- }
- ],
- "description": "Tiny utility to get the number of CPU cores.",
- "keywords": [
- "CPU",
- "core"
- ],
- "support": {
- "issues": "https://github.com/theofidry/cpu-core-counter/issues",
- "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0"
- },
- "funding": [
- {
- "url": "https://github.com/theofidry",
- "type": "github"
- }
- ],
- "time": "2025-08-14T07:29:31+00:00"
- },
- {
- "name": "jawira/case-converter",
- "version": "v3.6.0",
- "source": {
- "type": "git",
- "url": "https://github.com/jawira/case-converter.git",
- "reference": "de9956122568743a83e0fc7e2eaa92c1b0de3f18"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/jawira/case-converter/zipball/de9956122568743a83e0fc7e2eaa92c1b0de3f18",
- "reference": "de9956122568743a83e0fc7e2eaa92c1b0de3f18",
- "shasum": ""
- },
- "require": {
- "ext-mbstring": "*",
- "php": ">=7.4"
- },
- "require-dev": {
- "behat/behat": "^3.0",
- "phpstan/phpstan": "^v2",
- "phpunit/phpunit": "^9.0"
- },
- "suggest": {
- "pds/skeleton": "PHP Package Development Standards",
- "phing/phing": "PHP Build Tool"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Jawira\\CaseConverter\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jawira Portugal",
- "email": "dev@tugal.be"
- }
- ],
- "description": "Convert strings between 13 naming conventions: Snake case, Camel case, Pascal case, Kebab case, Ada case, Train case, Cobol case, Macro case, Upper case, Lower case, Sentence case, Title case and Dot notation.",
- "homepage": "https://jawira.github.io/case-converter/",
- "keywords": [
- "Ada case",
- "Cobol case",
- "Macro case",
- "Train case",
- "camel case",
- "dot notation",
- "kebab case",
- "lower case",
- "pascal case",
- "sentence case",
- "snake case",
- "title case",
- "upper case"
- ],
- "support": {
- "issues": "https://github.com/jawira/case-converter/issues",
- "source": "https://github.com/jawira/case-converter/tree/v3.6.0"
- },
- "time": "2025-06-13T21:12:55+00:00"
- },
- {
- "name": "justinrainbow/json-schema",
- "version": "6.5.2",
- "source": {
- "type": "git",
- "url": "https://github.com/jsonrainbow/json-schema.git",
- "reference": "ac0d369c09653cf7af561f6d91a705bc617a87b8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/ac0d369c09653cf7af561f6d91a705bc617a87b8",
- "reference": "ac0d369c09653cf7af561f6d91a705bc617a87b8",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "marc-mabe/php-enum": "^4.0",
- "php": "^7.2 || ^8.0"
- },
- "require-dev": {
- "friendsofphp/php-cs-fixer": "3.3.0",
- "json-schema/json-schema-test-suite": "^23.2",
- "marc-mabe/php-enum-phpstan": "^2.0",
- "phpspec/prophecy": "^1.19",
- "phpstan/phpstan": "^1.12",
- "phpunit/phpunit": "^8.5"
- },
- "bin": [
- "bin/validate-json"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "6.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "JsonSchema\\": "src/JsonSchema/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bruno Prieto Reis",
- "email": "bruno.p.reis@gmail.com"
- },
- {
- "name": "Justin Rainbow",
- "email": "justin.rainbow@gmail.com"
- },
- {
- "name": "Igor Wiedler",
- "email": "igor@wiedler.ch"
- },
- {
- "name": "Robert Schönthal",
- "email": "seroscho@googlemail.com"
- }
- ],
- "description": "A library to validate a json schema.",
- "homepage": "https://github.com/jsonrainbow/json-schema",
- "keywords": [
- "json",
- "schema"
- ],
- "support": {
- "issues": "https://github.com/jsonrainbow/json-schema/issues",
- "source": "https://github.com/jsonrainbow/json-schema/tree/6.5.2"
- },
- "time": "2025-09-09T09:42:27+00:00"
- },
- {
- "name": "kelunik/certificate",
- "version": "v1.1.3",
- "source": {
- "type": "git",
- "url": "https://github.com/kelunik/certificate.git",
- "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e",
- "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e",
- "shasum": ""
- },
- "require": {
- "ext-openssl": "*",
- "php": ">=7.0"
- },
- "require-dev": {
- "amphp/php-cs-fixer-config": "^2",
- "phpunit/phpunit": "^6 | 7 | ^8 | ^9"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Kelunik\\Certificate\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "Access certificate details and transform between different formats.",
- "keywords": [
- "DER",
- "certificate",
- "certificates",
- "openssl",
- "pem",
- "x509"
- ],
- "support": {
- "issues": "https://github.com/kelunik/certificate/issues",
- "source": "https://github.com/kelunik/certificate/tree/v1.1.3"
- },
- "time": "2023-02-03T21:26:53+00:00"
- },
- {
- "name": "league/uri",
- "version": "7.5.1",
- "source": {
- "type": "git",
- "url": "https://github.com/thephpleague/uri.git",
- "reference": "81fb5145d2644324614cc532b28efd0215bda430"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430",
- "reference": "81fb5145d2644324614cc532b28efd0215bda430",
- "shasum": ""
- },
- "require": {
- "league/uri-interfaces": "^7.5",
- "php": "^8.1"
- },
- "conflict": {
- "league/uri-schemes": "^1.0"
- },
- "suggest": {
- "ext-bcmath": "to improve IPV4 host parsing",
- "ext-fileinfo": "to create Data URI from file contennts",
- "ext-gmp": "to improve IPV4 host parsing",
- "ext-intl": "to handle IDN host with the best performance",
- "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain",
- "league/uri-components": "Needed to easily manipulate URI objects components",
- "php-64bit": "to improve IPV4 host parsing",
- "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "7.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "League\\Uri\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ignace Nyamagana Butera",
- "email": "nyamsprod@gmail.com",
- "homepage": "https://nyamsprod.com"
- }
- ],
- "description": "URI manipulation library",
- "homepage": "https://uri.thephpleague.com",
- "keywords": [
- "data-uri",
- "file-uri",
- "ftp",
- "hostname",
- "http",
- "https",
- "middleware",
- "parse_str",
- "parse_url",
- "psr-7",
- "query-string",
- "querystring",
- "rfc3986",
- "rfc3987",
- "rfc6570",
- "uri",
- "uri-template",
- "url",
- "ws"
- ],
- "support": {
- "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.5.1"
- },
- "funding": [
- {
- "url": "https://github.com/sponsors/nyamsprod",
- "type": "github"
- }
- ],
- "time": "2024-12-08T08:40:02+00:00"
- },
- {
- "name": "league/uri-interfaces",
- "version": "7.5.0",
- "source": {
- "type": "git",
- "url": "https://github.com/thephpleague/uri-interfaces.git",
- "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742",
- "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742",
- "shasum": ""
- },
- "require": {
- "ext-filter": "*",
- "php": "^8.1",
- "psr/http-factory": "^1",
- "psr/http-message": "^1.1 || ^2.0"
- },
- "suggest": {
- "ext-bcmath": "to improve IPV4 host parsing",
- "ext-gmp": "to improve IPV4 host parsing",
- "ext-intl": "to handle IDN host with the best performance",
- "php-64bit": "to improve IPV4 host parsing",
- "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "7.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "League\\Uri\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ignace Nyamagana Butera",
- "email": "nyamsprod@gmail.com",
- "homepage": "https://nyamsprod.com"
- }
- ],
- "description": "Common interfaces and classes for URI representation and interaction",
- "homepage": "https://uri.thephpleague.com",
- "keywords": [
- "data-uri",
- "file-uri",
- "ftp",
- "hostname",
- "http",
- "https",
- "parse_str",
- "parse_url",
- "psr-7",
- "query-string",
- "querystring",
- "rfc3986",
- "rfc3987",
- "rfc6570",
- "uri",
- "url",
- "ws"
- ],
- "support": {
- "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.5.0"
- },
- "funding": [
- {
- "url": "https://github.com/sponsors/nyamsprod",
- "type": "github"
- }
- ],
- "time": "2024-12-08T08:18:47+00:00"
- },
- {
- "name": "localheinz/diff",
- "version": "1.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/localheinz/diff.git",
- "reference": "33bd840935970cda6691c23fc7d94ae764c0734c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/localheinz/diff/zipball/33bd840935970cda6691c23fc7d94ae764c0734c",
- "reference": "33bd840935970cda6691c23fc7d94ae764c0734c",
- "shasum": ""
- },
- "require": {
- "php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^7.5.0 || ^8.5.23",
- "symfony/process": "^4.2 || ^5"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- }
- ],
- "description": "Fork of sebastian/diff for use with ergebnis/composer-normalize",
- "homepage": "https://github.com/localheinz/diff",
- "keywords": [
- "diff",
- "udiff",
- "unidiff",
- "unified diff"
- ],
- "support": {
- "issues": "https://github.com/localheinz/diff/issues",
- "source": "https://github.com/localheinz/diff/tree/1.3.0"
- },
- "time": "2025-08-30T09:44:18+00:00"
- },
- {
- "name": "marc-mabe/php-enum",
- "version": "v4.7.2",
- "source": {
- "type": "git",
- "url": "https://github.com/marc-mabe/php-enum.git",
- "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/bb426fcdd65c60fb3638ef741e8782508fda7eef",
- "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef",
- "shasum": ""
- },
- "require": {
- "ext-reflection": "*",
- "php": "^7.1 | ^8.0"
- },
- "require-dev": {
- "phpbench/phpbench": "^0.16.10 || ^1.0.4",
- "phpstan/phpstan": "^1.3.1",
- "phpunit/phpunit": "^7.5.20 | ^8.5.22 | ^9.5.11",
- "vimeo/psalm": "^4.17.0 | ^5.26.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-3.x": "3.2-dev",
- "dev-master": "4.7-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "MabeEnum\\": "src/"
- },
- "classmap": [
- "stubs/Stringable.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Marc Bennewitz",
- "email": "dev@mabe.berlin",
- "homepage": "https://mabe.berlin/",
- "role": "Lead"
- }
- ],
- "description": "Simple and fast implementation of enumerations with native PHP",
- "homepage": "https://github.com/marc-mabe/php-enum",
- "keywords": [
- "enum",
- "enum-map",
- "enum-set",
- "enumeration",
- "enumerator",
- "enummap",
- "enumset",
- "map",
- "set",
- "type",
- "type-hint",
- "typehint"
- ],
- "support": {
- "issues": "https://github.com/marc-mabe/php-enum/issues",
- "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.2"
- },
- "time": "2025-09-14T11:18:39+00:00"
- },
- {
- "name": "myclabs/deep-copy",
- "version": "1.13.4",
- "source": {
- "type": "git",
- "url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
- "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
- "shasum": ""
- },
- "require": {
- "php": "^7.1 || ^8.0"
- },
- "conflict": {
- "doctrine/collections": "<1.6.8",
- "doctrine/common": "<2.13.3 || >=3 <3.2.2"
- },
- "require-dev": {
- "doctrine/collections": "^1.6.8",
- "doctrine/common": "^2.13.3 || ^3.2.2",
- "phpspec/prophecy": "^1.10",
- "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/DeepCopy/deep_copy.php"
- ],
- "psr-4": {
- "DeepCopy\\": "src/DeepCopy/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Create deep copies (clones) of your objects",
- "keywords": [
- "clone",
- "copy",
- "duplicate",
- "object",
- "object graph"
- ],
- "support": {
- "issues": "https://github.com/myclabs/DeepCopy/issues",
- "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
- },
- "funding": [
- {
- "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
- "type": "tidelift"
- }
- ],
- "time": "2025-08-01T08:46:24+00:00"
- },
- {
- "name": "netresearch/jsonmapper",
- "version": "v5.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/cweiske/jsonmapper.git",
- "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c",
- "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "ext-pcre": "*",
- "ext-reflection": "*",
- "ext-spl": "*",
- "php": ">=7.1"
- },
- "require-dev": {
- "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0",
- "squizlabs/php_codesniffer": "~3.5"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "JsonMapper": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "OSL-3.0"
- ],
- "authors": [
- {
- "name": "Christian Weiske",
- "email": "cweiske@cweiske.de",
- "homepage": "http://github.com/cweiske/jsonmapper/",
- "role": "Developer"
- }
- ],
- "description": "Map nested JSON structures onto PHP classes",
- "support": {
- "email": "cweiske@cweiske.de",
- "issues": "https://github.com/cweiske/jsonmapper/issues",
- "source": "https://github.com/cweiske/jsonmapper/tree/v5.0.0"
- },
- "time": "2024-09-08T10:20:00+00:00"
- },
- {
- "name": "nikic/php-parser",
- "version": "v5.6.1",
- "source": {
- "type": "git",
- "url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
- "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
- "shasum": ""
- },
- "require": {
- "ext-ctype": "*",
- "ext-json": "*",
- "ext-tokenizer": "*",
- "php": ">=7.4"
- },
- "require-dev": {
- "ircmaxell/php-yacc": "^0.0.7",
- "phpunit/phpunit": "^9.0"
- },
- "bin": [
- "bin/php-parse"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "PhpParser\\": "lib/PhpParser"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Nikita Popov"
- }
- ],
- "description": "A PHP parser written in PHP",
- "keywords": [
- "parser",
- "php"
- ],
- "support": {
- "issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1"
- },
- "time": "2025-08-13T20:13:15+00:00"
- },
- {
- "name": "opis/json-schema",
- "version": "2.4.1",
- "source": {
- "type": "git",
- "url": "https://github.com/opis/json-schema.git",
- "reference": "712827751c62b465daae6e725bf0cf5ffbf965e1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/opis/json-schema/zipball/712827751c62b465daae6e725bf0cf5ffbf965e1",
- "reference": "712827751c62b465daae6e725bf0cf5ffbf965e1",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "opis/string": "^2.0",
- "opis/uri": "^1.0",
- "php": "^7.4 || ^8.0"
- },
- "require-dev": {
- "ext-bcmath": "*",
- "ext-intl": "*",
- "phpunit/phpunit": "^9.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Opis\\JsonSchema\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Apache-2.0"
- ],
- "authors": [
- {
- "name": "Sorin Sarca",
- "email": "sarca_sorin@hotmail.com"
- },
- {
- "name": "Marius Sarca",
- "email": "marius.sarca@gmail.com"
- }
- ],
- "description": "Json Schema Validator for PHP",
- "homepage": "https://opis.io/json-schema",
- "keywords": [
- "json",
- "json-schema",
- "schema",
- "validation",
- "validator"
- ],
- "support": {
- "issues": "https://github.com/opis/json-schema/issues",
- "source": "https://github.com/opis/json-schema/tree/2.4.1"
- },
- "time": "2024-12-30T20:20:21+00:00"
- },
- {
- "name": "opis/string",
- "version": "2.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/opis/string.git",
- "reference": "ba0b9607b9809462b0e28a11e4881a8d77431feb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/opis/string/zipball/ba0b9607b9809462b0e28a11e4881a8d77431feb",
- "reference": "ba0b9607b9809462b0e28a11e4881a8d77431feb",
- "shasum": ""
- },
- "require": {
- "ext-iconv": "*",
- "ext-json": "*",
- "php": "^7.4 || ^8.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^9.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Opis\\String\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Apache-2.0"
- ],
- "authors": [
- {
- "name": "Marius Sarca",
- "email": "marius.sarca@gmail.com"
- },
- {
- "name": "Sorin Sarca",
- "email": "sarca_sorin@hotmail.com"
- }
- ],
- "description": "Multibyte strings as objects",
- "homepage": "https://opis.io/string",
- "keywords": [
- "multi-byte",
- "opis",
- "string",
- "string manipulation",
- "utf-8"
- ],
- "support": {
- "issues": "https://github.com/opis/string/issues",
- "source": "https://github.com/opis/string/tree/2.0.2"
- },
- "time": "2024-12-30T21:43:22+00:00"
- },
- {
- "name": "opis/uri",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/opis/uri.git",
- "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/opis/uri/zipball/0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a",
- "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a",
- "shasum": ""
- },
- "require": {
- "opis/string": "^2.0",
- "php": "^7.4 || ^8.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^9"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Opis\\Uri\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Apache-2.0"
- ],
- "authors": [
- {
- "name": "Marius Sarca",
- "email": "marius.sarca@gmail.com"
- },
- {
- "name": "Sorin Sarca",
- "email": "sarca_sorin@hotmail.com"
- }
- ],
- "description": "Build, parse and validate URIs and URI-templates",
- "homepage": "https://opis.io",
- "keywords": [
- "URI Template",
- "parse url",
- "punycode",
- "uri",
- "uri components",
- "url",
- "validate uri"
- ],
- "support": {
- "issues": "https://github.com/opis/uri/issues",
- "source": "https://github.com/opis/uri/tree/1.1.0"
- },
- "time": "2021-05-22T15:57:08+00:00"
- },
- {
- "name": "phar-io/composer-distributor",
- "version": "1.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/composer-distributor.git",
- "reference": "dd7d936290b2a42b0c64bfe08090b5c597c280c9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/composer-distributor/zipball/dd7d936290b2a42b0c64bfe08090b5c597c280c9",
- "reference": "dd7d936290b2a42b0c64bfe08090b5c597c280c9",
- "shasum": ""
- },
- "require": {
- "composer-plugin-api": "^1.1 || ^2.0",
- "ext-dom": "*",
- "ext-libxml": "*",
- "phar-io/filesystem": "^2.0",
- "phar-io/gnupg": "^1.0",
- "php": "^7.3 || ^8.0"
- },
- "require-dev": {
- "composer/composer": "^2.0",
- "phpunit/phpunit": "^9.4"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "PharIo\\ComposerDistributor\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Andreas Heigl",
- "email": "andreas@heigl.org",
- "role": "Developer"
- },
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Feldmann",
- "email": "sf@sebastian-feldmann.info",
- "role": "Developer"
- }
- ],
- "description": "Base Code for a composer plugin that installs PHAR-files",
- "homepage": "https://phar.io",
- "keywords": [
- "bin",
- "binary",
- "composer",
- "distribute",
- "phar",
- "phive"
- ],
- "support": {
- "issues": "https://github.com/phar-io/composer-distributor/issues",
- "source": "https://github.com/phar-io/composer-distributor/tree/1.0.2"
- },
- "funding": [
- {
- "url": "https://phar.io",
- "type": "other"
- }
- ],
- "time": "2023-05-31T17:05:49+00:00"
- },
- {
- "name": "phar-io/executor",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/executor.git",
- "reference": "5bfb7400224a0c1cf83343660af85c7f5a073473"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/executor/zipball/5bfb7400224a0c1cf83343660af85c7f5a073473",
- "reference": "5bfb7400224a0c1cf83343660af85c7f5a073473",
- "shasum": ""
- },
- "require": {
- "phar-io/filesystem": "^2.0",
- "php": "^7.2||^8.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- }
- ],
- "support": {
- "issues": "https://github.com/phar-io/executor/issues",
- "source": "https://github.com/phar-io/executor/tree/1.0.1"
- },
- "time": "2020-11-30T10:53:57+00:00"
- },
- {
- "name": "phar-io/filesystem",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/filesystem.git",
- "reference": "222e3ea432262a05706b7066697c21257664d9d1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/filesystem/zipball/222e3ea432262a05706b7066697c21257664d9d1",
- "reference": "222e3ea432262a05706b7066697c21257664d9d1",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- }
- ],
- "support": {
- "issues": "https://github.com/phar-io/filesystem/issues",
- "source": "https://github.com/phar-io/filesystem/tree/2.0.1"
- },
- "time": "2020-11-30T10:16:22+00:00"
- },
- {
- "name": "phar-io/gnupg",
- "version": "1.0.3",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/gnupg.git",
- "reference": "ed8ab1740ac4e9db99500e7252911f2821357093"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/gnupg/zipball/ed8ab1740ac4e9db99500e7252911f2821357093",
- "reference": "ed8ab1740ac4e9db99500e7252911f2821357093",
- "shasum": ""
- },
- "require": {
- "phar-io/executor": "^1.0",
- "phar-io/filesystem": "^2.0",
- "php": "^7.2||^8.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- }
- ],
- "description": "Thin GnuPG wrapper class around the gnupg binary, mimicking the pecl/gnupg api",
- "support": {
- "issues": "https://github.com/phar-io/gnupg/issues",
- "source": "https://github.com/phar-io/gnupg/tree/1.0.3"
- },
- "time": "2024-08-22T20:45:57+00:00"
- },
- {
- "name": "phar-io/manifest",
- "version": "2.0.4",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/manifest.git",
- "reference": "54750ef60c58e43759730615a392c31c80e23176"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
- "reference": "54750ef60c58e43759730615a392c31c80e23176",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-libxml": "*",
- "ext-phar": "*",
- "ext-xmlwriter": "*",
- "phar-io/version": "^3.0.1",
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "Developer"
- }
- ],
- "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
- "support": {
- "issues": "https://github.com/phar-io/manifest/issues",
- "source": "https://github.com/phar-io/manifest/tree/2.0.4"
- },
- "funding": [
- {
- "url": "https://github.com/theseer",
- "type": "github"
- }
- ],
- "time": "2024-03-03T12:33:53+00:00"
- },
- {
- "name": "phar-io/version",
- "version": "3.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phar-io/version.git",
- "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
- "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Heuer",
- "email": "sebastian@phpeople.de",
- "role": "Developer"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "Developer"
- }
- ],
- "description": "Library for handling version information and constraints",
- "support": {
- "issues": "https://github.com/phar-io/version/issues",
- "source": "https://github.com/phar-io/version/tree/3.2.1"
- },
- "time": "2022-02-21T01:04:05+00:00"
- },
- {
- "name": "phpdocumentor/reflection-common",
- "version": "2.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-2.x": "2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
- }
- ],
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
- "homepage": "http://www.phpdoc.org",
- "keywords": [
- "FQSEN",
- "phpDocumentor",
- "phpdoc",
- "reflection",
- "static analysis"
- ],
- "support": {
- "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
- "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
- },
- "time": "2020-06-27T09:03:43+00:00"
- },
- {
- "name": "phpdocumentor/reflection-docblock",
- "version": "5.6.3",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9",
- "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9",
- "shasum": ""
- },
- "require": {
- "doctrine/deprecations": "^1.1",
- "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"
- },
- "require-dev": {
- "mockery/mockery": "~1.3.5 || ~1.6.0",
- "phpstan/extension-installer": "^1.1",
- "phpstan/phpstan": "^1.8",
- "phpstan/phpstan-mockery": "^1.1",
- "phpstan/phpstan-webmozart-assert": "^1.2",
- "phpunit/phpunit": "^9.5",
- "psalm/phar": "^5.26"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- },
- {
- "name": "Jaap van Otterdijk",
- "email": "opensource@ijaap.nl"
- }
- ],
- "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.3"
- },
- "time": "2025-08-01T19:43:32+00:00"
- },
- {
- "name": "phpdocumentor/type-resolver",
- "version": "1.10.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
- "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
- "shasum": ""
- },
- "require": {
- "doctrine/deprecations": "^1.0",
- "php": "^7.3 || ^8.0",
- "phpdocumentor/reflection-common": "^2.0",
- "phpstan/phpdoc-parser": "^1.18|^2.0"
- },
- "require-dev": {
- "ext-tokenizer": "*",
- "phpbench/phpbench": "^1.2",
- "phpstan/extension-installer": "^1.1",
- "phpstan/phpstan": "^1.8",
- "phpstan/phpstan-phpunit": "^1.1",
- "phpunit/phpunit": "^9.5",
- "rector/rector": "^0.13.9",
- "vimeo/psalm": "^4.25"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-1.x": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "phpDocumentor\\Reflection\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Mike van Riel",
- "email": "me@mikevanriel.com"
- }
- ],
- "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.10.0"
- },
- "time": "2024-11-09T15:12:26+00:00"
- },
- {
- "name": "phpstan/phpdoc-parser",
- "version": "2.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
- "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
- "shasum": ""
- },
- "require": {
- "php": "^7.4 || ^8.0"
- },
- "require-dev": {
- "doctrine/annotations": "^2.0",
- "nikic/php-parser": "^5.3.0",
- "php-parallel-lint/php-parallel-lint": "^1.2",
- "phpstan/extension-installer": "^1.0",
- "phpstan/phpstan": "^2.0",
- "phpstan/phpstan-phpunit": "^2.0",
- "phpstan/phpstan-strict-rules": "^2.0",
- "phpunit/phpunit": "^9.6",
- "symfony/process": "^5.2"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "PHPStan\\PhpDocParser\\": [
- "src/"
- ]
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "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"
- },
- "time": "2025-08-30T15:50:23+00:00"
- },
- {
- "name": "phpstan/phpstan",
- "version": "1.12.32",
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/2770dcdf5078d0b0d53f94317e06affe88419aa8",
- "reference": "2770dcdf5078d0b0d53f94317e06affe88419aa8",
- "shasum": ""
- },
- "require": {
- "php": "^7.2|^8.0"
- },
- "conflict": {
- "phpstan/phpstan-shim": "*"
- },
- "bin": [
- "phpstan",
- "phpstan.phar"
- ],
- "type": "library",
- "autoload": {
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "PHPStan - PHP Static Analysis Tool",
- "keywords": [
- "dev",
- "static analysis"
- ],
- "support": {
- "docs": "https://phpstan.org/user-guide/getting-started",
- "forum": "https://github.com/phpstan/phpstan/discussions",
- "issues": "https://github.com/phpstan/phpstan/issues",
- "security": "https://github.com/phpstan/phpstan/security/policy",
- "source": "https://github.com/phpstan/phpstan-src"
- },
- "funding": [
- {
- "url": "https://github.com/ondrejmirtes",
- "type": "github"
- },
- {
- "url": "https://github.com/phpstan",
- "type": "github"
- }
- ],
- "time": "2025-09-30T10:16:31+00:00"
- },
- {
- "name": "phpunit/php-code-coverage",
- "version": "10.1.16",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "7e308268858ed6baedc8704a304727d20bc07c77"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77",
- "reference": "7e308268858ed6baedc8704a304727d20bc07c77",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-libxml": "*",
- "ext-xmlwriter": "*",
- "nikic/php-parser": "^4.19.1 || ^5.1.0",
- "php": ">=8.1",
- "phpunit/php-file-iterator": "^4.1.0",
- "phpunit/php-text-template": "^3.0.1",
- "sebastian/code-unit-reverse-lookup": "^3.0.0",
- "sebastian/complexity": "^3.2.0",
- "sebastian/environment": "^6.1.0",
- "sebastian/lines-of-code": "^2.0.2",
- "sebastian/version": "^4.0.1",
- "theseer/tokenizer": "^1.2.3"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.1"
- },
- "suggest": {
- "ext-pcov": "PHP extension that provides line coverage",
- "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "10.1.x-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
- "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
- "keywords": [
- "coverage",
- "testing",
- "xunit"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
- "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2024-08-22T04:31:57+00:00"
- },
- {
- "name": "phpunit/php-file-iterator",
- "version": "4.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c",
- "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "4.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "FilterIterator implementation that filters files based on a list of suffixes.",
- "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
- "keywords": [
- "filesystem",
- "iterator"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
- "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
- "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-08-31T06:24:48+00:00"
- },
- {
- "name": "phpunit/php-invoker",
- "version": "4.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-invoker.git",
- "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
- "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "ext-pcntl": "*",
- "phpunit/phpunit": "^10.0"
- },
- "suggest": {
- "ext-pcntl": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "4.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Invoke callables with a timeout",
- "homepage": "https://github.com/sebastianbergmann/php-invoker/",
- "keywords": [
- "process"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
- "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T06:56:09+00:00"
- },
- {
- "name": "phpunit/php-text-template",
- "version": "3.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-text-template.git",
- "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748",
- "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Simple template engine.",
- "homepage": "https://github.com/sebastianbergmann/php-text-template/",
- "keywords": [
- "template"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
- "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
- "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-08-31T14:07:24+00:00"
- },
- {
- "name": "phpunit/php-timer",
- "version": "6.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d",
- "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "6.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Utility class for timing",
- "homepage": "https://github.com/sebastianbergmann/php-timer/",
- "keywords": [
- "timer"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/php-timer/issues",
- "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T06:57:52+00:00"
- },
- {
- "name": "phpunit/phpunit",
- "version": "10.5.60",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "f2e26f52f80ef77832e359205f216eeac00e320c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f2e26f52f80ef77832e359205f216eeac00e320c",
- "reference": "f2e26f52f80ef77832e359205f216eeac00e320c",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-json": "*",
- "ext-libxml": "*",
- "ext-mbstring": "*",
- "ext-xml": "*",
- "ext-xmlwriter": "*",
- "myclabs/deep-copy": "^1.13.4",
- "phar-io/manifest": "^2.0.4",
- "phar-io/version": "^3.2.1",
- "php": ">=8.1",
- "phpunit/php-code-coverage": "^10.1.16",
- "phpunit/php-file-iterator": "^4.1.0",
- "phpunit/php-invoker": "^4.0.0",
- "phpunit/php-text-template": "^3.0.1",
- "phpunit/php-timer": "^6.0.0",
- "sebastian/cli-parser": "^2.0.1",
- "sebastian/code-unit": "^2.0.0",
- "sebastian/comparator": "^5.0.4",
- "sebastian/diff": "^5.1.1",
- "sebastian/environment": "^6.1.0",
- "sebastian/exporter": "^5.1.4",
- "sebastian/global-state": "^6.0.2",
- "sebastian/object-enumerator": "^5.0.0",
- "sebastian/recursion-context": "^5.0.1",
- "sebastian/type": "^4.0.0",
- "sebastian/version": "^4.0.1"
- },
- "suggest": {
- "ext-soap": "To be able to generate mocks based on WSDL files"
- },
- "bin": [
- "phpunit"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "10.5-dev"
- }
- },
- "autoload": {
- "files": [
- "src/Framework/Assert/Functions.php"
- ],
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "The PHP Unit Testing framework.",
- "homepage": "https://phpunit.de/",
- "keywords": [
- "phpunit",
- "testing",
- "xunit"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/phpunit/issues",
- "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.60"
- },
- "funding": [
- {
- "url": "https://phpunit.de/sponsors.html",
- "type": "custom"
- },
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- },
- {
- "url": "https://liberapay.com/sebastianbergmann",
- "type": "liberapay"
- },
- {
- "url": "https://thanks.dev/u/gh/sebastianbergmann",
- "type": "thanks_dev"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
- "type": "tidelift"
- }
- ],
- "time": "2025-12-06T07:50:42+00:00"
- },
- {
- "name": "psr/container",
- "version": "2.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/container.git",
- "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
- "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
- "shasum": ""
- },
- "require": {
- "php": ">=7.4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Container\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
- }
- ],
- "description": "Common Container Interface (PHP FIG PSR-11)",
- "homepage": "https://github.com/php-fig/container",
- "keywords": [
- "PSR-11",
- "container",
- "container-interface",
- "container-interop",
- "psr"
- ],
- "support": {
- "issues": "https://github.com/php-fig/container/issues",
- "source": "https://github.com/php-fig/container/tree/2.0.2"
- },
- "time": "2021-11-05T16:47:00+00:00"
- },
- {
- "name": "psr/http-factory",
- "version": "1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-factory.git",
- "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
- "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1",
- "psr/http-message": "^1.0 || ^2.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
- }
- ],
- "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories",
- "keywords": [
- "factory",
- "http",
- "message",
- "psr",
- "psr-17",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-factory"
- },
- "time": "2024-04-15T12:06:14+00:00"
- },
- {
- "name": "psr/http-message",
- "version": "2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
- "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
- "shasum": ""
- },
- "require": {
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "support": {
- "source": "https://github.com/php-fig/http-message/tree/2.0"
- },
- "time": "2023-04-04T09:54:51+00:00"
- },
- {
- "name": "psr/log",
- "version": "3.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/log.git",
- "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
- "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
- "shasum": ""
- },
- "require": {
- "php": ">=8.0.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Log\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "https://www.php-fig.org/"
- }
- ],
- "description": "Common interface for logging libraries",
- "homepage": "https://github.com/php-fig/log",
- "keywords": [
- "log",
- "psr",
- "psr-3"
- ],
- "support": {
- "source": "https://github.com/php-fig/log/tree/3.0.2"
- },
- "time": "2024-09-11T13:17:53+00:00"
- },
- {
- "name": "ramsey/conventional-commits",
- "version": "1.6.0",
- "source": {
- "type": "git",
- "url": "https://github.com/ramsey/conventional-commits.git",
- "reference": "3eb46b9046d91f5b35462ff770a9d0326601783d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ramsey/conventional-commits/zipball/3eb46b9046d91f5b35462ff770a9d0326601783d",
- "reference": "3eb46b9046d91f5b35462ff770a9d0326601783d",
- "shasum": ""
- },
- "require": {
- "composer-runtime-api": "^2.0",
- "composer/composer": "^2.4",
- "ext-json": "*",
- "jawira/case-converter": "^3.5",
- "opis/json-schema": "^2.3",
- "php": "^8.1",
- "symfony/console": "^6.0 || ^7.0",
- "symfony/filesystem": "^6.0 || ^7.0"
- },
- "require-dev": {
- "captainhook/captainhook": "^5.15",
- "captainhook/plugin-composer": "^5.3",
- "ergebnis/composer-normalize": "^2.30",
- "hamcrest/hamcrest-php": "^2.0",
- "mockery/mockery": "^1.5",
- "php-parallel-lint/php-console-highlighter": "^1.0",
- "php-parallel-lint/php-parallel-lint": "^1.3",
- "phpstan/extension-installer": "^1.2",
- "phpstan/phpstan": "^1.10",
- "phpstan/phpstan-mockery": "^1.1",
- "phpstan/phpstan-phpunit": "^1.3",
- "phpunit/phpunit": "^10.1",
- "ramsey/coding-standard": "^2.3",
- "ramsey/composer-repl": "^1.4",
- "roave/security-advisories": "dev-latest",
- "sebastianfeldmann/cli": "^3.4",
- "sebastianfeldmann/git": "^3.8",
- "spatie/phpunit-snapshot-assertions": "^5.1",
- "symfony/process": "^6.0 || ^7.0"
- },
- "suggest": {
- "captainhook/captainhook": "Manage your project's Git hooks with CaptainHook, and use ramsey/conventional-commits in your commit-msg and prepare-commit-msg hooks."
- },
- "bin": [
- "bin/conventional-commits"
- ],
- "type": "library",
- "extra": {
- "captainhook": {
- "force-install": true
- },
- "branch-alias": {
- "dev-main": "1.x-dev"
- },
- "ramsey/conventional-commits": {
- "configFile": "conventional-commits.json"
- }
- },
- "autoload": {
- "psr-4": {
- "Ramsey\\CaptainHook\\": "src/CaptainHook/",
- "Ramsey\\ConventionalCommits\\": "src/ConventionalCommits/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ben Ramsey",
- "email": "ben@benramsey.com",
- "homepage": "https://benramsey.com"
- }
- ],
- "description": "A PHP library for creating and validating commit messages according to the Conventional Commits specification. Includes a CaptainHook action!",
- "keywords": [
- "HOOK",
- "captainhook",
- "commit",
- "commit-msg",
- "conventional",
- "conventional-commits",
- "git",
- "plugin"
- ],
- "support": {
- "issues": "https://github.com/ramsey/conventional-commits/issues",
- "source": "https://github.com/ramsey/conventional-commits/tree/1.6.0"
- },
- "funding": [
- {
- "url": "https://github.com/ramsey",
- "type": "github"
- }
- ],
- "time": "2025-03-01T19:18:27+00:00"
- },
- {
- "name": "react/promise",
- "version": "v3.3.0",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/promise.git",
- "reference": "23444f53a813a3296c1368bb104793ce8d88f04a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a",
- "reference": "23444f53a813a3296c1368bb104793ce8d88f04a",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1.0"
- },
- "require-dev": {
- "phpstan/phpstan": "1.12.28 || 1.4.10",
- "phpunit/phpunit": "^9.6 || ^7.5"
- },
- "type": "library",
- "autoload": {
- "files": [
- "src/functions_include.php"
- ],
- "psr-4": {
- "React\\Promise\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jan Sorgalla",
- "email": "jsorgalla@gmail.com",
- "homepage": "https://sorgalla.com/"
- },
- {
- "name": "Christian Lück",
- "email": "christian@clue.engineering",
- "homepage": "https://clue.engineering/"
- },
- {
- "name": "Cees-Jan Kiewiet",
- "email": "reactphp@ceesjankiewiet.nl",
- "homepage": "https://wyrihaximus.net/"
- },
- {
- "name": "Chris Boden",
- "email": "cboden@gmail.com",
- "homepage": "https://cboden.dev/"
- }
- ],
- "description": "A lightweight implementation of CommonJS Promises/A for PHP",
- "keywords": [
- "promise",
- "promises"
- ],
- "support": {
- "issues": "https://github.com/reactphp/promise/issues",
- "source": "https://github.com/reactphp/promise/tree/v3.3.0"
- },
- "funding": [
- {
- "url": "https://opencollective.com/reactphp",
- "type": "open_collective"
- }
- ],
- "time": "2025-08-19T18:57:03+00:00"
- },
- {
- "name": "revolt/event-loop",
- "version": "v1.0.7",
- "source": {
- "type": "git",
- "url": "https://github.com/revoltphp/event-loop.git",
- "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/09bf1bf7f7f574453efe43044b06fafe12216eb3",
- "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "ext-json": "*",
- "jetbrains/phpstorm-stubs": "^2019.3",
- "phpunit/phpunit": "^9",
- "psalm/phar": "^5.15"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Revolt\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Aaron Piotrowski",
- "email": "aaron@trowski.com"
- },
- {
- "name": "Cees-Jan Kiewiet",
- "email": "ceesjank@gmail.com"
- },
- {
- "name": "Christian Lück",
- "email": "christian@clue.engineering"
- },
- {
- "name": "Niklas Keller",
- "email": "me@kelunik.com"
- }
- ],
- "description": "Rock-solid event loop for concurrent PHP applications.",
- "keywords": [
- "async",
- "asynchronous",
- "concurrency",
- "event",
- "event-loop",
- "non-blocking",
- "scheduler"
- ],
- "support": {
- "issues": "https://github.com/revoltphp/event-loop/issues",
- "source": "https://github.com/revoltphp/event-loop/tree/v1.0.7"
- },
- "time": "2025-01-25T19:27:39+00:00"
- },
- {
- "name": "sebastian/cli-parser",
- "version": "2.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/cli-parser.git",
- "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084",
- "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "2.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library for parsing CLI options",
- "homepage": "https://github.com/sebastianbergmann/cli-parser",
- "support": {
- "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
- "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
- "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2024-03-02T07:12:49+00:00"
- },
- {
- "name": "sebastian/code-unit",
- "version": "2.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/code-unit.git",
- "reference": "a81fee9eef0b7a76af11d121767abc44c104e503"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503",
- "reference": "a81fee9eef0b7a76af11d121767abc44c104e503",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "2.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Collection of value objects that represent the PHP code units",
- "homepage": "https://github.com/sebastianbergmann/code-unit",
- "support": {
- "issues": "https://github.com/sebastianbergmann/code-unit/issues",
- "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T06:58:43+00:00"
- },
- {
- "name": "sebastian/code-unit-reverse-lookup",
- "version": "3.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
- "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Looks up which function or method a line of code belongs to",
- "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "support": {
- "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
- "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T06:59:15+00:00"
- },
- {
- "name": "sebastian/comparator",
- "version": "5.0.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e8e53097718d2b53cfb2aa859b06a41abf58c62e",
- "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-mbstring": "*",
- "php": ">=8.1",
- "sebastian/diff": "^5.0",
- "sebastian/exporter": "^5.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "5.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- }
- ],
- "description": "Provides the functionality to compare PHP values for equality",
- "homepage": "https://github.com/sebastianbergmann/comparator",
- "keywords": [
- "comparator",
- "compare",
- "equality"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/comparator/issues",
- "security": "https://github.com/sebastianbergmann/comparator/security/policy",
- "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.4"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- },
- {
- "url": "https://liberapay.com/sebastianbergmann",
- "type": "liberapay"
- },
- {
- "url": "https://thanks.dev/u/gh/sebastianbergmann",
- "type": "thanks_dev"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
- "type": "tidelift"
- }
- ],
- "time": "2025-09-07T05:25:07+00:00"
- },
- {
- "name": "sebastian/complexity",
- "version": "3.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/complexity.git",
- "reference": "68ff824baeae169ec9f2137158ee529584553799"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799",
- "reference": "68ff824baeae169ec9f2137158ee529584553799",
- "shasum": ""
- },
- "require": {
- "nikic/php-parser": "^4.18 || ^5.0",
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.2-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library for calculating the complexity of PHP code units",
- "homepage": "https://github.com/sebastianbergmann/complexity",
- "support": {
- "issues": "https://github.com/sebastianbergmann/complexity/issues",
- "security": "https://github.com/sebastianbergmann/complexity/security/policy",
- "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-12-21T08:37:17+00:00"
- },
- {
- "name": "sebastian/diff",
- "version": "5.1.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e",
- "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0",
- "symfony/process": "^6.4"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "5.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- }
- ],
- "description": "Diff implementation",
- "homepage": "https://github.com/sebastianbergmann/diff",
- "keywords": [
- "diff",
- "udiff",
- "unidiff",
- "unified diff"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/diff/issues",
- "security": "https://github.com/sebastianbergmann/diff/security/policy",
- "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2024-03-02T07:15:17+00:00"
- },
- {
- "name": "sebastian/environment",
- "version": "6.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "8074dbcd93529b357029f5cc5058fd3e43666984"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984",
- "reference": "8074dbcd93529b357029f5cc5058fd3e43666984",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "suggest": {
- "ext-posix": "*"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "6.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Provides functionality to handle HHVM/PHP environments",
- "homepage": "https://github.com/sebastianbergmann/environment",
- "keywords": [
- "Xdebug",
- "environment",
- "hhvm"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/environment/issues",
- "security": "https://github.com/sebastianbergmann/environment/security/policy",
- "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2024-03-23T08:47:14+00:00"
- },
- {
- "name": "sebastian/exporter",
- "version": "5.1.4",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "0735b90f4da94969541dac1da743446e276defa6"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6",
- "reference": "0735b90f4da94969541dac1da743446e276defa6",
- "shasum": ""
- },
- "require": {
- "ext-mbstring": "*",
- "php": ">=8.1",
- "sebastian/recursion-context": "^5.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "5.1-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Volker Dusch",
- "email": "github@wallbash.com"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
- },
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Provides the functionality to export PHP variables for visualization",
- "homepage": "https://www.github.com/sebastianbergmann/exporter",
- "keywords": [
- "export",
- "exporter"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/exporter/issues",
- "security": "https://github.com/sebastianbergmann/exporter/security/policy",
- "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- },
- {
- "url": "https://liberapay.com/sebastianbergmann",
- "type": "liberapay"
- },
- {
- "url": "https://thanks.dev/u/gh/sebastianbergmann",
- "type": "thanks_dev"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter",
- "type": "tidelift"
- }
- ],
- "time": "2025-09-24T06:09:11+00:00"
- },
- {
- "name": "sebastian/global-state",
- "version": "6.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
- "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1",
- "sebastian/object-reflector": "^3.0",
- "sebastian/recursion-context": "^5.0"
- },
- "require-dev": {
- "ext-dom": "*",
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "6.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Snapshotting of global state",
- "homepage": "https://www.github.com/sebastianbergmann/global-state",
- "keywords": [
- "global state"
- ],
- "support": {
- "issues": "https://github.com/sebastianbergmann/global-state/issues",
- "security": "https://github.com/sebastianbergmann/global-state/security/policy",
- "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2024-03-02T07:19:19+00:00"
- },
- {
- "name": "sebastian/lines-of-code",
- "version": "2.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/lines-of-code.git",
- "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0",
- "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0",
- "shasum": ""
- },
- "require": {
- "nikic/php-parser": "^4.18 || ^5.0",
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "2.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library for counting the lines of code in PHP source code",
- "homepage": "https://github.com/sebastianbergmann/lines-of-code",
- "support": {
- "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
- "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
- "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-12-21T08:38:20+00:00"
- },
- {
- "name": "sebastian/object-enumerator",
- "version": "5.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906",
- "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1",
- "sebastian/object-reflector": "^3.0",
- "sebastian/recursion-context": "^5.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "5.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Traverses array structures and object graphs to enumerate all referenced objects",
- "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "support": {
- "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
- "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T07:08:32+00:00"
- },
- {
- "name": "sebastian/object-reflector",
- "version": "3.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "24ed13d98130f0e7122df55d06c5c4942a577957"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957",
- "reference": "24ed13d98130f0e7122df55d06c5c4942a577957",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- }
- ],
- "description": "Allows reflection of object attributes, including inherited and non-public ones",
- "homepage": "https://github.com/sebastianbergmann/object-reflector/",
- "support": {
- "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
- "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T07:06:18+00:00"
- },
- {
- "name": "sebastian/recursion-context",
- "version": "5.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a",
- "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.5"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "5.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
- {
- "name": "Adam Harvey",
- "email": "aharvey@php.net"
- }
- ],
- "description": "Provides functionality to recursively process PHP variables",
- "homepage": "https://github.com/sebastianbergmann/recursion-context",
- "support": {
- "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
- "security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
- "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- },
- {
- "url": "https://liberapay.com/sebastianbergmann",
- "type": "liberapay"
- },
- {
- "url": "https://thanks.dev/u/gh/sebastianbergmann",
- "type": "thanks_dev"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
- "type": "tidelift"
- }
- ],
- "time": "2025-08-10T07:50:56+00:00"
- },
- {
- "name": "sebastian/type",
- "version": "4.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/type.git",
- "reference": "462699a16464c3944eefc02ebdd77882bd3925bf"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf",
- "reference": "462699a16464c3944eefc02ebdd77882bd3925bf",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^10.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "4.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Collection of value objects that represent the types of the PHP type system",
- "homepage": "https://github.com/sebastianbergmann/type",
- "support": {
- "issues": "https://github.com/sebastianbergmann/type/issues",
- "source": "https://github.com/sebastianbergmann/type/tree/4.0.0"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-03T07:10:45+00:00"
- },
- {
- "name": "sebastian/version",
- "version": "4.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/sebastianbergmann/version.git",
- "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17",
- "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "4.0-dev"
- }
- },
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
- }
- ],
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
- "homepage": "https://github.com/sebastianbergmann/version",
- "support": {
- "issues": "https://github.com/sebastianbergmann/version/issues",
- "source": "https://github.com/sebastianbergmann/version/tree/4.0.1"
- },
- "funding": [
- {
- "url": "https://github.com/sebastianbergmann",
- "type": "github"
- }
- ],
- "time": "2023-02-07T11:34:05+00:00"
- },
- {
- "name": "seld/jsonlint",
- "version": "1.11.0",
- "source": {
- "type": "git",
- "url": "https://github.com/Seldaek/jsonlint.git",
- "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/1748aaf847fc731cfad7725aec413ee46f0cc3a2",
- "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2",
- "shasum": ""
- },
- "require": {
- "php": "^5.3 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1.11",
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13"
- },
- "bin": [
- "bin/jsonlint"
- ],
- "type": "library",
- "autoload": {
- "psr-4": {
- "Seld\\JsonLint\\": "src/Seld/JsonLint/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "https://seld.be"
- }
- ],
- "description": "JSON Linter",
- "keywords": [
- "json",
- "linter",
- "parser",
- "validator"
- ],
- "support": {
- "issues": "https://github.com/Seldaek/jsonlint/issues",
- "source": "https://github.com/Seldaek/jsonlint/tree/1.11.0"
- },
- "funding": [
- {
- "url": "https://github.com/Seldaek",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint",
- "type": "tidelift"
- }
- ],
- "time": "2024-07-11T14:55:45+00:00"
- },
- {
- "name": "seld/phar-utils",
- "version": "1.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/Seldaek/phar-utils.git",
- "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/ea2f4014f163c1be4c601b9b7bd6af81ba8d701c",
- "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Seld\\PharUtils\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be"
- }
- ],
- "description": "PHAR file format utilities, for when PHP phars you up",
- "keywords": [
- "phar"
- ],
- "support": {
- "issues": "https://github.com/Seldaek/phar-utils/issues",
- "source": "https://github.com/Seldaek/phar-utils/tree/1.2.1"
- },
- "time": "2022-08-31T10:31:18+00:00"
- },
- {
- "name": "seld/signal-handler",
- "version": "2.0.2",
- "source": {
- "type": "git",
- "url": "https://github.com/Seldaek/signal-handler.git",
- "reference": "04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98",
- "reference": "04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2.0"
- },
- "require-dev": {
- "phpstan/phpstan": "^1",
- "phpstan/phpstan-deprecation-rules": "^1.0",
- "phpstan/phpstan-phpunit": "^1",
- "phpstan/phpstan-strict-rules": "^1.3",
- "phpunit/phpunit": "^7.5.20 || ^8.5.23",
- "psr/log": "^1 || ^2 || ^3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "2.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Seld\\Signal\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "Simple unix signal handler that silently fails where signals are not supported for easy cross-platform development",
- "keywords": [
- "posix",
- "sigint",
- "signal",
- "sigterm",
- "unix"
- ],
- "support": {
- "issues": "https://github.com/Seldaek/signal-handler/issues",
- "source": "https://github.com/Seldaek/signal-handler/tree/2.0.2"
- },
- "time": "2023-09-03T09:24:00+00:00"
- },
- {
- "name": "spatie/array-to-xml",
- "version": "3.4.0",
- "source": {
- "type": "git",
- "url": "https://github.com/spatie/array-to-xml.git",
- "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67",
- "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "php": "^8.0"
- },
- "require-dev": {
- "mockery/mockery": "^1.2",
- "pestphp/pest": "^1.21",
- "spatie/pest-plugin-snapshots": "^1.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "3.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Spatie\\ArrayToXml\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Freek Van der Herten",
- "email": "freek@spatie.be",
- "homepage": "https://freek.dev",
- "role": "Developer"
- }
- ],
- "description": "Convert an array to xml",
- "homepage": "https://github.com/spatie/array-to-xml",
- "keywords": [
- "array",
- "convert",
- "xml"
- ],
- "support": {
- "source": "https://github.com/spatie/array-to-xml/tree/3.4.0"
- },
- "funding": [
- {
- "url": "https://spatie.be/open-source/support-us",
- "type": "custom"
- },
- {
- "url": "https://github.com/spatie",
- "type": "github"
- }
- ],
- "time": "2024-12-16T12:45:15+00:00"
- },
- {
- "name": "squizlabs/php_codesniffer",
- "version": "4.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
- "reference": "0525c73950de35ded110cffafb9892946d7771b5"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0525c73950de35ded110cffafb9892946d7771b5",
- "reference": "0525c73950de35ded110cffafb9892946d7771b5",
- "shasum": ""
- },
- "require": {
- "ext-simplexml": "*",
- "ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": ">=7.2.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.4.0 || ^9.3.4 || ^10.5.32 || 11.3.3 - 11.5.28 || ^11.5.31"
- },
- "bin": [
- "bin/phpcbf",
- "bin/phpcs"
- ],
- "type": "library",
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Greg Sherwood",
- "role": "Former lead"
- },
- {
- "name": "Juliette Reinders Folmer",
- "role": "Current lead"
- },
- {
- "name": "Contributors",
- "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
- }
- ],
- "description": "PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.",
- "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
- "keywords": [
- "phpcs",
- "standards",
- "static analysis"
- ],
- "support": {
- "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
- "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
- "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
- "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
- },
- "funding": [
- {
- "url": "https://github.com/PHPCSStandards",
- "type": "github"
- },
- {
- "url": "https://github.com/jrfnl",
- "type": "github"
- },
- {
- "url": "https://opencollective.com/php_codesniffer",
- "type": "open_collective"
- },
- {
- "url": "https://thanks.dev/u/gh/phpcsstandards",
- "type": "thanks_dev"
- }
- ],
- "time": "2025-11-10T16:43:36+00:00"
- },
- {
- "name": "symfony/console",
- "version": "v7.3.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/console.git",
- "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
- "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
- "shasum": ""
- },
- "require": {
- "php": ">=8.2",
- "symfony/deprecation-contracts": "^2.5|^3",
- "symfony/polyfill-mbstring": "~1.0",
- "symfony/service-contracts": "^2.5|^3",
- "symfony/string": "^7.2"
- },
- "conflict": {
- "symfony/dependency-injection": "<6.4",
- "symfony/dotenv": "<6.4",
- "symfony/event-dispatcher": "<6.4",
- "symfony/lock": "<6.4",
- "symfony/process": "<6.4"
- },
- "provide": {
- "psr/log-implementation": "1.0|2.0|3.0"
- },
- "require-dev": {
- "psr/log": "^1|^2|^3",
- "symfony/config": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/lock": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/stopwatch": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Console\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Eases the creation of beautiful and testable command line interfaces",
- "homepage": "https://symfony.com",
- "keywords": [
- "cli",
- "command-line",
- "console",
- "terminal"
- ],
- "support": {
- "source": "https://github.com/symfony/console/tree/v7.3.4"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-09-22T15:31:00+00:00"
- },
- {
- "name": "symfony/deprecation-contracts",
- "version": "v3.6.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62",
- "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/contracts",
- "name": "symfony/contracts"
- },
- "branch-alias": {
- "dev-main": "3.6-dev"
- }
- },
- "autoload": {
- "files": [
- "function.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "A generic function and convention to trigger deprecation notices",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2024-09-25T14:21:43+00:00"
- },
- {
- "name": "symfony/filesystem",
- "version": "v7.3.2",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/filesystem.git",
- "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd",
- "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd",
- "shasum": ""
- },
- "require": {
- "php": ">=8.2",
- "symfony/polyfill-ctype": "~1.8",
- "symfony/polyfill-mbstring": "~1.8"
- },
- "require-dev": {
- "symfony/process": "^6.4|^7.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Filesystem\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Provides basic utilities for the filesystem",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/filesystem/tree/v7.3.2"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-07-07T08:17:47+00:00"
- },
- {
- "name": "symfony/finder",
- "version": "v7.3.2",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/finder.git",
- "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe",
- "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe",
- "shasum": ""
- },
- "require": {
- "php": ">=8.2"
- },
- "require-dev": {
- "symfony/filesystem": "^6.4|^7.0"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Finder\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Finds files and directories via an intuitive fluent interface",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/finder/tree/v7.3.2"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-07-15T13:41:35+00:00"
- },
- {
- "name": "symfony/polyfill-ctype",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
- "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "provide": {
- "ext-ctype": "*"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2024-09-09T11:45:10+00:00"
- },
- {
- "name": "symfony/polyfill-intl-grapheme",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70",
- "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "suggest": {
- "ext-intl": "For best performance"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for intl's grapheme_* functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "grapheme",
- "intl",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-06-27T09:58:17+00:00"
- },
- {
- "name": "symfony/polyfill-intl-normalizer",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "3833d7255cc303546435cb650316bff708a1c75c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
- "reference": "3833d7255cc303546435cb650316bff708a1c75c",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "suggest": {
- "ext-intl": "For best performance"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for intl's Normalizer class and related functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "intl",
- "normalizer",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2024-09-09T11:45:10+00:00"
- },
- {
- "name": "symfony/polyfill-mbstring",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
- "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
- "shasum": ""
- },
- "require": {
- "ext-iconv": "*",
- "php": ">=7.2"
- },
- "provide": {
- "ext-mbstring": "*"
- },
- "suggest": {
- "ext-mbstring": "For best performance"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2024-12-23T08:48:59+00:00"
- },
- {
- "name": "symfony/polyfill-php73",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb",
- "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php73\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2024-09-09T11:45:10+00:00"
- },
- {
- "name": "symfony/polyfill-php80",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
- "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php80\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ion Bazan",
- "email": "ion.bazan@gmail.com"
- },
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-01-02T08:10:11+00:00"
- },
- {
- "name": "symfony/polyfill-php81",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php81.git",
- "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
- "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php81\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2024-09-09T11:45:10+00:00"
- },
- {
- "name": "symfony/polyfill-php84",
- "version": "v1.33.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php84.git",
- "reference": "d8ced4d875142b6a7426000426b8abc631d6b191"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191",
- "reference": "d8ced4d875142b6a7426000426b8abc631d6b191",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/polyfill",
- "name": "symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php84\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-06-24T13:30:11+00:00"
- },
- {
- "name": "symfony/process",
- "version": "v7.3.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b",
- "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b",
- "shasum": ""
- },
- "require": {
- "php": ">=8.2"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Process\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Executes commands in sub-processes",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/process/tree/v7.3.4"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-09-11T10:12:26+00:00"
- },
- {
- "name": "symfony/service-contracts",
- "version": "v3.6.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/service-contracts.git",
- "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
- "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
- "shasum": ""
- },
- "require": {
- "php": ">=8.1",
- "psr/container": "^1.1|^2.0",
- "symfony/deprecation-contracts": "^2.5|^3"
- },
- "conflict": {
- "ext-psr": "<1.1|>=2"
- },
- "type": "library",
- "extra": {
- "thanks": {
- "url": "https://github.com/symfony/contracts",
- "name": "symfony/contracts"
- },
- "branch-alias": {
- "dev-main": "3.6-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Contracts\\Service\\": ""
- },
- "exclude-from-classmap": [
- "/Test/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Generic abstractions related to writing services",
- "homepage": "https://symfony.com",
- "keywords": [
- "abstractions",
- "contracts",
- "decoupling",
- "interfaces",
- "interoperability",
- "standards"
- ],
- "support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.6.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-04-25T09:37:31+00:00"
- },
- {
- "name": "symfony/string",
- "version": "v7.3.4",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/string.git",
- "reference": "f96476035142921000338bad71e5247fbc138872"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872",
- "reference": "f96476035142921000338bad71e5247fbc138872",
- "shasum": ""
- },
- "require": {
- "php": ">=8.2",
- "symfony/polyfill-ctype": "~1.8",
- "symfony/polyfill-intl-grapheme": "~1.0",
- "symfony/polyfill-intl-normalizer": "~1.0",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "conflict": {
- "symfony/translation-contracts": "<2.5"
- },
- "require-dev": {
- "symfony/emoji": "^7.1",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/intl": "^6.4|^7.0",
- "symfony/translation-contracts": "^2.5|^3.0",
- "symfony/var-exporter": "^6.4|^7.0"
- },
- "type": "library",
- "autoload": {
- "files": [
- "Resources/functions.php"
- ],
- "psr-4": {
- "Symfony\\Component\\String\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
- "homepage": "https://symfony.com",
- "keywords": [
- "grapheme",
- "i18n",
- "string",
- "unicode",
- "utf-8",
- "utf8"
- ],
- "support": {
- "source": "https://github.com/symfony/string/tree/v7.3.4"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://github.com/nicolas-grekas",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2025-09-11T14:36:48+00:00"
- },
- {
- "name": "theseer/tokenizer",
- "version": "1.2.3",
- "source": {
- "type": "git",
- "url": "https://github.com/theseer/tokenizer.git",
- "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
- "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
- "shasum": ""
- },
- "require": {
- "ext-dom": "*",
- "ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": "^7.2 || ^8.0"
- },
- "type": "library",
- "autoload": {
- "classmap": [
- "src/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
- }
- ],
- "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
- "support": {
- "issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
- },
- "funding": [
- {
- "url": "https://github.com/theseer",
- "type": "github"
- }
- ],
- "time": "2024-03-03T12:36:25+00:00"
- },
- {
- "name": "vimeo/psalm",
- "version": "6.14.2",
- "source": {
- "type": "git",
- "url": "https://github.com/vimeo/psalm.git",
- "reference": "bbd217fc98c0daa0a13aea2a7f119d03ba3fc9a0"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/vimeo/psalm/zipball/bbd217fc98c0daa0a13aea2a7f119d03ba3fc9a0",
- "reference": "bbd217fc98c0daa0a13aea2a7f119d03ba3fc9a0",
- "shasum": ""
- },
- "require": {
- "amphp/amp": "^3",
- "amphp/byte-stream": "^2",
- "amphp/parallel": "^2.3",
- "composer-runtime-api": "^2",
- "composer/semver": "^1.4 || ^2.0 || ^3.0",
- "composer/xdebug-handler": "^2.0 || ^3.0",
- "danog/advanced-json-rpc": "^3.1",
- "dnoegel/php-xdg-base-dir": "^0.1.1",
- "ext-ctype": "*",
- "ext-dom": "*",
- "ext-json": "*",
- "ext-libxml": "*",
- "ext-mbstring": "*",
- "ext-simplexml": "*",
- "ext-tokenizer": "*",
- "felixfbecker/language-server-protocol": "^1.5.3",
- "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0",
- "netresearch/jsonmapper": "^5.0",
- "nikic/php-parser": "^5.0.0",
- "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/polyfill-php84": "^1.31.0"
- },
- "provide": {
- "psalm/psalm": "self.version"
- },
- "require-dev": {
- "amphp/phpunit-util": "^3",
- "bamarni/composer-bin-plugin": "^1.4",
- "brianium/paratest": "^6.9",
- "danog/class-finder": "^0.4.8",
- "dg/bypass-finals": "^1.5",
- "ext-curl": "*",
- "mockery/mockery": "^1.5",
- "nunomaduro/mock-final-classes": "^1.1",
- "php-parallel-lint/php-parallel-lint": "^1.2",
- "phpstan/phpdoc-parser": "^1.6",
- "phpunit/phpunit": "^9.6",
- "psalm/plugin-mockery": "^1.1",
- "psalm/plugin-phpunit": "^0.19",
- "slevomat/coding-standard": "^8.4",
- "squizlabs/php_codesniffer": "^3.6",
- "symfony/process": "^6.0 || ^7.0"
- },
- "suggest": {
- "ext-curl": "In order to send data to shepherd",
- "ext-igbinary": "^2.0.5 is required, used to serialize caching data"
- },
- "bin": [
- "psalm",
- "psalm-language-server",
- "psalm-plugin",
- "psalm-refactor",
- "psalm-review",
- "psalter"
- ],
- "type": "project",
- "extra": {
- "branch-alias": {
- "dev-1.x": "1.x-dev",
- "dev-2.x": "2.x-dev",
- "dev-3.x": "3.x-dev",
- "dev-4.x": "4.x-dev",
- "dev-5.x": "5.x-dev",
- "dev-6.x": "6.x-dev",
- "dev-master": "7.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psalm\\": "src/Psalm/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Matthew Brown"
- },
- {
- "name": "Daniil Gentili",
- "email": "daniil@daniil.it"
- }
- ],
- "description": "A static analysis tool for finding errors in PHP applications",
- "keywords": [
- "code",
- "inspection",
- "php",
- "static analysis"
- ],
- "support": {
- "docs": "https://psalm.dev/docs",
- "issues": "https://github.com/vimeo/psalm/issues",
- "source": "https://github.com/vimeo/psalm"
- },
- "time": "2025-12-11T08:58:52+00:00"
- },
- {
- "name": "webmozart/assert",
- "version": "1.11.0",
- "source": {
- "type": "git",
- "url": "https://github.com/webmozarts/assert.git",
- "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
- "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
- "shasum": ""
- },
- "require": {
- "ext-ctype": "*",
- "php": "^7.2 || ^8.0"
- },
- "conflict": {
- "phpstan/phpstan": "<0.12.20",
- "vimeo/psalm": "<4.6.1 || 4.6.2"
- },
- "require-dev": {
- "phpunit/phpunit": "^8.5.13"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.10-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Webmozart\\Assert\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@gmail.com"
- }
- ],
- "description": "Assertions to validate method input/output with nice error messages.",
- "keywords": [
- "assert",
- "check",
- "validate"
- ],
- "support": {
- "issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/1.11.0"
- },
- "time": "2022-06-03T18:03:27+00:00"
- }
- ],
- "aliases": [],
- "minimum-stability": "dev",
- "stability-flags": {},
- "prefer-stable": true,
- "prefer-lowest": false,
- "platform": {
- "php": "^8.1"
- },
- "platform-dev": {
- "ext-ctype": "*"
- },
- "plugin-api-version": "2.9.0"
-}
diff --git a/phpbench.json b/phpbench.json
new file mode 100644
index 0000000..c73d2a1
--- /dev/null
+++ b/phpbench.json
@@ -0,0 +1,27 @@
+{
+ "$schema": "./vendor/phpbench/phpbench/phpbench.schema.json",
+ "runner.bootstrap": "vendor/autoload.php",
+ "runner.path": "tests/benchmark",
+ "runner.php_config": {
+ "memory_limit": "1G"
+ },
+ "report.generators": {
+ "default": {
+ "extends": "aggregate",
+ "cols": [
+ "benchmark",
+ "subject",
+ "set",
+ "revs",
+ "its",
+ "mem_peak",
+ "best",
+ "mean",
+ "mode",
+ "worst",
+ "stdev",
+ "rstdev"
+ ]
+ }
+ }
+}
diff --git a/phpcs.xml b/phpcs.xml
index c91dea3..47abfb9 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,7 +1,387 @@
+ Coding standard for Visus CUID2 PHP library.
+
+
+
+
+
+
src
+ tests
+
*/vendor/*
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+ error
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5
+
+
+
diff --git a/phpstan.neon b/phpstan.neon
index 29a11a9..049fe2d 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,5 +1,12 @@
+includes:
+ - vendor/phpstan/phpstan/conf/bleedingEdge.neon
+
parameters:
+ tmpDir: ./build/cache/phpstan
level: max
+ treatPhpDocTypesAsCertain: false
paths:
- src
- - tests
\ No newline at end of file
+ - tests
+ excludePaths:
+ - vendor
diff --git a/phpunit.xml b/phpunit.xml
index 7a7ee75..93a561e 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,22 +1,16 @@
+ cacheDirectory=".phpunit.cache"
+ failOnWarning="true"
+ failOnRisky="true"
+ beStrictAboutOutputDuringTests="true">
-
+
tests
-
-
-
-
-
-
-
-
-
src
@@ -25,7 +19,7 @@
src/compat.php
-
-
-
+
+
+
diff --git a/psalm.xml b/psalm.xml
deleted file mode 100644
index 5d7adfd..0000000
--- a/psalm.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/sonar-project.properties b/sonar-project.properties
index d29d698..e90a0a5 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -6,5 +6,5 @@ sonar.projectBaseDir=.
sonar.sources=src
sonar.tests=tests
-sonar.php.coverage.reportPaths=build/logs/clover.xml
-sonar.php.tests.reportPath=build/logs/execution.xml
\ No newline at end of file
+sonar.php.coverage.reportPaths=build/coverage/xml/clover.xml
+sonar.php.tests.reportPath=build/coverage/xml/execution.xml
diff --git a/src/Counter.php b/src/Counter.php
index acf4aa4..b2b4c08 100644
--- a/src/Counter.php
+++ b/src/Counter.php
@@ -5,66 +5,129 @@
namespace Visus\Cuid2;
use Exception;
+use Random\Engine\Secure;
+use Random\Randomizer;
/**
- * Singleton responsible for keeping track of iterations.
+ * Singleton responsible for maintaining a monotonically increasing counter for CUID2 generation.
+ *
+ * This class prevents collisions when generating multiple CUIDs in rapid succession within the same
+ * process. The counter is initialized with a cryptographically secure random value and increments
+ * with each CUID generated.
+ *
+ * The counter uses a bias-free random initialization algorithm to ensure uniform distribution
+ * within the RANGE (0 to 476782367). When the counter reaches RANGE, it wraps back to 0 to
+ * prevent integer overflow in long-running processes.
+ *
+ * Thread Safety:
+ * - In PHP, each request/process maintains its own singleton instance
+ * - The singleton pattern ensures consistency within a single process lifecycle
+ * - Different processes will have different counter values (by design)
+ *
+ * Singleton Protections:
+ * - Cannot be cloned (__clone is private)
+ * - Cannot be unserialized (__wakeup throws exception)
+ * - Cannot be directly instantiated (constructor is private)
+ *
+ * @internal This class is internal to the CUID2 library and should not be used directly.
*
- * @internal
* @psalm-internal Visus\Cuid2
*/
final class Counter
{
/**
* The range for the counter value.
+ *
* 476782367 is chosen to provide a large enough space for unique values while fitting within
* the constraints of the CUID2 specification. This value is derived from the maximum safe
* integer range for the algorithm, ensuring uniform distribution and minimizing bias when
- * generating random values. See https://github.com/paralleldrive/cuid2 for details.
+ * generating random values.
+ *
+ * The counter wraps back to 0 when this value is reached to prevent integer overflow.
+ *
+ * @see https://github.com/paralleldrive/cuid2 CUID2 specification
*/
private const RANGE = 476782367;
- private const MAX_ATTEMPTS = 1000;
-
+ /**
+ * The singleton instance.
+ */
private static ?Counter $instance = null;
/**
+ * The current counter value.
+ *
+ * Initialized with a cryptographically secure random value in the range [0, RANGE) and
+ * increments with each call to getNextValue(). Wraps back to 0 when RANGE is reached.
+ *
* @psalm-readonly-allow-private-mutation
*/
private int $value;
+ /**
+ * Initializes the counter with a cryptographically secure random value.
+ *
+ * Uses PHP 8.2's Random extension with the Secure engine, which provides
+ * cryptographically secure random number generation with automatic bias-free
+ * sampling. This eliminates the need for manual rejection sampling algorithms.
+ *
+ * The Randomizer handles:
+ * - CSPRNG (Cryptographically Secure Pseudo-Random Number Generator)
+ * - Bias-free integer generation via internal rejection sampling
+ * - Uniform distribution within the specified range
+ *
+ * @throws Exception If the random source is unavailable (extremely rare in PHP 8.2+).
+ */
private function __construct()
{
- $max = PHP_INT_MAX - (PHP_INT_MAX % self::RANGE);
-
- // Fallback: If the bias-free range is insufficient (i.e., max is less than half of PHP_INT_MAX),
- // use a simple modulus operation, which may introduce bias but is acceptable as a last resort.
- // The threshold of half PHP_INT_MAX is chosen because, for values of $max below this,
- // the probability of bias in the modulus operation increases significantly, and the
- // number of attempts required for bias-free sampling may become impractically large.
- // This is a pragmatic balance between statistical correctness and performance.
- if ($max < PHP_INT_MAX / 2) {
- $this->value = random_int(0, PHP_INT_MAX) % self::RANGE;
- return;
- }
-
- $attempts = -1;
-
- do {
- if (++$attempts > self::MAX_ATTEMPTS) {
- $this->value = random_int(0, PHP_INT_MAX) % self::RANGE;
- return;
- }
+ $randomizer = new Randomizer(new Secure());
+ $this->value = $randomizer->getInt(0, self::RANGE - 1);
+ }
- $randomInt = random_int(0, PHP_INT_MAX);
- } while ($randomInt >= $max);
+ /**
+ * Prevents cloning of the singleton instance.
+ *
+ * Cloning would break the singleton pattern and could lead to inconsistent counter
+ * states, potentially causing CUID collisions. This method is intentionally private
+ * and empty to prevent cloning attempts.
+ *
+ * @codeCoverageIgnore
+ */
+ private function __clone(): void
+ {
+ // Prevent cloning
+ }
- $this->value = $randomInt % self::RANGE;
+ /**
+ * Prevents unserialization of the singleton instance.
+ *
+ * Unserializing would create a new instance with a potentially outdated counter value,
+ * breaking the singleton pattern and risking CUID collisions. This method throws an
+ * exception if unserialization is attempted.
+ *
+ * @throws InvalidOperationException Always thrown to prevent unserialization.
+ */
+ public function __wakeup(): void
+ {
+ throw new InvalidOperationException('Cannot unserialize singleton');
}
/**
- * Gets the current instance.
+ * Gets or creates the singleton Counter instance.
+ *
+ * This method implements lazy initialization - the Counter is only created when first
+ * accessed. Subsequent calls return the same instance, ensuring a consistent counter
+ * value throughout the process lifecycle.
+ *
+ * Usage:
+ * ```php
+ * $counter = Counter::getInstance();
+ * $value = $counter->getNextValue();
+ * ```
+ *
+ * @return Counter The singleton Counter instance.
*
- * @return Counter
+ * @throws Exception If the random source is unavailable during first initialization.
*/
public static function getInstance(): Counter
{
@@ -72,12 +135,36 @@ public static function getInstance(): Counter
}
/**
- * Gets the next value from the current instance.
+ * Returns the current counter value and increments it for the next call.
*
- * @return int
+ * This method is the core of collision prevention in CUID2 generation. Each call
+ * returns a unique value within the current process, ensuring CUIDs generated in
+ * rapid succession have different counter components.
+ *
+ * The counter automatically wraps back to 0 when it reaches RANGE (476782367),
+ * preventing integer overflow in long-running processes while maintaining uniqueness
+ * through other CUID components (timestamp, random, fingerprint).
+ *
+ * Behavior:
+ * - Returns current value
+ * - Increments internal counter
+ * - Wraps to 0 at RANGE boundary
+ *
+ * Usage:
+ * ```php
+ * $counter = Counter::getInstance();
+ * $val1 = $counter->getNextValue(); // e.g., 123456
+ * $val2 = $counter->getNextValue(); // e.g., 123457
+ * $val3 = $counter->getNextValue(); // e.g., 123458
+ * ```
+ *
+ * @return int The current counter value before incrementing (range: 0 to RANGE-1).
*/
public function getNextValue(): int
{
- return $this->value++;
+ $value = $this->value;
+ $this->value = ($this->value + 1) % self::RANGE;
+
+ return $value;
}
}
diff --git a/src/Cuid2.php b/src/Cuid2.php
index 4448206..2cb9759 100644
--- a/src/Cuid2.php
+++ b/src/Cuid2.php
@@ -4,7 +4,6 @@
namespace Visus\Cuid2;
-use DateTime;
use Exception;
use JsonSerializable;
use MathPHP\Exception\BadParameterException;
@@ -12,66 +11,133 @@
use OutOfRangeException;
use Override;
+/**
+ * Generates collision-resistant, URL-safe unique identifiers (CUID2).
+ *
+ * This class implements the CUID2 specification to generate unique, sortable identifiers
+ * that are more secure and collision-resistant than traditional UUIDs. Each CUID consists of:
+ * - Random lowercase letter prefix (a-z)
+ * - Timestamp in milliseconds (collision prevention across time)
+ * - Monotonic counter (collision prevention in rapid succession)
+ * - Machine/process fingerprint (uniqueness across machines)
+ * - Cryptographically secure random data
+ *
+ * All components are hashed with SHA3-512 and converted to base36 for the final identifier.
+ *
+ * Performance Characteristics:
+ * - CUID value generated immediately during construction
+ * - Value cached for zero-overhead repeated access
+ * - Binary data stored directly (no pack/unpack overhead)
+ * - High-resolution timestamp using hrtime()
+ * - Immutable once constructed
+ *
+ * Example:
+ * ```php
+ * $cuid = new Cuid2(); // Default 24 characters
+ * $short = new Cuid2(10); // Shorter 10 character ID
+ * echo $cuid; // e.g., "tz4a98xxat96iws9zmbrgj3a"
+ * ```
+ *
+ * @see https://github.com/paralleldrive/cuid2 CUID2 specification
+ */
final class Cuid2 implements JsonSerializable
{
+ /**
+ * Base36 alphabet used for encoding (0-9, a-z).
+ */
public const BASE36_ALPHANUMERIC = '0123456789abcdefghijklmnopqrstuvwxyz';
/**
+ * Cached list of available hash algorithms.
+ *
* @var array|null
*/
private static ?array $algorithmsCache = null;
+ /**
+ * Cached result of SHA3-512 algorithm support check.
+ */
private static ?bool $isAlgorithmSupported = null;
+ /**
+ * Monotonic counter value for this CUID (prevents rapid-succession collisions).
+ */
private readonly int $counter;
/**
- * @var array
+ * Machine/process fingerprint as binary data (ensures uniqueness across machines).
*/
- private readonly array $fingerprint;
+ private readonly string $fingerprint;
/**
+ * Configured length of the CUID string.
+ *
* @var int<1, max>
*/
private readonly int $length;
+ /**
+ * Random lowercase letter prefix (a-z).
+ */
private readonly string $prefix;
/**
- * @var array
+ * Cryptographically secure random bytes.
*/
- private readonly array $random;
+ private readonly string $random;
+ /**
+ * Timestamp in milliseconds when this CUID was created.
+ */
private readonly int $timestamp;
/**
- * Initializes a new instance of Cuid2.
+ * The final rendered CUID string value (cached for performance).
+ */
+ private readonly string $value;
+
+ /**
+ * Initializes a new CUID2 instance.
+ *
+ * Generates all components (timestamp, counter, fingerprint, random data) and immediately
+ * renders the final CUID string for predictable performance and efficient repeated access.
*
- * @param int $maxLength The maximum string length value of the CUID.
- * @throws OutOfRangeException The value of $maxLength was less than 4 or greater than 32.
- * @throws Exception
+ * @param int $maxLength Total length of the CUID string (4-32 characters, default 24).
+ *
+ * @throws OutOfRangeException If $maxLength is less than 4 or greater than 32.
+ * @throws Exception If random byte generation fails (extremely rare).
+ * @throws BadParameterException If base conversion fails (should never occur).
*/
public function __construct(int $maxLength = 24)
{
if ($maxLength < 4 || $maxLength > 32) {
- throw new OutOfRangeException("maxLength: cannot be less than 4 or greater than 32.");
+ throw new OutOfRangeException('maxLength: cannot be less than 4 or greater than 32.');
}
+ /** @phpstan-var int<4, 32> $maxLength */
$this->length = $maxLength;
+ $this->timestamp = self::generateTimestamp();
$this->counter = Counter::getInstance()->getNextValue();
-
$this->fingerprint = Fingerprint::getInstance()->getValue();
+ $this->random = self::generateRandom($maxLength);
$this->prefix = chr(random_int(97, 122));
- $this->random = self::generateRandom();
- $this->timestamp = self::generateTimestamp();
+
+ // Generate value immediately for consistent performance characteristics
+ $this->value = $this->render();
}
/**
- * Generates a new CUID2.
+ * Static factory method to generate a new CUID2.
+ *
+ * Convenience method equivalent to `new Cuid2($maxLength)`.
+ *
+ * @param int $maxLength Total length of the CUID string (4-32 characters, default 24).
+ *
+ * @return Cuid2 A new CUID2 instance.
*
- * @param int $maxLength
- * @return Cuid2
- * @throws Exception
+ * @throws OutOfRangeException If $maxLength is less than 4 or greater than 32.
+ * @throws Exception If random byte generation fails (extremely rare).
+ * @throws BadParameterException If base conversion fails (should never occur).
*/
public static function generate(int $maxLength = 24): Cuid2
{
@@ -79,96 +145,151 @@ public static function generate(int $maxLength = 24): Cuid2
}
/**
- * Validates whether the given string is a valid CUID2 identifier.
+ * Validates whether a string conforms to the CUID2 format.
*
- * Function does not guarantee that the provided value is a CUID2 generated by this library,
- * only that it conforms to the CUID2 format.
+ * Performs format validation only - checks length and character pattern.
+ * Does NOT verify the string was actually generated by this library.
*
- * @param string $id The CUID2 identifier to validate.
- * @param int|null $expectedLength The expected length of the CUID2 identifier.
- * If null, lengths of 4 to 32 characters are checked.
+ * Format requirements:
+ * - First character: lowercase letter (a-z)
+ * - Remaining characters: lowercase alphanumeric (a-z, 0-9)
+ * - Total length: 4-32 characters
*
- * @return bool True if the identifier is valid, false otherwise.
+ * @param string $id The string to validate.
+ * @param int|null $expectedLength Optional expected length for strict validation.
+ * If null, any length between 4-32 is accepted.
+ *
+ * @return bool True if the string matches CUID2 format, false otherwise.
*/
public static function isValid(string $id, ?int $expectedLength = null): bool
{
$length = strlen($id);
- $isLengthValid = ($length >= 4 && $length <= 32) &&
- ($expectedLength === null ||
- ($expectedLength >= 4 && $expectedLength <= 32 && $length === $expectedLength));
+ // Validate all length constraints in one check
+ if (
+ $length < 4 || $length > 32 ||
+ ($expectedLength !== null && ($expectedLength < 4 || $expectedLength > 32 || $length !== $expectedLength))
+ ) {
+ return false;
+ }
- if (!$isLengthValid) {
+ // Fast character-by-character validation
+ // First character must be lowercase letter
+ if ($id[0] < 'a' || $id[0] > 'z') {
return false;
}
- $pattern = $expectedLength !== null
- ? sprintf('/^[a-z][a-z0-9]{%d}$/', $expectedLength - 1)
- : '/^[a-z][a-z0-9]{3,31}$/';
+ // Remaining characters must be lowercase alphanumeric
+ $validChars = true;
+ for ($i = 1; $i < $length; $i++) {
+ $char = $id[$i];
+ $isDigit = $char >= '0' && $char <= '9';
+ $isLowerLetter = $char >= 'a' && $char <= 'z';
+
+ if (!$isDigit && !$isLowerLetter) {
+ $validChars = false;
- return preg_match($pattern, $id) === 1;
+ break;
+ }
+ }
+
+ return $validChars;
}
/**
- * @throws Exception
+ * Returns the CUID string when the object is used in string context.
+ *
+ * @return string The cached CUID string value.
*/
public function __toString(): string
{
- return $this->render();
+ return $this->value;
}
/**
- * @return array
- * @throws Exception
+ * Returns the CUID string representation.
+ *
+ * @return string The cached CUID string value.
*/
- private function generateRandom(): array
+ public function toString(): string
{
- $result = unpack('C*', random_bytes($this->length));
- return $result === false ? [] : $result;
+ return $this->value;
}
- private static function generateTimestamp(): int
+ /**
+ * Specifies data to be serialized to JSON.
+ *
+ * @return string The CUID string value for JSON encoding.
+ */
+ #[Override]
+ public function jsonSerialize(): string
{
- return (int) (new DateTime())->format('Uv');
+ return $this->value;
}
/**
- * @throws Exception
+ * Generates cryptographically secure random bytes.
+ *
+ * Uses PHP's random_bytes() which provides CSPRNG (Cryptographically Secure
+ * Pseudo-Random Number Generator) for high-quality entropy.
+ *
+ * @param int<1, max> $length Number of random bytes to generate.
+ *
+ * @return string Binary string of random bytes.
+ *
+ * @throws Exception If an appropriate source of randomness cannot be found.
*/
- public function toString(): string
+ private static function generateRandom(int $length): string
{
- return $this->render();
+ return random_bytes($length);
}
/**
- * @inheritdoc
- * @throws Exception
+ * Generates current timestamp in milliseconds.
+ *
+ * Uses hrtime() high-resolution monotonic timer for better performance and precision
+ * compared to DateTime object creation. The monotonic clock is not affected by system
+ * time adjustments.
+ *
+ * @return int Current timestamp in milliseconds since an arbitrary epoch.
*/
- #[Override]
- public function jsonSerialize(): string
+ private static function generateTimestamp(): int
{
- return $this->render();
+ return (int) (hrtime(as_number: true) / 1_000_000);
}
/**
- * @throws Exception
- * @throws BadParameterException
+ * Renders the CUID2 by hashing all components and converting to base36.
+ *
+ * Process:
+ * 1. Verifies SHA3-512 algorithm support
+ * 2. Initializes SHA3-512 hash context
+ * 3. Updates hash with timestamp, counter, random bytes, and fingerprint (binary data)
+ * 4. Finalizes hash to get base16 (hex) string
+ * 5. Converts base16 to base36 using GMP (preferred) or math-php fallback
+ * 6. Prepends random letter prefix and truncates to requested length
+ *
+ * @return string The final CUID2 identifier string.
+ *
+ * @throws InvalidOperationException If SHA3-512 algorithm is not supported.
+ * @throws BadParameterException If base conversion fails (should never occur).
*/
private function render(): string
{
self::$isAlgorithmSupported ??= self::isSupportedAlgorithm('sha3-512');
if (!self::$isAlgorithmSupported) {
+ // @codeCoverageIgnoreStart
// phpcs:ignore Generic.Files.LineLength
throw new InvalidOperationException('SHA3-512 appears to be unsupported - make sure you have support for it, or upgrade your version of PHP.');
+ // @codeCoverageIgnoreEnd
}
$hash = hash_init('sha3-512');
- hash_update($hash, (string)$this->timestamp);
- hash_update($hash, (string)$this->counter);
-
- hash_update($hash, bin2hex(pack('C*', ...$this->random)));
- hash_update($hash, bin2hex(pack('C*', ...$this->fingerprint)));
+ hash_update($hash, (string) $this->timestamp);
+ hash_update($hash, (string) $this->counter);
+ hash_update($hash, $this->random);
+ hash_update($hash, $this->fingerprint);
$hash = hash_final($hash);
@@ -178,11 +299,19 @@ private function render(): string
}
/**
- * Converts Base16 to Base36
+ * Converts a base16 (hexadecimal) string to base36.
+ *
+ * Uses GMP extension if available for significantly better performance,
+ * otherwise falls back to math-php library for arbitrary precision arithmetic.
*
- * @param string $value
- * @return string
- * @throws BadParameterException
+ * Base36 encoding uses 0-9 and a-z (36 characters total), producing shorter
+ * strings than hexadecimal while remaining URL-safe and case-insensitive.
+ *
+ * @param string $value Base16 (hexadecimal) string to convert.
+ *
+ * @return string The value encoded in base36.
+ *
+ * @throws BadParameterException If base conversion fails (should never occur with valid input).
*/
private static function convert(string $value): string
{
@@ -191,18 +320,23 @@ private static function convert(string $value): string
}
$integer = BaseEncoderDecoder::createArbitraryInteger($value, 16);
+
return BaseEncoderDecoder::toBase($integer, 36, self::BASE36_ALPHANUMERIC);
}
/**
- * Checks if the given algorithm is supported.
+ * Checks if a hash algorithm is supported by the current PHP installation.
*
- * @param string $algorithm the algorithm to check.
- * @return bool true if the algorithm is supported, false otherwise.
+ * Results are cached in a static property to avoid repeated calls to hash_algos().
+ *
+ * @param string $algorithm Hash algorithm name to check (e.g., 'sha3-512').
+ *
+ * @return bool True if the algorithm is supported, false otherwise.
*/
private static function isSupportedAlgorithm(string $algorithm): bool
{
self::$algorithmsCache ??= hash_algos();
+
return in_array($algorithm, self::$algorithmsCache, true);
}
}
diff --git a/src/Fingerprint.php b/src/Fingerprint.php
index c1a080d..bd5d86b 100644
--- a/src/Fingerprint.php
+++ b/src/Fingerprint.php
@@ -6,25 +6,90 @@
use Exception;
+use const PHP_OS_FAMILY;
+
/**
- * Singleton responsible for generating and storing a fingerprint
+ * Singleton responsible for generating and storing a unique machine/process fingerprint for CUID2 generation.
+ *
+ * This class ensures that CUIDs generated on different machines or in different processes are unique
+ * by creating a fingerprint that combines:
+ * - Hostname (machine identification)
+ * - Process ID (process identification)
+ * - Environment variables (additional entropy and context)
+ * - Random fallback (when hostname is unavailable)
+ *
+ * The fingerprint is computed once per process lifecycle and cached for performance. It is hashed
+ * using SHA3-512 to create a uniform, high-entropy identifier that becomes part of every CUID
+ * generated in this process.
+ *
+ * Thread Safety:
+ * - In PHP, each request/process maintains its own singleton instance
+ * - The singleton pattern ensures the fingerprint remains consistent within a single process
+ * - Different processes will have different fingerprints (by design)
+ *
+ * Singleton Protections:
+ * - Cannot be cloned (__clone is private)
+ * - Cannot be unserialized (__wakeup throws exception)
+ * - Cannot be directly instantiated (constructor is private)
+ *
+ * @internal This class is internal to the CUID2 library and should not be used directly.
*
- * @internal
* @psalm-internal Visus\Cuid2
*/
final class Fingerprint
{
+ /**
+ * Maximum hostname length on Windows systems.
+ *
+ * Windows limits NetBIOS names to 15 characters. This constant ensures the random
+ * fallback identity matches the expected length constraints of the platform.
+ */
+ private const WINDOWS_HOSTNAME_LENGTH = 15;
+
+ /**
+ * Maximum hostname length on Unix-like systems.
+ *
+ * Unix-like systems (Linux, macOS, BSD) typically support hostnames up to 64 characters,
+ * but we use 32 characters to balance uniqueness with performance and storage efficiency.
+ */
+ private const UNIX_HOSTNAME_LENGTH = 32;
+
+ /**
+ * The singleton instance.
+ */
private static ?Fingerprint $instance = null;
+ /**
+ * Cached serialized environment variables.
+ *
+ * Environment variables are serialized once and cached to avoid repeated serialization
+ * overhead. This cache persists for the lifetime of the process.
+ */
private static ?string $cachedEnvironment = null;
/**
- * @var array
+ * The fingerprint value as binary string.
+ *
+ * Contains the raw bytes of the SHA3-512 hash that represents this machine/process
+ * fingerprint. Stored as a readonly string to ensure immutability after initialization.
+ *
+ * @psalm-readonly-allow-private-mutation
*/
- private readonly array $value;
+ private readonly string $value;
/**
- * @throws Exception
+ * Initializes the fingerprint by generating a unique machine/process identifier.
+ *
+ * The fingerprint combines multiple sources of entropy to ensure uniqueness:
+ * - Machine hostname (or random fallback if unavailable)
+ * - Process ID from the operating system
+ * - Serialized environment variables
+ *
+ * All components are hashed together using SHA3-512 to create a uniform,
+ * high-entropy fingerprint that helps ensure CUID uniqueness across different
+ * machines and processes.
+ *
+ * @throws Exception If SHA3-512 hashing is unavailable or fingerprint generation fails.
*/
private function __construct()
{
@@ -32,9 +97,52 @@ private function __construct()
}
/**
- * Gets the current instance.
+ * Prevents cloning of the singleton instance.
*
- * @return Fingerprint
+ * Cloning would break the singleton pattern and could lead to inconsistent fingerprints,
+ * potentially causing CUID collisions across cloned instances. This method is intentionally
+ * private and empty to prevent cloning attempts.
+ *
+ * @codeCoverageIgnore
+ */
+ private function __clone(): void
+ {
+ // Prevent cloning
+ }
+
+ /**
+ * Prevents unserialization of the singleton instance.
+ *
+ * Unserializing would create a new instance with a potentially outdated fingerprint,
+ * breaking the singleton pattern and risking CUID collisions. This method throws an
+ * exception if unserialization is attempted.
+ *
+ * @throws InvalidOperationException Always thrown to prevent unserialization.
+ */
+ public function __wakeup(): void
+ {
+ throw new InvalidOperationException('Cannot unserialize singleton');
+ }
+
+ /**
+ * Gets or creates the singleton Fingerprint instance.
+ *
+ * This method implements lazy initialization - the Fingerprint is only created when first
+ * accessed. Subsequent calls return the same instance, ensuring a consistent fingerprint
+ * throughout the process lifecycle.
+ *
+ * The fingerprint is computed once and cached, making this operation very efficient for
+ * repeated CUID generation within the same process.
+ *
+ * Usage:
+ * ```php
+ * $fingerprint = Fingerprint::getInstance();
+ * $value = $fingerprint->getValue();
+ * ```
+ *
+ * @return Fingerprint The singleton Fingerprint instance.
+ *
+ * @throws Exception If SHA3-512 hashing is unavailable during first initialization.
*/
public static function getInstance(): Fingerprint
{
@@ -42,59 +150,88 @@ public static function getInstance(): Fingerprint
}
/**
- * Gets the value from the instance.
+ * Returns the fingerprint value as a binary string.
*
- * @return array
+ * The fingerprint is represented as a binary string derived from the SHA3-512 hash
+ * of the combined identity components. This binary data is used as part of the CUID2
+ * generation process to ensure uniqueness across machines and processes.
+ *
+ * Usage:
+ * ```php
+ * $fingerprint = Fingerprint::getInstance();
+ * $bytes = $fingerprint->getValue(); // binary string
+ * ```
+ *
+ * @return string Binary string representing the fingerprint.
*/
- public function getValue(): array
+ public function getValue(): string
{
return $this->value;
}
/**
- * @return array
- * @throws Exception
+ * Generates the machine/process fingerprint by combining multiple entropy sources.
+ *
+ * This method creates a unique identifier by hashing together:
+ * 1. Machine identity (hostname or random fallback)
+ * 2. Process ID (from the operating system)
+ * 3. Environment variables (serialized for additional context)
+ *
+ * The combined data is hashed using SHA3-512 to produce a uniform, high-entropy
+ * fingerprint returned as a binary string.
+ *
+ * Platform Considerations:
+ * - Windows: Uses 15-character identity (NetBIOS limit)
+ * - Unix-like: Uses 32-character identity (balance of uniqueness and performance)
+ *
+ * Fallback Behavior:
+ * If the hostname cannot be determined (containerized environments, restricted systems),
+ * a random identity string is generated as a fallback to maintain uniqueness.
+ *
+ * @return string Binary string from the SHA3-512 hash.
+ *
+ * @throws Exception If SHA3-512 hashing is unavailable or hash generation fails.
*/
- private function generateFingerprint(): array
+ private function generateFingerprint(): string
{
- $hostnameLength = PHP_OS_FAMILY === 'Windows' ? 15 : 32;
+ $identity = gethostname();
- $hostname = gethostname();
+ // Fallback if native gethostname() returns false/empty (extremely rare)
+ // The compat.php polyfill already handles missing gethostname() function
+ // @codeCoverageIgnoreStart
+ if ($identity === false || $identity === '') {
+ $length = PHP_OS_FAMILY === 'Windows'
+ ? self::WINDOWS_HOSTNAME_LENGTH
+ : self::UNIX_HOSTNAME_LENGTH;
- $identity = !empty($hostname)
- ? $hostname
- : $this->generateRandomIdentity($hostnameLength);
+ $identity = substr(str_shuffle('abcdefghjkmnpqrstvwxyz0123456789'), 0, $length);
+ }
+ // @codeCoverageIgnoreEnd
$hash = hash_init('sha3-512');
hash_update($hash, $identity);
- hash_update($hash, (string)getmypid());
+ hash_update($hash, (string) getmypid());
hash_update($hash, $this->getCachedEnvironment());
- hash_update($hash, bin2hex(random_bytes(32)));
-
- $result = unpack('C*', hash_final($hash, true));
-
- return $result !== false ? array_values($result) : [];
- }
- private function getCachedEnvironment(): string
- {
- return self::$cachedEnvironment ??= serialize(getenv());
+ return hash_final($hash, true);
}
/**
- * @codeCoverageIgnore
+ * Returns a cached serialized representation of environment variables.
+ *
+ * Environment variables provide additional entropy and context for the fingerprint.
+ * They are serialized once and cached to avoid repeated serialization overhead on
+ * every CUID generation.
+ *
+ * The serialized environment is used as part of the hash input to ensure that
+ * processes with different environment configurations generate different fingerprints,
+ * even if they share the same hostname and process ID pattern.
+ *
+ * @return string Serialized environment variables, cached for the process lifetime.
*/
- private function generateRandomIdentity(int $length): string
+ private function getCachedEnvironment(): string
{
- $chars = 'abcdefghjkmnpqrstvwxyz0123456789';
- $result = '';
- $max = strlen($chars) - 1;
-
- for ($i = 0; $i < $length; $i++) {
- $result .= $chars[random_int(0, $max)];
- }
-
- return $result;
+ return self::$cachedEnvironment ??= serialize(getenv());
}
}
diff --git a/src/InvalidOperationException.php b/src/InvalidOperationException.php
index 6e2f32c..ecc4ba0 100644
--- a/src/InvalidOperationException.php
+++ b/src/InvalidOperationException.php
@@ -1,12 +1,14 @@
getProperty('instance');
+ $instance->setValue(null, null);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetInstanceReturnsSameSingletonInstance(): void
+ {
+ $counter1 = Counter::getInstance();
+ $counter2 = Counter::getInstance();
+
+ $this->assertSame($counter1, $counter2);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetNextValueReturnsInteger(): void
+ {
+ $counter = Counter::getInstance();
+ $value = $counter->getNextValue();
+
+ $this->assertGreaterThanOrEqual(0, $value);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetNextValueIncrementsSequentially(): void
+ {
+ $counter = Counter::getInstance();
+
+ $value1 = $counter->getNextValue();
+ $value2 = $counter->getNextValue();
+ $value3 = $counter->getNextValue();
+
+ $this->assertEquals($value1 + 1, $value2);
+ $this->assertEquals($value2 + 1, $value3);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetNextValueReturnsValueWithinRange(): void
+ {
+ $counter = Counter::getInstance();
+ $reflection = new ReflectionClass(Counter::class);
+ $rangeConstant = $reflection->getConstant('RANGE');
+
+ for ($i = 0; $i < 100; $i++) {
+ $value = $counter->getNextValue();
+ $this->assertGreaterThanOrEqual(0, $value);
+ $this->assertLessThan($rangeConstant, $value);
+ }
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetNextValueWrapsAtRange(): void
+ {
+ $counter = Counter::getInstance();
+ $reflection = new ReflectionClass(Counter::class);
+ /** @var int $rangeConstant */
+ $rangeConstant = $reflection->getConstant('RANGE');
+
+ // Use reflection to set the counter value near RANGE
+ $valueProperty = $reflection->getProperty('value');
+ $valueProperty->setValue($counter, $rangeConstant - 2);
+
+ $value1 = $counter->getNextValue();
+ $value2 = $counter->getNextValue();
+ $value3 = $counter->getNextValue();
+
+ $this->assertEquals($rangeConstant - 2, $value1);
+ $this->assertEquals($rangeConstant - 1, $value2);
+ $this->assertEquals(0, $value3); // Wrapped to 0
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testWakeupThrowsException(): void
+ {
+ $counter = Counter::getInstance();
+
+ $this->expectException(InvalidOperationException::class);
+ $this->expectExceptionMessage('Cannot unserialize singleton');
+
+ $counter->__wakeup();
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testInitialValueIsRandom(): void
+ {
+ // Create multiple instances (by resetting singleton) and verify they start with different values
+ $initialValues = [];
+
+ for ($i = 0; $i < 10; $i++) {
+ $reflection = new ReflectionClass(Counter::class);
+ $instance = $reflection->getProperty('instance');
+ $instance->setValue(null, null);
+
+ $counter = Counter::getInstance();
+ $initialValues[] = $counter->getNextValue();
+ }
+
+ // Statistical test: At least some values should be different
+ $uniqueValues = array_unique($initialValues);
+ $this->assertGreaterThan(1, count($uniqueValues));
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testPersistsAcrossMultipleCalls(): void
+ {
+ $counter1 = Counter::getInstance();
+ $value1 = $counter1->getNextValue();
+
+ $counter2 = Counter::getInstance();
+ $value2 = $counter2->getNextValue();
+
+ // Should be the same instance, so value2 should be value1 + 1
+ $this->assertEquals($value1 + 1, $value2);
+ }
+}
diff --git a/tests/Cuid2Test.php b/tests/Cuid2Test.php
index da0d4ff..9c15694 100644
--- a/tests/Cuid2Test.php
+++ b/tests/Cuid2Test.php
@@ -84,62 +84,45 @@ public static function invalidCuidProvider(): array
}
/**
- * Tests that the generated CUID2 contains only valid base36 characters.
- *
* @throws OutOfRangeException|Exception
*/
- public function testContainsOnlyBase36Characters(): void
+ public function testGeneratesValidBase36Format(): void
{
$cuid = new Cuid2();
- $result = (string)$cuid;
+ $result = (string) $cuid;
$this->assertMatchesRegularExpression(
- '/^[0-9a-z]+$/',
- $result,
- 'CUID should only contain base36 characters (0-9, a-z)'
- );
-
- $this->assertDoesNotMatchRegularExpression(
- '/[A-Z]/',
- $result,
- 'CUID should not contain uppercase letters'
- );
-
- $this->assertDoesNotMatchRegularExpression(
- '/[^0-9a-z]/',
+ '/^[a-z][0-9a-z]+$/',
$result,
- 'CUID should not contain special characters or spaces'
+ 'CUID should start with lowercase letter followed by base36 characters'
);
}
/**
- * Tests that the string representation of CUID2 is consistent across all methods.
- *
* @throws OutOfRangeException|Exception
*/
- public function testStringRepresentationConsistency(): void
+ public function testStringRepresentationsAreConsistent(): void
{
$cuid = new Cuid2();
$toString = $cuid->toString();
- $magicToString = (string)$cuid;
+ $magicToString = (string) $cuid;
$jsonSerialize = $cuid->jsonSerialize();
- $this->assertSame($toString, $magicToString, 'toString() and __toString() should return identical values');
- $this->assertSame($toString, $jsonSerialize, 'toString() and jsonSerialize() should return identical values');
+ $this->assertSame($toString, $magicToString);
+ $this->assertSame($toString, $jsonSerialize);
// Test immutability - multiple calls return same value
- $this->assertSame($toString, $cuid->toString(), 'Multiple calls to toString() should return same value');
- $this->assertSame($magicToString, (string)$cuid, 'Multiple casts to string should return same value');
+ $this->assertSame($toString, $cuid->toString());
+ $this->assertSame($magicToString, (string) $cuid);
}
/**
- * Tests that invalid lengths throw appropriate exceptions.
+ * @throws Exception
*
* @dataProvider invalidLengthProvider
- * @throws Exception
*/
- public function testInvalidLengthThrowsException(int $length): void
+ public function testThrowsExceptionForInvalidLength(int $length): void
{
$this->expectException(OutOfRangeException::class);
$this->expectExceptionMessage('maxLength: cannot be less than 4 or greater than 32.');
@@ -148,325 +131,119 @@ public function testInvalidLengthThrowsException(int $length): void
}
/**
- * Tests the default constructor produces correct format.
- *
* @throws OutOfRangeException|Exception
*/
- public function testDefaultConstructor(): void
+ public function testGeneratesDefaultLengthOf24(): void
{
$cuid = new Cuid2();
- $result = (string)$cuid;
+ $result = (string) $cuid;
- $this->assertEquals(24, strlen($result), 'Default CUID should be 24 characters long');
- $this->assertTrue(ctype_alnum($result), 'Default CUID should be alphanumeric');
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $result,
- 'CUID should start with lowercase letter'
- );
+ $this->assertEquals(24, strlen($result));
+ $this->assertMatchesRegularExpression('/^[a-z][0-9a-z]*$/', $result);
}
/**
- * Tests that different instances generate unique values.
- *
* @throws OutOfRangeException|Exception
*/
- public function testUniquenessAcrossInstances(): void
+ public function testGeneratesUniqueValuesAcrossInstances(): void
{
$cuid1 = new Cuid2();
$cuid2 = new Cuid2();
- $this->assertNotEquals(
- (string)$cuid1,
- (string)$cuid2,
- 'Different CUID instances should generate unique values'
- );
- }
-
- /**
- * Tests explicit toString method.
- *
- * @throws OutOfRangeException|Exception
- */
- public function testExplicitToString(): void
- {
- $cuid = new Cuid2();
- $value = $cuid->toString();
-
- $this->assertEquals(24, strlen($value), 'toString() should return 24 character string');
- $this->assertTrue(ctype_alnum($value), 'toString() result should be alphanumeric');
- $this->assertMatchesRegularExpression(
- '/^[a-z]/',
- $value,
- 'toString() result should start with lowercase letter'
- );
- }
-
- /**
- * Tests implicit string conversion.
- *
- * @throws OutOfRangeException|Exception
- */
- public function testImplicitStringConversion(): void
- {
- $cuid = new Cuid2();
-
- $castValue = (string)$cuid;
- $this->assertEquals(24, strlen($castValue), 'Cast to string should return 24 character string');
- $this->assertTrue(ctype_alnum($castValue), 'Cast to string result should be alphanumeric');
-
- ob_start();
- echo $cuid;
- $echoValue = ob_get_contents();
- ob_end_clean();
-
- $echoValue = !empty($echoValue) ? $echoValue : '';
-
- $this->assertEquals(24, strlen($echoValue), 'Echo output should be 24 characters long');
- $this->assertTrue(ctype_alnum($echoValue), 'Echo output should be alphanumeric');
- $this->assertEquals($castValue, $echoValue, 'Cast and echo should produce same result');
+ $this->assertNotEquals((string) $cuid1, (string) $cuid2);
}
/**
- * Tests JSON encoding integration.
- *
* @throws OutOfRangeException|Exception
*/
- public function testJsonEncodingIntegration(): void
+ public function testJsonEncodesCorrectly(): void
{
$cuid = new Cuid2();
$jsonString = json_encode($cuid);
-
- $this->assertIsString($jsonString, 'json_encode should return string');
- $this->assertStringStartsWith('"', $jsonString, 'JSON string should start with quote');
- $this->assertStringEndsWith('"', $jsonString, 'JSON string should end with quote');
+ $this->assertIsString($jsonString);
$decoded = json_decode($jsonString, true);
- $this->assertIsString($decoded, 'Decoded JSON should be string');
- $this->assertEquals(24, strlen($decoded), 'Decoded CUID should be 24 characters');
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $decoded,
- 'Decoded CUID should have correct format'
- );
- }
-
- /**
- * Tests JSON serialization method.
- *
- * @throws OutOfRangeException|Exception
- */
- public function testJsonSerialize(): void
- {
- $cuid = new Cuid2();
- $jsonValue = $cuid->jsonSerialize();
-
- $this->assertEquals(24, strlen($jsonValue), 'JSON serialized value should be 24 characters');
- $this->assertTrue(ctype_alnum($jsonValue), 'JSON serialized value should be alphanumeric');
- $this->assertMatchesRegularExpression(
- '/^[a-z]/',
- $jsonValue,
- 'JSON serialized value should start with lowercase letter'
- );
- }
-
- /**
- * Tests length consistency across different constructor parameters.
- *
- * @throws OutOfRangeException|Exception
- */
- public function testLengthConsistencyWithDifferentLengths(): void
- {
- $lengths = [4, 8, 12, 16, 20, 24, 28, 32];
-
- foreach ($lengths as $length) {
- $cuid1 = new Cuid2($length);
- $cuid2 = new Cuid2($length);
-
- $result1 = (string)$cuid1;
- $result2 = (string)$cuid2;
-
- $this->assertEquals($length, strlen($result1), "CUID with length $length should have correct length");
- $this->assertEquals($length, strlen($result2), "CUID with length $length should have correct length");
- $this->assertNotEquals($result1, $result2, 'Different instances with same length should be unique');
-
- // Verify format for each length
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $result1,
- "CUID with length $length should have correct format"
- );
-
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $result2,
- "CUID with length $length should have correct format"
- );
- }
+ $this->assertIsString($decoded);
+ $this->assertEquals((string) $cuid, $decoded);
+ $this->assertMatchesRegularExpression('/^[a-z][0-9a-z]*$/', $decoded);
}
/**
- * Tests that the prefix is always a lowercase letter.
- *
* @throws OutOfRangeException|Exception
*/
- public function testPrefixIsAlwaysLowercaseLetter(): void
+ public function testStartsWithLowercaseLetter(): void
{
- // Test multiple instances to verify consistency
for ($i = 0; $i < 50; $i++) {
$cuid = new Cuid2();
- $result = (string)$cuid;
+ $result = (string) $cuid;
$firstChar = $result[0];
- $this->assertTrue(ctype_alpha($firstChar), 'First character should be alphabetic');
- $this->assertTrue(ctype_lower($firstChar), 'First character should be lowercase');
- $this->assertGreaterThanOrEqual('a', $firstChar, 'First character should be >= "a"');
- $this->assertLessThanOrEqual('z', $firstChar, 'First character should be <= "z"');
+ $this->assertMatchesRegularExpression('/^[a-z]$/', $firstChar);
}
}
/**
- * Tests uniqueness of generated CUIDs with larger sample size.
- *
* @throws OutOfRangeException|Exception
*/
- public function testUniquenessWithLargeSample(): void
+ public function testGeneratesUniqueValuesInLargeSample(): void
{
$cuids = [];
$sampleSize = 1000;
for ($i = 0; $i < $sampleSize; $i++) {
- $cuids[] = (string)new Cuid2();
+ $cuids[] = (string) new Cuid2();
}
$uniqueCuids = array_unique($cuids);
- $this->assertCount($sampleSize, $uniqueCuids, "All $sampleSize generated CUIDs should be unique");
-
- // Verify each CUID has correct format
- foreach ($cuids as $index => $cuid) {
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $cuid,
- "CUID at index $index should have correct format"
- );
- }
+ $this->assertCount($sampleSize, $uniqueCuids);
}
/**
- * @dataProvider validLengthProvider
* @throws Exception
- */
- public function testValidLengthsProduceCorrectFormat(int $length): void
- {
- $cuid = new Cuid2($length);
- $result = (string)$cuid;
-
- $this->assertEquals($length, strlen($result), "CUID should have requested length of $length");
- $this->assertTrue(ctype_alnum($result), 'CUID should be alphanumeric');
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $result,
- 'CUID should start with lowercase letter and contain only base36 characters'
- );
- }
-
- /**
- * Tests variable length constructor with specific length.
*
- * @throws OutOfRangeException|Exception
+ * @dataProvider validLengthProvider
*/
- public function testVariableLengthConstructor(): void
+ public function testGeneratesCorrectLength(int $length): void
{
- $length = 10;
$cuid = new Cuid2($length);
- $result = (string)$cuid;
+ $result = (string) $cuid;
- $this->assertEquals($length, strlen($result), "CUID should have requested length of $length");
- $this->assertTrue(ctype_alnum($result), 'CUID should be alphanumeric');
- $this->assertMatchesRegularExpression(
- '/^[a-z]/',
- $result,
- 'CUID should start with lowercase letter'
- );
- }
-
- /**
- * Tests that CUIDs maintain format consistency across different lengths.
- *
- * @throws OutOfRangeException|Exception
- */
- public function testFormatConsistencyAcrossLengths(): void
- {
- $lengths = [4, 8, 16, 24, 32];
-
- foreach ($lengths as $length) {
- $cuid = new Cuid2($length);
- $result = (string)$cuid;
-
- // All CUIDs should follow the same format rules regardless of length
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $result,
- "CUID with length $length should follow format rules"
- );
-
- $this->assertEquals($length, strlen($result), "CUID should have exact length $length");
-
- // Verify no invalid characters
- $this->assertDoesNotMatchRegularExpression(
- '/[^0-9a-z]/',
- $result,
- 'CUID should not contain invalid characters'
- );
- }
+ $this->assertEquals($length, strlen($result));
+ $this->assertMatchesRegularExpression('/^[a-z][0-9a-z]*$/', $result);
}
/**
- * Tests the static generate method.
- *
* @throws OutOfRangeException|Exception
*/
- public function testStaticGenerateMethod(): void
+ public function testStaticGenerateCreatesDefaultLength(): void
{
$cuid = Cuid2::generate();
- $result = (string)$cuid;
+ $result = (string) $cuid;
- $this->assertEquals(24, strlen($result), 'Generated CUID should be 24 characters long');
- $this->assertTrue(ctype_alnum($result), 'Generated CUID should be alphanumeric');
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $result,
- 'Generated CUID should start with lowercase letter'
- );
+ $this->assertEquals(24, strlen($result));
+ $this->assertMatchesRegularExpression('/^[a-z][0-9a-z]*$/', $result);
}
/**
- * Tests the static generate method with custom length.
+ * @throws Exception
*
* @dataProvider validLengthProvider
- * @throws Exception
*/
- public function testStaticGenerateMethodWithLength(int $length): void
+ public function testStaticGenerateCreatesCustomLength(int $length): void
{
$cuid = Cuid2::generate($length);
- $result = (string)$cuid;
+ $result = (string) $cuid;
- $this->assertEquals($length, strlen($result), "Generated CUID should have requested length of $length");
- $this->assertTrue(ctype_alnum($result), 'Generated CUID should be alphanumeric');
- $this->assertMatchesRegularExpression(
- '/^[a-z][0-9a-z]*$/',
- $result,
- 'Generated CUID should start with lowercase letter and contain only base36 characters'
- );
+ $this->assertEquals($length, strlen($result));
+ $this->assertMatchesRegularExpression('/^[a-z][0-9a-z]*$/', $result);
}
/**
- * Tests that static generate method throws exception for invalid lengths.
+ * @throws Exception
*
* @dataProvider invalidLengthProvider
- * @throws Exception
*/
- public function testStaticGenerateMethodThrowsExceptionForInvalidLength(int $length): void
+ public function testStaticGenerateThrowsExceptionForInvalidLength(int $length): void
{
$this->expectException(OutOfRangeException::class);
$this->expectExceptionMessage('maxLength: cannot be less than 4 or greater than 32.');
@@ -475,225 +252,80 @@ public function testStaticGenerateMethodThrowsExceptionForInvalidLength(int $len
}
/**
- * Tests that static generate method produces unique values.
- *
* @throws OutOfRangeException|Exception
*/
- public function testStaticGenerateMethodUniqueness(): void
+ public function testStaticGenerateProducesUniqueValues(): void
{
$cuid1 = Cuid2::generate();
$cuid2 = Cuid2::generate();
- $this->assertNotEquals(
- (string)$cuid1,
- (string)$cuid2,
- 'Different calls to generate() should produce unique values'
- );
+ $this->assertNotEquals((string) $cuid1, (string) $cuid2);
}
/**
- * Tests equivalence between constructor and static generate method.
- *
- * @throws OutOfRangeException|Exception
- */
- public function testConstructorAndGenerateMethodEquivalence(): void
- {
- $length = 16;
-
- // Both methods should produce CUIDs with identical characteristics
- $constructorCuid = new Cuid2($length);
- $generateCuid = Cuid2::generate($length);
-
- $constructorResult = (string)$constructorCuid;
- $generateResult = (string)$generateCuid;
-
- // Should have same length and format, but different values
- $this->assertEquals(strlen($constructorResult),
- strlen($generateResult),
- 'Both methods should produce same length'
- );
-
- $this->assertMatchesRegularExpression('/^[a-z][0-9a-z]*$/',
- $constructorResult,
- 'Constructor result should have correct format'
- );
-
- $this->assertMatchesRegularExpression('/^[a-z][0-9a-z]*$/',
- $generateResult,
- 'Generate result should have correct format'
- );
-
- $this->assertNotEquals($constructorResult, $generateResult, 'Results should be unique');
- }
-
- /**
- * Tests isValid method with valid CUID2 strings.
- *
* @dataProvider validCuidProvider
*/
- public function testIsValidWithValidCuids(string $cuid, ?int $expectedLength = null): void
+ public function testIsValidAcceptsValidCuids(string $cuid, ?int $expectedLength = null): void
{
- $this->assertTrue(
- Cuid2::isValid($cuid, $expectedLength),
- "CUID '$cuid' should be considered valid"
- );
+ $this->assertTrue(Cuid2::isValid($cuid, $expectedLength));
}
/**
- * Tests isValid method with invalid CUID2 strings.
- *
* @dataProvider invalidCuidProvider
*/
- public function testIsValidWithInvalidCuids(string $cuid, ?int $expectedLength = null): void
+ public function testIsValidRejectsInvalidCuids(string $cuid, ?int $expectedLength = null): void
{
- $this->assertFalse(
- Cuid2::isValid($cuid, $expectedLength),
- "CUID '$cuid' should be considered invalid"
- );
+ $this->assertFalse(Cuid2::isValid($cuid, $expectedLength));
}
- /**
- * Tests isValid method with length validation.
- */
- public function testIsValidWithExpectedLength(): void
+ public function testIsValidChecksExpectedLength(): void
{
$validCuid = 'a1b2c3d4e5f6g7h8';
- // Should be valid when length matches
- $this->assertTrue(
- Cuid2::isValid($validCuid, 16),
- 'Valid CUID should pass when expected length matches actual length'
- );
-
- // Should be invalid when length doesn't match
- $this->assertFalse(
- Cuid2::isValid($validCuid, 24),
- 'Valid CUID should fail when expected length differs from actual length'
- );
-
- $this->assertFalse(
- Cuid2::isValid($validCuid, 8),
- 'Valid CUID should fail when expected length is shorter than actual length'
- );
+ $this->assertTrue(Cuid2::isValid($validCuid, 16));
+ $this->assertFalse(Cuid2::isValid($validCuid, 24));
+ $this->assertFalse(Cuid2::isValid($validCuid, 8));
}
- /**
- * Tests isValid method with edge cases for length validation.
- */
- public function testIsValidLengthEdgeCases(): void
+ public function testIsValidChecksLengthBounds(): void
{
- // Test minimum valid length
- $this->assertTrue(Cuid2::isValid('a1b2', 4), 'Minimum length CUID should be valid');
- $this->assertFalse(Cuid2::isValid('a1b', 3), 'Below minimum length should be invalid even with matching expected length');
+ $this->assertTrue(Cuid2::isValid('a1b2', 4));
+ $this->assertFalse(Cuid2::isValid('a1b', 3));
- // Test maximum valid length
$maxLengthCuid = 'a' . str_repeat('1', 31);
- $this->assertTrue(Cuid2::isValid($maxLengthCuid, 32), 'Maximum length CUID should be valid');
+ $this->assertTrue(Cuid2::isValid($maxLengthCuid, 32));
- // Test above maximum length
$tooLongCuid = 'a' . str_repeat('1', 32);
- $this->assertFalse(Cuid2::isValid($tooLongCuid, 33), 'Above maximum length should be invalid even with matching expected length');
+ $this->assertFalse(Cuid2::isValid($tooLongCuid, 33));
}
- /**
- * Tests isValid method without expected length parameter.
- */
- public function testIsValidWithoutExpectedLength(): void
+ public function testIsValidRejectsInvalidExpectedLength(): void
{
- $this->assertTrue(Cuid2::isValid('a1b2'), 'Valid minimum length CUID should pass without expected length');
- $this->assertTrue(Cuid2::isValid('a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'), 'Valid maximum length CUID should pass without expected length');
- $this->assertFalse(Cuid2::isValid('abc'), 'Too short CUID should fail without expected length');
- $this->assertFalse(Cuid2::isValid('A1b2'), 'CUID with uppercase should fail without expected length');
+ // Valid CUID but invalid expectedLength parameter
+ $validCuid = 'a1b2c3d4';
+
+ $this->assertFalse(Cuid2::isValid($validCuid, 3)); // expectedLength too small
+ $this->assertFalse(Cuid2::isValid($validCuid, 33)); // expectedLength too large
+ $this->assertFalse(Cuid2::isValid($validCuid, 0)); // expectedLength zero
+ $this->assertFalse(Cuid2::isValid($validCuid, -1)); // expectedLength negative
}
/**
- * Tests isValid method with generated CUIDs.
- *
* @throws Exception
*/
- public function testIsValidWithGeneratedCuids(): void
+ public function testIsValidAcceptsGeneratedCuids(): void
{
$lengths = [4, 8, 16, 24, 32];
foreach ($lengths as $length) {
$cuid = Cuid2::generate($length);
- $cuidString = (string)$cuid;
+ $cuidString = (string) $cuid;
- // Generated CUID should always be valid
- $this->assertTrue(
- Cuid2::isValid($cuidString),
- "Generated CUID of length $length should be valid"
- );
+ $this->assertTrue(Cuid2::isValid($cuidString));
+ $this->assertTrue(Cuid2::isValid($cuidString, $length));
- // Generated CUID should be valid with correct expected length
- $this->assertTrue(
- Cuid2::isValid($cuidString, $length),
- "Generated CUID should be valid with matching expected length $length"
- );
-
- // Generated CUID should be invalid with wrong expected length
$wrongLength = $length === 4 ? 8 : 4;
- $this->assertFalse(
- Cuid2::isValid($cuidString, $wrongLength),
- "Generated CUID should be invalid with wrong expected length $wrongLength"
- );
- }
- }
-
- /**
- * Tests isValid method with character set validation.
- */
- public function testIsValidCharacterSetValidation(): void
- {
- // Test all valid base36 characters
- $validChars = '0123456789abcdefghijklmnopqrstuvwxyz';
- $testCuid = 'a' . substr(str_shuffle($validChars), 0, 7);
- $this->assertTrue(Cuid2::isValid($testCuid), 'CUID with all valid base36 characters should be valid');
-
- // Test invalid characters
- $invalidChars = ['A', 'Z', '-', '_', '@', '#', '$', '%', '^', '&', '*'];
- foreach ($invalidChars as $invalidChar) {
- $invalidCuid = 'a1b2' . $invalidChar . '3d4';
- $this->assertFalse(
- Cuid2::isValid($invalidCuid),
- "CUID containing invalid character '$invalidChar' should be invalid"
- );
- }
- }
-
- /**
- * Tests isValid method regex pattern matching.
- */
- public function testIsValidRegexPattern(): void
- {
- // Test the regex pattern directly through various scenarios
- $validPatterns = [
- 'a123',
- 'z999',
- 'x1y2z3a4b5c6',
- 'q0w1e2r3t4y5u6i7o8p9',
- ];
-
- foreach ($validPatterns as $pattern) {
- $this->assertTrue(
- Cuid2::isValid($pattern),
- "Pattern '$pattern' should match valid CUID regex"
- );
- }
-
- $invalidPatterns = [
- 'A123', // uppercase
- 'a-23', // contains hyphen
- 'a_23', // contains underscore
- 'a 23', // contains space
- 'a.23', // contains dot
- ];
-
- foreach ($invalidPatterns as $pattern) {
- $this->assertFalse(
- Cuid2::isValid($pattern),
- "Pattern '$pattern' should not match valid CUID regex"
- );
+ $this->assertFalse(Cuid2::isValid($cuidString, $wrongLength));
}
}
}
diff --git a/tests/FingerprintTest.php b/tests/FingerprintTest.php
new file mode 100644
index 0000000..0a04012
--- /dev/null
+++ b/tests/FingerprintTest.php
@@ -0,0 +1,139 @@
+getProperty('instance');
+ $instance->setValue(null, null);
+
+ $cachedEnvironment = $reflection->getProperty('cachedEnvironment');
+ $cachedEnvironment->setValue(null, null);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetInstanceReturnsSameSingletonInstance(): void
+ {
+ $fingerprint1 = Fingerprint::getInstance();
+ $fingerprint2 = Fingerprint::getInstance();
+
+ $this->assertSame($fingerprint1, $fingerprint2);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetValueReturnsNonEmptyString(): void
+ {
+ $fingerprint = Fingerprint::getInstance();
+ $value = $fingerprint->getValue();
+
+ $this->assertNotEmpty($value);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetValueReturnsConsistentValue(): void
+ {
+ $fingerprint = Fingerprint::getInstance();
+
+ $value1 = $fingerprint->getValue();
+ $value2 = $fingerprint->getValue();
+ $value3 = $fingerprint->getValue();
+
+ $this->assertSame($value1, $value2);
+ $this->assertSame($value2, $value3);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetValueReturnsBinaryData(): void
+ {
+ $fingerprint = Fingerprint::getInstance();
+ $value = $fingerprint->getValue();
+
+ // SHA3-512 produces 64 bytes of binary data
+ $this->assertEquals(64, strlen($value));
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testGetValueIsDeterministicWithinProcess(): void
+ {
+ // Within the same process, fingerprint should be identical across instances
+ $fingerprint1 = Fingerprint::getInstance();
+ $value1 = $fingerprint1->getValue();
+
+ $fingerprint2 = Fingerprint::getInstance();
+ $value2 = $fingerprint2->getValue();
+
+ $this->assertSame($value1, $value2);
+ $this->assertSame($fingerprint1, $fingerprint2);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testWakeupThrowsException(): void
+ {
+ $fingerprint = Fingerprint::getInstance();
+
+ $this->expectException(InvalidOperationException::class);
+ $this->expectExceptionMessage('Cannot unserialize singleton');
+
+ $fingerprint->__wakeup();
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testFingerprintIncludesProcessContext(): void
+ {
+ // Create a fingerprint and verify it's unique (non-zero bytes)
+ $fingerprint = Fingerprint::getInstance();
+ $value = $fingerprint->getValue();
+
+ // Binary data should not be all zeros (extremely unlikely with SHA3-512)
+ $this->assertNotEquals(str_repeat("\x00", 64), $value);
+
+ // Should contain various byte values (high entropy)
+ $uniqueBytes = count(array_unique(str_split($value)));
+ $this->assertGreaterThan(10, $uniqueBytes);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public function testFingerprintValueIsImmutable(): void
+ {
+ $fingerprint = Fingerprint::getInstance();
+ $originalValue = $fingerprint->getValue();
+
+ // Call getValue multiple times
+ for ($i = 0; $i < 10; $i++) {
+ $currentValue = $fingerprint->getValue();
+ $this->assertSame($originalValue, $currentValue);
+ }
+ }
+}
diff --git a/tests/benchmark/Cuid2Bench.php b/tests/benchmark/Cuid2Bench.php
new file mode 100644
index 0000000..280abdd
--- /dev/null
+++ b/tests/benchmark/Cuid2Bench.php
@@ -0,0 +1,163 @@
+cuid;
+ }
+
+ /**
+ * Benchmark toString() method performance.
+ */
+ #[BeforeMethods('setUp')]
+ #[Revs(10000)]
+ #[Iterations(10)]
+ #[Warmup(2)]
+ #[Groups(['conversion', 'string'])]
+ public function benchToStringMethod(): void
+ {
+ // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable
+ $result = $this->cuid->toString();
+ }
+
+ /**
+ * Benchmark JSON serialization performance.
+ */
+ #[BeforeMethods('setUp')]
+ #[Revs(10000)]
+ #[Iterations(10)]
+ #[Warmup(2)]
+ #[Groups(['conversion', 'json'])]
+ public function benchJsonSerialize(): void
+ {
+ json_encode($this->cuid);
+ }
+
+ /**
+ * Benchmark batch generation of CUIDs.
+ *
+ * Tests performance when generating multiple CUIDs in sequence.
+ *
+ * @param array{count: int} $params
+ */
+ #[ParamProviders('provideBatchSizes')]
+ #[Revs(100)]
+ #[Iterations(10)]
+ #[Warmup(2)]
+ #[Groups(['generation', 'batch'])]
+ public function benchBatchGeneration(array $params): void
+ {
+ for ($i = 0; $i < $params['count']; $i++) {
+ new Cuid2();
+ }
+ }
+
+ /**
+ * Provides various CUID lengths for benchmarking.
+ *
+ * @return iterable
+ */
+ public function provideLengths(): iterable
+ {
+ yield 'minimum-4' => ['length' => 4];
+ yield 'short-10' => ['length' => 10];
+ yield 'default-24' => ['length' => 24];
+ yield 'maximum-32' => ['length' => 32];
+ }
+
+ /**
+ * Provides batch sizes for batch generation benchmarks.
+ *
+ * @return iterable
+ */
+ public function provideBatchSizes(): iterable
+ {
+ yield 'small-10' => ['count' => 10];
+ yield 'medium-100' => ['count' => 100];
+ yield 'large-1000' => ['count' => 1000];
+ }
+
+ /**
+ * CUID instance for conversion benchmarks.
+ */
+ private Cuid2 $cuid;
+
+ /**
+ * Set up CUID instance for conversion benchmarks.
+ */
+ public function setUp(): void
+ {
+ $this->cuid = new Cuid2();
+ }
+}
diff --git a/tests/benchmark/SingletonBench.php b/tests/benchmark/SingletonBench.php
new file mode 100644
index 0000000..ac6f3ef
--- /dev/null
+++ b/tests/benchmark/SingletonBench.php
@@ -0,0 +1,101 @@
+getNextValue();
+ }
+
+ /**
+ * Benchmark Fingerprint singleton getInstance() access.
+ *
+ * Tests the performance of accessing an already-initialized Fingerprint singleton.
+ * After the first access, this should be extremely fast due to caching.
+ */
+ #[Revs(100000)]
+ #[Iterations(10)]
+ #[Warmup(2)]
+ #[Groups(['singleton', 'fingerprint'])]
+ public function benchFingerprintGetInstance(): void
+ {
+ Fingerprint::getInstance();
+ }
+
+ /**
+ * Benchmark Fingerprint getValue() performance.
+ *
+ * Tests the performance of retrieving the cached fingerprint value.
+ * This should be extremely fast as it simply returns a readonly property.
+ */
+ #[Revs(100000)]
+ #[Iterations(10)]
+ #[Warmup(2)]
+ #[Groups(['singleton', 'fingerprint'])]
+ public function benchFingerprintGetValue(): void
+ {
+ // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable
+ $result = Fingerprint::getInstance()->getValue();
+ }
+
+ /**
+ * Benchmark combined singleton access for CUID generation.
+ *
+ * This simulates the singleton access pattern used during CUID generation,
+ * where both Counter and Fingerprint are accessed.
+ */
+ #[Revs(10000)]
+ #[Iterations(10)]
+ #[Warmup(2)]
+ #[Groups(['singleton', 'combined'])]
+ public function benchCombinedSingletonAccess(): void
+ {
+ // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable
+ $counterValue = Counter::getInstance()->getNextValue();
+ // @phpcs:ignore SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable
+ $fingerprintValue = Fingerprint::getInstance()->getValue();
+ }
+}
diff --git a/tests/benchmark/ValidationBench.php b/tests/benchmark/ValidationBench.php
new file mode 100644
index 0000000..98915f6
--- /dev/null
+++ b/tests/benchmark/ValidationBench.php
@@ -0,0 +1,149 @@
+longString);
+ }
+
+ /**
+ * Provides valid CUIDs of various lengths.
+ *
+ * @return iterable
+ */
+ public function provideValidCuids(): iterable
+ {
+ yield 'minimum-4' => ['cuid' => (new Cuid2(4))->toString()];
+ yield 'short-10' => ['cuid' => (new Cuid2(10))->toString()];
+ yield 'default-24' => ['cuid' => (new Cuid2())->toString()];
+ yield 'maximum-32' => ['cuid' => (new Cuid2(32))->toString()];
+ }
+
+ /**
+ * Provides valid CUIDs with their expected lengths.
+ *
+ * @return iterable
+ */
+ public function provideValidCuidsWithLength(): iterable
+ {
+ yield 'minimum-4' => ['cuid' => (new Cuid2(4))->toString(), 'length' => 4];
+ yield 'short-10' => ['cuid' => (new Cuid2(10))->toString(), 'length' => 10];
+ yield 'default-24' => ['cuid' => (new Cuid2())->toString(), 'length' => 24];
+ yield 'maximum-32' => ['cuid' => (new Cuid2(32))->toString(), 'length' => 32];
+ }
+
+ /**
+ * Provides invalid CUID strings.
+ *
+ * @return iterable
+ */
+ public function provideInvalidCuids(): iterable
+ {
+ yield 'uppercase-first' => ['cuid' => 'A23456789012345678901234'];
+ yield 'uppercase-middle' => ['cuid' => 'a234567890123456789O1234'];
+ yield 'contains-dash' => ['cuid' => 'a234567890-234567890123'];
+ yield 'contains-underscore' => ['cuid' => 'a2345678_01234567890123'];
+ yield 'contains-special' => ['cuid' => 'a23456789@1234567890123'];
+ yield 'starts-with-number' => ['cuid' => '123456789012345678901234'];
+ yield 'too-short' => ['cuid' => 'abc'];
+ }
+
+ /**
+ * Long invalid string for edge case testing.
+ */
+ private string $longString;
+
+ /**
+ * Set up long string for validation benchmark.
+ */
+ public function setUpLongString(): void
+ {
+ $this->longString = str_repeat('a', 100);
+ }
+}