diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..03ed54b6
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,24 @@
+#
+# JBZoo Toolbox - Csv-Blueprint.
+#
+# This file is part of the JBZoo Toolbox project.
+# For the full copyright and license information, please view the LICENSE
+# file that was distributed with this source code.
+#
+# @license MIT
+# @copyright Copyright (C) JBZoo.com, All rights reserved.
+# @see https://github.com/JBZoo/Csv-Blueprint
+#
+
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..0e97e3d1
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,33 @@
+#
+# JBZoo Toolbox - Csv-Blueprint.
+#
+# This file is part of the JBZoo Toolbox project.
+# For the full copyright and license information, please view the LICENSE
+# file that was distributed with this source code.
+#
+# @license MIT
+# @copyright Copyright (C) JBZoo.com, All rights reserved.
+# @see https://github.com/JBZoo/Csv-Blueprint
+#
+
+/.github export-ignore
+/build export-ignore
+/tests export-ignore
+/.editorconfig export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+/.phan.php export-ignore
+/.travis.yml export-ignore
+/composer.lock export-ignore
+/phpunit.xml.dist export-ignore
+/Makefile export-ignore
+
+* text eol=lf
+
+# (binary is a macro for -text -diff)
+*.png binary
+*.jpg binary
+*.jpeg binary
+*.gif binary
+*.ico binary
+*.ttf binary
diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml
new file mode 100644
index 00000000..5c2e204a
--- /dev/null
+++ b/.github/workflows/demo.yml
@@ -0,0 +1,68 @@
+#
+# JBZoo Toolbox - Csv-Blueprint.
+#
+# This file is part of the JBZoo Toolbox project.
+# For the full copyright and license information, please view the LICENSE
+# file that was distributed with this source code.
+#
+# @license MIT
+# @copyright Copyright (C) JBZoo.com, All rights reserved.
+# @see https://github.com/JBZoo/Csv-Blueprint
+#
+
+name: Demo
+
+on:
+ pull_request:
+ branches:
+ - "*"
+ push:
+ branches:
+ - 'master'
+
+env:
+ COLUMNS: 120
+ TERM_PROGRAM: Hyper
+
+jobs:
+ pure-php:
+ name: Pure PHP
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.3
+ tools: composer
+
+ - name: Build the Project
+ run: make update
+
+ - name: Validate CSV (default is table)
+ run: make demo-github
+ continue-on-error: true
+
+ - name: Validate CSV (text)
+ run: OUTPUT=text make demo-github
+ continue-on-error: true
+
+ - name: Validate CSV (github)
+ run: OUTPUT=github make demo-github
+ continue-on-error: true
+
+ - name: Validate CSV (gitlab)
+ run: OUTPUT=gitlab make demo-github
+ continue-on-error: true
+
+ - name: Validate CSV (teamcity)
+ run: OUTPUT=teamcity make demo-github
+ continue-on-error: true
+
+ - name: Validate CSV (junit)
+ run: OUTPUT=junit make demo-github
+ continue-on-error: true
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000..5cf213ea
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,140 @@
+#
+# JBZoo Toolbox - Csv-Blueprint.
+#
+# This file is part of the JBZoo Toolbox project.
+# For the full copyright and license information, please view the LICENSE
+# file that was distributed with this source code.
+#
+# @license MIT
+# @copyright Copyright (C) JBZoo.com, All rights reserved.
+# @see https://github.com/JBZoo/Csv-Blueprint
+#
+
+name: CI
+
+on:
+ pull_request:
+ branches:
+ - "*"
+ push:
+ branches:
+ - 'master'
+ schedule:
+ - cron: '12 */8 * * *'
+
+env:
+ COLUMNS: 120
+ TERM_PROGRAM: Hyper
+
+jobs:
+ phpunit:
+ name: PHPUnit
+ runs-on: ubuntu-latest
+ env:
+ JBZOO_COMPOSER_UPDATE_FLAGS: ${{ matrix.composer_flags }}
+ strategy:
+ matrix:
+ php-version: [ 8.1, 8.2, 8.3 ]
+ coverage: [ xdebug, none ]
+ composer_flags: [ "--prefer-lowest", "" ]
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+ coverage: ${{ matrix.coverage }}
+ tools: composer
+ extensions: ast
+
+ - name: Build the Project
+ run: make update --no-print-directory
+
+ - name: 🧪 PHPUnit Tests
+ run: make test --no-print-directory
+
+ - name: Uploading coverage to coveralls
+ if: ${{ matrix.coverage == 'xdebug' }}
+ continue-on-error: true
+ env:
+ COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: make report-coveralls --no-print-directory || true
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v3
+ continue-on-error: true
+ with:
+ name: PHPUnit - ${{ matrix.php-version }} - ${{ matrix.coverage }}
+ path: build/
+
+
+ linters:
+ name: Linters
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ php-version: [ 8.1, 8.2, 8.3 ]
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+ coverage: none
+ tools: composer
+ extensions: ast
+
+ - name: Build the Project
+ run: make update --no-print-directory
+
+ - name: 👍 Code Quality
+ run: make codestyle --no-print-directory
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v3
+ continue-on-error: true
+ with:
+ name: Linters - ${{ matrix.php-version }}
+ path: build/
+
+
+ report:
+ name: Reports
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ php-version: [ 8.1, 8.2, 8.3 ]
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-version }}
+ coverage: xdebug
+ tools: composer
+ extensions: ast
+
+ - name: Build the Project
+ run: make update --no-print-directory
+
+ - name: 📝 Build Reports
+ run: make report-all --no-print-directory
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v3
+ continue-on-error: true
+ with:
+ name: Reports - ${{ matrix.php-version }}
+ path: build/
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..b0f75c93
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+#
+# JBZoo Toolbox - Csv-Blueprint.
+#
+# This file is part of the JBZoo Toolbox project.
+# For the full copyright and license information, please view the LICENSE
+# file that was distributed with this source code.
+#
+# @license MIT
+# @copyright Copyright (C) JBZoo.com, All rights reserved.
+# @see https://github.com/JBZoo/Csv-Blueprint
+#
+
+.idea
+.DS_Store
+build
+vendor
+phpunit.xml
+*.cache
diff --git a/.phan.php b/.phan.php
new file mode 100644
index 00000000..8780395e
--- /dev/null
+++ b/.phan.php
@@ -0,0 +1,34 @@
+ [
+ 'src',
+
+ 'vendor/jbzoo/data/src',
+ 'vendor/jbzoo/cli/src',
+ 'vendor/jbzoo/utils/src',
+ 'vendor/jbzoo/ci-report-converter/src',
+ 'vendor/league/csv/src',
+ 'vendor/fakerphp/faker/src',
+ 'vendor/symfony/console',
+ ],
+]);
diff --git a/LICENSE b/LICENSE
index fcc81725..1183d723 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2024 JBZoo Toolbox
+Copyright (c) 2020 JBZoo Toolbox for developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..6629f209
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,55 @@
+#
+# JBZoo Toolbox - Csv-Blueprint.
+#
+# This file is part of the JBZoo Toolbox project.
+# For the full copyright and license information, please view the LICENSE
+# file that was distributed with this source code.
+#
+# @license MIT
+# @copyright Copyright (C) JBZoo.com, All rights reserved.
+# @see https://github.com/JBZoo/Csv-Blueprint
+#
+
+
+ifneq (, $(wildcard ./vendor/jbzoo/codestyle/src/init.Makefile))
+ include ./vendor/jbzoo/codestyle/src/init.Makefile
+endif
+
+OUTPUT ?= table
+
+update: ##@Project Install/Update all 3rd party dependencies
+ $(call title,"Install/Update all 3rd party dependencies")
+ @echo "Composer flags: $(JBZOO_COMPOSER_UPDATE_FLAGS)"
+ @composer update $(JBZOO_COMPOSER_UPDATE_FLAGS)
+
+
+test-all: ##@Project Run all project tests at once
+ @make test
+ @make codestyle
+
+
+demo-valid: ##@Project Run demo valid CSV
+ $(call title,"Demo - Valid CSV")
+ @${PHP_BIN} ./csv-blueprint validate:csv \
+ --csv=./tests/fixtures/demo.csv \
+ --schema=./tests/schemas/demo_valid.yml
+
+
+demo-invalid: ##@Project Run demo invalid CSV
+ $(call title,"Demo - Invalid CSV")
+ @${PHP_BIN} ./csv-blueprint validate:csv \
+ --csv=./tests/fixtures/demo.csv \
+ --schema=./tests/schemas/demo_invalid.yml
+
+
+demo-github: ##@Project Run demo invalid CSV
+ @${PHP_BIN} ./csv-blueprint validate:csv \
+ --csv=./tests/fixtures/demo.csv \
+ --schema=./tests/schemas/demo_invalid.yml \
+ --output=$(OUTPUT) \
+ --ansi
+
+
+demo: ##@Project Run all demo commands
+ @make demo-valid
+ @make demo-invalid
diff --git a/README.md b/README.md
index 7483a948..20a8749a 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,212 @@
-# csv-validator
\ No newline at end of file
+# JBZoo / Csv-Blueprint
+
+[![CI](https://github.com/JBZoo/Csv-Blueprint/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/JBZoo/Csv-Blueprint/actions/workflows/main.yml?query=branch%3Amaster) [![Coverage Status](https://coveralls.io/repos/github/JBZoo/Csv-Blueprint/badge.svg?branch=master)](https://coveralls.io/github/JBZoo/Csv-Blueprint?branch=master) [![Psalm Coverage](https://shepherd.dev/github/JBZoo/Csv-Blueprint/coverage.svg)](https://shepherd.dev/github/JBZoo/Csv-Blueprint) [![Psalm Level](https://shepherd.dev/github/JBZoo/Csv-Blueprint/level.svg)](https://shepherd.dev/github/JBZoo/Csv-Blueprint) [![CodeFactor](https://www.codefactor.io/repository/github/jbzoo/csv-blueprint/badge)](https://www.codefactor.io/repository/github/jbzoo/csv-blueprint/issues)
+[![Stable Version](https://poser.pugx.org/jbzoo/csv-blueprint/version)](https://packagist.org/packages/jbzoo/csv-blueprint/) [![Total Downloads](https://poser.pugx.org/jbzoo/csv-blueprint/downloads)](https://packagist.org/packages/jbzoo/csv-blueprint/stats) [![Dependents](https://poser.pugx.org/jbzoo/csv-blueprint/dependents)](https://packagist.org/packages/jbzoo/csv-blueprint/dependents?order_by=downloads) [![GitHub License](https://img.shields.io/github/license/jbzoo/csv-blueprint)](https://github.com/JBZoo/Csv-Blueprint/blob/master/LICENSE)
+
+
+
+
+### Installing
+
+```sh
+composer require jbzoo/csv-blueprint
+```
+
+
+### Usage
+
+
+### Schema file examples
+
+
+ Click to see: YAML format (with comment)
+
+```yml
+# It's a full example of the CSV schema file in YAML format.
+
+csv: # Here are default values. You can skip this section if you don't need to override the default values
+ header: true # If the first row is a header. If true, name of each column is required
+ delimiter: , # Delimiter character in CSV file
+ quote_char: \ # Quote character in CSV file
+ enclosure: "\"" # Enclosure for each field in CSV file
+ encoding: utf-8 # Only utf-8, utf-16, utf-32 (Experimental)
+ bom: false # If the file has a BOM (Byte Order Mark) at the beginning (Experimental)
+
+columns:
+ - name: "csv_header_name" # Any custom name of the column in the CSV file (first row). Required if "csv_structure.header" is true.
+ description: "Lorem ipsum" # Optional. Description of the column. Not used in the validation process.
+ rules:
+ # You can use the rules in any combination. Or not use any of them.
+ # They are grouped below simply for ease of navigation and reading.
+ # If you see the value for the rule is "true" - that's just an enable flag.
+ # In other cases, these are rule parameters.
+
+ # General rules
+ not_empty: true # Value is not empty string. Ignore spaces.
+ exact_value: Some string # Case-sensitive. Exact value for string in the column
+ allow_values: [ y, n, "" ] # Strict set of values that are allowed. Case-sensitive.
+
+ # Strings only
+ regex: /^[\d]{2}$/ # Any valid regex pattern. See https://www.php.net/manual/en/reference.pcre.pattern.syntax.php
+ min_length: 1 # Integer only. Min length of the string with spaces
+ max_length: 10 # Integer only. Max length of the string with spaces
+ only_trimed: true # Only trimed strings. Example: "Hello World" (not " Hello World ")
+ only_lowercase: true # String is only lower-case. Example: "hello world"
+ only_uppercase: true # String is only upper-case. Example: "HELLO WORLD"
+ only_capitalize: true # String is only capitalized. Example: "Hello World"
+
+ # Deciaml and integer numbers
+ min: 10 # Can be integer or float, negative and positive
+ max: 100.50 # Can be integer or float, negative and positive
+ precision: 2 # Strict(!) number of digits after the decimal point
+
+ # Dates
+ date_format: Y-m-d # See: https://www.php.net/manual/en/datetime.format.php
+ min_date: "2000-01-02" # See examples https://www.php.net/manual/en/function.strtotime.php
+ max_date: "+1 day" # See examples https://www.php.net/manual/en/function.strtotime.php
+
+ # Specific formats
+ is_bool: true # Allow only boolean values "true" and "false", case-insensitive
+ is_int: true # Check format only. Can be negative and positive. Without any separators
+ is_float: true # Check format only. Can be negative and positive. Dot as decimal separator
+ is_ip: true # Only IPv4. Example: "127.0.0.1"
+ is_url: true # Only URL format. Example: "https://example.com/page?query=string#anchor"
+ is_email: true # Only email format. Example: "user@example.com"
+ is_domain: true # Only domain name. Example: "example.com"
+ is_uuid4: true # Only UUID4 format. Example: "550e8400-e29b-41d4-a716-446655440000"
+ is_latitude: true # Can be integer or float. Example: 50.123456
+ is_longitude: true # Can be integer or float. Example: -89.123456
+ cardinal_direction: true # Valid cardinal direction. Examples: "N", "S", "NE", "SE", "none", ""
+ usa_market_name: true # Check if the value is a valid USA market name. Example: "New York, NY"
+
+```
+
+
+
+
+
+ Click to see: JSON Format
+
+```json
+{
+ "csv" : {
+ "header" : true,
+ "delimiter" : ",",
+ "quote_char" : "\\",
+ "enclosure" : "\"",
+ "encoding" : "utf-8",
+ "bom" : false
+ },
+ "columns" : [
+ {
+ "name" : "csv_header_name",
+ "description" : "Lorem ipsum",
+ "rules" : {
+ "not_empty" : true,
+ "exact_value" : "Some string",
+ "allow_values" : ["y", "n", ""],
+ "regex" : "\/^[\\d]{2}$\/",
+ "min_length" : 1,
+ "max_length" : 10,
+ "only_trimed" : true,
+ "only_lowercase" : true,
+ "only_uppercase" : true,
+ "only_capitalize" : true,
+ "min" : 10,
+ "max" : 100.5,
+ "precision" : 2,
+ "date_format" : "Y-m-d",
+ "min_date" : "2000-01-02",
+ "max_date" : "+1 day",
+ "is_bool" : true,
+ "is_int" : true,
+ "is_float" : true,
+ "is_ip" : true,
+ "is_url" : true,
+ "is_email" : true,
+ "is_domain" : true,
+ "is_uuid4" : true,
+ "is_latitude" : true,
+ "is_longitude" : true,
+ "cardinal_direction" : true,
+ "usa_market_name" : true
+ }
+ }
+ ]
+}
+
+```
+
+
+
+
+
+
+ Click to see: PHP Format
+
+```php
+ [
+ 'header' => true,
+ 'delimiter' => ',',
+ 'quote_char' => '\\',
+ 'enclosure' => '"',
+ 'encoding' => 'utf-8',
+ 'bom' => false,
+ ],
+ 'columns' => [
+ [
+ 'name' => 'csv_header_name',
+ 'description' => 'Lorem ipsum',
+ 'rules' => [
+ 'not_empty' => true,
+ 'exact_value' => 'Some string',
+ 'allow_values' => ['y', 'n', ''],
+ 'regex' => '/^[\\d]{2}$/',
+ 'min_length' => 1,
+ 'max_length' => 10,
+ 'only_trimed' => true,
+ 'only_lowercase' => true,
+ 'only_uppercase' => true,
+ 'only_capitalize' => true,
+ 'min' => 10,
+ 'max' => 100.5,
+ 'precision' => 2,
+ 'date_format' => 'Y-m-d',
+ 'min_date' => '2000-01-02',
+ 'max_date' => '+1 day',
+ 'is_bool' => true,
+ 'is_int' => true,
+ 'is_float' => true,
+ 'is_ip' => true,
+ 'is_url' => true,
+ 'is_email' => true,
+ 'is_domain' => true,
+ 'is_uuid4' => true,
+ 'is_latitude' => true,
+ 'is_longitude' => true,
+ 'cardinal_direction' => true,
+ 'usa_market_name' => true,
+ ],
+ ],
+ ],
+];
+
+```
+
+
+
+
+## Unit tests and check code style
+```sh
+make update
+make test-all
+```
+
+
+### License
+
+MIT
diff --git a/build/.gitkeep b/build/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/composer.json b/composer.json
new file mode 100644
index 00000000..ef26dcbe
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,63 @@
+{
+ "name" : "jbzoo/csv-blueprint",
+ "type" : "library",
+ "description" : "CLI Utility for Validating and Generating CSV Files Based on Custom Rules. It ensures your data meets specified criteria, streamlining data management and integrity checks.",
+ "license" : "MIT",
+ "keywords" : [
+ "jbzoo",
+ "csv",
+ "csv-validator",
+ "csv-validation",
+ "csv-generation",
+ "csv-format",
+ "csv-rules",
+ "csv-schema"
+ ],
+
+ "authors" : [
+ {
+ "name" : "Denis Smetannikov",
+ "email" : "admin@jbzoo.com",
+ "role" : "lead"
+ }
+ ],
+
+ "minimum-stability" : "dev",
+ "prefer-stable" : true,
+
+ "require" : {
+ "php" : "^8.1",
+ "ext-mbstring" : "*",
+
+ "jbzoo/data" : "^7.1",
+ "jbzoo/cli" : "^7.1",
+ "jbzoo/utils" : "^7.1",
+ "jbzoo/ci-report-converter" : "^7.2",
+ "league/csv" : "^9.15",
+ "fakerphp/faker" : "^1.23"
+ },
+
+ "require-dev" : {
+ "roave/security-advisories" : "dev-latest",
+ "jbzoo/toolbox-dev" : "^7.1"
+ },
+
+ "autoload" : {
+ "psr-4" : {"JBZoo\\CsvBlueprint\\" : "src"}
+ },
+
+ "autoload-dev" : {
+ "psr-4" : {"JBZoo\\PHPUnit\\" : "tests"}
+ },
+
+ "config" : {
+ "optimize-autoloader" : true,
+ "allow-plugins" : {"composer/package-versions-deprecated" : true}
+ },
+
+ "extra" : {
+ "branch-alias" : {
+ "dev-master" : "7.x-dev"
+ }
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 00000000..b3c61e26
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,8210 @@
+{
+ "_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": "aa2d64e2d78d191e4bc83a4ad90051b6",
+ "packages": [
+ {
+ "name": "bluepsyduck/symfony-process-manager",
+ "version": "1.3.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/BluePsyduck/symfony-process-manager.git",
+ "reference": "2988e74f063722a5c2868882a7ba41a63c83b34b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/BluePsyduck/symfony-process-manager/zipball/2988e74f063722a5c2868882a7ba41a63c83b34b",
+ "reference": "2988e74f063722a5c2868882a7ba41a63c83b34b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0",
+ "symfony/process": "^3.0 || ^4.0 || ^5.0 || ^6.0"
+ },
+ "require-dev": {
+ "bluepsyduck/test-helper": "^1.0",
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.0",
+ "phpunit/phpunit": "^8.0 || ^9.0",
+ "rregeer/phpunit-coverage-check": "^0.3",
+ "squizlabs/php_codesniffer": "^3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "BluePsyduck\\SymfonyProcessManager\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "GPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "BluePsyduck",
+ "email": "bluepsyduck@gmx.com"
+ }
+ ],
+ "description": "A process manager for Symfony processes, able to run them in parallel.",
+ "homepage": "https://github.com/BluePsyduck/symfony-process-manager",
+ "keywords": [
+ "manager",
+ "parallel",
+ "process",
+ "symfony"
+ ],
+ "support": {
+ "issues": "https://github.com/BluePsyduck/symfony-process-manager/issues",
+ "source": "https://github.com/BluePsyduck/symfony-process-manager/tree/1.3.3"
+ },
+ "time": "2021-12-03T21:30:28+00:00"
+ },
+ {
+ "name": "fakerphp/faker",
+ "version": "v1.23.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/FakerPHP/Faker.git",
+ "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b",
+ "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0",
+ "psr/container": "^1.0 || ^2.0",
+ "symfony/deprecation-contracts": "^2.2 || ^3.0"
+ },
+ "conflict": {
+ "fzaninotto/faker": "*"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.4.1",
+ "doctrine/persistence": "^1.3 || ^2.0",
+ "ext-intl": "*",
+ "phpunit/phpunit": "^9.5.26",
+ "symfony/phpunit-bridge": "^5.4.16"
+ },
+ "suggest": {
+ "doctrine/orm": "Required to use Faker\\ORM\\Doctrine",
+ "ext-curl": "Required by Faker\\Provider\\Image to download images.",
+ "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
+ "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
+ "ext-mbstring": "Required for multibyte Unicode string functionality."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Faker\\": "src/Faker/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "François Zaninotto"
+ }
+ ],
+ "description": "Faker is a PHP library that generates fake data for you.",
+ "keywords": [
+ "data",
+ "faker",
+ "fixtures"
+ ],
+ "support": {
+ "issues": "https://github.com/FakerPHP/Faker/issues",
+ "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1"
+ },
+ "time": "2024-01-02T13:46:09+00:00"
+ },
+ {
+ "name": "jbzoo/ci-report-converter",
+ "version": "7.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/CI-Report-Converter.git",
+ "reference": "b411b01d673f2d70cf8edf8693352c6ff831bd8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/CI-Report-Converter/zipball/b411b01d673f2d70cf8edf8693352c6ff831bd8c",
+ "reference": "b411b01d673f2d70cf8edf8693352c6ff831bd8c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-hash": "*",
+ "ext-simplexml": "*",
+ "jbzoo/cli": "^7.1.8",
+ "jbzoo/data": "^7.1",
+ "jbzoo/markdown": "^7.0",
+ "jbzoo/utils": "^7.1",
+ "php": "^8.1",
+ "symfony/console": ">=6.4"
+ },
+ "require-dev": {
+ "jbzoo/mermaid-php": "^7.2",
+ "jbzoo/toolbox-dev": "^7.1",
+ "roave/security-advisories": "dev-master"
+ },
+ "bin": [
+ "ci-report-converter"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "JBZoo\\CIReportConverter\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ }
+ ],
+ "description": "The tool converts different error reporting standards for deep integration with popular CI systems (TeamCity, IntelliJ IDEA, GitHub Actions, etc)",
+ "keywords": [
+ "Codestyle",
+ "Github Actions",
+ "IntelliJ IDEA",
+ "PHPStan",
+ "actions",
+ "checkstyle",
+ "ci",
+ "continuous integration",
+ "github",
+ "inspections",
+ "junit",
+ "phan",
+ "phpcs",
+ "phploc",
+ "phpmd",
+ "phpmnd",
+ "phpstorm",
+ "pmd",
+ "psalm",
+ "teamcity",
+ "teamcity-inspections",
+ "tests"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/CI-Report-Converter/issues",
+ "source": "https://github.com/JBZoo/CI-Report-Converter/tree/7.2.1"
+ },
+ "time": "2024-01-28T14:03:00+00:00"
+ },
+ {
+ "name": "jbzoo/cli",
+ "version": "7.1.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/Cli.git",
+ "reference": "7577c4d88d9724103269696a4c7726ec68211279"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/Cli/zipball/7577c4d88d9724103269696a4c7726ec68211279",
+ "reference": "7577c4d88d9724103269696a4c7726ec68211279",
+ "shasum": ""
+ },
+ "require": {
+ "bluepsyduck/symfony-process-manager": ">=1.3.3",
+ "jbzoo/event": "^7.0",
+ "jbzoo/utils": "^7.1",
+ "monolog/monolog": "^3.4",
+ "php": "^8.1",
+ "symfony/console": ">=6.4",
+ "symfony/lock": ">=6.4",
+ "symfony/process": ">=6.4"
+ },
+ "require-dev": {
+ "jbzoo/toolbox-dev": "^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "JBZoo\\Cli\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ }
+ ],
+ "description": "The framework helps create CLI tools and provides new tools for symfony/console, symfony/process.",
+ "keywords": [
+ "ELK",
+ "cli",
+ "command-line",
+ "console",
+ "console-application",
+ "cron",
+ "crontab",
+ "elastic",
+ "elk-stack",
+ "jbzoo",
+ "logstash",
+ "process",
+ "symfony",
+ "symfony-console",
+ "symfony-process",
+ "terminal"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/Cli/issues",
+ "source": "https://github.com/JBZoo/Cli/tree/7.1.8"
+ },
+ "time": "2024-01-28T13:57:00+00:00"
+ },
+ {
+ "name": "jbzoo/data",
+ "version": "7.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/Data.git",
+ "reference": "8666e8cdc912c3fd6176aa0ca5ab29bd1a7d0ab2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/Data/zipball/8666e8cdc912c3fd6176aa0ca5ab29bd1a7d0ab2",
+ "reference": "8666e8cdc912c3fd6176aa0ca5ab29bd1a7d0ab2",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "jbzoo/toolbox-dev": "^7.1",
+ "jbzoo/utils": "^7.1.1",
+ "symfony/polyfill-ctype": ">=1.28.0",
+ "symfony/polyfill-mbstring": ">=1.28.0",
+ "symfony/polyfill-php73": ">=1.28.0",
+ "symfony/polyfill-php80": ">=1.28.0",
+ "symfony/polyfill-php81": ">=1.28.0",
+ "symfony/yaml": ">=6.4"
+ },
+ "suggest": {
+ "jbzoo/utils": ">=7.1",
+ "symfony/yaml": ">=6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "JBZoo\\Data\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ }
+ ],
+ "description": "An extended version of the ArrayObject object for working with system settings or just for working with data arrays",
+ "keywords": [
+ "array",
+ "arrayobject",
+ "config",
+ "data",
+ "ini",
+ "json",
+ "params",
+ "yml"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/Data/issues",
+ "source": "https://github.com/JBZoo/Data/tree/7.1.1"
+ },
+ "time": "2024-01-28T08:47:08+00:00"
+ },
+ {
+ "name": "jbzoo/event",
+ "version": "7.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/Event.git",
+ "reference": "09c87f83acc79252cc7f01b173c4c6eb399e62a1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/Event/zipball/09c87f83acc79252cc7f01b173c4c6eb399e62a1",
+ "reference": "09c87f83acc79252cc7f01b173c4c6eb399e62a1",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "jbzoo/data": "^7.1",
+ "jbzoo/toolbox-dev": "^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "JBZoo\\Event\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ },
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "https://sabre.io/event/"
+ }
+ ],
+ "description": "Library for event-based development",
+ "keywords": [
+ "HOOK",
+ "emit",
+ "emitter",
+ "event-manager",
+ "eventmanager",
+ "events",
+ "jbzoo",
+ "listener",
+ "observer",
+ "signal"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/Event/issues",
+ "source": "https://github.com/JBZoo/Event/tree/7.0.1"
+ },
+ "time": "2024-01-28T08:57:37+00:00"
+ },
+ {
+ "name": "jbzoo/markdown",
+ "version": "7.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/Markdown.git",
+ "reference": "02e9d756ed91d33c63a7794db1279af56e4da5e9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/Markdown/zipball/02e9d756ed91d33c63a7794db1279af56e4da5e9",
+ "reference": "02e9d756ed91d33c63a7794db1279af56e4da5e9",
+ "shasum": ""
+ },
+ "require": {
+ "jbzoo/utils": "^7.1",
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "jbzoo/toolbox-dev": "^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "JBZoo\\Markdown\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ }
+ ],
+ "description": "Tools to render markdown text from PHP code",
+ "keywords": [
+ "Rendering",
+ "jbzoo",
+ "markdown",
+ "readme",
+ "text"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/Markdown/issues",
+ "source": "https://github.com/JBZoo/Markdown/tree/7.0.1"
+ },
+ "time": "2024-01-28T12:43:57+00:00"
+ },
+ {
+ "name": "jbzoo/utils",
+ "version": "7.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/Utils.git",
+ "reference": "55ddbe0558f2e4a8f69b4469d9ead97f2de5e13f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/Utils/zipball/55ddbe0558f2e4a8f69b4469d9ead97f2de5e13f",
+ "reference": "55ddbe0558f2e4a8f69b4469d9ead97f2de5e13f",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-filter": "*",
+ "ext-gd": "*",
+ "ext-posix": "*",
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "jbzoo/data": "^7.1",
+ "jbzoo/toolbox-dev": "^7.1",
+ "symfony/process": ">=6.4"
+ },
+ "suggest": {
+ "ext-intl": "*",
+ "ext-mbstring": "Provides multibyte specific string functions",
+ "jbzoo/data": ">=4.0",
+ "symfony/polyfill-mbstring": "For UTF-8 if ext-mbstring disabled",
+ "symfony/process": "For Cli::exec() method only"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/defines.php",
+ "src/aliases.php"
+ ],
+ "psr-4": {
+ "JBZoo\\Utils\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ },
+ {
+ "name": "Brandon Wamboldt",
+ "email": "brandon.wamboldt@gmail.com"
+ },
+ {
+ "name": "Luís Nóbrega",
+ "email": "luis.barros.nobrega@gmail.com"
+ }
+ ],
+ "description": "Collection of PHP functions, mini classes and snippets for everyday developer's routine life.",
+ "keywords": [
+ "array",
+ "cli",
+ "collection",
+ "command line",
+ "dates",
+ "email",
+ "env",
+ "environment",
+ "filesystem",
+ "filter",
+ "helper",
+ "helpers",
+ "http",
+ "image",
+ "mbstring",
+ "misc",
+ "serialize",
+ "slugify",
+ "string",
+ "timer",
+ "url",
+ "utility",
+ "utils"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/Utils/issues",
+ "source": "https://github.com/JBZoo/Utils/tree/7.1.2"
+ },
+ "time": "2024-01-28T08:37:18+00:00"
+ },
+ {
+ "name": "league/csv",
+ "version": "9.15.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/csv.git",
+ "reference": "fa7e2441c0bc9b2360f4314fd6c954f7ff40d435"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/csv/zipball/fa7e2441c0bc9b2360f4314fd6c954f7ff40d435",
+ "reference": "fa7e2441c0bc9b2360f4314fd6c954f7ff40d435",
+ "shasum": ""
+ },
+ "require": {
+ "ext-filter": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "php": "^8.1.2"
+ },
+ "require-dev": {
+ "doctrine/collections": "^2.1.4",
+ "ext-dom": "*",
+ "ext-xdebug": "*",
+ "friendsofphp/php-cs-fixer": "^v3.22.0",
+ "phpbench/phpbench": "^1.2.15",
+ "phpstan/phpstan": "^1.10.57",
+ "phpstan/phpstan-deprecation-rules": "^1.1.4",
+ "phpstan/phpstan-phpunit": "^1.3.15",
+ "phpstan/phpstan-strict-rules": "^1.5.2",
+ "phpunit/phpunit": "^10.5.9",
+ "symfony/var-dumper": "^6.4.2"
+ },
+ "suggest": {
+ "ext-dom": "Required to use the XMLConverter and the HTMLConverter classes",
+ "ext-iconv": "Needed to ease transcoding CSV using iconv stream filters"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "League\\Csv\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ignace Nyamagana Butera",
+ "email": "nyamsprod@gmail.com",
+ "homepage": "https://github.com/nyamsprod/",
+ "role": "Developer"
+ }
+ ],
+ "description": "CSV data manipulation made easy in PHP",
+ "homepage": "https://csv.thephpleague.com",
+ "keywords": [
+ "convert",
+ "csv",
+ "export",
+ "filter",
+ "import",
+ "read",
+ "transform",
+ "write"
+ ],
+ "support": {
+ "docs": "https://csv.thephpleague.com",
+ "issues": "https://github.com/thephpleague/csv/issues",
+ "rss": "https://github.com/thephpleague/csv/releases.atom",
+ "source": "https://github.com/thephpleague/csv"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sponsors/nyamsprod",
+ "type": "github"
+ }
+ ],
+ "time": "2024-02-20T20:00:00+00:00"
+ },
+ {
+ "name": "monolog/monolog",
+ "version": "3.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/monolog.git",
+ "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448",
+ "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^2.0 || ^3.0"
+ },
+ "provide": {
+ "psr/log-implementation": "3.0.0"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "^3.0",
+ "doctrine/couchdb": "~1.0@dev",
+ "elasticsearch/elasticsearch": "^7 || ^8",
+ "ext-json": "*",
+ "graylog2/gelf-php": "^1.4.2 || ^2.0",
+ "guzzlehttp/guzzle": "^7.4.5",
+ "guzzlehttp/psr7": "^2.2",
+ "mongodb/mongodb": "^1.8",
+ "php-amqplib/php-amqplib": "~2.4 || ^3",
+ "phpstan/phpstan": "^1.9",
+ "phpstan/phpstan-deprecation-rules": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.4",
+ "phpunit/phpunit": "^10.1",
+ "predis/predis": "^1.1 || ^2",
+ "ruflin/elastica": "^7",
+ "symfony/mailer": "^5.4 || ^6",
+ "symfony/mime": "^5.4 || ^6"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+ "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+ "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
+ "ext-mbstring": "Allow to work properly with unicode symbols",
+ "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+ "ext-openssl": "Required to send log messages using SSL",
+ "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+ "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+ "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Monolog\\": "src/Monolog"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "https://seld.be"
+ }
+ ],
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+ "homepage": "https://github.com/Seldaek/monolog",
+ "keywords": [
+ "log",
+ "logging",
+ "psr-3"
+ ],
+ "support": {
+ "issues": "https://github.com/Seldaek/monolog/issues",
+ "source": "https://github.com/Seldaek/monolog/tree/3.5.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Seldaek",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-10-27T15:32:31+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/log",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376",
+ "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.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/2.0.0"
+ },
+ "time": "2021-07-14T16:41:46+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v6.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "0d9e4eb5ad413075624378f474c4167ea202de78"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78",
+ "reference": "0d9e4eb5ad413075624378f474c4167ea202de78",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/string": "^5.4|^6.0|^7.0"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4",
+ "symfony/dotenv": "<5.4",
+ "symfony/event-dispatcher": "<5.4",
+ "symfony/lock": "<5.4",
+ "symfony/process": "<5.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/lock": "^5.4|^6.0|^7.0",
+ "symfony/messenger": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
+ "symfony/stopwatch": "^5.4|^6.0|^7.0",
+ "symfony/var-dumper": "^5.4|^6.0|^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/v6.4.4"
+ },
+ "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-02-22T20:27:10+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "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.4.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": "2023-05-23T14:45:45+00:00"
+ },
+ {
+ "name": "symfony/lock",
+ "version": "v6.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/lock.git",
+ "reference": "1cabf3cc775b1aa6008ebd471fa773444af4e956"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/lock/zipball/1cabf3cc775b1aa6008ebd471fa773444af4e956",
+ "reference": "1cabf3cc775b1aa6008ebd471fa773444af4e956",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/log": "^1|^2|^3",
+ "symfony/deprecation-contracts": "^2.5|^3"
+ },
+ "conflict": {
+ "doctrine/dbal": "<2.13",
+ "symfony/cache": "<6.2"
+ },
+ "require-dev": {
+ "doctrine/dbal": "^2.13|^3|^4",
+ "predis/predis": "^1.1|^2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Lock\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jérémy Derussé",
+ "email": "jeremy@derusse.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Creates and manages locks, a mechanism to provide exclusive access to a shared resource",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cas",
+ "flock",
+ "locking",
+ "mutex",
+ "redlock",
+ "semaphore"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/lock/tree/v6.4.3"
+ },
+ "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-01-23T14:51:35+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.29.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/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.29.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-01-29T20:11:03+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.29.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/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.29.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-01-29T20:11:03+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.29.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/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.29.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-01-29T20:11:03+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.29.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/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.29.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-01-29T20:11:03+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v6.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "710e27879e9be3395de2b98da3f52a946039f297"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297",
+ "reference": "710e27879e9be3395de2b98da3f52a946039f297",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "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/v6.4.4"
+ },
+ "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-02-20T12:31:00+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v3.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/container": "^1.1|^2.0"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "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.4.1"
+ },
+ "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": "2023-12-26T14:02:43+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v6.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9",
+ "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "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/error-handler": "^5.4|^6.0|^7.0",
+ "symfony/http-client": "^5.4|^6.0|^7.0",
+ "symfony/intl": "^6.2|^7.0",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^5.4|^6.0|^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/v6.4.4"
+ },
+ "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-02-01T13:16:41+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "amphp/amp",
+ "version": "v2.6.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/amphp/amp.git",
+ "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
+ "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "amphp/php-cs-fixer-config": "dev-master",
+ "amphp/phpunit-util": "^1",
+ "ext-json": "*",
+ "jetbrains/phpstorm-stubs": "^2019.3",
+ "phpunit/phpunit": "^7 | ^8 | ^9",
+ "psalm/phar": "^3.11@dev",
+ "react/promise": "^2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "lib/functions.php",
+ "lib/Internal/functions.php"
+ ],
+ "psr-4": {
+ "Amp\\": "lib"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Daniel Lowrey",
+ "email": "rdlowrey@php.net"
+ },
+ {
+ "name": "Aaron Piotrowski",
+ "email": "aaron@trowski.com"
+ },
+ {
+ "name": "Bob Weinand",
+ "email": "bobwei9@hotmail.com"
+ },
+ {
+ "name": "Niklas Keller",
+ "email": "me@kelunik.com"
+ }
+ ],
+ "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": {
+ "irc": "irc://irc.freenode.org/amphp",
+ "issues": "https://github.com/amphp/amp/issues",
+ "source": "https://github.com/amphp/amp/tree/v2.6.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/amphp",
+ "type": "github"
+ }
+ ],
+ "time": "2022-02-20T17:52:18+00:00"
+ },
+ {
+ "name": "amphp/byte-stream",
+ "version": "v1.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/amphp/byte-stream.git",
+ "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd",
+ "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd",
+ "shasum": ""
+ },
+ "require": {
+ "amphp/amp": "^2",
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "amphp/php-cs-fixer-config": "dev-master",
+ "amphp/phpunit-util": "^1.4",
+ "friendsofphp/php-cs-fixer": "^2.3",
+ "jetbrains/phpstorm-stubs": "^2019.3",
+ "phpunit/phpunit": "^6 || ^7 || ^8",
+ "psalm/phar": "^3.11.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "lib/functions.php"
+ ],
+ "psr-4": {
+ "Amp\\ByteStream\\": "lib"
+ }
+ },
+ "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": "http://amphp.org/byte-stream",
+ "keywords": [
+ "amp",
+ "amphp",
+ "async",
+ "io",
+ "non-blocking",
+ "stream"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/amphp",
+ "issues": "https://github.com/amphp/byte-stream/issues",
+ "source": "https://github.com/amphp/byte-stream/tree/v1.8.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/amphp",
+ "type": "github"
+ }
+ ],
+ "time": "2021-03-30T17:13:30+00:00"
+ },
+ {
+ "name": "composer/pcre",
+ "version": "3.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/pcre.git",
+ "reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/4775f35b2d70865807c89d32c8e7385b86eb0ace",
+ "reference": "4775f35b2d70865807c89d32c8e7385b86eb0ace",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.3",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "symfony/phpunit-bridge": "^5"
+ },
+ "type": "library",
+ "extra": {
+ "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.1.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-03-07T15:38:35+00:00"
+ },
+ {
+ "name": "composer/semver",
+ "version": "3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
+ "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.4",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
+ },
+ "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.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": "2023-08-31T09:50:34+00:00"
+ },
+ {
+ "name": "composer/xdebug-handler",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/xdebug-handler.git",
+ "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
+ "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+ "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",
+ "symfony/phpunit-bridge": "^6.0"
+ },
+ "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": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/xdebug-handler/issues",
+ "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+ },
+ "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": "2022-02-25T21:32:43+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.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "phpstan/phpstan": "1.4.10 || 1.10.15",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psalm/plugin-phpunit": "0.18.4",
+ "psr/log": "^1 || ^2 || ^3",
+ "vimeo/psalm": "4.30.0 || 5.12.0"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+ }
+ },
+ "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.3"
+ },
+ "time": "2024-01-30T19:34:25+00:00"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^11",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/phpstan": "^1.9.4",
+ "phpstan/phpstan-phpunit": "^1.3",
+ "phpunit/phpunit": "^9.5.27",
+ "vimeo/psalm": "^5.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-30T00:23:10+00:00"
+ },
+ {
+ "name": "felixfbecker/advanced-json-rpc",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git",
+ "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+ "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+ "shasum": ""
+ },
+ "require": {
+ "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+ "php": "^7.1 || ^8.0",
+ "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "AdvancedJsonRpc\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "ISC"
+ ],
+ "authors": [
+ {
+ "name": "Felix Becker",
+ "email": "felix.b@outlook.com"
+ }
+ ],
+ "description": "A more advanced JSONRPC implementation",
+ "support": {
+ "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues",
+ "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1"
+ },
+ "time": "2021-06-11T22:34:44+00:00"
+ },
+ {
+ "name": "felixfbecker/language-server-protocol",
+ "version": "v1.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/felixfbecker/php-language-server-protocol.git",
+ "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842",
+ "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842",
+ "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.2"
+ },
+ "time": "2022-03-02T22:36:06+00:00"
+ },
+ {
+ "name": "fidry/cpu-core-counter",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theofidry/cpu-core-counter.git",
+ "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42",
+ "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42",
+ "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": "^1.9.2",
+ "phpstan/phpstan-deprecation-rules": "^1.0.0",
+ "phpstan/phpstan-phpunit": "^1.2.2",
+ "phpstan/phpstan-strict-rules": "^1.4.4",
+ "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.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theofidry",
+ "type": "github"
+ }
+ ],
+ "time": "2024-02-07T09:43:46+00:00"
+ },
+ {
+ "name": "friendsofphp/php-cs-fixer",
+ "version": "v3.51.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
+ "reference": "127fa74f010da99053e3f5b62672615b72dd6efd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/127fa74f010da99053e3f5b62672615b72dd6efd",
+ "reference": "127fa74f010da99053e3f5b62672615b72dd6efd",
+ "shasum": ""
+ },
+ "require": {
+ "composer/semver": "^3.4",
+ "composer/xdebug-handler": "^3.0.3",
+ "ext-filter": "*",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "php": "^7.4 || ^8.0",
+ "sebastian/diff": "^4.0 || ^5.0 || ^6.0",
+ "symfony/console": "^5.4 || ^6.0 || ^7.0",
+ "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0",
+ "symfony/filesystem": "^5.4 || ^6.0 || ^7.0",
+ "symfony/finder": "^5.4 || ^6.0 || ^7.0",
+ "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0",
+ "symfony/polyfill-mbstring": "^1.28",
+ "symfony/polyfill-php80": "^1.28",
+ "symfony/polyfill-php81": "^1.28",
+ "symfony/process": "^5.4 || ^6.0 || ^7.0",
+ "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0"
+ },
+ "require-dev": {
+ "facile-it/paraunit": "^1.3 || ^2.0",
+ "justinrainbow/json-schema": "^5.2",
+ "keradus/cli-executor": "^2.1",
+ "mikey179/vfsstream": "^1.6.11",
+ "php-coveralls/php-coveralls": "^2.7",
+ "php-cs-fixer/accessible-object": "^1.1",
+ "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4",
+ "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4",
+ "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2",
+ "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0",
+ "symfony/yaml": "^5.4 || ^6.0 || ^7.0"
+ },
+ "suggest": {
+ "ext-dom": "For handling output formats in XML",
+ "ext-mbstring": "For handling non-UTF8 characters."
+ },
+ "bin": [
+ "php-cs-fixer"
+ ],
+ "type": "application",
+ "autoload": {
+ "psr-4": {
+ "PhpCsFixer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Dariusz Rumiński",
+ "email": "dariusz.ruminski@gmail.com"
+ }
+ ],
+ "description": "A tool to automatically fix PHP code style",
+ "keywords": [
+ "Static code analysis",
+ "fixer",
+ "standards",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.51.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/keradus",
+ "type": "github"
+ }
+ ],
+ "time": "2024-02-28T19:50:06+00:00"
+ },
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "7.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "41042bc7ab002487b876a0683fc8dce04ddce104"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104",
+ "reference": "41042bc7ab002487b876a0683fc8dce04ddce104",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "guzzlehttp/promises": "^1.5.3 || ^2.0.1",
+ "guzzlehttp/psr7": "^1.9.1 || ^2.5.1",
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-client": "^1.0",
+ "symfony/deprecation-contracts": "^2.2 || ^3.0"
+ },
+ "provide": {
+ "psr/http-client-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "ext-curl": "*",
+ "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
+ "php-http/message-factory": "^1.1",
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15",
+ "psr/log": "^1.1 || ^2.0 || ^3.0"
+ },
+ "suggest": {
+ "ext-curl": "Required for CURL handler support",
+ "ext-intl": "Required for Internationalized Domain Name (IDN) support",
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Jeremy Lindblom",
+ "email": "jeremeamia@gmail.com",
+ "homepage": "https://github.com/jeremeamia"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "psr-18",
+ "psr-7",
+ "rest",
+ "web service"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/guzzle/issues",
+ "source": "https://github.com/guzzle/guzzle/tree/7.8.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-12-03T20:35:24+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223",
+ "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2.5 || ^8.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/promises/issues",
+ "source": "https://github.com/guzzle/promises/tree/2.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-12-03T20:19:20+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "2.6.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221",
+ "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.1 || ^2.0",
+ "ralouphie/getallheaders": "^3.0"
+ },
+ "provide": {
+ "psr/http-factory-implementation": "1.0",
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "http-interop/http-factory-tests": "^0.9",
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15"
+ },
+ "suggest": {
+ "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://sagikazarmark.hu"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "psr-7",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/psr7/issues",
+ "source": "https://github.com/guzzle/psr7/tree/2.6.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-12-03T20:05:35+00:00"
+ },
+ {
+ "name": "jbzoo/codestyle",
+ "version": "7.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/Codestyle.git",
+ "reference": "50c3261d9d566d1e1f94b34b8c2a2ef64e035b0c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/Codestyle/zipball/50c3261d9d566d1e1f94b34b8c2a2ef64e035b0c",
+ "reference": "50c3261d9d566d1e1f94b34b8c2a2ef64e035b0c",
+ "shasum": ""
+ },
+ "require": {
+ "friendsofphp/php-cs-fixer": ">=3.48.0",
+ "jbzoo/data": "^7.1",
+ "kubawerlos/php-cs-fixer-custom-fixers": ">=3.19.2",
+ "nikic/php-parser": ">=4.18.0",
+ "pdepend/pdepend": ">=2.16.2",
+ "phan/phan": ">=5.4.3",
+ "php": "^8.1",
+ "phpmd/phpmd": ">=2.15.0",
+ "phpmetrics/phpmetrics": ">=2.8.2",
+ "phpstan/phpstan": ">=1.10.57",
+ "phpstan/phpstan-strict-rules": ">=1.5.2",
+ "povils/phpmnd": ">=3.4.0",
+ "squizlabs/php_codesniffer": ">=3.8.1",
+ "symfony/console": ">=6.4",
+ "symfony/finder": ">=6.4",
+ "symfony/yaml": ">=6.4",
+ "vimeo/psalm": ">=5.20.0"
+ },
+ "require-dev": {
+ "jbzoo/phpunit": "^7.0",
+ "jbzoo/utils": "^7.1.1",
+ "symfony/var-dumper": ">=6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/compatibility.php"
+ ],
+ "psr-4": {
+ "JBZoo\\Codestyle\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of QA tools and JBZoo code standards",
+ "keywords": [
+ "Codestyle",
+ "PHPStan",
+ "coding-standard",
+ "jbzoo",
+ "phan",
+ "php",
+ "php-cs-fixer",
+ "phpcompatibility",
+ "phpcs",
+ "phpmd",
+ "phpmetrics",
+ "phpunit",
+ "psalm",
+ "qa",
+ "tests"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/Codestyle/issues",
+ "source": "https://github.com/JBZoo/Codestyle/tree/7.1.0"
+ },
+ "time": "2024-01-27T21:57:08+00:00"
+ },
+ {
+ "name": "jbzoo/jbdump",
+ "version": "1.5.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/JBDump.git",
+ "reference": "044e1f9f648d2467d9161732f1195a44d452ca50"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/JBDump/zipball/044e1f9f648d2467d9161732f1195a44d452ca50",
+ "reference": "044e1f9f648d2467d9161732f1195a44d452ca50",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.10"
+ },
+ "replace": {
+ "smetdenis/jbdump": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "autoload.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "SmetDenis",
+ "email": "admin@jbzoo.com"
+ },
+ {
+ "name": "Kaloyan K. Tsvetkov",
+ "email": "kaloyan@kaloyan.info"
+ },
+ {
+ "name": "Jeremy Dorn",
+ "email": "jeremy@jeremydorn.com"
+ },
+ {
+ "name": "Florin Patan",
+ "email": "florinpatan@gmail.com"
+ }
+ ],
+ "description": "Script for debug and dump PHP variables and other stuff. This tool is a nice replacement for print_r() and var_dump() functions.",
+ "keywords": [
+ "debug",
+ "debugging",
+ "dump",
+ "dumper",
+ "jbdump",
+ "krumo",
+ "php",
+ "pretty",
+ "print",
+ "print_r",
+ "var_dump",
+ "vars"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/JBDump/issues",
+ "source": "https://github.com/JBZoo/JBDump/tree/1.5.6"
+ },
+ "time": "2021-03-31T09:21:47+00:00"
+ },
+ {
+ "name": "jbzoo/phpunit",
+ "version": "7.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/PHPUnit.git",
+ "reference": "4a70dd033b90a08498cbd7147a1c3150198f51f8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/PHPUnit/zipball/4a70dd033b90a08498cbd7147a1c3150198f51f8",
+ "reference": "4a70dd033b90a08498cbd7147a1c3150198f51f8",
+ "shasum": ""
+ },
+ "require": {
+ "ext-filter": "*",
+ "ext-mbstring": "*",
+ "jbzoo/markdown": "^7.0",
+ "php": "^8.1",
+ "phpunit/phpunit": "^9.6.16",
+ "ulrichsg/getopt-php": ">=4.0.3"
+ },
+ "require-dev": {
+ "guzzlehttp/guzzle": ">=7.8.1",
+ "jbzoo/codestyle": "^7.1",
+ "jbzoo/data": "^7.1",
+ "jbzoo/http-client": "^7.0",
+ "jbzoo/toolbox-dev": "^7.0",
+ "jbzoo/utils": "^7.1",
+ "symfony/process": ">=6.4.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions/defines.php",
+ "src/functions/aliases.php",
+ "src/functions/tools.php"
+ ],
+ "psr-4": {
+ "JBZoo\\PHPUnit\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ }
+ ],
+ "description": "PHPUnit toolbox with short assert aliases and useful functions around testing",
+ "keywords": [
+ "aliases",
+ "assert",
+ "assertion",
+ "debug",
+ "jbzoo",
+ "phpunit",
+ "short-syntax",
+ "testing"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/PHPUnit/issues",
+ "source": "https://github.com/JBZoo/PHPUnit/tree/7.1.0"
+ },
+ "time": "2024-01-27T22:11:15+00:00"
+ },
+ {
+ "name": "jbzoo/toolbox-dev",
+ "version": "7.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/JBZoo/Toolbox-Dev.git",
+ "reference": "1048efcb712eb2392e19e1b30201d191a97d66ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/JBZoo/Toolbox-Dev/zipball/1048efcb712eb2392e19e1b30201d191a97d66ca",
+ "reference": "1048efcb712eb2392e19e1b30201d191a97d66ca",
+ "shasum": ""
+ },
+ "require": {
+ "fakerphp/faker": ">=1.23.0",
+ "jbzoo/codestyle": "^7.1",
+ "jbzoo/jbdump": ">=1.5.6|^7.0",
+ "jbzoo/markdown": "^7.0",
+ "jbzoo/phpunit": "^7.1",
+ "php": "^8.1",
+ "php-coveralls/php-coveralls": ">=2.7.0",
+ "symfony/var-dumper": ">=6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/var-dumper.php"
+ ],
+ "psr-4": {
+ "JBZoo\\ToolboxDev\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Denis Smetannikov",
+ "email": "admin@jbzoo.com",
+ "role": "lead"
+ }
+ ],
+ "description": "Developer toolbox only for JBZoo libs on github+travis",
+ "keywords": [
+ "Toolbox",
+ "debug",
+ "dev",
+ "dev-kit",
+ "developer",
+ "devkit",
+ "jbzoo"
+ ],
+ "support": {
+ "issues": "https://github.com/JBZoo/Toolbox-Dev/issues",
+ "source": "https://github.com/JBZoo/Toolbox-Dev/tree/7.1.0"
+ },
+ "time": "2024-01-27T22:19:13+00:00"
+ },
+ {
+ "name": "kubawerlos/php-cs-fixer-custom-fixers",
+ "version": "v3.21.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers.git",
+ "reference": "3d1bb75be0df6c6fba4487c75b9e425a2c1d27c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/3d1bb75be0df6c6fba4487c75b9e425a2c1d27c9",
+ "reference": "3d1bb75be0df6c6fba4487c75b9e425a2c1d27c9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-filter": "*",
+ "ext-tokenizer": "*",
+ "friendsofphp/php-cs-fixer": "^3.50",
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6.4 || ^10.0.14"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpCsFixerCustomFixers\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kuba Werłos",
+ "email": "werlos@gmail.com"
+ }
+ ],
+ "description": "A set of custom fixers for PHP CS Fixer",
+ "support": {
+ "issues": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/issues",
+ "source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.21.0"
+ },
+ "time": "2024-02-24T08:53:34+00:00"
+ },
+ {
+ "name": "microsoft/tolerant-php-parser",
+ "version": "v0.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/microsoft/tolerant-php-parser.git",
+ "reference": "3eccfd273323aaf69513e2f1c888393f5947804b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/3eccfd273323aaf69513e2f1c888393f5947804b",
+ "reference": "3eccfd273323aaf69513e2f1c888393f5947804b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5.15"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Microsoft\\PhpParser\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Rob Lourens",
+ "email": "roblou@microsoft.com"
+ }
+ ],
+ "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios",
+ "support": {
+ "issues": "https://github.com/microsoft/tolerant-php-parser/issues",
+ "source": "https://github.com/microsoft/tolerant-php-parser/tree/v0.1.2"
+ },
+ "time": "2022-10-05T17:30:19+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.11.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "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",
+ "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.11.1"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-08T13:26:56+00:00"
+ },
+ {
+ "name": "netresearch/jsonmapper",
+ "version": "v4.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cweiske/jsonmapper.git",
+ "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/132c75c7dd83e45353ebb9c6c9f591952995bbf0",
+ "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0",
+ "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/v4.4.1"
+ },
+ "time": "2024-01-31T06:18:54+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.18.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
+ "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-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/v4.18.0"
+ },
+ "time": "2023-12-10T21:03:43+00:00"
+ },
+ {
+ "name": "pdepend/pdepend",
+ "version": "2.16.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/pdepend/pdepend.git",
+ "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
+ "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.7",
+ "symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/polyfill-mbstring": "^1.19"
+ },
+ "require-dev": {
+ "easy-doc/easy-doc": "0.0.0|^1.2.3",
+ "gregwar/rst": "^1.0",
+ "squizlabs/php_codesniffer": "^2.0.0"
+ },
+ "bin": [
+ "src/bin/pdepend"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PDepend\\": "src/main/php/PDepend"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "Official version of pdepend to be handled with Composer",
+ "keywords": [
+ "PHP Depend",
+ "PHP_Depend",
+ "dev",
+ "pdepend"
+ ],
+ "support": {
+ "issues": "https://github.com/pdepend/pdepend/issues",
+ "source": "https://github.com/pdepend/pdepend/tree/2.16.2"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-12-17T18:09:59+00:00"
+ },
+ {
+ "name": "phan/phan",
+ "version": "5.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phan/phan.git",
+ "reference": "86a7acd99c1239b8867b49feca2398851212e7fe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phan/phan/zipball/86a7acd99c1239b8867b49feca2398851212e7fe",
+ "reference": "86a7acd99c1239b8867b49feca2398851212e7fe",
+ "shasum": ""
+ },
+ "require": {
+ "composer/semver": "^1.4|^2.0|^3.0",
+ "composer/xdebug-handler": "^2.0|^3.0",
+ "ext-filter": "*",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "felixfbecker/advanced-json-rpc": "^3.0.4",
+ "microsoft/tolerant-php-parser": "0.1.2",
+ "netresearch/jsonmapper": "^1.6.0|^2.0|^3.0|^4.0",
+ "php": "^7.2.0|^8.0.0",
+ "sabre/event": "^5.1.3",
+ "symfony/console": "^3.2|^4.0|^5.0|^6.0|^7.0",
+ "symfony/polyfill-mbstring": "^1.11.0",
+ "symfony/polyfill-php80": "^1.20.0",
+ "tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5.0"
+ },
+ "suggest": {
+ "ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.16+ is recommended.",
+ "ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8",
+ "ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable",
+ "ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8",
+ "ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions.",
+ "ext-var_representation": "Suggested for converting values to strings in issue messages"
+ },
+ "bin": [
+ "phan",
+ "phan_client",
+ "tocheckstyle"
+ ],
+ "type": "project",
+ "autoload": {
+ "psr-4": {
+ "Phan\\": "src/Phan"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Tyson Andre"
+ },
+ {
+ "name": "Rasmus Lerdorf"
+ },
+ {
+ "name": "Andrew S. Morrison"
+ }
+ ],
+ "description": "A static analyzer for PHP",
+ "keywords": [
+ "analyzer",
+ "php",
+ "static",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/phan/phan/issues",
+ "source": "https://github.com/phan/phan/tree/5.4.3"
+ },
+ "time": "2023-12-26T17:57:35+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": "php-coveralls/php-coveralls",
+ "version": "v2.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-coveralls/php-coveralls.git",
+ "reference": "b36fa4394e519dafaddc04ae03976bc65a25ba15"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-coveralls/php-coveralls/zipball/b36fa4394e519dafaddc04ae03976bc65a25ba15",
+ "reference": "b36fa4394e519dafaddc04ae03976bc65a25ba15",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "guzzlehttp/guzzle": "^6.0 || ^7.0",
+ "php": "^7.0 || ^8.0",
+ "psr/log": "^1.0 || ^2.0",
+ "symfony/config": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/console": "^2.1 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/stopwatch": "^2.0 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/yaml": "^2.0.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.4.3 || ^6.0 || ^7.0 || >=8.0 <8.5.29 || >=9.0 <9.5.23",
+ "sanmai/phpunit-legacy-adapter": "^6.1 || ^8.0"
+ },
+ "suggest": {
+ "symfony/http-kernel": "Allows Symfony integration"
+ },
+ "bin": [
+ "bin/php-coveralls"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpCoveralls\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kitamura Satoshi",
+ "email": "with.no.parachute@gmail.com",
+ "homepage": "https://www.facebook.com/satooshi.jp",
+ "role": "Original creator"
+ },
+ {
+ "name": "Takashi Matsuo",
+ "email": "tmatsuo@google.com"
+ },
+ {
+ "name": "Google Inc"
+ },
+ {
+ "name": "Dariusz Ruminski",
+ "email": "dariusz.ruminski@gmail.com",
+ "homepage": "https://github.com/keradus"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/php-coveralls/php-coveralls/graphs/contributors"
+ }
+ ],
+ "description": "PHP client library for Coveralls API",
+ "homepage": "https://github.com/php-coveralls/php-coveralls",
+ "keywords": [
+ "ci",
+ "coverage",
+ "github",
+ "test"
+ ],
+ "support": {
+ "issues": "https://github.com/php-coveralls/php-coveralls/issues",
+ "source": "https://github.com/php-coveralls/php-coveralls/tree/v2.7.0"
+ },
+ "time": "2023-11-22T10:21:01+00:00"
+ },
+ {
+ "name": "php-parallel-lint/php-console-color",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-parallel-lint/PHP-Console-Color.git",
+ "reference": "7adfefd530aa2d7570ba87100a99e2483a543b88"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Color/zipball/7adfefd530aa2d7570ba87100a99e2483a543b88",
+ "reference": "7adfefd530aa2d7570ba87100a99e2483a543b88",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "replace": {
+ "jakub-onderka/php-console-color": "*"
+ },
+ "require-dev": {
+ "php-parallel-lint/php-code-style": "^2.0",
+ "php-parallel-lint/php-parallel-lint": "^1.0",
+ "php-parallel-lint/php-var-dump-check": "0.*",
+ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHP_Parallel_Lint\\PhpConsoleColor\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jakub Onderka",
+ "email": "jakub.onderka@gmail.com"
+ }
+ ],
+ "description": "Simple library for creating colored console ouput.",
+ "support": {
+ "issues": "https://github.com/php-parallel-lint/PHP-Console-Color/issues",
+ "source": "https://github.com/php-parallel-lint/PHP-Console-Color/tree/v1.0.1"
+ },
+ "time": "2021-12-25T06:49:29+00:00"
+ },
+ {
+ "name": "php-parallel-lint/php-console-highlighter",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-parallel-lint/PHP-Console-Highlighter.git",
+ "reference": "5b4803384d3303cf8e84141039ef56c8a123138d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Highlighter/zipball/5b4803384d3303cf8e84141039ef56c8a123138d",
+ "reference": "5b4803384d3303cf8e84141039ef56c8a123138d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.2",
+ "php-parallel-lint/php-console-color": "^1.0.1"
+ },
+ "replace": {
+ "jakub-onderka/php-console-highlighter": "*"
+ },
+ "require-dev": {
+ "php-parallel-lint/php-code-style": "^2.0",
+ "php-parallel-lint/php-parallel-lint": "^1.0",
+ "php-parallel-lint/php-var-dump-check": "0.*",
+ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHP_Parallel_Lint\\PhpConsoleHighlighter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jakub Onderka",
+ "email": "acci@acci.cz",
+ "homepage": "http://www.acci.cz/"
+ }
+ ],
+ "description": "Highlight PHP code in terminal",
+ "support": {
+ "issues": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/issues",
+ "source": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/tree/v1.0.0"
+ },
+ "time": "2022-02-18T08:23:19+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.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
+ "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
+ "shasum": ""
+ },
+ "require": {
+ "ext-filter": "*",
+ "php": "^7.2 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.2",
+ "phpdocumentor/type-resolver": "^1.3",
+ "webmozart/assert": "^1.9.1"
+ },
+ "require-dev": {
+ "mockery/mockery": "~1.3.2",
+ "psalm/phar": "^4.8"
+ },
+ "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": "account@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.3.0"
+ },
+ "time": "2021-10-19T17:43:47+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "1.8.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.3 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.0",
+ "phpstan/phpdoc-parser": "^1.13"
+ },
+ "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.8.2"
+ },
+ "time": "2024-02-23T11:10:43+00:00"
+ },
+ {
+ "name": "phpmd/phpmd",
+ "version": "2.15.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpmd/phpmd.git",
+ "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0",
+ "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0",
+ "shasum": ""
+ },
+ "require": {
+ "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0",
+ "ext-xml": "*",
+ "pdepend/pdepend": "^2.16.1",
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "easy-doc/easy-doc": "0.0.0 || ^1.3.2",
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "gregwar/rst": "^1.0",
+ "mikey179/vfsstream": "^1.6.8",
+ "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2"
+ },
+ "bin": [
+ "src/bin/phpmd"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "PHPMD\\": "src/main/php"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Manuel Pichler",
+ "email": "github@manuel-pichler.de",
+ "homepage": "https://github.com/manuelpichler",
+ "role": "Project Founder"
+ },
+ {
+ "name": "Marc Würth",
+ "email": "ravage@bluewin.ch",
+ "homepage": "https://github.com/ravage84",
+ "role": "Project Maintainer"
+ },
+ {
+ "name": "Other contributors",
+ "homepage": "https://github.com/phpmd/phpmd/graphs/contributors",
+ "role": "Contributors"
+ }
+ ],
+ "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
+ "homepage": "https://phpmd.org/",
+ "keywords": [
+ "dev",
+ "mess detection",
+ "mess detector",
+ "pdepend",
+ "phpmd",
+ "pmd"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/phpmd",
+ "issues": "https://github.com/phpmd/phpmd/issues",
+ "source": "https://github.com/phpmd/phpmd/tree/2.15.0"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-12-11T08:22:20+00:00"
+ },
+ {
+ "name": "phpmetrics/phpmetrics",
+ "version": "v2.8.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpmetrics/PhpMetrics.git",
+ "reference": "4b77140a11452e63c7a9b98e0648320bf6710090"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpmetrics/PhpMetrics/zipball/4b77140a11452e63c7a9b98e0648320bf6710090",
+ "reference": "4b77140a11452e63c7a9b98e0648320bf6710090",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "nikic/php-parser": "^3|^4",
+ "php": ">=5.5"
+ },
+ "replace": {
+ "halleck45/php-metrics": "*",
+ "halleck45/phpmetrics": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14",
+ "sebastian/comparator": ">=1.2.3",
+ "squizlabs/php_codesniffer": "^3.5",
+ "symfony/dom-crawler": "^3.0 || ^4.0 || ^5.0"
+ },
+ "bin": [
+ "bin/phpmetrics"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "./src/functions.php"
+ ],
+ "psr-0": {
+ "Hal\\": "./src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jean-François Lépine",
+ "email": "lepinejeanfrancois@yahoo.fr",
+ "homepage": "http://www.lepine.pro",
+ "role": "Copyright Holder"
+ }
+ ],
+ "description": "Static analyzer tool for PHP : Coupling, Cyclomatic complexity, Maintainability Index, Halstead's metrics... and more !",
+ "homepage": "http://www.phpmetrics.org",
+ "keywords": [
+ "analysis",
+ "qa",
+ "quality",
+ "testing"
+ ],
+ "support": {
+ "issues": "https://github.com/PhpMetrics/PhpMetrics/issues",
+ "source": "https://github.com/phpmetrics/PhpMetrics/tree/v2.8.2"
+ },
+ "time": "2023-03-08T15:03:36+00:00"
+ },
+ {
+ "name": "phpstan/phpdoc-parser",
+ "version": "1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "231e3186624c03d7e7c890ec662b81e6b0405227"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/231e3186624c03d7e7c890ec662b81e6b0405227",
+ "reference": "231e3186624c03d7e7c890ec662b81e6b0405227",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^2.0",
+ "nikic/php-parser": "^4.15",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^1.5",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpstan/phpstan-strict-rules": "^1.0",
+ "phpunit/phpunit": "^9.5",
+ "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/1.26.0"
+ },
+ "time": "2024-02-23T16:05:55+00:00"
+ },
+ {
+ "name": "phpstan/phpstan",
+ "version": "1.10.60",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/95dcea7d6c628a3f2f56d091d8a0219485a86bbe",
+ "reference": "95dcea7d6c628a3f2f56d091d8a0219485a86bbe",
+ "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"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-03-07T13:30:19+00:00"
+ },
+ {
+ "name": "phpstan/phpstan-strict-rules",
+ "version": "1.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan-strict-rules.git",
+ "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542",
+ "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0",
+ "phpstan/phpstan": "^1.10.34"
+ },
+ "require-dev": {
+ "nikic/php-parser": "^4.13.0",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/phpstan-deprecation-rules": "^1.1",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "phpstan-extension",
+ "extra": {
+ "phpstan": {
+ "includes": [
+ "rules.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Extra strict and opinionated rules for PHPStan",
+ "support": {
+ "issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
+ "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2"
+ },
+ "time": "2023-10-30T14:35:06+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "9.2.31",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965",
+ "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3",
+ "phpunit/php-file-iterator": "^3.0.3",
+ "phpunit/php-text-template": "^2.0.2",
+ "sebastian/code-unit-reverse-lookup": "^2.0.2",
+ "sebastian/complexity": "^2.0",
+ "sebastian/environment": "^5.1.2",
+ "sebastian/lines-of-code": "^1.0.3",
+ "sebastian/version": "^3.0.1",
+ "theseer/tokenizer": "^1.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "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-master": "9.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 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/9.2.31"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:37:42+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "3.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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": "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",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-02T12:48:52+00:00"
+ },
+ {
+ "name": "phpunit/php-invoker",
+ "version": "3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-pcntl": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-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/3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:58:55+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T05:33:50+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "5.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.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/5.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:16:10+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "9.6.17",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1a156980d78a6666721b7e8e8502fe210b587fcd",
+ "reference": "1a156980d78a6666721b7e8e8502fe210b587fcd",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.3.1 || ^2",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.10.1",
+ "phar-io/manifest": "^2.0.3",
+ "phar-io/version": "^3.0.2",
+ "php": ">=7.3",
+ "phpunit/php-code-coverage": "^9.2.28",
+ "phpunit/php-file-iterator": "^3.0.5",
+ "phpunit/php-invoker": "^3.1.1",
+ "phpunit/php-text-template": "^2.0.3",
+ "phpunit/php-timer": "^5.0.2",
+ "sebastian/cli-parser": "^1.0.1",
+ "sebastian/code-unit": "^1.0.6",
+ "sebastian/comparator": "^4.0.8",
+ "sebastian/diff": "^4.0.3",
+ "sebastian/environment": "^5.1.3",
+ "sebastian/exporter": "^4.0.5",
+ "sebastian/global-state": "^5.0.1",
+ "sebastian/object-enumerator": "^4.0.3",
+ "sebastian/resource-operations": "^3.0.3",
+ "sebastian/type": "^3.2",
+ "sebastian/version": "^3.0.2"
+ },
+ "suggest": {
+ "ext-soap": "To be able to generate mocks based on WSDL files",
+ "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.6-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/9.6.17"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-02-23T13:14:51+00:00"
+ },
+ {
+ "name": "povils/phpmnd",
+ "version": "v3.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/povils/phpmnd.git",
+ "reference": "1f3eb869e3a2c4fddbe0995fddd97b75caa2c203"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/povils/phpmnd/zipball/1f3eb869e3a2c4fddbe0995fddd97b75caa2c203",
+ "reference": "1f3eb869e3a2c4fddbe0995fddd97b75caa2c203",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": "^7.4 || ^8.0",
+ "php-parallel-lint/php-console-highlighter": "^1.0",
+ "phpunit/php-timer": "^2.0||^3.0||^4.0||^5.0||^6.0",
+ "symfony/console": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/finder": "^4.4 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6",
+ "squizlabs/php_codesniffer": "^2.8.1||^3.5"
+ },
+ "bin": [
+ "bin/phpmnd"
+ ],
+ "type": "application",
+ "autoload": {
+ "psr-4": {
+ "Povils\\PHPMND\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Povilas Susinskas",
+ "email": "povilassusinskas@gmail.com"
+ }
+ ],
+ "description": "A tool to detect Magic numbers in codebase",
+ "support": {
+ "issues": "https://github.com/povils/phpmnd/issues",
+ "source": "https://github.com/povils/phpmnd/tree/v3.4.1"
+ },
+ "time": "2024-03-02T17:53:44+00:00"
+ },
+ {
+ "name": "psr/event-dispatcher",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/event-dispatcher.git",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\EventDispatcher\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Standard interfaces for event handling.",
+ "keywords": [
+ "events",
+ "psr",
+ "psr-14"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/event-dispatcher/issues",
+ "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
+ },
+ "time": "2019-01-08T18:20:26+00:00"
+ },
+ {
+ "name": "psr/http-client",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-client.git",
+ "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
+ "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0 || ^8.0",
+ "psr/http-message": "^1.0 || ^2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Client\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP clients",
+ "homepage": "https://github.com/php-fig/http-client",
+ "keywords": [
+ "http",
+ "http-client",
+ "psr",
+ "psr-18"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-client"
+ },
+ "time": "2023-09-23T14:17:50+00:00"
+ },
+ {
+ "name": "psr/http-factory",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "e616d01114759c4c489f93b099585439f795fe35"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
+ "reference": "e616d01114759c4c489f93b099585439f795fe35",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0.0",
+ "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": "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/tree/1.0.2"
+ },
+ "time": "2023-04-10T20:10:41+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": "ralouphie/getallheaders",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/getallheaders.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "description": "A polyfill for getallheaders.",
+ "support": {
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+ },
+ "time": "2019-03-08T08:55:37+00:00"
+ },
+ {
+ "name": "roave/security-advisories",
+ "version": "dev-latest",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Roave/SecurityAdvisories.git",
+ "reference": "83b3589bb774f27084c7f358c13f465d94afa036"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/83b3589bb774f27084c7f358c13f465d94afa036",
+ "reference": "83b3589bb774f27084c7f358c13f465d94afa036",
+ "shasum": ""
+ },
+ "conflict": {
+ "3f/pygmentize": "<1.2",
+ "admidio/admidio": "<4.2.13",
+ "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3",
+ "aheinze/cockpit": "<2.2",
+ "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5",
+ "airesvsg/acf-to-rest-api": "<=3.1",
+ "akaunting/akaunting": "<2.1.13",
+ "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53",
+ "alextselegidis/easyappointments": "<1.5",
+ "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1",
+ "amazing/media2click": ">=1,<1.3.3",
+ "amphp/artax": "<1.0.6|>=2,<2.0.6",
+ "amphp/http": "<1.0.1",
+ "amphp/http-client": ">=4,<4.4",
+ "anchorcms/anchor-cms": "<=0.12.7",
+ "andreapollastri/cipi": "<=3.1.15",
+ "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5",
+ "apache-solr-for-typo3/solr": "<2.8.3",
+ "apereo/phpcas": "<1.6",
+ "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3",
+ "appwrite/server-ce": "<=1.2.1",
+ "arc/web": "<3",
+ "area17/twill": "<1.2.5|>=2,<2.5.3",
+ "artesaos/seotools": "<0.17.2",
+ "asymmetricrypt/asymmetricrypt": "<9.9.99",
+ "athlon1600/php-proxy": "<=5.1",
+ "athlon1600/php-proxy-app": "<=3",
+ "austintoddj/canvas": "<=3.4.2",
+ "automad/automad": "<=1.10.9",
+ "awesome-support/awesome-support": "<=6.0.7",
+ "aws/aws-sdk-php": "<3.288.1",
+ "azuracast/azuracast": "<0.18.3",
+ "backdrop/backdrop": "<1.24.2",
+ "backpack/crud": "<3.4.9",
+ "bacula-web/bacula-web": "<8.0.0.0-RC2-dev",
+ "badaso/core": "<2.7",
+ "bagisto/bagisto": "<2.1",
+ "barrelstrength/sprout-base-email": "<1.2.7",
+ "barrelstrength/sprout-forms": "<3.9",
+ "barryvdh/laravel-translation-manager": "<0.6.2",
+ "barzahlen/barzahlen-php": "<2.0.1",
+ "baserproject/basercms": "<5.0.9",
+ "bassjobsen/bootstrap-3-typeahead": ">4.0.2",
+ "bigfork/silverstripe-form-capture": ">=3,<3.1.1",
+ "billz/raspap-webgui": "<2.9.5",
+ "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3",
+ "bmarshall511/wordpress_zero_spam": "<5.2.13",
+ "bolt/bolt": "<3.7.2",
+ "bolt/core": "<=4.2",
+ "bottelet/flarepoint": "<2.2.1",
+ "bref/bref": "<2.1.13",
+ "brightlocal/phpwhois": "<=4.2.5",
+ "brotkrueml/codehighlight": "<2.7",
+ "brotkrueml/schema": "<1.13.1|>=2,<2.5.1",
+ "brotkrueml/typo3-matomo-integration": "<1.3.2",
+ "buddypress/buddypress": "<7.2.1",
+ "bugsnag/bugsnag-laravel": ">=2,<2.0.2",
+ "bytefury/crater": "<6.0.2",
+ "cachethq/cachet": "<2.5.1",
+ "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
+ "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
+ "cardgate/magento2": "<2.0.33",
+ "cardgate/woocommerce": "<=3.1.15",
+ "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
+ "cartalyst/sentry": "<=2.1.6",
+ "catfan/medoo": "<1.7.5",
+ "cecil/cecil": "<7.47.1",
+ "centreon/centreon": "<22.10.0.0-beta1",
+ "cesnet/simplesamlphp-module-proxystatistics": "<3.1",
+ "chriskacerguis/codeigniter-restserver": "<=2.7.1",
+ "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3",
+ "ckeditor/ckeditor": "<4.24",
+ "cockpit-hq/cockpit": "<=2.6.3|==2.7",
+ "codeception/codeception": "<3.1.3|>=4,<4.1.22",
+ "codeigniter/framework": "<3.1.9",
+ "codeigniter4/framework": "<=4.4.2",
+ "codeigniter4/shield": "<1.0.0.0-beta8",
+ "codiad/codiad": "<=2.8.4",
+ "composer/composer": "<1.10.27|>=2,<2.2.23|>=2.3,<2.7",
+ "concrete5/concrete5": "<9.2.7",
+ "concrete5/core": "<8.5.8|>=9,<9.1",
+ "contao-components/mediaelement": ">=2.14.2,<2.21.1",
+ "contao/contao": ">=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4",
+ "contao/core": ">=2,<3.5.39",
+ "contao/core-bundle": ">=3,<3.5.35|>=4,<4.9.42|>=4.10,<4.13.28|>=5,<5.1.10",
+ "contao/listing-bundle": ">=4,<4.4.8",
+ "contao/managed-edition": "<=1.5",
+ "corveda/phpsandbox": "<1.3.5",
+ "cosenary/instagram": "<=2.3",
+ "craftcms/cms": "<4.6.2",
+ "croogo/croogo": "<4",
+ "cuyz/valinor": "<0.12",
+ "czproject/git-php": "<4.0.3",
+ "darylldoyle/safe-svg": "<1.9.10",
+ "datadog/dd-trace": ">=0.30,<0.30.2",
+ "datatables/datatables": "<1.10.10",
+ "david-garcia/phpwhois": "<=4.3.1",
+ "dbrisinajumi/d2files": "<1",
+ "dcat/laravel-admin": "<=2.1.3.0-beta",
+ "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3",
+ "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4",
+ "desperado/xml-bundle": "<=0.1.7",
+ "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2",
+ "doctrine/annotations": "<1.2.7",
+ "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
+ "doctrine/common": "<2.4.3|>=2.5,<2.5.1",
+ "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4",
+ "doctrine/doctrine-bundle": "<1.5.2",
+ "doctrine/doctrine-module": "<=0.7.1",
+ "doctrine/mongodb-odm": "<1.0.2",
+ "doctrine/mongodb-odm-bundle": "<3.0.1",
+ "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4",
+ "dolibarr/dolibarr": "<18.0.2",
+ "dompdf/dompdf": "<2.0.4",
+ "doublethreedigital/guest-entries": "<3.1.2",
+ "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2",
+ "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
+ "duncanmcclean/guest-entries": "<3.1.2",
+ "dweeves/magmi": "<=0.7.24",
+ "ec-cube/ec-cube": "<2.4.4",
+ "ecodev/newsletter": "<=4",
+ "ectouch/ectouch": "<=2.7.2",
+ "elefant/cms": "<2.0.7",
+ "elgg/elgg": "<3.3.24|>=4,<4.0.5",
+ "elijaa/phpmemcacheadmin": "<=1.3",
+ "encore/laravel-admin": "<=1.8.19",
+ "endroid/qr-code-bundle": "<3.4.2",
+ "enhavo/enhavo-app": "<=0.13.1",
+ "enshrined/svg-sanitize": "<0.15",
+ "erusev/parsedown": "<1.7.2",
+ "ether/logs": "<3.0.4",
+ "evolutioncms/evolution": "<=3.2.3",
+ "exceedone/exment": "<4.4.3|>=5,<5.0.3",
+ "exceedone/laravel-admin": "<2.2.3|==3",
+ "ezsystems/demobundle": ">=5.4,<5.4.6.1-dev",
+ "ezsystems/ez-support-tools": ">=2.2,<2.2.3",
+ "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev",
+ "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev",
+ "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24",
+ "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26",
+ "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1",
+ "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12",
+ "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.34",
+ "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8",
+ "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev",
+ "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15",
+ "ezsystems/ezplatform-user": ">=1,<1.0.1",
+ "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31",
+ "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.06,<=2019.03.5.1",
+ "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3",
+ "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15",
+ "ezyang/htmlpurifier": "<4.1.1",
+ "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2",
+ "facturascripts/facturascripts": "<=2022.08",
+ "feehi/cms": "<=2.1.1",
+ "feehi/feehicms": "<=2.1.1",
+ "fenom/fenom": "<=2.12.1",
+ "filegator/filegator": "<7.8",
+ "firebase/php-jwt": "<6",
+ "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2",
+ "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6",
+ "flarum/core": "<1.8.5",
+ "flarum/framework": "<1.8.5",
+ "flarum/mentions": "<1.6.3",
+ "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15",
+ "flarum/tags": "<=0.1.0.0-beta13",
+ "floriangaerber/magnesium": "<0.3.1",
+ "fluidtypo3/vhs": "<5.1.1",
+ "fof/byobu": ">=0.3.0.0-beta2,<1.1.7",
+ "fof/upload": "<1.2.3",
+ "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1",
+ "fooman/tcpdf": "<6.2.22",
+ "forkcms/forkcms": "<5.11.1",
+ "fossar/tcpdf-parser": "<6.2.22",
+ "francoisjacquet/rosariosis": "<11",
+ "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2",
+ "friendsofsymfony/oauth2-php": "<1.3",
+ "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
+ "friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
+ "friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
+ "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6",
+ "froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.1",
+ "froxlor/froxlor": "<=2.1.1",
+ "fuel/core": "<1.8.1",
+ "funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3",
+ "gaoming13/wechat-php-sdk": "<=1.10.2",
+ "genix/cms": "<=1.1.11",
+ "getgrav/grav": "<1.7.44",
+ "getkirby/cms": "<4.1.1",
+ "getkirby/kirby": "<=2.5.12",
+ "getkirby/panel": "<2.5.14",
+ "getkirby/starterkit": "<=3.7.0.2",
+ "gilacms/gila": "<=1.15.4",
+ "gleez/cms": "<=1.2|==2",
+ "globalpayments/php-sdk": "<2",
+ "gogentooss/samlbase": "<1.2.7",
+ "google/protobuf": "<3.15",
+ "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3",
+ "gree/jose": "<2.2.1",
+ "gregwar/rst": "<1.0.3",
+ "grumpydictator/firefly-iii": "<6.1.7",
+ "gugoan/economizzer": "<=0.9.0.0-beta1",
+ "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5",
+ "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5",
+ "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2",
+ "harvesthq/chosen": "<1.8.7",
+ "helloxz/imgurl": "<=2.31",
+ "hhxsv5/laravel-s": "<3.7.36",
+ "hillelcoren/invoice-ninja": "<5.3.35",
+ "himiklab/yii2-jqgrid-widget": "<1.0.8",
+ "hjue/justwriting": "<=1",
+ "hov/jobfair": "<1.0.13|>=2,<2.0.2",
+ "httpsoft/http-message": "<1.0.12",
+ "hyn/multi-tenant": ">=5.6,<5.7.2",
+ "ibexa/admin-ui": ">=4.2,<4.2.3",
+ "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.4",
+ "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3",
+ "ibexa/post-install": "<=1.0.4",
+ "ibexa/solr": ">=4.5,<4.5.4",
+ "ibexa/user": ">=4,<4.4.3",
+ "icecoder/icecoder": "<=8.1",
+ "idno/known": "<=1.3.1",
+ "illuminate/auth": "<5.5.10",
+ "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4",
+ "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40",
+ "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
+ "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75",
+ "impresscms/impresscms": "<=1.4.5",
+ "impresspages/impresspages": "<=1.0.12",
+ "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3",
+ "in2code/ipandlanguageredirect": "<5.1.2",
+ "in2code/lux": "<17.6.1|>=18,<24.0.2",
+ "innologi/typo3-appointments": "<2.0.6",
+ "intelliants/subrion": "<4.2.2",
+ "islandora/islandora": ">=2,<2.4.1",
+ "ivankristianto/phpwhois": "<=4.3",
+ "jackalope/jackalope-doctrine-dbal": "<1.7.4",
+ "james-heinrich/getid3": "<1.9.21",
+ "james-heinrich/phpthumb": "<1.7.12",
+ "jasig/phpcas": "<1.3.3",
+ "jcbrand/converse.js": "<3.3.3",
+ "joomla/application": "<1.0.13",
+ "joomla/archive": "<1.1.12|>=2,<2.0.1",
+ "joomla/filesystem": "<1.6.2|>=2,<2.0.1",
+ "joomla/filter": "<1.4.4|>=2,<2.0.1",
+ "joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12",
+ "joomla/input": ">=2,<2.0.2",
+ "joomla/joomla-cms": ">=2.5,<3.9.12",
+ "joomla/session": "<1.3.1",
+ "joyqi/hyper-down": "<=2.4.27",
+ "jsdecena/laracom": "<2.0.9",
+ "jsmitty12/phpwhois": "<5.1",
+ "juzaweb/cms": "<=3.4",
+ "kazist/phpwhois": "<=4.2.6",
+ "kelvinmo/simplexrd": "<3.1.1",
+ "kevinpapst/kimai2": "<1.16.7",
+ "khodakhah/nodcms": "<=3",
+ "kimai/kimai": "<2.1",
+ "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4",
+ "klaviyo/magento2-extension": ">=1,<3",
+ "knplabs/knp-snappy": "<=1.4.2",
+ "kohana/core": "<3.3.3",
+ "krayin/laravel-crm": "<1.2.2",
+ "kreait/firebase-php": ">=3.2,<3.8.1",
+ "la-haute-societe/tcpdf": "<6.2.22",
+ "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2",
+ "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1",
+ "laminas/laminas-http": "<2.14.2",
+ "laravel/fortify": "<1.11.1",
+ "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75",
+ "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
+ "latte/latte": "<2.10.8",
+ "lavalite/cms": "<=9",
+ "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5",
+ "league/commonmark": "<0.18.3",
+ "league/flysystem": "<1.1.4|>=2,<2.1.1",
+ "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3",
+ "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3",
+ "librenms/librenms": "<2017.08.18",
+ "liftkit/database": "<2.13.2",
+ "limesurvey/limesurvey": "<3.27.19",
+ "livehelperchat/livehelperchat": "<=3.91",
+ "livewire/livewire": ">2.2.4,<2.2.6",
+ "lms/routes": "<2.1.1",
+ "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2",
+ "luyadev/yii-helpers": "<1.2.1",
+ "magento/community-edition": "<2.4.3.0-patch3|>=2.4.4,<2.4.5",
+ "magento/core": "<=1.9.4.5",
+ "magento/magento1ce": "<1.9.4.3-dev",
+ "magento/magento1ee": ">=1,<1.14.4.3-dev",
+ "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2.0-patch2",
+ "magneto/core": "<1.9.4.4-dev",
+ "maikuolan/phpmussel": ">=1,<1.6",
+ "mainwp/mainwp": "<=4.4.3.3",
+ "mantisbt/mantisbt": "<2.26.1",
+ "marcwillmann/turn": "<0.3.3",
+ "matyhtf/framework": "<3.0.6",
+ "mautic/core": "<4.3",
+ "mediawiki/core": "<1.36.2",
+ "mediawiki/matomo": "<2.4.3",
+ "mediawiki/semantic-media-wiki": "<4.0.2",
+ "melisplatform/melis-asset-manager": "<5.0.1",
+ "melisplatform/melis-cms": "<5.0.1",
+ "melisplatform/melis-front": "<5.0.1",
+ "mezzio/mezzio-swoole": "<3.7|>=4,<4.3",
+ "mgallegos/laravel-jqgrid": "<=1.3",
+ "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1",
+ "microsoft/microsoft-graph-beta": "<2.0.1",
+ "microsoft/microsoft-graph-core": "<2.0.2",
+ "microweber/microweber": "<=2.0.4",
+ "miniorange/miniorange-saml": "<1.4.3",
+ "mittwald/typo3_forum": "<1.2.1",
+ "mobiledetect/mobiledetectlib": "<2.8.32",
+ "modx/revolution": "<=2.8.3.0-patch",
+ "mojo42/jirafeau": "<4.4",
+ "mongodb/mongodb": ">=1,<1.9.2",
+ "monolog/monolog": ">=1.8,<1.12",
+ "moodle/moodle": "<4.3.3",
+ "mos/cimage": "<0.7.19",
+ "movim/moxl": ">=0.8,<=0.10",
+ "mpdf/mpdf": "<=7.1.7",
+ "munkireport/comment": "<4.1",
+ "munkireport/managedinstalls": "<2.6",
+ "munkireport/munkireport": ">=2.5.3,<5.6.3",
+ "mustache/mustache": ">=2,<2.14.1",
+ "namshi/jose": "<2.2",
+ "neoan3-apps/template": "<1.1.1",
+ "neorazorx/facturascripts": "<2022.04",
+ "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
+ "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3",
+ "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9",
+ "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2",
+ "neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
+ "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15",
+ "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6",
+ "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13",
+ "nilsteampassnet/teampass": "<3.0.10",
+ "nonfiction/nterchange": "<4.1.1",
+ "notrinos/notrinos-erp": "<=0.7",
+ "noumo/easyii": "<=0.9",
+ "nukeviet/nukeviet": "<4.5.02",
+ "nyholm/psr7": "<1.6.1",
+ "nystudio107/craft-seomatic": "<3.4.12",
+ "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1",
+ "october/backend": "<1.1.2",
+ "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1",
+ "october/october": "<=3.4.4",
+ "october/rain": "<1.0.472|>=1.1,<1.1.2",
+ "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.2",
+ "omeka/omeka-s": "<4.0.3",
+ "onelogin/php-saml": "<2.10.4",
+ "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5",
+ "open-web-analytics/open-web-analytics": "<1.7.4",
+ "opencart/opencart": "<=3.0.3.7|>=4,<4.0.2.3-dev",
+ "openid/php-openid": "<2.3",
+ "openmage/magento-lts": "<20.5",
+ "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2",
+ "orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5",
+ "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1",
+ "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1",
+ "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7",
+ "oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1",
+ "oro/customer-portal": ">=4.2,<=4.2.8|>=5,<5.0.11|>=5.1,<5.1.1",
+ "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<5.0.8",
+ "oxid-esales/oxideshop-ce": "<4.5",
+ "packbackbooks/lti-1-3-php-library": "<5",
+ "padraic/humbug_get_contents": "<1.1.2",
+ "pagarme/pagarme-php": "<3",
+ "pagekit/pagekit": "<=1.0.18",
+ "paragonie/random_compat": "<2",
+ "passbolt/passbolt_api": "<2.11",
+ "paypal/merchant-sdk-php": "<3.12",
+ "pear/archive_tar": "<1.4.14",
+ "pear/auth": "<1.2.4",
+ "pear/crypt_gpg": "<1.6.7",
+ "pear/pear": "<=1.10.1",
+ "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1",
+ "personnummer/personnummer": "<3.0.2",
+ "phanan/koel": "<5.1.4",
+ "phenx/php-svg-lib": "<0.5.2",
+ "php-mod/curl": "<2.3.2",
+ "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1",
+ "phpems/phpems": ">=6,<=6.1.3",
+ "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7",
+ "phpmailer/phpmailer": "<6.5",
+ "phpmussel/phpmussel": ">=1,<1.6",
+ "phpmyadmin/phpmyadmin": "<5.2.1",
+ "phpmyfaq/phpmyfaq": "<3.2.5",
+ "phpoffice/phpexcel": "<1.8",
+ "phpoffice/phpspreadsheet": "<1.16",
+ "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36",
+ "phpservermon/phpservermon": "<3.6",
+ "phpsysinfo/phpsysinfo": "<3.4.3",
+ "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
+ "phpwhois/phpwhois": "<=4.2.5",
+ "phpxmlrpc/extras": "<0.6.1",
+ "phpxmlrpc/phpxmlrpc": "<4.9.2",
+ "pi/pi": "<=2.5",
+ "pimcore/admin-ui-classic-bundle": "<1.3.4",
+ "pimcore/customer-management-framework-bundle": "<4.0.6",
+ "pimcore/data-hub": "<1.2.4",
+ "pimcore/demo": "<10.3",
+ "pimcore/ecommerce-framework-bundle": "<1.0.10",
+ "pimcore/perspective-editor": "<1.5.1",
+ "pimcore/pimcore": "<11.1.1",
+ "pixelfed/pixelfed": "<0.11.11",
+ "plotly/plotly.js": "<2.25.2",
+ "pocketmine/bedrock-protocol": "<8.0.2",
+ "pocketmine/pocketmine-mp": "<5.11.2",
+ "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1",
+ "pressbooks/pressbooks": "<5.18",
+ "prestashop/autoupgrade": ">=4,<4.10.1",
+ "prestashop/blockreassurance": "<=5.1.3",
+ "prestashop/blockwishlist": ">=2,<2.1.1",
+ "prestashop/contactform": ">=1.0.1,<4.3",
+ "prestashop/gamification": "<2.3.2",
+ "prestashop/prestashop": "<8.1.4",
+ "prestashop/productcomments": "<5.0.2",
+ "prestashop/ps_emailsubscription": "<2.6.1",
+ "prestashop/ps_facetedsearch": "<3.4.1",
+ "prestashop/ps_linklist": "<3.1",
+ "privatebin/privatebin": "<1.4",
+ "processwire/processwire": "<=3.0.210",
+ "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7",
+ "propel/propel1": ">=1,<=1.7.1",
+ "pterodactyl/panel": "<1.7",
+ "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2",
+ "ptrofimov/beanstalk_console": "<1.7.14",
+ "pubnub/pubnub": "<6.1",
+ "pusher/pusher-php-server": "<2.2.1",
+ "pwweb/laravel-core": "<=0.3.6.0-beta",
+ "pyrocms/pyrocms": "<=3.9.1",
+ "rainlab/blog-plugin": "<1.4.1",
+ "rainlab/debugbar-plugin": "<3.1",
+ "rainlab/user-plugin": "<=1.4.5",
+ "rankmath/seo-by-rank-math": "<=1.0.95",
+ "rap2hpoutre/laravel-log-viewer": "<0.13",
+ "react/http": ">=0.7,<1.9",
+ "really-simple-plugins/complianz-gdpr": "<6.4.2",
+ "redaxo/source": "<=5.15.1",
+ "remdex/livehelperchat": "<4.29",
+ "reportico-web/reportico": "<=7.1.21",
+ "rhukster/dom-sanitizer": "<1.0.7",
+ "rmccue/requests": ">=1.6,<1.8",
+ "robrichards/xmlseclibs": ">=1,<3.0.4",
+ "roots/soil": "<4.1",
+ "rudloff/alltube": "<3.0.3",
+ "s-cart/core": "<6.9",
+ "s-cart/s-cart": "<6.9",
+ "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1",
+ "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9",
+ "scheb/two-factor-bundle": "<3.26|>=4,<4.11",
+ "sensiolabs/connect": "<4.2.3",
+ "serluck/phpwhois": "<=4.2.6",
+ "sfroemken/url_redirect": "<=1.2.1",
+ "sheng/yiicms": "<=1.2",
+ "shopware/core": "<=6.5.7.3",
+ "shopware/platform": "<=6.5.7.3|>=6.5.8,<6.5.8.7-dev",
+ "shopware/production": "<=6.3.5.2",
+ "shopware/shopware": "<=5.7.17",
+ "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev",
+ "shopxo/shopxo": "<2.2.6",
+ "showdoc/showdoc": "<2.10.4",
+ "silverstripe-australia/advancedreports": ">=1,<=2",
+ "silverstripe/admin": "<1.13.19|>=2,<2.1.8",
+ "silverstripe/assets": ">=1,<1.11.1",
+ "silverstripe/cms": "<4.11.3",
+ "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1",
+ "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
+ "silverstripe/framework": "<4.13.39|>=5,<5.1.11",
+ "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3",
+ "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1",
+ "silverstripe/recipe-cms": ">=4.5,<4.5.3",
+ "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1",
+ "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4",
+ "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1",
+ "silverstripe/subsites": ">=2,<2.6.1",
+ "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1",
+ "silverstripe/userforms": "<3",
+ "silverstripe/versioned-admin": ">=1,<1.11.1",
+ "simple-updates/phpwhois": "<=1",
+ "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12",
+ "simplesamlphp/simplesamlphp": "<1.18.6",
+ "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
+ "simplesamlphp/simplesamlphp-module-openid": "<1",
+ "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9",
+ "simplesamlphp/xml-security": "==1.6.11",
+ "simplito/elliptic-php": "<1.0.6",
+ "sitegeist/fluid-components": "<3.5",
+ "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3",
+ "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1",
+ "slim/slim": "<2.6",
+ "slub/slub-events": "<3.0.3",
+ "smarty/smarty": "<3.1.48|>=4,<4.3.1",
+ "snipe/snipe-it": "<=6.2.2",
+ "socalnick/scn-social-auth": "<1.15.2",
+ "socialiteproviders/steam": "<1.1",
+ "spatie/browsershot": "<3.57.4",
+ "spipu/html2pdf": "<5.2.8",
+ "spoon/library": "<1.4.1",
+ "spoonity/tcpdf": "<6.2.22",
+ "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
+ "ssddanbrown/bookstack": "<22.02.3",
+ "statamic/cms": "<4.46",
+ "stormpath/sdk": "<9.9.99",
+ "studio-42/elfinder": "<2.1.62",
+ "subhh/libconnect": "<7.0.8|>=8,<8.1",
+ "sukohi/surpass": "<1",
+ "sulu/sulu": "<1.6.44|>=2,<2.4.17|>=2.5,<2.5.13",
+ "sumocoders/framework-user-bundle": "<1.4",
+ "superbig/craft-audit": "<3.0.2",
+ "swag/paypal": "<5.4.4",
+ "swiftmailer/swiftmailer": ">=4,<5.4.5",
+ "swiftyedit/swiftyedit": "<1.2",
+ "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2",
+ "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1",
+ "sylius/grid-bundle": "<1.10.1",
+ "sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1",
+ "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4",
+ "sylius/sylius": "<1.9.10|>=1.10,<1.10.11|>=1.11,<1.11.2",
+ "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99",
+ "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4",
+ "symbiote/silverstripe-seed": "<6.0.3",
+ "symbiote/silverstripe-versionedfiles": "<=2.0.3",
+ "symfont/process": ">=0",
+ "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8",
+ "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
+ "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4",
+ "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
+ "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4",
+ "symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7",
+ "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
+ "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
+ "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1",
+ "symfony/mime": ">=4.3,<4.3.8",
+ "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
+ "symfony/polyfill": ">=1,<1.10",
+ "symfony/polyfill-php55": ">=1,<1.10",
+ "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
+ "symfony/routing": ">=2,<2.0.19",
+ "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8",
+ "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
+ "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9",
+ "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
+ "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8",
+ "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2|>=5.4,<5.4.31|>=6,<6.3.8",
+ "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12",
+ "symfony/symfony": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8",
+ "symfony/translation": ">=2,<2.0.17",
+ "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8",
+ "symfony/ux-autocomplete": "<2.11.2",
+ "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3",
+ "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8",
+ "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
+ "symfony/webhook": ">=6.3,<6.3.8",
+ "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7|>=2.2.0.0-beta1,<2.2.0.0-beta2",
+ "symphonycms/symphony-2": "<2.6.4",
+ "t3/dce": "<0.11.5|>=2.2,<2.6.2",
+ "t3g/svg-sanitizer": "<1.0.3",
+ "t3s/content-consent": "<1.0.3|>=2,<2.0.2",
+ "tastyigniter/tastyigniter": "<3.3",
+ "tcg/voyager": "<=1.4",
+ "tecnickcom/tcpdf": "<6.2.22",
+ "terminal42/contao-tablelookupwizard": "<3.3.5",
+ "thelia/backoffice-default-template": ">=2.1,<2.1.2",
+ "thelia/thelia": ">=2.1,<2.1.3",
+ "theonedemon/phpwhois": "<=4.2.5",
+ "thinkcmf/thinkcmf": "<=5.1.7",
+ "thorsten/phpmyfaq": "<3.2.2",
+ "tikiwiki/tiki-manager": "<=17.1",
+ "tinymce/tinymce": "<5.10.9|>=6,<6.7.3",
+ "tinymighty/wiki-seo": "<1.2.2",
+ "titon/framework": "<9.9.99",
+ "tobiasbg/tablepress": "<=2.0.0.0-RC1",
+ "topthink/framework": "<6.0.14",
+ "topthink/think": "<=6.1.1",
+ "topthink/thinkphp": "<=3.2.3",
+ "torrentpier/torrentpier": "<=2.4.1",
+ "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2",
+ "tribalsystems/zenario": "<=9.4.59197",
+ "truckersmp/phpwhois": "<=4.3.1",
+ "ttskch/pagination-service-provider": "<1",
+ "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3",
+ "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2",
+ "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
+ "typo3/cms-core": "<=8.7.56|>=9,<=9.5.45|>=10,<=10.4.42|>=11,<=11.5.34|>=12,<=12.4.10|==13",
+ "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1",
+ "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1",
+ "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
+ "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5",
+ "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8",
+ "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30",
+ "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
+ "typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3",
+ "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
+ "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1",
+ "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
+ "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10",
+ "ua-parser/uap-php": "<3.8",
+ "uasoft-indonesia/badaso": "<=2.9.7",
+ "unisharp/laravel-filemanager": "<2.6.4",
+ "userfrosting/userfrosting": ">=0.3.1,<4.6.3",
+ "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2",
+ "uvdesk/community-skeleton": "<=1.1.1",
+ "vanilla/safecurl": "<0.9.2",
+ "verot/class.upload.php": "<=2.1.6",
+ "vova07/yii2-fileapi-widget": "<0.1.9",
+ "vrana/adminer": "<4.8.1",
+ "waldhacker/hcaptcha": "<2.1.2",
+ "wallabag/tcpdf": "<6.2.22",
+ "wallabag/wallabag": "<2.6.7",
+ "wanglelecc/laracms": "<=1.0.3",
+ "web-auth/webauthn-framework": ">=3.3,<3.3.4",
+ "webbuilders-group/silverstripe-kapost-bridge": "<0.4",
+ "webcoast/deferred-image-processing": "<1.0.2",
+ "webklex/laravel-imap": "<5.3",
+ "webklex/php-imap": "<5.3",
+ "webpa/webpa": "<3.1.2",
+ "wikibase/wikibase": "<=1.39.3",
+ "wikimedia/parsoid": "<0.12.2",
+ "willdurand/js-translation-bundle": "<2.1.1",
+ "winter/wn-backend-module": "<1.2.4",
+ "winter/wn-system-module": "<1.2.4",
+ "wintercms/winter": "<1.2.3",
+ "woocommerce/woocommerce": "<6.6",
+ "wp-cli/wp-cli": ">=0.12,<2.5",
+ "wp-graphql/wp-graphql": "<=1.14.5",
+ "wpanel/wpanel4-cms": "<=4.3.1",
+ "wpcloud/wp-stateless": "<3.2",
+ "wwbn/avideo": "<=12.4",
+ "xataface/xataface": "<3",
+ "xpressengine/xpressengine": "<3.0.15",
+ "yeswiki/yeswiki": "<4.1",
+ "yetiforce/yetiforce-crm": "<=6.4",
+ "yidashi/yii2cmf": "<=2",
+ "yii2mod/yii2-cms": "<1.9.2",
+ "yiisoft/yii": "<1.1.29",
+ "yiisoft/yii2": "<2.0.38",
+ "yiisoft/yii2-authclient": "<2.2.15",
+ "yiisoft/yii2-bootstrap": "<2.0.4",
+ "yiisoft/yii2-dev": "<2.0.43",
+ "yiisoft/yii2-elasticsearch": "<2.0.5",
+ "yiisoft/yii2-gii": "<=2.2.4",
+ "yiisoft/yii2-jui": "<2.0.4",
+ "yiisoft/yii2-redis": "<2.0.8",
+ "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6",
+ "yoast-seo-for-typo3/yoast_seo": "<7.2.3",
+ "yourls/yourls": "<=1.8.2",
+ "yuan1994/tpadmin": "<=1.3.12",
+ "zencart/zencart": "<=1.5.7.0-beta",
+ "zendesk/zendesk_api_client_php": "<2.2.11",
+ "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3",
+ "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2",
+ "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2",
+ "zendframework/zend-db": "<2.2.10|>=2.3,<2.3.5",
+ "zendframework/zend-developer-tools": ">=1.2.2,<1.2.3",
+ "zendframework/zend-diactoros": "<1.8.4",
+ "zendframework/zend-feed": "<2.10.3",
+ "zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1",
+ "zendframework/zend-http": "<2.8.1",
+ "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6",
+ "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3",
+ "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2",
+ "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1",
+ "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4",
+ "zendframework/zend-validator": ">=2.3,<2.3.6",
+ "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1",
+ "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6",
+ "zendframework/zendframework": "<=3",
+ "zendframework/zendframework1": "<1.12.20",
+ "zendframework/zendopenid": "<2.0.2",
+ "zendframework/zendrest": "<2.0.2",
+ "zendframework/zendservice-amazon": "<2.0.3",
+ "zendframework/zendservice-api": "<1",
+ "zendframework/zendservice-audioscrobbler": "<2.0.2",
+ "zendframework/zendservice-nirvanix": "<2.0.2",
+ "zendframework/zendservice-slideshare": "<2.0.2",
+ "zendframework/zendservice-technorati": "<2.0.2",
+ "zendframework/zendservice-windowsazure": "<2.0.2",
+ "zendframework/zendxml": ">=1,<1.0.1",
+ "zenstruck/collection": "<0.2.1",
+ "zetacomponents/mail": "<1.8.2",
+ "zf-commons/zfc-user": "<1.2.2",
+ "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3",
+ "zfr/zfr-oauth2-server-module": "<0.1.2",
+ "zoujingli/thinkadmin": "<=6.1.53"
+ },
+ "default-branch": true,
+ "type": "metapackage",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "role": "maintainer"
+ },
+ {
+ "name": "Ilya Tribusean",
+ "email": "slash3b@gmail.com",
+ "role": "maintainer"
+ }
+ ],
+ "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
+ "keywords": [
+ "dev"
+ ],
+ "support": {
+ "issues": "https://github.com/Roave/SecurityAdvisories/issues",
+ "source": "https://github.com/Roave/SecurityAdvisories/tree/latest"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Ocramius",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/roave/security-advisories",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-03-08T12:05:25+00:00"
+ },
+ {
+ "name": "sabre/event",
+ "version": "5.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sabre-io/event.git",
+ "reference": "d7da22897125d34d7eddf7977758191c06a74497"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sabre-io/event/zipball/d7da22897125d34d7eddf7977758191c06a74497",
+ "reference": "d7da22897125d34d7eddf7977758191c06a74497",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~2.17.1",
+ "phpstan/phpstan": "^0.12",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/coroutine.php",
+ "lib/Loop/functions.php",
+ "lib/Promise/functions.php"
+ ],
+ "psr-4": {
+ "Sabre\\Event\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "sabre/event is a library for lightweight event-based programming",
+ "homepage": "http://sabre.io/event/",
+ "keywords": [
+ "EventEmitter",
+ "async",
+ "coroutine",
+ "eventloop",
+ "events",
+ "hooks",
+ "plugin",
+ "promise",
+ "reactor",
+ "signal"
+ ],
+ "support": {
+ "forum": "https://groups.google.com/group/sabredav-discuss",
+ "issues": "https://github.com/sabre-io/event/issues",
+ "source": "https://github.com/fruux/sabre-event"
+ },
+ "time": "2021-11-04T06:51:17+00:00"
+ },
+ {
+ "name": "sebastian/cli-parser",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.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",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:27:43+00:00"
+ },
+ {
+ "name": "sebastian/code-unit",
+ "version": "1.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.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/1.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:08:54+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.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/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:30:19+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "4.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/diff": "^4.0",
+ "sebastian/exporter": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-09-14T12:41:17+00:00"
+ },
+ {
+ "name": "sebastian/complexity",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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 calculating the complexity of PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/complexity",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/complexity/issues",
+ "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:19:30+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "4.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-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",
+ "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:30:58+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "5.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-posix": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.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": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:03:51+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "4.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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": "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",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:33:00+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "5.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:35:11+00:00"
+ },
+ {
+ "name": "sebastian/lines-of-code",
+ "version": "1.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.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",
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:20:34+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:12:34+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.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/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:14:26+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "4.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:07:39+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:45:17+00:00"
+ },
+ {
+ "name": "sebastian/type",
+ "version": "3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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": "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/3.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:13:03+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "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": "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/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:39:44+00:00"
+ },
+ {
+ "name": "spatie/array-to-xml",
+ "version": "3.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/array-to-xml.git",
+ "reference": "c95fd4db94ec199f798d4b5b4a81757bd20d88ab"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/c95fd4db94ec199f798d4b5b4a81757bd20d88ab",
+ "reference": "c95fd4db94ec199f798d4b5b4a81757bd20d88ab",
+ "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",
+ "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.2.3"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2024-02-07T10:39:02+00:00"
+ },
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "3.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
+ "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
+ "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
+ },
+ "bin": [
+ "bin/phpcbf",
+ "bin/phpcs"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "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, JavaScript and CSS 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"
+ }
+ ],
+ "time": "2024-02-16T15:06:51+00:00"
+ },
+ {
+ "name": "symfony/config",
+ "version": "v6.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/config.git",
+ "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/config/zipball/6ea4affc27f2086c9d16b92ab5429ce1e3c38047",
+ "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/filesystem": "^5.4|^6.0|^7.0",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "conflict": {
+ "symfony/finder": "<5.4",
+ "symfony/service-contracts": "<2.5"
+ },
+ "require-dev": {
+ "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
+ "symfony/finder": "^5.4|^6.0|^7.0",
+ "symfony/messenger": "^5.4|^6.0|^7.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/yaml": "^5.4|^6.0|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Config\\": ""
+ },
+ "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": "Helps you find, load, combine, autofill and validate configuration values of any kind",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/config/tree/v6.4.4"
+ },
+ "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-02-26T07:52:26+00:00"
+ },
+ {
+ "name": "symfony/dependency-injection",
+ "version": "v6.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dependency-injection.git",
+ "reference": "6236e5e843cb763e9d0f74245678b994afea5363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6236e5e843cb763e9d0f74245678b994afea5363",
+ "reference": "6236e5e843cb763e9d0f74245678b994afea5363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/container": "^1.1|^2.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/service-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^6.2.10|^7.0"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2",
+ "symfony/config": "<6.1",
+ "symfony/finder": "<5.4",
+ "symfony/proxy-manager-bridge": "<6.3",
+ "symfony/yaml": "<5.4"
+ },
+ "provide": {
+ "psr/container-implementation": "1.1|2.0",
+ "symfony/service-implementation": "1.1|2.0|3.0"
+ },
+ "require-dev": {
+ "symfony/config": "^6.1|^7.0",
+ "symfony/expression-language": "^5.4|^6.0|^7.0",
+ "symfony/yaml": "^5.4|^6.0|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\DependencyInjection\\": ""
+ },
+ "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": "Allows you to standardize and centralize the way objects are constructed in your application",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/dependency-injection/tree/v6.4.4"
+ },
+ "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-02-22T20:27:10+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v6.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae9d3a6f3003a6caf56acd7466d8d52378d44fef",
+ "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/event-dispatcher-contracts": "^2.5|^3"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4",
+ "symfony/service-contracts": "<2.5"
+ },
+ "provide": {
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/error-handler": "^5.4|^6.0|^7.0",
+ "symfony/expression-language": "^5.4|^6.0|^7.0",
+ "symfony/http-foundation": "^5.4|^6.0|^7.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^5.4|^6.0|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "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 tools that allow your application components to communicate with each other by dispatching events and listening to them",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.3"
+ },
+ "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-01-23T14:51:35+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "a76aed96a42d2b521153fb382d418e30d18b59df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df",
+ "reference": "a76aed96a42d2b521153fb382d418e30d18b59df",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/event-dispatcher": "^1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\EventDispatcher\\": ""
+ }
+ },
+ "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 dispatching event",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.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": "2023-05-23T14:45:45+00:00"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v6.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb",
+ "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8"
+ },
+ "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/v6.4.3"
+ },
+ "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-01-23T14:51:35+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "11d736e97f116ac375a81f96e662911a34cd50ce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce",
+ "reference": "11d736e97f116ac375a81f96e662911a34cd50ce",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/filesystem": "^6.0|^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/v6.4.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": "2023-10-31T17:30:12+00:00"
+ },
+ {
+ "name": "symfony/options-resolver",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/options-resolver.git",
+ "reference": "22301f0e7fdeaacc14318928612dee79be99860e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e",
+ "reference": "22301f0e7fdeaacc14318928612dee79be99860e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ },
+ "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 an improved replacement for the array_replace PHP function",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/options-resolver/tree/v6.4.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": "2023-08-08T10:16:24+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.29.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/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.29.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-01-29T20:11:03+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php81",
+ "version": "v1.29.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php81.git",
+ "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d",
+ "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/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.29.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-01-29T20:11:03+00:00"
+ },
+ {
+ "name": "symfony/stopwatch",
+ "version": "v6.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/stopwatch.git",
+ "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/416596166641f1f728b0a64f5b9dd07cceb410c1",
+ "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/service-contracts": "^2.5|^3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Stopwatch\\": ""
+ },
+ "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 a way to profile code",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/stopwatch/tree/v6.4.3"
+ },
+ "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-01-23T14:35:58+00:00"
+ },
+ {
+ "name": "symfony/var-dumper",
+ "version": "v6.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "b439823f04c98b84d4366c79507e9da6230944b1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b439823f04c98b84d4366c79507e9da6230944b1",
+ "reference": "b439823f04c98b84d4366c79507e9da6230944b1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/console": "<5.4"
+ },
+ "require-dev": {
+ "ext-iconv": "*",
+ "symfony/console": "^5.4|^6.0|^7.0",
+ "symfony/error-handler": "^6.3|^7.0",
+ "symfony/http-kernel": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
+ "symfony/uid": "^5.4|^6.0|^7.0",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\VarDumper\\": ""
+ },
+ "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 mechanisms for walking through any arbitrary PHP variable",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "debug",
+ "dump"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-dumper/tree/v6.4.4"
+ },
+ "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-02-15T11:23:52+00:00"
+ },
+ {
+ "name": "symfony/var-exporter",
+ "version": "v6.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-exporter.git",
+ "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0bd342e24aef49fc82a21bd4eedd3e665d177e5b",
+ "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3"
+ },
+ "require-dev": {
+ "symfony/var-dumper": "^5.4|^6.0|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\VarExporter\\": ""
+ },
+ "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": "Allows exporting any serializable PHP data structure to plain PHP code",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "clone",
+ "construct",
+ "export",
+ "hydrate",
+ "instantiate",
+ "lazy-loading",
+ "proxy",
+ "serialize"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-exporter/tree/v6.4.4"
+ },
+ "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-02-26T08:37:45+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v6.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "d75715985f0f94f978e3a8fa42533e10db921b90"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/d75715985f0f94f978e3a8fa42533e10db921b90",
+ "reference": "d75715985f0f94f978e3a8fa42533e10db921b90",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "symfony/console": "<5.4"
+ },
+ "require-dev": {
+ "symfony/console": "^5.4|^6.0|^7.0"
+ },
+ "bin": [
+ "Resources/bin/yaml-lint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "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": "Loads and dumps YAML files",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/yaml/tree/v6.4.3"
+ },
+ "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-01-23T14:51:35+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": "tysonandre/var_representation_polyfill",
+ "version": "0.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/TysonAndre/var_representation_polyfill.git",
+ "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/TysonAndre/var_representation_polyfill/zipball/e9116c2c352bb0835ca428b442dde7767c11ad32",
+ "reference": "e9116c2c352bb0835ca428b442dde7767c11ad32",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.2.0|^8.0.0"
+ },
+ "provide": {
+ "ext-var_representation": "*"
+ },
+ "require-dev": {
+ "phan/phan": "^5.4.1",
+ "phpunit/phpunit": "^8.5.0"
+ },
+ "suggest": {
+ "ext-var_representation": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.1.3-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/var_representation.php"
+ ],
+ "psr-4": {
+ "VarRepresentation\\": "src/VarRepresentation"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Tyson Andre"
+ }
+ ],
+ "description": "Polyfill for var_representation: convert a variable to a string in a way that fixes the shortcomings of var_export",
+ "keywords": [
+ "var_export",
+ "var_representation"
+ ],
+ "support": {
+ "issues": "https://github.com/TysonAndre/var_representation_polyfill/issues",
+ "source": "https://github.com/TysonAndre/var_representation_polyfill/tree/0.1.3"
+ },
+ "time": "2022-08-31T12:59:22+00:00"
+ },
+ {
+ "name": "ulrichsg/getopt-php",
+ "version": "v4.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/getopt-php/getopt-php.git",
+ "reference": "91c31c9bc0ff9bbe22b0b02c63c7f5ddb8d2a8d5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/getopt-php/getopt-php/zipball/91c31c9bc0ff9bbe22b0b02c63c7f5ddb8d2a8d5",
+ "reference": "91c31c9bc0ff9bbe22b0b02c63c7f5ddb8d2a8d5",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*",
+ "squizlabs/php_codesniffer": "^3.5.8",
+ "tflori/phpunit-printer": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "GetOpt\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ulrich Schmidt-Goertz",
+ "email": "ulrich@schmidt-goertz.de"
+ },
+ {
+ "name": "Thomas Flori",
+ "email": "thflori@gmail.com"
+ }
+ ],
+ "description": "Command line arguments parser for PHP 7.1 and above",
+ "homepage": "http://getopt-php.github.io/getopt-php",
+ "support": {
+ "issues": "https://github.com/getopt-php/getopt-php/issues",
+ "source": "https://github.com/getopt-php/getopt-php/tree/v4.0.3"
+ },
+ "time": "2022-12-13T20:37:45+00:00"
+ },
+ {
+ "name": "vimeo/psalm",
+ "version": "5.22.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/vimeo/psalm.git",
+ "reference": "d768d914152dbbf3486c36398802f74e80cfde48"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/vimeo/psalm/zipball/d768d914152dbbf3486c36398802f74e80cfde48",
+ "reference": "d768d914152dbbf3486c36398802f74e80cfde48",
+ "shasum": ""
+ },
+ "require": {
+ "amphp/amp": "^2.4.2",
+ "amphp/byte-stream": "^1.5",
+ "composer-runtime-api": "^2",
+ "composer/semver": "^1.4 || ^2.0 || ^3.0",
+ "composer/xdebug-handler": "^2.0 || ^3.0",
+ "dnoegel/php-xdg-base-dir": "^0.1.1",
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "felixfbecker/advanced-json-rpc": "^3.1",
+ "felixfbecker/language-server-protocol": "^1.5.2",
+ "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0",
+ "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+ "nikic/php-parser": "^4.16",
+ "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
+ "sebastian/diff": "^4.0 || ^5.0 || ^6.0",
+ "spatie/array-to-xml": "^2.17.0 || ^3.0",
+ "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/filesystem": "^5.4 || ^6.0 || ^7.0"
+ },
+ "conflict": {
+ "nikic/php-parser": "4.17.0"
+ },
+ "provide": {
+ "psalm/psalm": "self.version"
+ },
+ "require-dev": {
+ "amphp/phpunit-util": "^2.0",
+ "bamarni/composer-bin-plugin": "^1.4",
+ "brianium/paratest": "^6.9",
+ "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.18",
+ "slevomat/coding-standard": "^8.4",
+ "squizlabs/php_codesniffer": "^3.6",
+ "symfony/process": "^4.4 || ^5.0 || ^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",
+ "psalter"
+ ],
+ "type": "project",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.x-dev",
+ "dev-4.x": "4.x-dev",
+ "dev-3.x": "3.x-dev",
+ "dev-2.x": "2.x-dev",
+ "dev-1.x": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psalm\\": "src/Psalm/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matthew Brown"
+ }
+ ],
+ "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": "2024-02-22T23:39:07+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": {
+ "roave/security-advisories": 20
+ },
+ "prefer-stable": true,
+ "prefer-lowest": false,
+ "platform": {
+ "php": "^8.1",
+ "ext-mbstring": "*"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.3.0"
+}
diff --git a/csv-blueprint b/csv-blueprint
new file mode 100644
index 00000000..c98a086a
--- /dev/null
+++ b/csv-blueprint
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+registerCommandsByPath(PATH_ROOT . '/src/Commands', __NAMESPACE__)
+ ->setLogo(
+ <<<'EOF'
+ _____ ______ _ _ _
+ / __ \ | ___ \ | (_) | |
+ | / \/_____ __ | |_/ / |_ _ ___ _ __ _ __ _ _ __ | |_
+ | | / __\ \ / / | ___ \ | | | |/ _ \ '_ \| '__| | '_ \| __|
+ | \__/\__ \\ V / | |_/ / | |_| | __/ |_) | | | | | | | |_
+ \____/___/ \_/ \____/|_|\__,_|\___| .__/|_| |_|_| |_|\__|
+ | |
+ |_|
+ EOF,
+ )
+ ->run();
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 00000000..9ca3124e
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,53 @@
+
+
+
+
+
+ src
+
+
+
+
+
+
+
+
+
+
+
+ tests
+
+
+
+
+
+
+
diff --git a/schema-examples/full.json b/schema-examples/full.json
new file mode 100644
index 00000000..51bf4158
--- /dev/null
+++ b/schema-examples/full.json
@@ -0,0 +1,46 @@
+{
+ "csv" : {
+ "header" : true,
+ "delimiter" : ",",
+ "quote_char" : "\\",
+ "enclosure" : "\"",
+ "encoding" : "utf-8",
+ "bom" : false
+ },
+ "columns" : [
+ {
+ "name" : "csv_header_name",
+ "description" : "Lorem ipsum",
+ "rules" : {
+ "not_empty" : true,
+ "exact_value" : "Some string",
+ "allow_values" : ["y", "n", ""],
+ "regex" : "\/^[\\d]{2}$\/",
+ "min_length" : 1,
+ "max_length" : 10,
+ "only_trimed" : true,
+ "only_lowercase" : true,
+ "only_uppercase" : true,
+ "only_capitalize" : true,
+ "min" : 10,
+ "max" : 100.5,
+ "precision" : 2,
+ "date_format" : "Y-m-d",
+ "min_date" : "2000-01-02",
+ "max_date" : "+1 day",
+ "is_bool" : true,
+ "is_int" : true,
+ "is_float" : true,
+ "is_ip" : true,
+ "is_url" : true,
+ "is_email" : true,
+ "is_domain" : true,
+ "is_uuid4" : true,
+ "is_latitude" : true,
+ "is_longitude" : true,
+ "cardinal_direction" : true,
+ "usa_market_name" : true
+ }
+ }
+ ]
+}
diff --git a/schema-examples/full.php b/schema-examples/full.php
new file mode 100644
index 00000000..b5bae14a
--- /dev/null
+++ b/schema-examples/full.php
@@ -0,0 +1,62 @@
+ [
+ 'header' => true,
+ 'delimiter' => ',',
+ 'quote_char' => '\\',
+ 'enclosure' => '"',
+ 'encoding' => 'utf-8',
+ 'bom' => false,
+ ],
+ 'columns' => [
+ [
+ 'name' => 'csv_header_name',
+ 'description' => 'Lorem ipsum',
+ 'rules' => [
+ 'not_empty' => true,
+ 'exact_value' => 'Some string',
+ 'allow_values' => ['y', 'n', ''],
+ 'regex' => '/^[\\d]{2}$/',
+ 'min_length' => 1,
+ 'max_length' => 10,
+ 'only_trimed' => true,
+ 'only_lowercase' => true,
+ 'only_uppercase' => true,
+ 'only_capitalize' => true,
+ 'min' => 10,
+ 'max' => 100.5,
+ 'precision' => 2,
+ 'date_format' => 'Y-m-d',
+ 'min_date' => '2000-01-02',
+ 'max_date' => '+1 day',
+ 'is_bool' => true,
+ 'is_int' => true,
+ 'is_float' => true,
+ 'is_ip' => true,
+ 'is_url' => true,
+ 'is_email' => true,
+ 'is_domain' => true,
+ 'is_uuid4' => true,
+ 'is_latitude' => true,
+ 'is_longitude' => true,
+ 'cardinal_direction' => true,
+ 'usa_market_name' => true,
+ ],
+ ],
+ ],
+];
diff --git a/schema-examples/full.yml b/schema-examples/full.yml
new file mode 100644
index 00000000..b49102eb
--- /dev/null
+++ b/schema-examples/full.yml
@@ -0,0 +1,68 @@
+#
+# JBZoo Toolbox - Csv-Blueprint.
+#
+# This file is part of the JBZoo Toolbox project.
+# For the full copyright and license information, please view the LICENSE
+# file that was distributed with this source code.
+#
+# @license MIT
+# @copyright Copyright (C) JBZoo.com, All rights reserved.
+# @see https://github.com/JBZoo/Csv-Blueprint
+#
+
+# It's a full example of the CSV schema file in YAML format.
+
+csv: # Here are default values. You can skip this section if you don't need to override the default values
+ header: true # If the first row is a header. If true, name of each column is required
+ delimiter: , # Delimiter character in CSV file
+ quote_char: \ # Quote character in CSV file
+ enclosure: "\"" # Enclosure for each field in CSV file
+ encoding: utf-8 # Only utf-8, utf-16, utf-32 (Experimental)
+ bom: false # If the file has a BOM (Byte Order Mark) at the beginning (Experimental)
+
+columns:
+ - name: "csv_header_name" # Any custom name of the column in the CSV file (first row). Required if "csv_structure.header" is true.
+ description: "Lorem ipsum" # Optional. Description of the column. Not used in the validation process.
+ rules:
+ # You can use the rules in any combination. Or not use any of them.
+ # They are grouped below simply for ease of navigation and reading.
+ # If you see the value for the rule is "true" - that's just an enable flag.
+ # In other cases, these are rule parameters.
+
+ # General rules
+ not_empty: true # Value is not empty string. Ignore spaces.
+ exact_value: Some string # Case-sensitive. Exact value for string in the column
+ allow_values: [ y, n, "" ] # Strict set of values that are allowed. Case-sensitive.
+
+ # Strings only
+ regex: /^[\d]{2}$/ # Any valid regex pattern. See https://www.php.net/manual/en/reference.pcre.pattern.syntax.php
+ min_length: 1 # Integer only. Min length of the string with spaces
+ max_length: 10 # Integer only. Max length of the string with spaces
+ only_trimed: true # Only trimed strings. Example: "Hello World" (not " Hello World ")
+ only_lowercase: true # String is only lower-case. Example: "hello world"
+ only_uppercase: true # String is only upper-case. Example: "HELLO WORLD"
+ only_capitalize: true # String is only capitalized. Example: "Hello World"
+
+ # Deciaml and integer numbers
+ min: 10 # Can be integer or float, negative and positive
+ max: 100.50 # Can be integer or float, negative and positive
+ precision: 2 # Strict(!) number of digits after the decimal point
+
+ # Dates
+ date_format: Y-m-d # See: https://www.php.net/manual/en/datetime.format.php
+ min_date: "2000-01-02" # See examples https://www.php.net/manual/en/function.strtotime.php
+ max_date: "+1 day" # See examples https://www.php.net/manual/en/function.strtotime.php
+
+ # Specific formats
+ is_bool: true # Allow only boolean values "true" and "false", case-insensitive
+ is_int: true # Check format only. Can be negative and positive. Without any separators
+ is_float: true # Check format only. Can be negative and positive. Dot as decimal separator
+ is_ip: true # Only IPv4. Example: "127.0.0.1"
+ is_url: true # Only URL format. Example: "https://example.com/page?query=string#anchor"
+ is_email: true # Only email format. Example: "user@example.com"
+ is_domain: true # Only domain name. Example: "example.com"
+ is_uuid4: true # Only UUID4 format. Example: "550e8400-e29b-41d4-a716-446655440000"
+ is_latitude: true # Can be integer or float. Example: 50.123456
+ is_longitude: true # Can be integer or float. Example: -89.123456
+ cardinal_direction: true # Valid cardinal direction. Examples: "N", "S", "NE", "SE", "none", ""
+ usa_market_name: true # Check if the value is a valid USA market name. Example: "New York, NY"
diff --git a/src/Commands/CreateCsv.php b/src/Commands/CreateCsv.php
new file mode 100644
index 00000000..0128051f
--- /dev/null
+++ b/src/Commands/CreateCsv.php
@@ -0,0 +1,59 @@
+setName('create:csv')
+ ->setDescription('Generate random CSV file by rules from yml file. Data based on fakerphp/faker library.')
+ ->addArgument(
+ 'rule-file',
+ InputArgument::REQUIRED,
+ 'Path to rule file (yml)',
+ )
+ ->addOption(
+ 'seed',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'Seed for random data generation (fakerphp/faker library)',
+ )
+ ->addOption(
+ 'to-file',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'If set, the generated CSV will be saved to the specified file. '
+ . 'Otherwise, the result will be output to the console as STDOUT.',
+ );
+
+ parent::configure();
+ }
+
+ protected function executeAction(): int
+ {
+ throw new \RuntimeException('Not implemented yet');
+ }
+}
diff --git a/src/Commands/CreateSchema.php b/src/Commands/CreateSchema.php
new file mode 100644
index 00000000..feadeafa
--- /dev/null
+++ b/src/Commands/CreateSchema.php
@@ -0,0 +1,59 @@
+setName('create:schema')
+ ->setDescription('Generate random CSV file by rules from yml file. Data based on fakerphp/faker library.')
+ ->addArgument(
+ 'rule-file',
+ InputArgument::REQUIRED,
+ 'Path to rule file (yml)',
+ )
+ ->addOption(
+ 'seed',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'Seed for random data generation (fakerphp/faker library)',
+ )
+ ->addOption(
+ 'to-file',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'If set, the generated CSV will be saved to the specified file. '
+ . 'Otherwise, the result will be output to the console as STDOUT.',
+ );
+
+ parent::configure();
+ }
+
+ protected function executeAction(): int
+ {
+ throw new \RuntimeException('Not implemented yet');
+ }
+}
diff --git a/src/Commands/ValidateCsv.php b/src/Commands/ValidateCsv.php
new file mode 100644
index 00000000..091396c3
--- /dev/null
+++ b/src/Commands/ValidateCsv.php
@@ -0,0 +1,132 @@
+setName('validate:csv')
+ ->setDescription('Validate CSV file by rule')
+ ->addOption(
+ 'csv',
+ 'c',
+ InputOption::VALUE_REQUIRED,
+ 'CSV filepath to validate. If not set or empty, then the STDIN is used.',
+ )
+ ->addOption(
+ 'schema',
+ 's',
+ InputOption::VALUE_REQUIRED,
+ 'Schema rule filepath',
+ )
+ ->addOption(
+ 'output',
+ 'o',
+ InputOption::VALUE_REQUIRED,
+ 'Report output format. Available options: ' .
+ \implode(', ', ErrorSuite::getAvaiableRenderFormats()) . '',
+ ErrorSuite::RENDER_TABLE,
+ );
+
+ parent::configure();
+ }
+
+ protected function executeAction(): int
+ {
+ $csvFilename = $this->getCsvFilepath();
+ $schemaFilename = $this->getSchemaFilepath();
+
+ $csvFile = new CsvFile($csvFilename, $schemaFilename);
+ $errorSuite = $csvFile->validate();
+ if ($errorSuite->count() > 0) {
+ $this->_(
+ $errorSuite->render($this->getOptString('output')),
+ $this->isTextMode() ? OutLvl::E : OutLvl::DEFAULT,
+ );
+
+ if ($this->isTextMode()) {
+ $this->_(
+ 'CSV file is not valid! Found ' . $errorSuite->count() . ' errors.',
+ OutLvl::E,
+ );
+ }
+
+ return self::FAILURE;
+ }
+
+ if ($this->isTextMode()) {
+ $this->_('Looks good!');
+ }
+
+ return self::SUCCESS;
+ }
+
+ private function getCsvFilepath(): string
+ {
+ $csvFilename = $this->getOptString('csv');
+
+ if (\file_exists($csvFilename) === false) {
+ throw new Exception("CSV file not found: {$csvFilename}");
+ }
+
+ if ($this->isTextMode()) {
+ $this->_('CSV : ' . \realpath($csvFilename));
+ }
+
+ return $csvFilename;
+ }
+
+ private function getSchemaFilepath(): string
+ {
+ $schemaFilename = $this->getOptString('schema');
+
+ if (\file_exists($schemaFilename) === false) {
+ throw new Exception("Schema file not found: {$schemaFilename}");
+ }
+
+ if ($this->isTextMode()) {
+ $this->_('Schema : ' . \realpath($schemaFilename));
+ }
+
+ return $schemaFilename;
+ }
+
+ private function isTextMode(): bool
+ {
+ return $this->getOutputMode() === ErrorSuite::RENDER_TEXT
+ || $this->getOutputMode() === ErrorSuite::RENDER_GITHUB
+ || $this->getOutputMode() === ErrorSuite::RENDER_TEAMCITY
+ || $this->getOutputMode() === ErrorSuite::RENDER_TABLE;
+ }
+
+ private function getOutputMode(): string
+ {
+ return $this->getOptString('output', ErrorSuite::RENDER_TABLE, ErrorSuite::getAvaiableRenderFormats());
+ }
+}
diff --git a/src/Commands/ValidateDir.php b/src/Commands/ValidateDir.php
new file mode 100644
index 00000000..c3785aba
--- /dev/null
+++ b/src/Commands/ValidateDir.php
@@ -0,0 +1,50 @@
+setName('validate:dir')
+ ->setDescription('Validate CSV file(s) by rules from yml file(s)')
+ ->addArgument(
+ 'csv-file-or-dir',
+ InputArgument::REQUIRED,
+ 'Path to CSV file or directory with CSV files',
+ )
+ ->addArgument(
+ 'rule-file-or-dir',
+ InputArgument::REQUIRED,
+ 'Path to rule file (yml) or directory with rule files',
+ );
+
+ parent::configure();
+ }
+
+ protected function executeAction(): int
+ {
+ throw new \RuntimeException('Not implemented yet');
+ }
+}
diff --git a/src/Csv/Column.php b/src/Csv/Column.php
new file mode 100644
index 00000000..1cc88b66
--- /dev/null
+++ b/src/Csv/Column.php
@@ -0,0 +1,133 @@
+ '',
+ 'name' => '',
+ 'description' => '',
+ 'type' => 'base', // TODO: class
+ 'required' => false,
+ 'allow_empty' => false,
+ 'regex' => null,
+ 'rules' => [],
+ 'aggregate_rules' => [],
+ ];
+
+ private int $id;
+ private Data $column;
+ private array $rules;
+ private array $aggregateRules;
+
+ public function __construct(int $id, array $config)
+ {
+ $this->id = $id;
+ $this->column = new Data($config);
+ $this->rules = $this->prepareRuleSet('rules');
+ $this->aggregateRules = $this->prepareRuleSet('aggregate_rules');
+ }
+
+ public function getName(): string
+ {
+ return $this->column->getString('name', self::FALLBACK_VALUES['name']);
+ }
+
+ public function getId(): int
+ {
+ return $this->id;
+ }
+
+ public function getDescription(): string
+ {
+ return $this->column->getString('description', self::FALLBACK_VALUES['description']);
+ }
+
+ public function getHumanName(): string
+ {
+ return $this->getId() . ':' . \trim($this->getName());
+ }
+
+ public function getKey(): string
+ {
+ if ($this->getName() !== '') {
+ return $this->getName();
+ }
+
+ return (string)$this->getId();
+ }
+
+ public function getType(): string
+ {
+ return $this->column->getString('type', self::FALLBACK_VALUES['type']);
+ }
+
+ public function isRequired(): bool
+ {
+ return $this->column->getBool('required', self::FALLBACK_VALUES['required']);
+ }
+
+ public function getRegex(): ?string
+ {
+ $regex = $this->column->getStringNull('regex', self::FALLBACK_VALUES['regex']);
+
+ return Utils::prepareRegex($regex);
+ }
+
+ public function getRules(): array
+ {
+ return $this->rules;
+ }
+
+ public function getAggregateRules(): array
+ {
+ return $this->aggregateRules;
+ }
+
+ public function getInherit(): string
+ {
+ return $this->column->getString('inherit', self::FALLBACK_VALUES['inherit']);
+ }
+
+ public function validate(string $cellValue, int $line): ErrorSuite
+ {
+ return (new Validator($this))->validate($cellValue, $line);
+ }
+
+ private function prepareRuleSet(string $schemaKey): array
+ {
+ $rules = [];
+
+ $ruleSetConfig = $this->column->getSelf($schemaKey, [])->getArrayCopy();
+
+ foreach ($ruleSetConfig as $ruleName => $ruleValue) {
+ if (\str_starts_with((string)$ruleName, 'custom_')) {
+ $rules[$ruleName] = \array_merge(['class' => '', 'args' => []], $ruleValue);
+ } else {
+ $rules[$ruleName] = $ruleValue;
+ }
+ }
+
+ return $rules;
+ }
+}
diff --git a/src/Csv/CsvFile.php b/src/Csv/CsvFile.php
new file mode 100644
index 00000000..d39e35ac
--- /dev/null
+++ b/src/Csv/CsvFile.php
@@ -0,0 +1,160 @@
+csvFilename = $csvFilename;
+ $this->schema = new Schema($csvSchemaFilenameOrArray);
+ $this->structure = $this->schema->getCsvStructure();
+ $this->reader = $this->prepareReader();
+ }
+
+ public function getCsvFilename(): string
+ {
+ return \pathinfo((string)\realpath($this->csvFilename), \PATHINFO_BASENAME);
+ }
+
+ public function getCsvStructure(): ParseConfig
+ {
+ return $this->structure;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getHeader(): array
+ {
+ if ($this->structure->isHeader()) {
+ return $this->reader->getHeader();
+ }
+
+ return [];
+ }
+
+ public function getRecords(): \Iterator
+ {
+ return $this->reader->getRecords($this->getHeader());
+ }
+
+ public function getRecordsChunk(int $offset = 0, int $limit = -1): \League\Csv\TabularDataReader
+ {
+ return Statement::create(null, $offset, $limit)->process($this->reader, $this->getHeader());
+ }
+
+ public function validate(bool $quickStop = false): ErrorSuite
+ {
+ $errors = new ErrorSuite($this->getCsvFilename());
+
+ $errors->addErrorSuit($this->validateHeader())
+ ->addErrorSuit($this->validateEachCell($quickStop))
+ ->addErrorSuit(self::validateAggregateRules($quickStop));
+
+ return $errors;
+ }
+
+ private function prepareReader(): LeagueReader
+ {
+ $reader = LeagueReader::createFromPath($this->csvFilename)
+ ->setDelimiter($this->structure->getDelimiter())
+ ->setEnclosure($this->structure->getEnclosure())
+ ->setEscape($this->structure->getQuoteChar())
+ ->setHeaderOffset($this->structure->isHeader() ? 0 : null);
+
+ if ($this->structure->isBom()) {
+ $reader->includeInputBOM();
+ } else {
+ $reader->skipInputBOM();
+ }
+
+ return $reader;
+ }
+
+ private function validateHeader(): ErrorSuite
+ {
+ $errors = new ErrorSuite();
+
+ if (!$this->getCsvStructure()->isHeader()) {
+ return $errors;
+ }
+
+ foreach ($this->schema->getColumns() as $column) {
+ if ($column->getName() === '') {
+ $error = new Error(
+ 'csv.header',
+ "Property \"name\" is not defined in schema: \"{$this->schema->getFilename()}\"",
+ $column->getHumanName(),
+ 1,
+ );
+
+ $errors->addError($error);
+ }
+ }
+
+ return $errors;
+ }
+
+ private function validateEachCell(bool $quickStop = false): ErrorSuite
+ {
+ $errors = new ErrorSuite();
+
+ foreach ($this->getRecords() as $line => $record) {
+ $columns = $this->schema->getColumnsMappedByHeader($this->getHeader());
+
+ foreach ($columns as $column) {
+ if ($column === null) {
+ continue;
+ }
+
+ $errors->addErrorSuit($column->validate($record[$column->getKey()], (int)$line + 1));
+ if ($quickStop && $errors->count() > 0) {
+ return $errors;
+ }
+ }
+ }
+
+ return $errors;
+ }
+
+ private static function validateAggregateRules(bool $quickStop = false): ErrorSuite
+ {
+ $errors = new ErrorSuite();
+
+ if ($quickStop && $errors->count() > 0) {
+ return $errors;
+ }
+
+ return new ErrorSuite();
+ }
+}
diff --git a/src/Csv/Exception.php b/src/Csv/Exception.php
new file mode 100644
index 00000000..2e1cca41
--- /dev/null
+++ b/src/Csv/Exception.php
@@ -0,0 +1,21 @@
+ null,
+ 'bom' => false,
+ 'delimiter' => ',',
+ 'quote_char' => '\\',
+ 'enclosure' => '"',
+ 'encoding' => 'utf-8',
+ 'header' => true,
+ 'strict_column_order' => false,
+ 'other_columns_possible' => false,
+ ];
+
+ private Data $structure;
+
+ public function __construct(array $config)
+ {
+ $this->structure = new Data($config);
+ }
+
+ public function getInherit(): ?string
+ {
+ return $this->structure->getStringNull('inherit', self::FALLBACK_VALUES['inherit']);
+ }
+
+ public function isBom(): bool
+ {
+ return $this->structure->getBool('bom', self::FALLBACK_VALUES['bom']);
+ }
+
+ public function getDelimiter(): string
+ {
+ $value = $this->structure->getString('delimiter', self::FALLBACK_VALUES['delimiter']);
+ if (\strlen($value) === 1) {
+ return $value;
+ }
+
+ throw new \InvalidArgumentException('Delimiter must be a single character');
+ }
+
+ public function getQuoteChar(): string
+ {
+ $value = $this->structure->getString('quote_char', self::FALLBACK_VALUES['quote_char']);
+ if (\strlen($value) === 1) {
+ return $value;
+ }
+
+ throw new \InvalidArgumentException('Quote char must be a single character');
+ }
+
+ public function getEnclosure(): string
+ {
+ $value = $this->structure->getString('enclosure', self::FALLBACK_VALUES['enclosure']);
+
+ if (\strlen($value) === 1) {
+ return $value;
+ }
+
+ throw new \InvalidArgumentException('Enclosure must be a single character');
+ }
+
+ public function getEncoding(): string
+ {
+ $encoding = \strtolower(\trim($this->structure->getString('encoding', self::FALLBACK_VALUES['encoding'])));
+
+ $availableOptions = [ // TODO: add flexible handler for this
+ self::ENCODING_UTF8,
+ self::ENCODING_UTF16,
+ self::ENCODING_UTF32,
+ ];
+
+ $result = \in_array($encoding, $availableOptions, true) ? $encoding : null;
+ if ($result !== null) {
+ return $result;
+ }
+
+ throw new \InvalidArgumentException("Invalid encoding: {$encoding}");
+ }
+
+ public function isHeader(): bool
+ {
+ return $this->structure->getBool('header', self::FALLBACK_VALUES['header']);
+ }
+
+ public function isStrictColumnOrder(): bool
+ {
+ return $this->structure->getBool('strict_column_order', self::FALLBACK_VALUES['strict_column_order']);
+ }
+
+ public function isOtherColumnsPossible(): bool
+ {
+ return $this->structure->getBool('other_columns_possible', self::FALLBACK_VALUES['other_columns_possible']);
+ }
+
+ public function getArrayCopy(): array
+ {
+ return [
+ // System rules
+ // 'inherit' => $this->getInherit(), // TODO Implement me
+ // Reading rules
+ 'header' => $this->isHeader(),
+ 'delimiter' => $this->getDelimiter(),
+ 'quote_char' => $this->getQuoteChar(),
+ 'enclosure' => $this->getEnclosure(),
+ 'encoding' => $this->getEncoding(),
+ 'bom' => $this->isBom(),
+ // Global validation rules
+ // 'strict_column_order' => $this->isStrictColumnOrder(), // TODO Implement me
+ // 'other_columns_possible' => $this->isOtherColumnsPossible(), // TODO Implement me
+ ];
+ }
+}
diff --git a/src/Exception.php b/src/Exception.php
new file mode 100644
index 00000000..1780922a
--- /dev/null
+++ b/src/Exception.php
@@ -0,0 +1,21 @@
+filename = '_custom_array_';
+ $this->data = new Data($csvSchemaFilenameOrArray);
+ } elseif (
+ \is_string($csvSchemaFilenameOrArray)
+ && $csvSchemaFilenameOrArray !== ''
+ && \file_exists($csvSchemaFilenameOrArray)
+ ) {
+ $this->filename = $csvSchemaFilenameOrArray;
+ $this->data = new Data();
+ $fileExtension = \pathinfo($csvSchemaFilenameOrArray, \PATHINFO_EXTENSION);
+
+ if ($fileExtension === 'yml' || $fileExtension === 'yaml') {
+ $this->data = yml($csvSchemaFilenameOrArray);
+ } elseif ($fileExtension === 'json') {
+ $this->data = json($csvSchemaFilenameOrArray);
+ } elseif ($fileExtension === 'php') {
+ $this->data = phpArray($csvSchemaFilenameOrArray);
+ } else {
+ throw new \InvalidArgumentException("Unsupported file extension: {$fileExtension}");
+ }
+ } else {
+ $this->filename = null;
+ $this->data = new Data();
+ }
+
+ $this->columns = $this->prepareColumns();
+ }
+
+ public function getFilename(): ?string
+ {
+ return $this->filename;
+ }
+
+ public function getCsvStructure(): ParseConfig
+ {
+ return new ParseConfig($this->data->getArray('csv'));
+ }
+
+ /**
+ * @return Column[]
+ */
+ public function getColumns(): array
+ {
+ return $this->columns;
+ }
+
+ /**
+ * @return Column[]|null[]
+ * @phan-suppress PhanPartialTypeMismatchReturn
+ */
+ public function getColumnsMappedByHeader(array $header): array
+ {
+ $map = [];
+
+ foreach ($header as $headerName) {
+ $map[$headerName] = $this->columns[$headerName] ?? null;
+ }
+
+ return $map;
+ }
+
+ public function getColumn(int|string $columNameOrId): ?Column
+ {
+ if (\is_int($columNameOrId)) {
+ $column = \array_values($this->getColumns())[$columNameOrId] ?? null;
+ } else {
+ $column = $this->getColumns()[$columNameOrId] ?? null;
+ }
+
+ if ($column === null) {
+ throw new Exception("Column \"{$columNameOrId}\" not found in schema \"{$this->filename}\"");
+ }
+
+ return $column;
+ }
+
+ public function getFinenamePattern(): ?string
+ {
+ return $this->data->getStringNull('finename_pattern');
+ }
+
+ public function getIncludes(): array
+ {
+ $result = [];
+
+ foreach ($this->data->getArray('includes') as $includedPath) {
+ [$schemaPath, $alias] = \explode(' as ', $includedPath);
+
+ $schemaPath = \trim($schemaPath);
+ $alias = \trim($alias);
+
+ $result[$alias] = $schemaPath;
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return Column[]
+ */
+ private function prepareColumns(): array
+ {
+ $result = [];
+
+ foreach ($this->data->getArray('columns') as $columnId => $columnPreferences) {
+ $column = new Column((int)$columnId, $columnPreferences);
+
+ $result[$column->getKey()] = $column;
+ }
+
+ return $result;
+ }
+}
diff --git a/src/Utils.php b/src/Utils.php
new file mode 100644
index 00000000..dd26fed0
--- /dev/null
+++ b/src/Utils.php
@@ -0,0 +1,47 @@
+getRuleCode()}\" at line {$this->getLine()}, " .
+ "column \"{$this->getColumnName()}\". {$this->getMessage()}.";
+ }
+
+ public function getRuleCode(): string
+ {
+ return $this->ruleCode;
+ }
+
+ public function getMessage(): string
+ {
+ return \rtrim($this->message, '.');
+ }
+
+ public function getColumnName(): string
+ {
+ return $this->columnName;
+ }
+
+ public function getLine(): int
+ {
+ return $this->line;
+ }
+
+ public function toArray(): array
+ {
+ return [
+ 'ruleCode' => $this->ruleCode,
+ 'message' => $this->message,
+ 'columnName' => $this->columnName,
+ 'line' => $this->line,
+ ];
+ }
+}
diff --git a/src/Validators/ErrorSuite.php b/src/Validators/ErrorSuite.php
new file mode 100644
index 00000000..35055d6b
--- /dev/null
+++ b/src/Validators/ErrorSuite.php
@@ -0,0 +1,169 @@
+render(self::RENDER_TEXT);
+ }
+
+ public function render(string $mode = self::RENDER_TEXT): string
+ {
+ if ($this->count() === 0) {
+ return '';
+ }
+
+ $sourceSuite = $this->prepareSourceSuite();
+ $map = [
+ self::RENDER_TEXT => fn (): string => $this->renderPlainText(),
+ self::RENDER_TABLE => fn (): string => $this->renderTable(),
+ self::RENDER_GITHUB => static fn (): string => (new GithubCliConverter())->fromInternal($sourceSuite),
+ self::RENDER_GITLAB => static fn (): string => (new GitLabJsonConverter())->fromInternal($sourceSuite),
+ self::RENDER_TEAMCITY => static fn (): string => (new TeamCityTestsConverter())->fromInternal($sourceSuite),
+ self::RENDER_JUNIT => static fn (): string => (new JUnitConverter())->fromInternal($sourceSuite),
+ ];
+
+ if (isset($map[$mode])) {
+ return $map[$mode]();
+ }
+
+ throw new Exception("Unknown error render mode: {$mode}");
+ }
+
+ /**
+ * @return Error[]
+ */
+ public function getErrors(): array
+ {
+ return $this->errors;
+ }
+
+ public function addError(?Error $error): self
+ {
+ if ($error === null) {
+ return $this;
+ }
+
+ $this->errors[] = $error;
+
+ return $this;
+ }
+
+ public function addErrorSuit(?self $errorSuite): self
+ {
+ if ($errorSuite === null) {
+ return $this;
+ }
+
+ $this->errors = \array_merge($this->getErrors(), $errorSuite->getErrors());
+
+ return $this;
+ }
+
+ public function count(): int
+ {
+ return \count($this->errors);
+ }
+
+ public function get(int $index): ?Error
+ {
+ return $this->errors[$index] ?? null;
+ }
+
+ public static function getAvaiableRenderFormats(): array
+ {
+ return [
+ self::RENDER_TEXT,
+ self::RENDER_TABLE,
+ self::RENDER_GITHUB,
+ self::RENDER_GITLAB,
+ self::RENDER_TEAMCITY,
+ self::RENDER_JUNIT,
+ ];
+ }
+
+ private function renderPlainText(): string
+ {
+ $result = [];
+
+ foreach ($this->errors as $error) {
+ $result[] = (string)$error;
+ }
+
+ return \implode("\n", $result);
+ }
+
+ private function renderTable(): string
+ {
+ $buffer = new BufferedOutput();
+ $table = (new Table($buffer))
+ ->setHeaderTitle($this->csvFilename)
+ ->setFooterTitle($this->csvFilename)
+ ->setHeaders(['Line', 'id:Column', 'Rule', 'Message'])
+ ->setColumnMaxWidth(0, 10)
+ ->setColumnMaxWidth(1, 20)
+ ->setColumnMaxWidth(2, 20)
+ ->setColumnMaxWidth(3, 60);
+
+ foreach ($this->errors as $error) {
+ $table->addRow([$error->getLine(), $error->getColumnName(), $error->getRuleCode(), $error->getMessage()]);
+ }
+
+ $table->render();
+
+ return $buffer->fetch();
+ }
+
+ private function prepareSourceSuite(): SourceSuite
+ {
+ $suite = new SourceSuite($this->csvFilename);
+
+ foreach ($this->errors as $error) {
+ $caseName = $error->getRuleCode() . ' at column ' . $error->getColumnName();
+ $case = $suite->addTestCase($caseName);
+ $case->line = $error->getLine();
+ $case->file = $this->csvFilename;
+ $case->errOut = $error->getMessage();
+ }
+
+ return $suite;
+ }
+}
diff --git a/src/Validators/Exception.php b/src/Validators/Exception.php
new file mode 100644
index 00000000..46a595ca
--- /dev/null
+++ b/src/Validators/Exception.php
@@ -0,0 +1,21 @@
+columnNameId = $columnNameId;
+ $this->options = $options;
+ $this->ruleCode = $this->getRuleCode();
+ }
+
+ public function validate(?string $cellValue, int $line = 0): ?Error
+ {
+ $error = $this->validateRule($cellValue);
+ if ($error !== null) {
+ return new Error($this->ruleCode, $error, $this->columnNameId, $line);
+ }
+
+ return null;
+ }
+
+ protected function getOptionAsBool(): bool
+ {
+ return bool($this->options);
+ }
+
+ protected function getOptionAsString(): string
+ {
+ if (\is_array($this->options)) {
+ return (string)json($this->options);
+ }
+
+ return (string)$this->options;
+ }
+
+ protected function getOptionAsInt(): int
+ {
+ return int($this->options);
+ }
+
+ protected function getOptionAsFloat(): float
+ {
+ return float($this->options);
+ }
+
+ protected function getOptionAsArray(): array
+ {
+ return (array)$this->options;
+ }
+
+ protected function getOptionAsData(): Data
+ {
+ return data($this->options);
+ }
+
+ protected function getOptionAsDate(): \DateTimeImmutable
+ {
+ return new \DateTimeImmutable($this->getOptionAsString(), new \DateTimeZone('UTC'));
+ }
+
+ private function getRuleCode(): string
+ {
+ return Utils::camelToKebabCase((new \ReflectionClass($this))->getShortName());
+ }
+}
diff --git a/src/Validators/Rules/AllowValues.php b/src/Validators/Rules/AllowValues.php
new file mode 100644
index 00000000..ed83ecd4
--- /dev/null
+++ b/src/Validators/Rules/AllowValues.php
@@ -0,0 +1,36 @@
+getOptionAsArray();
+
+ if (\count($allowedValues) === 0) {
+ return 'Allowed values are not defined';
+ }
+
+ if (!\in_array($cellValue, $allowedValues, true)) {
+ return "Value \"{$cellValue}\" is not allowed. " .
+ 'Allowed values: ["' . \implode('", "', $allowedValues) . '"]';
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/CardinalDirection.php b/src/Validators/Rules/CardinalDirection.php
new file mode 100644
index 00000000..f1cf9be9
--- /dev/null
+++ b/src/Validators/Rules/CardinalDirection.php
@@ -0,0 +1,34 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ return parent::validateRule((string)$cellValue);
+ }
+
+ public function getOptionAsArray(): array
+ {
+ return ['N', 'S', 'E', 'W', 'NE', 'SE', 'NW', 'SW', 'none', ''];
+ }
+}
diff --git a/src/Validators/Rules/DateFormat.php b/src/Validators/Rules/DateFormat.php
new file mode 100644
index 00000000..3e3e45ea
--- /dev/null
+++ b/src/Validators/Rules/DateFormat.php
@@ -0,0 +1,39 @@
+getOptionAsString();
+ if ($expectedDateFormat === '') {
+ return 'Date format is not defined';
+ }
+
+ if ($cellValue === null || $cellValue === '') {
+ return 'Date format of value "" is not valid. Expected format: "' . $expectedDateFormat . '"';
+ }
+
+ $date = \DateTimeImmutable::createFromFormat($expectedDateFormat, $cellValue);
+ if ($date === false || $date->format($expectedDateFormat) !== $cellValue) {
+ return "Date format of value \"{$cellValue}\" is not valid. Expected format: \"{$expectedDateFormat}\"";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/ExactValue.php b/src/Validators/Rules/ExactValue.php
new file mode 100644
index 00000000..31f71d80
--- /dev/null
+++ b/src/Validators/Rules/ExactValue.php
@@ -0,0 +1,29 @@
+getOptionAsString() !== (string)$cellValue) {
+ return "Value \"{$cellValue}\" is not strict equal to \"{$this->getOptionAsString()}\"";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsBool.php b/src/Validators/Rules/IsBool.php
new file mode 100644
index 00000000..e4260f5b
--- /dev/null
+++ b/src/Validators/Rules/IsBool.php
@@ -0,0 +1,34 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ return parent::validateRule(\strtolower((string)$cellValue));
+ }
+
+ public function getOptionAsArray(): array
+ {
+ return ['true', 'false'];
+ }
+}
diff --git a/src/Validators/Rules/IsDomain.php b/src/Validators/Rules/IsDomain.php
new file mode 100644
index 00000000..88bea459
--- /dev/null
+++ b/src/Validators/Rules/IsDomain.php
@@ -0,0 +1,35 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ $domainPattern = '/^(?!-)[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,})$/';
+
+ if (\preg_match($domainPattern, (string)$cellValue) === 0) {
+ return "Value \"{$cellValue}\" is not a valid domain";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsEmail.php b/src/Validators/Rules/IsEmail.php
new file mode 100644
index 00000000..010f51ea
--- /dev/null
+++ b/src/Validators/Rules/IsEmail.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if (\filter_var($cellValue, \FILTER_VALIDATE_EMAIL) === false) {
+ return "Value \"{$cellValue}\" is not a valid email";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsFloat.php b/src/Validators/Rules/IsFloat.php
new file mode 100644
index 00000000..74b61dea
--- /dev/null
+++ b/src/Validators/Rules/IsFloat.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if (\preg_match('/^-?\d+(\.\d+)?$/', (string)$cellValue) === 0) {
+ return "Value \"{$cellValue}\" is not a float number";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsInt.php b/src/Validators/Rules/IsInt.php
new file mode 100644
index 00000000..069fca8f
--- /dev/null
+++ b/src/Validators/Rules/IsInt.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if (\preg_match('/^-?\d+$/', (string)$cellValue) === 0) {
+ return "Value \"{$cellValue}\" is not an integer";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsIp.php b/src/Validators/Rules/IsIp.php
new file mode 100644
index 00000000..814c3bf1
--- /dev/null
+++ b/src/Validators/Rules/IsIp.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if (\filter_var($cellValue, \FILTER_VALIDATE_IP) === false) {
+ return "Value \"{$cellValue}\" is not a valid IP";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsLatitude.php b/src/Validators/Rules/IsLatitude.php
new file mode 100644
index 00000000..5085519e
--- /dev/null
+++ b/src/Validators/Rules/IsLatitude.php
@@ -0,0 +1,42 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ $result = parent::validateRule($cellValue);
+ if ($result !== null) {
+ return $result;
+ }
+
+ $latitude = (float)$cellValue;
+ if ($latitude < $this->min || $latitude > $this->max) {
+ return "Value \"{$cellValue}\" is not a valid latitude ({$this->min} <= x <= {$this->max})";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsLongitude.php b/src/Validators/Rules/IsLongitude.php
new file mode 100644
index 00000000..97b06c28
--- /dev/null
+++ b/src/Validators/Rules/IsLongitude.php
@@ -0,0 +1,42 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ $result = parent::validateRule($cellValue);
+ if ($result !== null) {
+ return $result;
+ }
+
+ $longitude = (float)$cellValue;
+ if ($longitude < $this->min || $longitude > $this->max) {
+ return "Value \"{$cellValue}\" is not a valid longitude ({$this->min} <= x <= {$this->max})";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsUrl.php b/src/Validators/Rules/IsUrl.php
new file mode 100644
index 00000000..8bc1a242
--- /dev/null
+++ b/src/Validators/Rules/IsUrl.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if (\filter_var($cellValue, \FILTER_VALIDATE_URL) === false) {
+ return "Value \"{$cellValue}\" is not a valid URL";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/IsUuid4.php b/src/Validators/Rules/IsUuid4.php
new file mode 100644
index 00000000..86a5b55b
--- /dev/null
+++ b/src/Validators/Rules/IsUuid4.php
@@ -0,0 +1,35 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ $uuid4 = '/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89ABab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/';
+
+ if (\preg_match($uuid4, (string)$cellValue) === 0) {
+ return 'Value is not a valid UUID v4';
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/Max.php b/src/Validators/Rules/Max.php
new file mode 100644
index 00000000..9ce9b0a8
--- /dev/null
+++ b/src/Validators/Rules/Max.php
@@ -0,0 +1,34 @@
+getOptionAsFloat() < (float)$cellValue) {
+ return "Value \"{$cellValue}\" is greater than \"{$this->getOptionAsFloat()}\"";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/MaxDate.php b/src/Validators/Rules/MaxDate.php
new file mode 100644
index 00000000..434ceeb2
--- /dev/null
+++ b/src/Validators/Rules/MaxDate.php
@@ -0,0 +1,33 @@
+getOptionAsDate();
+ $cellDate = new \DateTimeImmutable((string)$cellValue);
+
+ if ($cellDate->getTimestamp() > $minDate->getTimestamp()) {
+ return "Value \"{$cellValue}\" is more than the maximum " .
+ "date \"{$minDate->format(\DATE_RFC3339_EXTENDED)}\"";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/MaxLength.php b/src/Validators/Rules/MaxLength.php
new file mode 100644
index 00000000..6cac2d8f
--- /dev/null
+++ b/src/Validators/Rules/MaxLength.php
@@ -0,0 +1,32 @@
+getOptionAsInt();
+ $length = \mb_strlen((string)$cellValue);
+
+ if ($length > $minLength) {
+ return "Value \"{$cellValue}\" (legth: {$length}) is too long. Max length is {$minLength}";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/Min.php b/src/Validators/Rules/Min.php
new file mode 100644
index 00000000..06ec2e21
--- /dev/null
+++ b/src/Validators/Rules/Min.php
@@ -0,0 +1,34 @@
+getOptionAsFloat() > (float)$cellValue) {
+ return "Value \"{$cellValue}\" is less than \"{$this->getOptionAsFloat()}\"";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/MinDate.php b/src/Validators/Rules/MinDate.php
new file mode 100644
index 00000000..225a4c43
--- /dev/null
+++ b/src/Validators/Rules/MinDate.php
@@ -0,0 +1,33 @@
+getOptionAsDate();
+ $cellDate = new \DateTimeImmutable((string)$cellValue);
+
+ if ($cellDate->getTimestamp() < $minDate->getTimestamp()) {
+ return "Value \"{$cellValue}\" is less than the minimum " .
+ "date \"{$minDate->format(\DATE_RFC3339_EXTENDED)}\"";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/MinLength.php b/src/Validators/Rules/MinLength.php
new file mode 100644
index 00000000..dab97808
--- /dev/null
+++ b/src/Validators/Rules/MinLength.php
@@ -0,0 +1,32 @@
+getOptionAsInt();
+ $length = \mb_strlen((string)$cellValue);
+
+ if ($length < $minLength) {
+ return "Value \"{$cellValue}\" (legth: {$length}) is too short. Min length is {$minLength}";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/NotEmpty.php b/src/Validators/Rules/NotEmpty.php
new file mode 100644
index 00000000..b99339d7
--- /dev/null
+++ b/src/Validators/Rules/NotEmpty.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if ($cellValue === null || $cellValue === '') {
+ return 'Value is empty';
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/OnlyCapitalize.php b/src/Validators/Rules/OnlyCapitalize.php
new file mode 100644
index 00000000..49771bfd
--- /dev/null
+++ b/src/Validators/Rules/OnlyCapitalize.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if ($cellValue !== null && $cellValue !== \ucfirst($cellValue)) {
+ return "Value \"{$cellValue}\" should be in capitalize";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/OnlyLowercase.php b/src/Validators/Rules/OnlyLowercase.php
new file mode 100644
index 00000000..3e4c8e4c
--- /dev/null
+++ b/src/Validators/Rules/OnlyLowercase.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if ($cellValue !== null && $cellValue !== \mb_strtolower($cellValue)) {
+ return "Value \"{$cellValue}\" should be in lowercase";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/OnlyTrimed.php b/src/Validators/Rules/OnlyTrimed.php
new file mode 100644
index 00000000..1da94d95
--- /dev/null
+++ b/src/Validators/Rules/OnlyTrimed.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if (\trim((string)$cellValue) !== (string)$cellValue) {
+ return "Value \"{$cellValue}\" is not trimmed";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/OnlyUppercase.php b/src/Validators/Rules/OnlyUppercase.php
new file mode 100644
index 00000000..f3014b36
--- /dev/null
+++ b/src/Validators/Rules/OnlyUppercase.php
@@ -0,0 +1,33 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if ($cellValue !== null && \mb_strtoupper($cellValue, 'UTF-8') !== $cellValue) {
+ return "Value \"{$cellValue}\" is not uppercase";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/Precision.php b/src/Validators/Rules/Precision.php
new file mode 100644
index 00000000..e1bfe56c
--- /dev/null
+++ b/src/Validators/Rules/Precision.php
@@ -0,0 +1,44 @@
+getOptionAsInt() !== $valuePrecision) {
+ return "Value \"{$cellValue}\" has a precision of {$valuePrecision} " .
+ "but should have a precision of {$this->getOptionAsInt()}";
+ }
+
+ return null;
+ }
+
+ private static function getFloatPrecision(?string $cellValue): int
+ {
+ $floatAsString = (string)$cellValue;
+ $dotPosition = \strpos($floatAsString, '.');
+
+ if ($dotPosition === false) {
+ return 0;
+ }
+
+ return \strlen($floatAsString) - $dotPosition - 1;
+ }
+}
diff --git a/src/Validators/Rules/Regex.php b/src/Validators/Rules/Regex.php
new file mode 100644
index 00000000..27b707ea
--- /dev/null
+++ b/src/Validators/Rules/Regex.php
@@ -0,0 +1,37 @@
+getOptionAsString());
+
+ if ($regex === null || $regex === '') {
+ return 'Regex pattern is not defined';
+ }
+
+ if (\preg_match($regex, (string)$cellValue) === 0) {
+ return "Value \"{$cellValue}\" does not match the pattern \"{$regex}\"";
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Rules/RuleException.php b/src/Validators/Rules/RuleException.php
new file mode 100644
index 00000000..48ed9cb6
--- /dev/null
+++ b/src/Validators/Rules/RuleException.php
@@ -0,0 +1,21 @@
+getOptionAsBool()) {
+ return null;
+ }
+
+ if (\preg_match('/^[A-Za-z0-9\s-]+, [A-Z]{2}$/u', (string)$cellValue) === 0) {
+ return "Invalid market name format for value \"{$cellValue}\". " .
+ 'Market name must have format "New York, NY"';
+ }
+
+ return null;
+ }
+}
diff --git a/src/Validators/Ruleset.php b/src/Validators/Ruleset.php
new file mode 100644
index 00000000..42efff96
--- /dev/null
+++ b/src/Validators/Ruleset.php
@@ -0,0 +1,63 @@
+columnNameId = $columnNameId;
+ $this->rules = [];
+
+ foreach ($rules as $ruleName => $options) {
+ $this->rules[] = $this->createRule((string)$ruleName, $options);
+ }
+ }
+
+ /**
+ * @psalm-suppress MoreSpecificReturnType
+ * @psalm-suppress LessSpecificReturnStatement
+ */
+ public function createRule(string $ruleName, null|array|bool|float|int|string $options = null): AbstarctRule
+ {
+ $classname = __NAMESPACE__ . '\\Rules\\' . Utils::kebabToCamelCase($ruleName);
+ if (\class_exists($classname)) {
+ // @phpstan-ignore-next-line
+ return new $classname($this->columnNameId, $options);
+ }
+
+ throw new Exception("Rule \"{$ruleName}\" not found. Expected class: \"{$classname}\"");
+ }
+
+ public function validate(?string $cellValue, int $line): ErrorSuite
+ {
+ $errors = new ErrorSuite();
+
+ foreach ($this->rules as $rule) {
+ $errors->addError($rule->validate($cellValue, $line));
+ }
+
+ return $errors;
+ }
+}
diff --git a/src/Validators/Validator.php b/src/Validators/Validator.php
new file mode 100644
index 00000000..2d8c857c
--- /dev/null
+++ b/src/Validators/Validator.php
@@ -0,0 +1,34 @@
+ruleset = new Ruleset($column->getRules(), $column->getHumanName());
+ }
+
+ public function validate(?string $cellValue, int $line): ErrorSuite
+ {
+ return $this->ruleset->validate($cellValue, $line);
+ }
+}
diff --git a/tests/Blueprint/CsvReaderTest.php b/tests/Blueprint/CsvReaderTest.php
new file mode 100644
index 00000000..4291b685
--- /dev/null
+++ b/tests/Blueprint/CsvReaderTest.php
@@ -0,0 +1,82 @@
+getCsvFilename());
+
+ isSame([], $csv->getHeader());
+
+ isSame([
+ ['1', 'true'],
+ ['2', 'true'],
+ ['3', 'false'],
+ ], $this->fetchRows($csv->getRecords()));
+
+ isSame([['2', 'true']], $this->fetchRows($csv->getRecordsChunk(1, 1)));
+
+ isSame([['2', 'true'], ['3', 'false']], $this->fetchRows($csv->getRecordsChunk(1)));
+ }
+
+ public function testReadCsvFileWithHeader(): void
+ {
+ $csv = new CsvFile(self::CSV_SIMPLE_HEADER, self::SCHEMA_SIMPLE_HEADER);
+ isSame('simple_header.csv', $csv->getCsvFilename());
+
+ isSame(['seq', 'bool', 'exact'], $csv->getHeader());
+
+ isSame([
+ ['seq' => '1', 'bool' => 'true', 'exact' => '1'],
+ ['seq' => '2', 'bool' => 'true', 'exact' => '1'],
+ ['seq' => '3', 'bool' => 'false', 'exact' => '1'],
+ ], $this->fetchRows($csv->getRecords()));
+
+ isSame(
+ [['seq' => '2', 'bool' => 'true', 'exact' => '1']],
+ $this->fetchRows($csv->getRecordsChunk(1, 1)),
+ );
+
+ isSame(
+ [['seq' => '2', 'bool' => 'true', 'exact' => '1'], ['seq' => '3', 'bool' => 'false', 'exact' => '1']],
+ $this->fetchRows($csv->getRecordsChunk(1, 2)),
+ );
+ }
+
+ private function fetchRows(iterable $records): array
+ {
+ return \array_reduce(\iterator_to_array($records), static function ($acc, $record) {
+ $acc[] = $record;
+
+ return $acc;
+ }, []);
+ }
+}
diff --git a/tests/Blueprint/MiscTest.php b/tests/Blueprint/MiscTest.php
new file mode 100644
index 00000000..09a91b88
--- /dev/null
+++ b/tests/Blueprint/MiscTest.php
@@ -0,0 +1,165 @@
+findArray('columns.0.rules');
+ $rulesInConfig = \array_keys($rulesInConfig);
+ \sort($rulesInConfig);
+
+ $finder = (new Finder())
+ ->files()
+ ->in(PROJECT_ROOT . '/src/Validators/Rules')
+ ->ignoreDotFiles(false)
+ ->ignoreVCS(true)
+ ->name('/\\.php$/');
+
+ foreach ($finder as $file) {
+ $ruleName = Utils::camelToKebabCase($file->getFilenameWithoutExtension());
+ $excludeRules = [
+ 'abstarct_rule',
+ 'exception',
+ 'rule_exception',
+ ];
+
+ if (\in_array($ruleName, $excludeRules, true)) {
+ continue;
+ }
+
+ $rulesInCode[] = $ruleName;
+ }
+ \sort($rulesInCode);
+
+ isSame($rulesInCode, $rulesInConfig);
+ }
+
+ public function testCsvStrutureDefaultValues(): void
+ {
+ $defaultsInDoc = yml(PROJECT_ROOT . '/schema-examples/full.yml')->findArray('csv');
+
+ $schema = new Schema([]);
+ $schema->getCsvStructure()->getArrayCopy();
+
+ isSame($defaultsInDoc, $schema->getCsvStructure()->getArrayCopy());
+ }
+
+ public function testCheckYmlSchemaExampleInReadme(): void
+ {
+ $this->testCheckExampleInReadme(
+ PROJECT_ROOT . '/schema-examples/full.yml',
+ 'yml',
+ 'YAML format (with comment)',
+ 12,
+ );
+ }
+
+ public function testCheckPhpSchemaExampleInReadme(): void
+ {
+ $this->testCheckExampleInReadme(PROJECT_ROOT . '/schema-examples/full.php', 'php', 'PHP Format', 14);
+ }
+
+ public function testCheckJsonSchemaExampleInReadme(): void
+ {
+ $this->testCheckExampleInReadme(PROJECT_ROOT . '/schema-examples/full.json', 'json', 'JSON Format', 0);
+ }
+
+ public function testCompareExamplesWithOrig(): void
+ {
+ $basepath = PROJECT_ROOT . '/schema-examples/full';
+
+ $origYml = yml("{$basepath}.yml")->getArrayCopy();
+
+ // To update examples ONLY!!!
+ // file_put_contents("{$basepath}.php", (string)phpArray($origYml));
+ // file_put_contents("{$basepath}.json", (string)json($origYml));
+
+ isSame($origYml, phpArray("{$basepath}.php")->getArrayCopy(), 'PHP config is invalid');
+ isSame($origYml, json("{$basepath}.json")->getArrayCopy(), 'JSON config is invalid');
+ }
+
+ private function testCheckExampleInReadme(
+ string $filepath,
+ string $type,
+ string $title,
+ int $skipFirstLines = 0,
+ ): void {
+ $filepath = \implode(
+ "\n",
+ \array_slice(\explode("\n", \file_get_contents($filepath)), $skipFirstLines),
+ );
+
+ if ($type === 'php') {
+ $tmpl = \implode("\n", ['```php', 'getSpoiler("Click to see: {$title}", $tmpl);
+
+ isFileContains($tmpl, PROJECT_ROOT . '/README.md');
+ }
+
+ private function getSpoiler(string $title, string $body): string
+ {
+ return \implode("\n", [
+ '',
+ " {$title}
",
+ '',
+ "{$body}",
+ '',
+ ' ',
+ '',
+ ]);
+ }
+}
diff --git a/tests/Blueprint/RulesTest.php b/tests/Blueprint/RulesTest.php
new file mode 100644
index 00000000..56f89de0
--- /dev/null
+++ b/tests/Blueprint/RulesTest.php
@@ -0,0 +1,604 @@
+validate('1'));
+ isSame(null, $rule->validate('2'));
+ isSame(null, $rule->validate('3'));
+ isSame(
+ '"allow_values" at line 0, column "prop". ' .
+ 'Value "" is not allowed. Allowed values: ["1", "2", "3"].',
+ (string)$rule->validate(''),
+ );
+ isSame(
+ '"allow_values" at line 0, column "prop". ' .
+ 'Value "invalid" is not allowed. Allowed values: ["1", "2", "3"].',
+ (string)$rule->validate('invalid'),
+ );
+
+ $rule = new AllowValues('prop', ['1', '2', '3', '']);
+ isSame(null, $rule->validate(''));
+
+ $rule = new AllowValues('prop', ['1', '2', '3', ' ']);
+ isSame(null, $rule->validate(' '));
+ }
+
+ public function testDateFormat(): void
+ {
+ $rule = new DateFormat('prop', 'Y-m-d');
+ isSame(null, $rule->validate('2000-12-31'));
+ isSame(
+ '"date_format" at line 0, column "prop". ' .
+ 'Date format of value "" is not valid. Expected format: "Y-m-d".',
+ (string)$rule->validate(''),
+ );
+ isSame(
+ '"date_format" at line 0, column "prop". ' .
+ 'Date format of value "2000-01-02 12:34:56" is not valid. Expected format: "Y-m-d".',
+ (string)$rule->validate('2000-01-02 12:34:56'),
+ );
+ }
+
+ public function testExactValue(): void
+ {
+ $rule = new ExactValue('prop', '123');
+ isSame(null, $rule->validate('123'));
+ isSame(
+ '"exact_value" at line 0, column "prop". Value "" is not strict equal to "123".',
+ (string)$rule->validate(''),
+ );
+ isSame(
+ '"exact_value" at line 0, column "prop". Value "2000-01-02" is not strict equal to "123".',
+ (string)$rule->validate('2000-01-02'),
+ );
+ }
+
+ public function testIsBool(): void
+ {
+ $rule = new IsBool('prop', true);
+ isSame(null, $rule->validate('true'));
+ isSame(null, $rule->validate('false'));
+ isSame(null, $rule->validate('TRUE'));
+ isSame(null, $rule->validate('FALSE'));
+ isSame(null, $rule->validate('True'));
+ isSame(null, $rule->validate('False'));
+ isSame(
+ '"is_bool" at line 0, column "prop". Value "" is not allowed. Allowed values: ["true", "false"].',
+ (string)$rule->validate(''),
+ );
+ isSame(
+ '"is_bool" at line 0, column "prop". Value "1" is not allowed. Allowed values: ["true", "false"].',
+ (string)$rule->validate('1'),
+ );
+ }
+
+ public function testIsDomain(): void
+ {
+ $rule = new IsDomain('prop', true);
+ isSame(null, $rule->validate('example.com'));
+ isSame(null, $rule->validate('sub.example.com'));
+ isSame(null, $rule->validate('sub.sub.example.com'));
+ isSame(null, $rule->validate('sub.sub-example.com'));
+ isSame(null, $rule->validate('sub-sub-example.com'));
+ isSame(null, $rule->validate('sub-sub-example.qwerty'));
+ isSame(
+ '"is_domain" at line 0, column "prop". Value "example" is not a valid domain.',
+ (string)(string)$rule->validate('example'),
+ );
+ isSame(
+ '"is_domain" at line 0, column "prop". Value "" is not a valid domain.',
+ (string)$rule->validate(''),
+ );
+ }
+
+ public function testIsEmail(): void
+ {
+ $rule = new IsEmail('prop', true);
+ isSame(null, $rule->validate('user@example.com'));
+ isSame(null, $rule->validate('user@sub.example.com'));
+ isSame(
+ '"is_email" at line 0, column "prop". Value "user:pass@example.com" is not a valid email.',
+ (string)(string)$rule->validate('user:pass@example.com'),
+ );
+ }
+
+ public function testIsFloat(): void
+ {
+ $rule = new IsFloat('prop', true);
+ isSame(null, $rule->validate('1'));
+ isSame(null, $rule->validate('01'));
+ isSame(null, $rule->validate('1.0'));
+ isSame(null, $rule->validate('01.0'));
+ isSame(null, $rule->validate('-1'));
+ isSame(null, $rule->validate('-1.0'));
+ isSame(
+ '"is_float" at line 0, column "prop". Value "1.000.000" is not a float number.',
+ (string)$rule->validate('1.000.000'),
+ );
+ isSame(
+ '"is_float" at line 0, column "prop". Value "" is not a float number.',
+ (string)$rule->validate(''),
+ );
+ isSame(
+ '"is_float" at line 0, column "prop". Value " 1" is not a float number.',
+ (string)$rule->validate(' 1'),
+ );
+ }
+
+ public function testIsInt(): void
+ {
+ $rule = new IsInt('prop', true);
+ isSame(null, $rule->validate('1'));
+ isSame(null, $rule->validate('01'));
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('00'));
+ isSame(null, $rule->validate('-1'));
+ isSame(
+ '"is_int" at line 0, column "prop". Value "1.000.000" is not an integer.',
+ (string)$rule->validate('1.000.000'),
+ );
+ isSame(
+ '"is_int" at line 0, column "prop". Value "1.1" is not an integer.',
+ (string)(string)$rule->validate('1.1'),
+ );
+ isSame(
+ '"is_int" at line 0, column "prop". Value "1.0" is not an integer.',
+ (string)$rule->validate('1.0'),
+ );
+ isSame(
+ '"is_int" at line 0, column "prop". Value "" is not an integer.',
+ (string)$rule->validate(''),
+ );
+ isSame(
+ '"is_int" at line 0, column "prop". Value " 1" is not an integer.',
+ (string)(string)$rule->validate(' 1'),
+ );
+ isSame(
+ '"is_int" at line 0, column "prop". Value "1 " is not an integer.',
+ (string)(string)$rule->validate('1 '),
+ );
+ }
+
+ public function testIsIp(): void
+ {
+ $rule = new IsIp('prop', true);
+ isSame(null, $rule->validate('127.0.0.1'));
+ isSame(null, $rule->validate('0.0.0.0'));
+ isSame(
+ '"is_ip" at line 0, column "prop". Value "1.2.3" is not a valid IP.',
+ (string)$rule->validate('1.2.3'),
+ );
+ }
+
+ public function testIsLatitude(): void
+ {
+ $rule = new IsLatitude('prop', true);
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('90'));
+ isSame(null, $rule->validate('-90'));
+ isSame(
+ '"is_latitude" at line 0, column "prop". Value "123" is not a valid latitude (-90 <= x <= 90).',
+ (string)$rule->validate('123'),
+ );
+ isSame(
+ '"is_latitude" at line 0, column "prop". Value "90.1" is not a valid latitude (-90 <= x <= 90).',
+ (string)$rule->validate('90.1'),
+ );
+ isSame(
+ '"is_latitude" at line 0, column "prop". Value "90.1.1.1.1" is not a float number.',
+ (string)$rule->validate('90.1.1.1.1'),
+ );
+ }
+
+ public function testIsLongitude(): void
+ {
+ $rule = new IsLongitude('prop', true);
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('180'));
+ isSame(null, $rule->validate('-180'));
+ isSame(
+ '"is_longitude" at line 0, column "prop". Value "1230" is not a valid longitude (-180 <= x <= 180).',
+ (string)$rule->validate('1230'),
+ );
+ isSame(
+ '"is_longitude" at line 0, column "prop". ' .
+ 'Value "180.0001" is not a valid longitude (-180 <= x <= 180).',
+ (string)$rule->validate('180.0001'),
+ );
+ isSame(
+ '"is_longitude" at line 0, column "prop". Value "-180.1" is not a valid longitude (-180 <= x <= 180).',
+ (string)$rule->validate('-180.1'),
+ );
+ isSame(
+ '"is_longitude" at line 0, column "prop". Value "1.0.0.0" is not a float number.',
+ (string)$rule->validate('1.0.0.0'),
+ );
+ }
+
+ public function testIsUrl(): void
+ {
+ $rule = new IsUrl('prop', true);
+ isSame(null, $rule->validate('http://example.com'));
+ isSame(null, $rule->validate('http://example.com/home-page'));
+ isSame(null, $rule->validate('ftp://user:pass@example.com/home-page?param=value&v=asd#anchor'));
+ isSame(
+ '"is_url" at line 0, column "prop". Value "123" is not a valid URL.',
+ (string)$rule->validate('123'),
+ );
+ isSame(
+ '"is_url" at line 0, column "prop". Value "//example.com" is not a valid URL.',
+ (string)$rule->validate('//example.com'),
+ );
+ }
+
+ public function testMin(): void
+ {
+ $rule = new Min('prop', 10);
+ isSame(null, $rule->validate('10'));
+ isSame(null, $rule->validate('11'));
+ isSame(
+ '"min" at line 0, column "prop". Value "9" is less than "10".',
+ (string)$rule->validate('9'),
+ );
+ isSame(
+ '"min" at line 0, column "prop". Value "example.com" is not a float number.',
+ (string)$rule->validate('example.com'),
+ );
+
+ $rule = new Min('prop', 10.1);
+ isSame(null, $rule->validate('10.1'));
+ isSame(null, $rule->validate('11'));
+ isSame(
+ '"min" at line 0, column "prop". Value "9" is less than "10.1".',
+ (string)$rule->validate('9'),
+ );
+ isSame(
+ '"min" at line 0, column "prop". Value "example.com" is not a float number.',
+ (string)$rule->validate('example.com'),
+ );
+ }
+
+ public function testMax(): void
+ {
+ $rule = new Max('prop', 10);
+ isSame(null, $rule->validate('9'));
+ isSame(null, $rule->validate('10'));
+ isSame(
+ '"max" at line 0, column "prop". Value "123" is greater than "10".',
+ (string)$rule->validate('123'),
+ );
+ isSame(
+ '"max" at line 0, column "prop". Value "example.com" is not a float number.',
+ (string)$rule->validate('example.com'),
+ );
+
+ $rule = new Max('prop', 10.1);
+ isSame(null, $rule->validate('9'));
+ isSame(null, $rule->validate('10.0'));
+ isSame(null, $rule->validate('10.1'));
+ isSame(
+ '"max" at line 0, column "prop". Value "10.2" is greater than "10.1".',
+ (string)$rule->validate('10.2'),
+ );
+ }
+
+ public function testMinDate(): void
+ {
+ $rule = new MinDate('prop', '2000-01-10');
+ isSame(null, $rule->validate('2000-01-10'));
+ isSame(
+ '"min_date" at line 0, column "prop". ' .
+ 'Value "2000-01-09" is less than the minimum date "2000-01-10T00:00:00.000+00:00".',
+ (string)$rule->validate('2000-01-09'),
+ );
+
+ $rule = new MinDate('prop', '2000-01-10 00:00:00 +01:00');
+ isSame(null, $rule->validate('2000-01-10 00:00:00 +01:00'));
+ isSame(
+ '"min_date" at line 0, column "prop". ' .
+ 'Value "2000-01-09 23:59:59 Europe/Berlin" is less than the minimum date "2000-01-10T00:00:00.000+01:00".',
+ (string)$rule->validate('2000-01-09 23:59:59 Europe/Berlin'),
+ );
+
+ $rule = new MinDate('prop', '-1000 years');
+ isSame(null, $rule->validate('2000-01-10 00:00:00 +01:00'));
+ }
+
+ public function testMaxDate(): void
+ {
+ $rule = new MaxDate('prop', '2000-01-10');
+ isSame(null, $rule->validate('2000-01-09'));
+ isSame(
+ '"max_date" at line 0, column "prop". ' .
+ 'Value "2000-01-11" is more than the maximum date "2000-01-10T00:00:00.000+00:00".',
+ (string)$rule->validate('2000-01-11'),
+ );
+
+ $rule = new MaxDate('prop', '2000-01-10 00:00:00');
+ isSame(null, $rule->validate('2000-01-10 00:00:00'));
+ isSame(
+ '"max_date" at line 0, column "prop". ' .
+ 'Value "2000-01-10 00:00:01" is more than the maximum date "2000-01-10T00:00:00.000+00:00".',
+ (string)$rule->validate('2000-01-10 00:00:01'),
+ );
+
+ $rule = new MaxDate('prop', '+1 day');
+ isSame(null, $rule->validate('2000-01-10 00:00:00 +01:00'));
+ }
+
+ public function testMinLength(): void
+ {
+ $rule = new MinLength('prop', 5);
+ isSame(null, $rule->validate('12345'));
+ isSame(null, $rule->validate(' '));
+ isSame(null, $rule->validate(' 1 '));
+ isSame(
+ '"min_length" at line 0, column "prop". Value "1234" (legth: 4) is too short. Min length is 5.',
+ (string)$rule->validate('1234'),
+ );
+ isSame(
+ '"min_length" at line 0, column "prop". Value "123 " (legth: 4) is too short. Min length is 5.',
+ (string)$rule->validate('123 '),
+ );
+ isSame(
+ '"min_length" at line 0, column "prop". Value "" (legth: 0) is too short. Min length is 5.',
+ (string)$rule->validate(''),
+ );
+ }
+
+ public function testMaxLength(): void
+ {
+ $rule = new MaxLength('prop', 5);
+ isSame(null, $rule->validate(''));
+ isSame(null, $rule->validate('1234'));
+ isSame(null, $rule->validate('12345'));
+ isSame(null, $rule->validate(' '));
+ isSame(null, $rule->validate(' 1 '));
+ isSame(
+ '"max_length" at line 0, column "prop". Value "123456" (legth: 6) is too long. Max length is 5.',
+ (string)$rule->validate('123456'),
+ );
+ isSame(
+ '"max_length" at line 0, column "prop". Value "12345 " (legth: 6) is too long. Max length is 5.',
+ (string)$rule->validate('12345 '),
+ );
+ }
+
+ public function testNotEmpty(): void
+ {
+ $rule = new NotEmpty('prop', true);
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('false'));
+ isSame(null, $rule->validate('1'));
+ isSame(null, $rule->validate(' 0'));
+ isSame(null, $rule->validate(' '));
+ isSame(
+ '"not_empty" at line 0, column "prop". Value is empty.',
+ (string)$rule->validate(''),
+ );
+ isSame(
+ '"not_empty" at line 0, column "prop". Value is empty.',
+ (string)$rule->validate(null),
+ );
+ }
+
+ public function testOnlyCapitalize(): void
+ {
+ $rule = new OnlyCapitalize('prop', true);
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('False'));
+ isSame(null, $rule->validate('Qwe Rty'));
+ isSame(null, $rule->validate(' Qwe Rty'));
+ isSame(null, $rule->validate(' '));
+ isSame(
+ '"only_capitalize" at line 0, column "prop". Value "qwerty" should be in capitalize.',
+ (string)$rule->validate('qwerty'),
+ );
+ isSame(
+ '"only_capitalize" at line 0, column "prop". Value "qwe Rty" should be in capitalize.',
+ (string)$rule->validate('qwe Rty'),
+ );
+ }
+
+ public function testOnlyLowercase(): void
+ {
+ $rule = new OnlyLowercase('prop', true);
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('false'));
+ isSame(null, $rule->validate('qwe rty'));
+ isSame(null, $rule->validate(' qwe rty'));
+ isSame(null, $rule->validate(' '));
+ isSame(
+ '"only_lowercase" at line 0, column "prop". Value "Qwerty" should be in lowercase.',
+ (string)$rule->validate('Qwerty'),
+ );
+ isSame(
+ '"only_lowercase" at line 0, column "prop". Value "qwe Rty" should be in lowercase.',
+ (string)$rule->validate('qwe Rty'),
+ );
+ }
+
+ public function testOnlyUppercase(): void
+ {
+ $rule = new OnlyUppercase('prop', true);
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('FALSE'));
+ isSame(null, $rule->validate('QWE RTY'));
+ isSame(null, $rule->validate(' '));
+ isSame(
+ '"only_uppercase" at line 0, column "prop". Value "Qwerty" is not uppercase.',
+ (string)$rule->validate('Qwerty'),
+ );
+ isSame(
+ '"only_uppercase" at line 0, column "prop". Value "qwe Rty" is not uppercase.',
+ (string)$rule->validate('qwe Rty'),
+ );
+ }
+
+ public function testPrecision(): void
+ {
+ $rule = new Precision('prop', 0);
+ isSame(null, $rule->validate('0'));
+ isSame(null, $rule->validate('10'));
+ isSame(null, $rule->validate('-10'));
+ isSame(
+ '"precision" at line 0, column "prop". ' .
+ 'Value "1.1" has a precision of 1 but should have a precision of 0.',
+ (string)$rule->validate('1.1'),
+ );
+ isSame(
+ '"precision" at line 0, column "prop". ' .
+ 'Value "1.0" has a precision of 1 but should have a precision of 0.',
+ (string)$rule->validate('1.0'),
+ );
+
+ $rule = new Precision('prop', 1);
+ isSame(null, $rule->validate('0.0'));
+ isSame(null, $rule->validate('10.0'));
+ isSame(null, $rule->validate('-10.0'));
+ isSame(
+ '"precision" at line 0, column "prop". ' .
+ 'Value "1" has a precision of 0 but should have a precision of 1.',
+ (string)$rule->validate('1'),
+ );
+ isSame(
+ '"precision" at line 0, column "prop". ' .
+ 'Value "1.01" has a precision of 2 but should have a precision of 1.',
+ (string)$rule->validate('1.01'),
+ );
+
+ $rule = new Precision('prop', 2);
+ isSame(null, $rule->validate('0.01'));
+ isSame(null, $rule->validate('10.00'));
+ isSame(null, $rule->validate('-10.00'));
+ isSame(
+ '"precision" at line 0, column "prop". ' .
+ 'Value "2.0" has a precision of 1 but should have a precision of 2.',
+ (string)$rule->validate('2.0'),
+ );
+ isSame(
+ '"precision" at line 0, column "prop". ' .
+ 'Value "1.000" has a precision of 3 but should have a precision of 2.',
+ (string)$rule->validate('1.000'),
+ );
+ }
+
+ public function testRegex(): void
+ {
+ $rule = new Regex('prop', '/^a/');
+ isSame(null, $rule->validate('abc'));
+ isSame(null, $rule->validate('aaa'));
+ isSame(null, $rule->validate('a'));
+ isSame(
+ '"regex" at line 0, column "prop". Value "1bc" does not match the pattern "/^a/".',
+ (string)$rule->validate('1bc'),
+ );
+
+ $rule = new Regex('prop', '^a');
+ isSame(null, $rule->validate('abc'));
+ isSame(null, $rule->validate('aaa'));
+ isSame(null, $rule->validate('a'));
+ isSame(
+ '"regex" at line 0, column "prop". Value "1bc" does not match the pattern "/^a/u".',
+ (string)$rule->validate('1bc'),
+ );
+ }
+
+ public function testUnitFacing(): void
+ {
+ $rule = new CardinalDirection('prop', true);
+ isSame(null, $rule->validate('N'));
+ isSame(null, $rule->validate('S'));
+ isSame(null, $rule->validate('E'));
+ isSame(null, $rule->validate('W'));
+ isSame(null, $rule->validate('NE'));
+ isSame(null, $rule->validate('SE'));
+ isSame(null, $rule->validate('NW'));
+ isSame(null, $rule->validate('SW'));
+ isSame(null, $rule->validate('none'));
+ isSame(
+ '"cardinal_direction" at line 0, column "prop". Value "qwe" is not allowed. ' .
+ 'Allowed values: ["N", "S", "E", "W", "NE", "SE", "NW", "SW", "none", ""].',
+ (string)$rule->validate('qwe'),
+ );
+ }
+
+ public function testUsaMarketName(): void
+ {
+ $rule = new UsaMarketName('prop', true);
+ isSame(null, $rule->validate('New York, NY'));
+ isSame(null, $rule->validate('City, ST'));
+ isSame(
+ '"usa_market_name" at line 0, column "prop". ' .
+ 'Invalid market name format for value ", ST". ' .
+ 'Market name must have format "New York, NY".',
+ (string)$rule->validate(', ST'),
+ );
+ }
+
+ public function testIsUuid4(): void
+ {
+ $rule = new IsUuid4('prop', true);
+ isSame(null, $rule->validate(Str::uuid()));
+ isSame(
+ '"is_uuid4" at line 0, column "prop". Value is not a valid UUID v4.',
+ (string)$rule->validate('123'),
+ );
+ }
+}
diff --git a/tests/Blueprint/SchemaTest.php b/tests/Blueprint/SchemaTest.php
new file mode 100644
index 00000000..aea2416a
--- /dev/null
+++ b/tests/Blueprint/SchemaTest.php
@@ -0,0 +1,233 @@
+getFilename());
+
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ isSame(self::SCHEMA_EXAMPLE_FULL, $schemaFull->getFilename());
+ }
+
+ public function testGetFinenamePattern(): void
+ {
+ $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY);
+ isSame(null, $schemaEmpty->getFinenamePattern());
+
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ isSame('^example\.csv$', $schemaFull->getFinenamePattern());
+ }
+
+ public function testScvStruture(): void
+ {
+ $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY);
+ isSame([
+ // 'inherit' => null,
+ 'header' => true,
+ 'delimiter' => ',',
+ 'quote_char' => '\\',
+ 'enclosure' => '"',
+ 'encoding' => 'utf-8',
+ 'bom' => false,
+ // 'strict_column_order' => false,
+ // 'other_columns_possible' => false,
+ ], $schemaEmpty->getCsvStructure()->getArrayCopy());
+
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ isSame([
+ // 'inherit' => 'alias_1',
+ 'header' => true,
+ 'delimiter' => ',',
+ 'quote_char' => '\\',
+ 'enclosure' => '"',
+ 'encoding' => 'utf-8',
+ 'bom' => false,
+ // 'strict_column_order' => true,
+ // 'other_columns_possible' => true,
+ ], $schemaFull->getCsvStructure()->getArrayCopy());
+ }
+
+ public function testColumns(): void
+ {
+ $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY);
+ isSame([], $schemaEmpty->getColumns());
+
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ isSame([
+ 0 => 0,
+ 1 => 'General available options',
+ 2 => 'Some String',
+ 3 => 'Some Integer',
+ 4 => 'Some Float',
+ 5 => 'Some Date',
+ 6 => 'Some Enum',
+ 7 => 'Some Boolean',
+ 8 => 'Some Inherited',
+ 9 => 'Some Latitude',
+ 10 => 'Some Longitude',
+ 11 => 'Some URL',
+ 12 => 'Some Email',
+ 13 => 'Some IP',
+ 14 => 'Some UUID',
+ 15 => 'Some Custom Rule',
+ ], \array_keys($schemaFull->getColumns()));
+ }
+
+ public function testColumnByNameAndId(): void
+ {
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ isNotNull($schemaFull->getColumn(1));
+ isNotNull($schemaFull->getColumn('General available options'));
+
+ isSame(
+ $schemaFull->getColumn(1),
+ $schemaFull->getColumn('General available options'),
+ );
+ }
+
+ public function testIncludes(): void
+ {
+ $schemaEmpty = new Schema(self::SCHEMA_EXAMPLE_EMPTY);
+ isSame([], $schemaEmpty->getIncludes());
+
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ isSame([
+ 'alias_1' => '/path/schema_1.yml',
+ 'alias_2' => './path/schema_2.yml',
+ 'alias_3' => '../path/schema_3.yml',
+ ], $schemaFull->getIncludes());
+ }
+
+ public function testGetUndefinedColumnById(): void
+ {
+ $this->expectExceptionMessage(
+ 'Column "1000" not found in schema "' . self::SCHEMA_EXAMPLE_EMPTY . '"',
+ );
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_EMPTY);
+ isNull($schemaFull->getColumn(1000));
+ }
+
+ public function testGetUndefinedColumnByName(): void
+ {
+ $this->expectExceptionMessage(
+ 'Column "undefined_column" not found in schema "' . self::SCHEMA_EXAMPLE_EMPTY . '"',
+ );
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_EMPTY);
+ isNull($schemaFull->getColumn('undefined_column'));
+ }
+
+ public function testGetColumnMinimal(): void
+ {
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ $column = $schemaFull->getColumn(0);
+
+ isSame('', $column->getName());
+ isSame('', $column->getDescription());
+ isSame('base', $column->getType());
+ isSame(null, $column->getRegex());
+ isSame('', $column->getInherit());
+ isFalse($column->isRequired());
+
+ isTrue(\is_array($column->getRules()));
+ isEmpty($column->getRules());
+
+ isTrue(\is_array($column->getAggregateRules()));
+ isEmpty($column->getAggregateRules());
+ }
+
+ public function testGetColumnProps(): void
+ {
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ $column = $schemaFull->getColumn(1);
+
+ isSame('General available options', $column->getName());
+ isSame('Some description', $column->getDescription());
+ isSame('some_type', $column->getType());
+ isSame('', $column->getInherit());
+
+ isTrue($column->isRequired());
+
+ isTrue(\is_array($column->getRules()));
+ isNotEmpty($column->getRules());
+
+ isTrue(\is_array($column->getAggregateRules()));
+ isNotEmpty($column->getAggregateRules());
+ }
+
+ public function testGetColumnRules(): void
+ {
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ $column = $schemaFull->getColumn('Some String');
+
+ isSame([
+ 'min_length' => 1,
+ 'max_length' => 10,
+ 'only_trimed' => false,
+ 'only_uppercase' => false,
+ 'only_lowercase' => false,
+ 'only_capitalize' => false,
+ ], $column->getRules());
+ }
+
+ public function testGetColumnAggregateRules(): void
+ {
+ $schemaFull = new Schema(self::SCHEMA_EXAMPLE_FULL);
+ $column = $schemaFull->getColumn(1);
+
+ isSame([
+ 'unique' => false,
+ 'sorted' => 'asc',
+ 'sorted_flag' => 'SORT_NATURAL',
+ 'count_min' => 1,
+ 'count_max' => 10,
+ 'count_empty_min' => 1,
+ 'count_empty_max' => 10,
+ 'count_filled_min' => 1,
+ 'count_filled_max' => 10,
+ 'custom_1' => [
+ 'class' => 'My\\Aggregate\\Rules1',
+ 'args' => ['value'],
+ ],
+ 'custom_2' => [
+ 'class' => 'My\\Aggregate\\Rules2',
+ 'args' => ['value1', 'value2'],
+ ],
+ 'custom_my_favorite_name' => [
+ 'class' => 'My\\Aggregate\\RulesXXX',
+ 'args' => [],
+ ],
+ ], $column->getAggregateRules());
+ }
+}
diff --git a/tests/Blueprint/ValidatorTest.php b/tests/Blueprint/ValidatorTest.php
new file mode 100644
index 00000000..8846c892
--- /dev/null
+++ b/tests/Blueprint/ValidatorTest.php
@@ -0,0 +1,367 @@
+expectExceptionMessage(
+ 'Rule "undefined_rule" not found. Expected class: "JBZoo\CsvBlueprint\Validators\Rules\UndefinedRule"',
+ );
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'undefined_rule', true));
+ $csv->validate();
+ }
+
+ public function testValidWithHeader(): void
+ {
+ $csv = new CsvFile(self::CSV_SIMPLE_HEADER, self::SCHEMA_SIMPLE_HEADER);
+ isSame('', (string)$csv->validate());
+ }
+
+ public function testValidWithoutHeader(): void
+ {
+ $csv = new CsvFile(self::CSV_SIMPLE_NO_HEADER, self::SCHEMA_SIMPLE_NO_HEADER);
+ isSame('', (string)$csv->validate());
+ }
+
+ public function testNotEmptyMessage(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'not_empty', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('integer', 'not_empty', true));
+ isSame(
+ '"not_empty" at line 19, column "0:integer". Value is empty.',
+ (string)$csv->validate(),
+ );
+ }
+
+ public function testNoName(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule(null, 'not_empty', true));
+ isSame(
+ '"csv.header" at line 1, column "0:". ' .
+ 'Property "name" is not defined in schema: "_custom_array_".',
+ (string)$csv->validate(),
+ );
+ }
+
+ public function testMin(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min', -10));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min', 10));
+ isSame(
+ '"min" at line 2, column "0:seq". Value "1" is less than "10".',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testMax(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max', 10000));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max', 10));
+ isSame(
+ '"max" at line 12, column "0:seq". Value "11" is greater than "10".',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testRegex(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '.*'));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '^[a-zA-Z0-9]+$'));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '[a-z]'));
+ isSame(
+ '"regex" at line 2, column "0:seq". Value "1" does not match the pattern "/[a-z]/u".',
+ (string)$csv->validate()->get(0),
+ );
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '/[a-z]/'));
+ isSame(
+ '"regex" at line 2, column "0:seq". Value "1" does not match the pattern "/[a-z]/".',
+ (string)$csv->validate()->get(0),
+ );
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'regex', '/[a-z]/i'));
+ isSame(
+ '"regex" at line 2, column "0:seq". Value "1" does not match the pattern "/[a-z]/i".',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testMinLength(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min_length', 1));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'min_length', 1000));
+ isSame(
+ '"min_length" at line 2, column "0:seq". Value "1" (legth: 1) is too short. Min length is 1000.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testMaxLength(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max_length', 10));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'max_length', 1));
+ isSame(
+ '"max_length" at line 11, column "0:seq". Value "10" (legth: 2) is too long. Max length is 1.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testOnlyTrimed(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_trimed', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('sentence', 'only_trimed', true));
+ isSame(
+ '"only_trimed" at line 14, column "0:sentence". Value " Urecam" is not trimmed.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testOnlyUppercase(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_uppercase', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'only_uppercase', true));
+ isSame(
+ '"only_uppercase" at line 2, column "0:bool". Value "true" is not uppercase.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testOnlyLowercase(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_lowercase', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'only_lowercase', true));
+ isSame(
+ '"only_lowercase" at line 8, column "0:bool". Value "False" should be in lowercase.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testOnlyCapitalize(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'only_capitalize', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'only_capitalize', true));
+ isSame(
+ '"only_capitalize" at line 2, column "0:bool". Value "true" should be in capitalize.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testPrecision(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'precision', 0));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'precision', 1));
+ isSame(
+ '"precision" at line 2, column "0:seq". ' .
+ 'Value "1" has a precision of 0 but should have a precision of 1.',
+ (string)$csv->validate()->get(0),
+ );
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('float', 'precision', 3));
+ isSame(
+ '"precision" at line 3, column "0:float". ' .
+ 'Value "506847750940.2624" has a precision of 4 but should have a precision of 3.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testMinDate(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'min_date', '2000-01-01'));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'min_date', '2120-01-01'));
+ isSame(
+ '"min_date" at line 2, column "0:date". ' .
+ 'Value "2042/11/18" is less than the minimum date "2120-01-01T00:00:00.000+00:00".',
+ (string)$csv->validate()->get(0),
+ );
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'min_date', '2042/11/17'));
+ isSame(
+ '"min_date" at line 5, column "0:date". ' .
+ 'Value "2032/09/09" is less than the minimum date "2042-11-17T00:00:00.000+00:00".',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testMaxDate(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'max_date', '2200-01-01'));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'max_date', '2120-01-01'));
+ isSame(
+ '"max_date" at line 23, column "0:date". ' .
+ 'Value "2120/02/01" is more than the maximum date "2120-01-01T00:00:00.000+00:00".',
+ (string)$csv->validate()->get(0),
+ );
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'max_date', '2042/11/17'));
+ isSame(
+ '"max_date" at line 2, column "0:date". ' .
+ 'Value "2042/11/18" is more than the maximum date "2042-11-17T00:00:00.000+00:00".',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testDateFormat(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'date_format', 'Y/m/d'));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('date', 'date_format', 'Y/m/d H:i:s'));
+ isSame(
+ '"date_format" at line 2, column "0:date". ' .
+ 'Date format of value "2042/11/18" is not valid. Expected format: "Y/m/d H:i:s".',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testAllowValues(): void
+ {
+ $csv = new CsvFile(
+ self::CSV_COMPLEX,
+ $this->getRule(
+ 'bool',
+ 'allow_values',
+ ['true', 'false', 'False', 'True'],
+ ),
+ );
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'allow_values', ['true', 'false']));
+ isSame(
+ '"allow_values" at line 8, column "0:bool". ' .
+ 'Value "False" is not allowed. Allowed values: ["true", "false"].',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testExactValue(): void
+ {
+ $csv = new CsvFile(self::CSV_SIMPLE_HEADER, $this->getRule('exact', 'exact_value', '1'));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_SIMPLE_HEADER, $this->getRule('exact', 'exact_value', '2'));
+ isSame(
+ '"exact_value" at line 2, column "0:exact". Value "1" is not strict equal to "2".',
+ (string)$csv->validate()->get(0),
+ );
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'exact_value', 'true'));
+ isSame(
+ '"exact_value" at line 4, column "0:bool". Value "false" is not strict equal to "true".',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testIsInt(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'is_int', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'is_int', true));
+ isSame(
+ '"is_int" at line 2, column "0:bool". Value "true" is not an integer.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testIsFloat(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('seq', 'is_float', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'is_float', true));
+ isSame(
+ '"is_float" at line 2, column "0:bool". Value "true" is not a float number.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testIsBool(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('bool', 'is_bool', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('yn', 'is_bool', true));
+ isSame(
+ '"is_bool" at line 2, column "0:yn". Value "n" is not allowed. Allowed values: ["true", "false"].',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ public function testIsEmail(): void
+ {
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('email', 'is_email', true));
+ isSame('', (string)$csv->validate());
+
+ $csv = new CsvFile(self::CSV_COMPLEX, $this->getRule('yn', 'is_email', true));
+ isSame(
+ '"is_email" at line 2, column "0:yn". Value "N" is not a valid email.',
+ (string)$csv->validate()->get(0),
+ );
+ }
+
+ private function getRule(?string $columnName, ?string $ruleName, array|bool|float|int|string $options): array
+ {
+ return ['columns' => [['name' => $columnName, 'rules' => [$ruleName => $options]]]];
+ }
+}
diff --git a/tests/CsvBlueprintPackageTest.php b/tests/CsvBlueprintPackageTest.php
new file mode 100644
index 00000000..e88aca12
--- /dev/null
+++ b/tests/CsvBlueprintPackageTest.php
@@ -0,0 +1,22 @@
+