diff --git a/.gitignore b/.gitignore index 793daca2..a19eb1e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ -/vendor/ /tests/_output /tests/_cache /var/ /docs.phar /.env +/.phpunit.cache/ /.phpunit.result.cache +/.php-cs-fixer.cache /composer.lock +vendor/ diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 00000000..2e788d47 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,34 @@ +setRules([ + '@PHP71Migration' => true, + '@PHPUnit75Migration:risky' => true, + '@Symfony' => true, + '@Symfony:risky' => true, + 'protected_to_private' => false, + 'native_constant_invocation' => ['strict' => false], + 'no_superfluous_phpdoc_tags' => [ + 'remove_inheritdoc' => true, + 'allow_unused_params' => true, // for future-ready params, to be replaced with https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/7377 + ], + 'header_comment' => ['header' => $fileHeaderComment], + 'modernize_strpos' => true, + 'get_class_to_class_keyword' => true, + 'nullable_type_declaration' => true, + ]) + ->setRiskyAllowed(true) + ->setFinder( + (new PhpCsFixer\Finder()) + ->in(__DIR__.'/src') + ) +; diff --git a/composer.json b/composer.json index 8e66adac..e4b89186 100644 --- a/composer.json +++ b/composer.json @@ -14,24 +14,42 @@ } }, "require": { - "php": ">=8.3", + "php": ">=8.2", "ext-json": "*", "ext-curl": "*", - "doctrine/rst-parser": "^0.5", - "scrivo/highlight.php": "^9.18.1", - "symfony/filesystem": "^5.2 || ^6.0 || ^7.0", - "symfony/finder": "^5.2 || ^6.0 || ^7.0", - "symfony/dom-crawler": "^5.2 || ^6.0 || ^7.0", - "symfony/css-selector": "^5.2 || ^6.0 || ^7.0", - "symfony/console": "^5.2 || ^6.0 || ^7.0", - "symfony/http-client": "^5.2 || ^6.0 || ^7.0", - "twig/twig": "^2.14 || ^3.3" + "phpdocumentor/guides": "^1.9", + "phpdocumentor/guides-cli": "^1.9", + "phpdocumentor/guides-code": "^1.7", + "phpdocumentor/guides-restructured-text": "^1.9", + "scrivo/highlight.php": "^9.12.0", + "symfony/config": "^6.0", + "symfony/filesystem": "^6.0", + "symfony/finder": "^6.0", + "symfony/event-dispatcher": "^6.0", + "symfony/dependency-injection": "^6.0", + "symfony/dom-crawler": "^6.0", + "symfony/css-selector": "^6.0", + "symfony/console": "^6.0", + "symfony/http-client": "^6.0", + "symfony/string": "^6.0", + "twig/twig": "^3.3", + "twig/string-extra": "^3.6" }, "require-dev": { - "gajus/dindent": "^2.0", - "symfony/phpunit-bridge": "^5.2 || ^6.0 || ^7.0", - "symfony/process": "^5.2 || ^6.0 || ^7.0", - "masterminds/html5": "^2.7" + "league/flysystem-memory": "^3.0", + "symfony/phpunit-bridge": "^7.4@dev", + "symfony/process": "^6.0", + "symfony/var-dumper": "^6.2" }, - "bin": ["bin/docs-builder"] + "scripts": { + "test": "SYMFONY_PHPUNIT_VERSION=12 simple-phpunit", + "psalm": [ + "composer update --no-scripts --working-dir=tools/psalm", + "./tools/psalm/vendor/bin/psalm" + ], + "cs": [ + "composer update --no-scripts --working-dir=tools/php-cs-fixer", + "./tools/php-cs-fixer/vendor/bin/php-cs-fixer fix" + ] + } } diff --git a/config/parser.php b/config/parser.php new file mode 100644 index 00000000..52e7a17d --- /dev/null +++ b/config/parser.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use phpDocumentor\Guides\RestructuredText\Parser\Productions\DirectiveContentRule; +use phpDocumentor\Guides\RestructuredText\TextRoles\TextRole; + +return static function (ContainerConfigurator $container) { + $container->services() + ->defaults()->autowire() + + ->load('SymfonyDocsBuilder\\Directives\\', '../src/Directives') + ->bind('$startingRule', service(DirectiveContentRule::class)) + ->tag('phpdoc.guides.directive') + + ->load('SymfonyDocsBuilder\\TextRole\\', '../src/TextRole') + ->tag('phpdoc.guides.parser.rst.text_role') + ; +}; diff --git a/config/renderer.php b/config/renderer.php new file mode 100644 index 00000000..b7eb5855 --- /dev/null +++ b/config/renderer.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use SymfonyDocsBuilder\Highlighter\SymfonyHighlighter; +use SymfonyDocsBuilder\NodeRenderer\CodeNodeRenderer; +use SymfonyDocsBuilder\NodeRenderer\MenuEntryRenderer; +use SymfonyDocsBuilder\Node\ExternalLinkNode; +use SymfonyDocsBuilder\Twig\CodeExtension; +use SymfonyDocsBuilder\Twig\UrlExtension; +use Twig\Extension\ExtensionInterface; +use Twig\Extra\String\StringExtension; +use phpDocumentor\Guides\Code\Highlighter\Highlighter; +use phpDocumentor\Guides\NodeRenderers\NodeRenderer; +use phpDocumentor\Guides\NodeRenderers\TemplateNodeRenderer; + +return static function (ContainerConfigurator $container) { + $container ->services() + ->defaults()->autowire()->autoconfigure() + ->instanceof(ExtensionInterface::class)->tag('twig.extension') + ->instanceof(NodeRenderer::class)->tag('phpdoc.guides.noderenderer.html', ['priority' => 10]) + + ->set(CodeExtension::class) + ->set(UrlExtension::class) + ->set(StringExtension::class) + + ->set(CodeNodeRenderer::class) + ->set(MenuEntryRenderer::class) + + ->set('symfony.node_renderer.html.inline.external_link', TemplateNodeRenderer::class) + ->arg('$template', 'inline/external-link.html.twig') + ->arg('$nodeClass', ExternalLinkNode::class) + + ->set(SymfonyHighlighter::class) + ->decorate(Highlighter::class) + ; +}; diff --git a/config/services.php b/config/services.php new file mode 100644 index 00000000..69243338 --- /dev/null +++ b/config/services.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Psr\EventDispatcher\EventDispatcherInterface; +use SymfonyDocsBuilder\Build\BuildConfig; +use SymfonyDocsBuilder\DocBuilder; +use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\EventDispatcher\EventDispatcher; + +return static function (ContainerConfigurator $container) { + $container->services() + ->defaults()->autowire() + + ->set(EventDispatcherInterface::class, EventDispatcher::class) + + ->set(BuildConfig::class) + + ->set(DocBuilder::class)->public() + ; +}; diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 00000000..145c9f34 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,31 @@ + + + + + tests + + + + + + src + + + + trigger_deprecation + Doctrine\Deprecations\Deprecation::trigger + Doctrine\Deprecations\Deprecation::delegateTriggerToBackend + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 00000000..5cbbfe3e --- /dev/null +++ b/psalm.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + diff --git a/resources/highlight.php/README.md b/resources/highlight.php/README.md new file mode 100644 index 00000000..54f7762f --- /dev/null +++ b/resources/highlight.php/README.md @@ -0,0 +1,30 @@ +# Custom Highlight Templates + +The highlight.php library takes its highlighting metadata/rules +from highlight.js. That library builds the highlighting metadata/rules +in Node and then outputs them as JSON: + +* Source Language files: https://github.com/highlightjs/highlight.js/tree/master/src/languages +* Final Language files: https://github.com/scrivo/highlight.php/tree/master/Highlight/languages + +In a few cases, we've extended the language rules, which (in theory) +should make it back upstream to highlight.js. These files began +as copies of the .json files (which were then prettified) then extended. + +A few things we've learned about how the language files work: + +* `begin` is the regex that marks the beginning of something +* `end` is optional. Without it, `begin` will be used, and as + soon as it finds a non-matching character, it will stop. + If you have a situation where using begin is causing + over-matching, then you can use end to tell it exactly where + to stop. +* `excludeEnd` can be used to match an entire string with `begin` + and `end`, but then only apply the class name to the part + matched by `start`. This was useful with `::` where we wanted + to match `::` THEN some valid string (to avoid over-matching + `::` in other situations). But, we only wanted the class name + applied to the `start` part (the `::` part). +* `contains` the way for building embedded rules. `function` is + a nice example, which outlines the `start` and `end` and then + also outlines some items that will be embedded inside of it. diff --git a/resources/highlight.php/php.json b/resources/highlight.php/php.json new file mode 100644 index 00000000..50b53fe7 --- /dev/null +++ b/resources/highlight.php/php.json @@ -0,0 +1,275 @@ +{ + "aliases": [ + "php", + "php3", + "php4", + "php5", + "php6", + "php7" + ], + "case_insensitive": true, + "keywords": "and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally", + "contains": [ + { + "className": "comment", + "begin": "#", + "end": "$", + "contains": [ + { + "begin": "\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b" + }, + { + "className": "doctag", + "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", + "relevance": 0 + } + ] + }, + { + "className": "comment", + "begin": "//", + "end": "$", + "contains": [ + { + "className": "meta", + "begin": "<\\?(php)?|\\?>" + }, + { + "$ref": "#contains.0.contains.0" + }, + { + "className": "doctag", + "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", + "relevance": 0 + } + ] + }, + { + "className": "comment", + "begin": "/\\*", + "end": "\\*/", + "contains": [ + { + "className": "doctag", + "begin": "@[A-Za-z]+" + }, + { + "$ref": "#contains.0.contains.0" + }, + { + "className": "doctag", + "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", + "relevance": 0 + } + ] + }, + { + "className": "comment", + "begin": "__halt_compiler.+?;", + "end": false, + "contains": [ + { + "$ref": "#contains.0.contains.0" + }, + { + "className": "doctag", + "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", + "relevance": 0 + } + ], + "endsWithParent": true, + "keywords": "__halt_compiler", + "lexemes": "[a-zA-Z_]\\w*" + }, + { + "className": "string", + "begin": "<<<['\"]?\\w+['\"]?$", + "end": "^\\w+;?$", + "contains": [ + { + "begin": "\\\\[\\s\\S]", + "relevance": 0 + }, + { + "className": "subst", + "variants": [ + { + "begin": "\\$\\w+" + }, + { + "begin": "\\{\\$", + "end": "\\}" + } + ] + } + ] + }, + { + "$ref": "#contains.1.contains.0" + }, + { + "className": "variable", + "begin": "\\$this\\b" + }, + { + "className": "variable", + "begin": "\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*" + }, + { + "className": "operator", + "begin": "(::|->)", + "end": "[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*", + "excludeEnd": true + }, + { + "className": "function", + "beginKeywords": "function", + "end": "[;{]", + "excludeEnd": true, + "illegal": "\\$|\\[|%", + "contains": [ + { + "className": "title", + "begin": "[a-zA-Z_]\\w*", + "relevance": 0 + }, + { + "className": "params", + "begin": "\\(", + "end": "\\)", + "contains": [ + "self", + { + "$ref": "#contains.7" + }, + { + "className": "comment", + "begin": "/\\*", + "end": "\\*/", + "contains": [ + { + "$ref": "#contains.0.contains.0" + }, + { + "className": "doctag", + "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", + "relevance": 0 + } + ] + }, + { + "className": "string", + "contains": [ + { + "$ref": "#contains.4.contains.0" + }, + { + "$ref": "#contains.1.contains.0" + } + ], + "variants": [ + { + "begin": "b\"", + "end": "\"" + }, + { + "begin": "b'", + "end": "'" + }, + { + "className": "string", + "begin": "'", + "end": "'", + "illegal": null, + "contains": [ + { + "$ref": "#contains.4.contains.0" + } + ] + }, + { + "className": "string", + "begin": "\"", + "end": "\"", + "illegal": null, + "contains": [ + { + "$ref": "#contains.4.contains.0" + }, + { + "className": "subst", + "begin": "\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]", + "relevance": 0 + }, + { + "className": "subst", + "begin": "\\\\[abfnrtv]\\|\\\\x[0-9a-fA-F]*\\\\\\|%[-+# *.0-9]*[dioxXucsfeEgGp]", + "relevance": 0 + } + ] + } + ] + }, + { + "variants": [ + { + "className": "number", + "begin": "\\b(0b[01]+)", + "relevance": 0 + }, + { + "className": "number", + "begin": "(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)", + "relevance": 0 + } + ] + } + ] + } + ] + }, + { + "className": "class", + "beginKeywords": "class interface", + "end": "{", + "excludeEnd": true, + "illegal": "[:\\(\\$\"]", + "contains": [ + { + "beginKeywords": "extends implements" + }, + { + "$ref": "#contains.9.contains.0" + } + ] + }, + { + "beginKeywords": "namespace", + "end": ";", + "illegal": "[\\.']", + "contains": [ + { + "$ref": "#contains.9.contains.0" + } + ] + }, + { + "beginKeywords": "use", + "end": ";", + "contains": [ + { + "$ref": "#contains.9.contains.0" + } + ] + }, + { + "begin": "=>" + }, + { + "$ref": "#contains.9.contains.1.contains.3" + }, + { + "$ref": "#contains.9.contains.1.contains.4" + } + ] +} diff --git a/resources/highlight.php/twig.json b/resources/highlight.php/twig.json new file mode 100644 index 00000000..b961028c --- /dev/null +++ b/resources/highlight.php/twig.json @@ -0,0 +1,79 @@ +{ + "aliases": [ + "craftcms" + ], + "case_insensitive": true, + "subLanguage": "xml", + "contains": [ + { + "className": "comment", + "begin": "\\{#", + "end": "#}", + "contains": [ + { + "begin": "\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b" + }, + { + "className": "doctag", + "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", + "relevance": 0 + } + ] + }, + { + "className": "template-tag", + "begin": "\\{%", + "end": "%}", + "contains": [ + { + "className": "name", + "begin": "\\w+", + "keywords": "apply autoescape block deprecated do embed extends filter flush for from if import include macro sandbox set use verbatim with endapply endautoescape endblock enddeprecated enddo endembed endextends endfilter endflush endfor endfrom endif endimport endinclude endmacro endsandbox endset enduse endverbatim endwith", + "starts": { + "endsWithParent": true, + "contains": [ + { + "begin": "\\|[A-Za-z_]+:?", + "keywords": "abs batch capitalize column convert_encoding date date_modify default escape filter first format inky_to_html inline_css join json_encode keys last length lower map markdown merge nl2br number_format raw reduce replace reverse round slice sort spaceless split striptags title trim upper url_encode", + "contains": [ + { + "beginKeywords": "attribute block constant cycle date dump include max min parent random range source template_from_string", + "keywords": { + "name": "attribute block constant cycle date dump include max min parent random range source template_from_string" + }, + "relevance": 0, + "contains": [ + { + "className": "params", + "begin": "\\(", + "end": "\\)" + } + ] + } + ] + }, + { + "$ref": "#contains.1.contains.0.starts.contains.0.contains.0" + } + ], + "relevance": 0 + } + } + ] + }, + { + "className": "template-variable", + "begin": "\\{\\{", + "end": "}}", + "contains": [ + "self", + { + "$ref": "#contains.1.contains.0.starts.contains.0" + }, + { + "$ref": "#contains.1.contains.0.starts.contains.0.contains.0" + } + ] + } + ] +} diff --git a/resources/templates/blank/html/layout.html.twig b/resources/templates/blank/html/layout.html.twig new file mode 100644 index 00000000..3ddfb62f --- /dev/null +++ b/resources/templates/blank/html/layout.html.twig @@ -0,0 +1 @@ +{% block body %}{% endblock %} diff --git a/resources/templates/symfonycom/html/_helpers.twig b/resources/templates/symfonycom/html/_helpers.twig new file mode 100644 index 00000000..df8eb3df --- /dev/null +++ b/resources/templates/symfonycom/html/_helpers.twig @@ -0,0 +1,12 @@ +{% macro link(url, text, attributes = {}) %} +{% set attributes = attributes|merge({ + class: (attributes.class|default ? attributes.class ~ ' ') ~ 'reference ' ~ (url is safe_url ? 'internal' : 'external') + }) +%} + + {{- text|raw -}} + +{% endmacro %} diff --git a/resources/templates/symfonycom/html/body/admonition.html.twig b/resources/templates/symfonycom/html/body/admonition.html.twig new file mode 100644 index 00000000..a92de66b --- /dev/null +++ b/resources/templates/symfonycom/html/body/admonition.html.twig @@ -0,0 +1,22 @@ +{# icons are from https://heroicons.com/ - MIT License #} +
+

+ {% if name in ['admonition', 'note'] -%} + + {% elseif name in ['hint', 'tip'] %} + + {% elseif name in ['attention', 'important', 'warning'] %} + + {% elseif name in ['caution', 'danger', 'error'] %} + + {% elseif name in ['versionadded', 'deprecated'] %} + {# don't show an icon for these directives #} + {% elseif name in ['seealso'] %} + + {% elseif name in ['screencast'] %} + + {% endif -%} + {{ text|raw }} +

+ {{ renderNode(node) }} +
diff --git a/resources/templates/symfonycom/html/body/code.html.twig b/resources/templates/symfonycom/html/body/code.html.twig new file mode 100644 index 00000000..2580254a --- /dev/null +++ b/resources/templates/symfonycom/html/body/code.html.twig @@ -0,0 +1,15 @@ +{% set size = ['-', 'sm', 'md', 'lg', 'xl'][loc | length] %} + +
+ {% if node.caption -%} +
{{ renderNode(node.caption) }}
+ {% endif -%} +
+
+            {{- line_numbers -}}
+        
+

+            {{- code|raw -}}
+        
+
+
diff --git a/resources/templates/symfonycom/html/body/configuration-block.html.twig b/resources/templates/symfonycom/html/body/configuration-block.html.twig new file mode 100644 index 00000000..f1f8bae7 --- /dev/null +++ b/resources/templates/symfonycom/html/body/configuration-block.html.twig @@ -0,0 +1,17 @@ +
+
+ {% for tab in node.tabs %} + + {% endfor %} +
+ + {% for tab in node.tabs %} +
+ {{ renderNode(tab.content) }} +
+ {% endfor %} +
diff --git a/resources/templates/symfonycom/html/body/image.html.twig b/resources/templates/symfonycom/html/body/image.html.twig new file mode 100644 index 00000000..08c16155 --- /dev/null +++ b/resources/templates/symfonycom/html/body/image.html.twig @@ -0,0 +1,5 @@ +{% set wrap_image_with_browser = 'with-browser' in node.classes %} +{% set src = node.value is external_target ? node.value : asset(node.value) %} +{% if wrap_image_with_browser %}
{% endif %} + +{% if wrap_image_with_browser %}
{% endif %} diff --git a/resources/templates/symfonycom/html/body/list/list-item.html.twig b/resources/templates/symfonycom/html/body/list/list-item.html.twig new file mode 100644 index 00000000..21fd05de --- /dev/null +++ b/resources/templates/symfonycom/html/body/list/list-item.html.twig @@ -0,0 +1,5 @@ +
  • + {%- for child in node.children -%} + {{ renderNode(child) }} + {%- endfor -%} +
  • diff --git a/resources/templates/symfonycom/html/body/menu/menu-item.html.twig b/resources/templates/symfonycom/html/body/menu/menu-item.html.twig new file mode 100644 index 00000000..5affffc6 --- /dev/null +++ b/resources/templates/symfonycom/html/body/menu/menu-item.html.twig @@ -0,0 +1,15 @@ +
  • + {{ renderNode(node.value.value) }} + {% if node.children|length %} + {% include "body/menu/menu-level.html.twig" with { + tocItems: node.children, + level: level + 1 + } %} + {% endif %} + {% if node.sections|length %} + {% include "body/menu/menu-level.html.twig" with { + entries: node.sections, + level: node.level + 1 + } %} + {% endif %} +
  • diff --git a/resources/templates/symfonycom/html/body/menu/menu-level.html.twig b/resources/templates/symfonycom/html/body/menu/menu-level.html.twig new file mode 100644 index 00000000..024fd6ab --- /dev/null +++ b/resources/templates/symfonycom/html/body/menu/menu-level.html.twig @@ -0,0 +1,7 @@ +{% set level = level | default(1) %} +{% set entries = entries | default(node.menuEntries) %} + diff --git a/resources/templates/symfonycom/html/body/menu/menu.html.twig b/resources/templates/symfonycom/html/body/menu/menu.html.twig new file mode 100644 index 00000000..82103a1f --- /dev/null +++ b/resources/templates/symfonycom/html/body/menu/menu.html.twig @@ -0,0 +1,3 @@ + diff --git a/resources/templates/symfonycom/html/body/menu/table-of-content.html.twig b/resources/templates/symfonycom/html/body/menu/table-of-content.html.twig new file mode 100644 index 00000000..0140d42b --- /dev/null +++ b/resources/templates/symfonycom/html/body/menu/table-of-content.html.twig @@ -0,0 +1,3 @@ +
    + {% include "body/menu/menu-level.html.twig" %} +
    diff --git a/resources/templates/symfonycom/html/body/table.html.twig b/resources/templates/symfonycom/html/body/table.html.twig new file mode 100644 index 00000000..757ada30 --- /dev/null +++ b/resources/templates/symfonycom/html/body/table.html.twig @@ -0,0 +1,31 @@ +
    + + {% if tableHeaderRows is not empty %} + + {% for tableHeaderRow in tableHeaderRows %} + + {% for column in tableHeaderRow.columns %} + 1 %} colspan="{{ column.colspan }}"{% endif %}> + {%- for child in column.children -%} + {{- renderNode(child) -}} + {% endfor %} + {% endfor %} + + {% endfor %} + + {% endif %} + + + {% for tableRow in tableRows %} + + {% for column in tableRow.columns %} + 1 %} colspan="{{ column.colSpan }}"{% endif %}{% if column.rowSpan > 1 %} rowspan="{{ column.rowSpan }}"{% endif %}> + {%- for child in column.children -%} + {{- renderNode(child) -}} + {% endfor %} + {% endfor %} + + {% endfor %} + + +
    diff --git a/resources/templates/symfonycom/html/body/topic.html.twig b/resources/templates/symfonycom/html/body/topic.html.twig new file mode 100644 index 00000000..27e45ff3 --- /dev/null +++ b/resources/templates/symfonycom/html/body/topic.html.twig @@ -0,0 +1,4 @@ +
    +

    {{ name|raw }}

    + {{ renderNode(node) }} +
    diff --git a/resources/templates/symfonycom/html/body/version-change.html.twig b/resources/templates/symfonycom/html/body/version-change.html.twig new file mode 100644 index 00000000..8dbcbc24 --- /dev/null +++ b/resources/templates/symfonycom/html/body/version-change.html.twig @@ -0,0 +1,6 @@ +
    +

    + {{ node.versionModified }} +

    + {{ renderNode(node.value) }} +
    diff --git a/resources/templates/symfonycom/html/inline/doc.html.twig b/resources/templates/symfonycom/html/inline/doc.html.twig new file mode 100644 index 00000000..04701ab3 --- /dev/null +++ b/resources/templates/symfonycom/html/inline/doc.html.twig @@ -0,0 +1 @@ +{{- include('inline/link.html.twig') -}} diff --git a/resources/templates/symfonycom/html/inline/external-link.html.twig b/resources/templates/symfonycom/html/inline/external-link.html.twig new file mode 100644 index 00000000..04701ab3 --- /dev/null +++ b/resources/templates/symfonycom/html/inline/external-link.html.twig @@ -0,0 +1 @@ +{{- include('inline/link.html.twig') -}} diff --git a/resources/templates/symfonycom/html/inline/link.html.twig b/resources/templates/symfonycom/html/inline/link.html.twig new file mode 100644 index 00000000..d2a010c5 --- /dev/null +++ b/resources/templates/symfonycom/html/inline/link.html.twig @@ -0,0 +1,13 @@ +{%- set attributes = { + title: node.title, + class: (node.classes ? node.classes|join(' ') ~ ' ') ~ 'reference ' ~ (node.url is safe_url ? 'internal' : 'external') + }|filter(v => v != '') +-%} + + {%- for child in node.children -%} + {{ renderNode(child) }} + {%- endfor -%} + diff --git a/resources/templates/symfonycom/html/inline/literal.html.twig b/resources/templates/symfonycom/html/inline/literal.html.twig new file mode 100644 index 00000000..cfce08ec --- /dev/null +++ b/resources/templates/symfonycom/html/inline/literal.html.twig @@ -0,0 +1 @@ +{{ node.value|e|fqcn }} diff --git a/resources/templates/symfonycom/html/inline/ref.html.twig b/resources/templates/symfonycom/html/inline/ref.html.twig new file mode 100644 index 00000000..04701ab3 --- /dev/null +++ b/resources/templates/symfonycom/html/inline/ref.html.twig @@ -0,0 +1 @@ +{{- include('inline/link.html.twig') -}} diff --git a/resources/templates/symfonycom/html/structure/header-title.html.twig b/resources/templates/symfonycom/html/structure/header-title.html.twig new file mode 100644 index 00000000..eb2d6ae6 --- /dev/null +++ b/resources/templates/symfonycom/html/structure/header-title.html.twig @@ -0,0 +1 @@ +{{ renderNode(node.value) }} diff --git a/resources/templates/symfonycom/html/structure/layout.html.twig b/resources/templates/symfonycom/html/structure/layout.html.twig new file mode 100644 index 00000000..dd3529e0 --- /dev/null +++ b/resources/templates/symfonycom/html/structure/layout.html.twig @@ -0,0 +1,13 @@ + + + + {{ title }} + {%- if title!=null and env.projectNode.title!=null %} - {% endif -%} + {%- if env.projectNode.title -%}{{ env.projectNode.title }}{%- endif -%} + {%~ block head %} + {%~ endblock %} + + + {% block body %}{% endblock %} + + diff --git a/resources/templates/symfonycom/html/structure/sidebar.html.twig b/resources/templates/symfonycom/html/structure/sidebar.html.twig new file mode 100644 index 00000000..c9c78752 --- /dev/null +++ b/resources/templates/symfonycom/html/structure/sidebar.html.twig @@ -0,0 +1,4 @@ +
    + + {{ renderNode(node) }} +
    diff --git a/src/Application.php b/src/Application.php index 7a0932df..df6cebc2 100644 --- a/src/Application.php +++ b/src/Application.php @@ -1,42 +1,31 @@ + * This file is part of the Guides SymfonyExtension package. + * + * (c) Wouter de Jong + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace SymfonyDocsBuilder; -use Symfony\Component\Console\Application as BaseApplication; +use Symfony\Component\Console\Application as SymfonyApplication; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use SymfonyDocsBuilder\Command\BuildDocsCommand; +use Symfony\Component\Console\Output\OutputInterface; -class Application +final class Application extends SymfonyApplication { - private $application; - private $buildConfig; - - public function __construct(string $symfonyVersion) - { - $this->application = new BaseApplication(); - $this->buildConfig = new BuildConfig(); + public function __construct( + private ?OutputInterface $output = null, + ) { + parent::__construct('Symfony Docs Builder'); } - public function run(InputInterface $input): int + #[\Override] + public function run(?InputInterface $input = null, ?OutputInterface $output = null): int { - $inputOption = new InputOption( - 'symfony-version', - null, - InputOption::VALUE_REQUIRED, - 'The symfony version of the doc to parse.', - false === getenv('SYMFONY_VERSION') ? 'master' : getenv('SYMFONY_VERSION') - ); - $this->application->getDefinition()->addOption($inputOption); - $this->application->add(new BuildDocsCommand($this->buildConfig)); - - return $this->application->run($input); + return parent::run($input, $output ?? $this->output); } } diff --git a/src/Build/BuildConfig.php b/src/Build/BuildConfig.php new file mode 100644 index 00000000..5367d49e --- /dev/null +++ b/src/Build/BuildConfig.php @@ -0,0 +1,51 @@ +symfonyVersion = $symfonyVersion; + } + + public function getSymfonyVersion(): string + { + return $this->symfonyVersion; + } + + public function getSymfonyRepositoryUrl(): string + { + return str_replace('{symfonyVersion}', $this->getSymfonyVersion(), self::SYMFONY_REPOSITORY_URL); + } + + public function getFormat(): string + { + return $this->format; + } + + public function createProjectNode(): ProjectNode + { + return new ProjectNode('Symfony', $this->symfonyVersion); + } +} diff --git a/src/Build/BuildEnvironment.php b/src/Build/BuildEnvironment.php new file mode 100644 index 00000000..c1b22578 --- /dev/null +++ b/src/Build/BuildEnvironment.php @@ -0,0 +1,21 @@ +sourceFilesystem = new FlysystemV3(new LeagueFilesystem($sourceAdapter ?? new InMemoryFilesystemAdapter())); + $this->outputFilesystem = new FlysystemV3(new LeagueFilesystem($outputAdapter ?? new InMemoryFilesystemAdapter())); + } + + #[\Override] + public function getSourceFilesystem(): FileSystem + { + return $this->sourceFilesystem; + } + + #[\Override] + public function getOutputFilesystem(): FileSystem + { + return $this->outputFilesystem; + } +} diff --git a/src/Build/LocalBuildEnvironment.php b/src/Build/LocalBuildEnvironment.php new file mode 100644 index 00000000..0fc7451b --- /dev/null +++ b/src/Build/LocalBuildEnvironment.php @@ -0,0 +1,74 @@ +setSourceDir($cwd); + } + } + + public function setSourceDir(string $sourceDir): void + { + if ($sourceDir === $this->sourceDir) { + return; + } + + $this->sourceDir = $sourceDir; + $this->sourceFilesystem = null; + + if (null == $this->outputDir) { + $this->setOutputDir($sourceDir.'/_output'); + } + } + + public function setOutputDir(string $outputDir): void + { + if ($outputDir !== $this->outputDir) { + $this->outputFilesystem = null; + } + $this->outputDir = $outputDir; + } + + #[\Override] + public function getSourceFilesystem(): FileSystem + { + if (null === $this->sourceDir) { + throw new \BadMethodCallException('Cannot get source filesystem: no source directory set.'); + } + + return $this->sourceFilesystem ??= new FlysystemV3(new LeagueFilesystem(new LocalFilesystemAdapter($this->sourceDir))); + } + + #[\Override] + public function getOutputFilesystem(): FileSystem + { + if (null === $this->outputDir) { + throw new \BadMethodCallException('Cannot get output filesystem: no output directory set.'); + } + + return $this->outputFilesystem ??= new FlysystemV3(new LeagueFilesystem(new LocalFilesystemAdapter($this->outputDir))); + } +} diff --git a/src/Build/StringBuildEnvironment.php b/src/Build/StringBuildEnvironment.php new file mode 100644 index 00000000..fc01e243 --- /dev/null +++ b/src/Build/StringBuildEnvironment.php @@ -0,0 +1,47 @@ +filesystem = new FlysystemV3(new LeagueFilesystem(new InMemoryFilesystemAdapter())); + $this->filesystem->put('index.rst', $contents); + } + + #[\Override] + public function getSourceFilesystem(): FileSystem + { + return $this->filesystem; + } + + #[\Override] + public function getOutputFilesystem(): FileSystem + { + return $this->filesystem; + } + + public function getOutput(): ?string + { + $output = $this->filesystem->read('/index.html'); + + return false === $output ? null : $output; + } +} diff --git a/src/DependencyInjection/CommandLocator.php b/src/DependencyInjection/CommandLocator.php new file mode 100644 index 00000000..7e819e07 --- /dev/null +++ b/src/DependencyInjection/CommandLocator.php @@ -0,0 +1,35 @@ +commands->get($commandName); + } catch (NotFoundExceptionInterface) { + throw new MissingHandlerException(\sprintf('No handler found for command "%s"', $commandName)); + } + } +} diff --git a/src/DependencyInjection/SymfonyExtension.php b/src/DependencyInjection/SymfonyExtension.php new file mode 100644 index 00000000..96c7b97c --- /dev/null +++ b/src/DependencyInjection/SymfonyExtension.php @@ -0,0 +1,74 @@ +load('services.php'); + $loader->load('parser.php'); + $loader->load('renderer.php'); + } + + #[\Override] + public function prepend(ContainerBuilder $container): void + { + $templatesDir = \dirname(__DIR__, 2).'/resources/templates'; + + $container->prependExtensionConfig('guides', [ + 'default_code_language' => 'php', + 'themes' => [ + 'symfonycom' => $templatesDir.'/symfonycom/html', + ], + ]); + + $container->prependExtensionConfig('code', [ + 'languages' => [ + 'php' => \dirname(__DIR__, 2).'/resources/highlight.php/php.json', + 'twig' => \dirname(__DIR__, 2).'/resources/highlight.php/twig.json', + ], + 'aliases' => [ + 'caddy' => 'plaintext', + 'env' => 'bash', + 'html+jinja' => 'twig', + 'html+twig' => 'twig', + 'jinja' => 'twig', + 'html+php' => 'html', + 'xml+php' => 'xml', + 'php-annotations' => 'php', + 'php-attributes' => 'php', + 'terminal' => 'bash', + 'rst' => 'markdown', + 'php-standalone' => 'php', + 'php-symfony' => 'php', + 'varnish4' => 'c', + 'varnish3' => 'c', + 'vcl' => 'c', + ], + ]); + } +} diff --git a/src/Directives/BestPracticeDirective.php b/src/Directives/BestPracticeDirective.php new file mode 100644 index 00000000..d86931b9 --- /dev/null +++ b/src/Directives/BestPracticeDirective.php @@ -0,0 +1,23 @@ +isBuildCacheEnabled() && $filesystem->exists($config->getOutputDir())) { - $filesystem->remove($config->getOutputDir()); - } - $filesystem->mkdir($config->getOutputDir()); - - $configFileParser = new ConfigFileParser($config, new NullOutput()); - $configFileParser->processConfigFile($config->getContentDir()); + public function __construct( + private CommandBus $commandBus, + private ThemeManager $themeManager, + private BuildConfig $buildConfig, + ) { + } - $builder = new Builder(KernelFactory::createKernel($config)); - $builder->build($config->getContentDir(), $config->getOutputDir()); + public function build(BuildEnvironment $buildEnvironment): void + { + $this->themeManager->useTheme('symfonycom'); - $buildResult = new BuildResult($builder); + $projectNode = $this->buildConfig->createProjectNode(); - $missingFilesChecker = new MissingFilesChecker($config); - $missingFiles = $missingFilesChecker->getMissingFiles(); - foreach ($missingFiles as $missingFile) { - $buildResult->appendError(sprintf('Missing file "%s"', $missingFile)); - } + /** @var list $documents */ + $documents = $this->commandBus->handle(new ParseDirectoryCommand($buildEnvironment->getSourceFilesystem(), '/', 'rst', $projectNode)); - if (!$buildResult->isSuccessful()) { - $buildResult->prependError(sprintf('Build errors from "%s"', date('Y-m-d h:i:s'))); - $filesystem->dumpFile($config->getOutputDir().'/build_errors.txt', implode("\n", $buildResult->getErrors())); - } + $documents = $this->commandBus->handle(new CompileDocumentsCommand($documents, new CompilerContext($projectNode))); - if ($config->isContentAString()) { - $htmlFilePath = $config->getOutputDir().'/index.html'; - if (is_file($htmlFilePath)) { - // generated HTML contents are a full HTML page, so we need to - // extract the contents of the tag - $crawler = new Crawler(file_get_contents($htmlFilePath)); - $buildResult->setStringResult(trim($crawler->filter('body')->html())); - } - } elseif ($config->getSubdirectoryToBuild()) { - $metas = $buildResult->getMetadata(); - $htmlForPdfGenerator = new HtmlForPdfGenerator($metas, $config); - $htmlForPdfGenerator->generateHtmlForPdf(); - } elseif ($config->generateJsonFiles()) { - $metas = $buildResult->getMetadata(); - $jsonGenerator = new JsonGenerator($metas, $config); - $buildResult->setJsonResults($jsonGenerator->generateJson($builder->getIndexName())); + foreach ($documents as $document) { + $this->commandBus->handle(new RenderDocumentCommand( + $document, + RenderContext::forDocument( + $document, + $documents, + $buildEnvironment->getSourceFilesystem(), + $buildEnvironment->getOutputFilesystem(), + '/', + 'html', + $projectNode + ) + )); } - - return $buildResult; } - public function buildString(string $contents): BuildResult + public function buildString(string $contents): string { - $filesystem = new Filesystem(); - $tmpDir = sys_get_temp_dir().'/doc_builder_build_string_'.random_int(1, 100000000); - if ($filesystem->exists($tmpDir)) { - $filesystem->remove($tmpDir); - } - $filesystem->mkdir($tmpDir); - - $filesystem->dumpFile($tmpDir.'/index.rst', $contents); + $buildEnvironment = new StringBuildEnvironment($contents); - $buildConfig = (new BuildConfig()) - ->setContentIsString() - ->setContentDir($tmpDir) - ->setOutputDir($tmpDir.'/output') - ->disableBuildCache() - ->disableJsonFileGeneration() - ; + $this->build($buildEnvironment); - $buildResult = $this->build($buildConfig); - $filesystem->remove($tmpDir); + $output = $buildEnvironment->getOutput(); + if (null === $output) { + throw new \LogicException('Cannot build HTML from the provided reStructuredText: no HTML output found.'); + } - return $buildResult; + return $output; } } diff --git a/src/DocsKernel.php b/src/DocsKernel.php index 8ffbedd7..7c91ed95 100644 --- a/src/DocsKernel.php +++ b/src/DocsKernel.php @@ -1,70 +1,135 @@ + * This file is part of the Guides SymfonyExtension package. + * + * (c) Wouter de Jong + * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace SymfonyDocsBuilder; -use Doctrine\Common\EventManager; -use Doctrine\RST\Builder; -use Doctrine\RST\Configuration; -use Doctrine\RST\ErrorManager; -use Doctrine\RST\Event\PostBuildRenderEvent; -use Doctrine\RST\Event\PreNodeRenderEvent; -use Doctrine\RST\Event\PreParseDocumentEvent; -use Doctrine\RST\Kernel; -use SymfonyDocsBuilder\Listener\AdmonitionListener; -use SymfonyDocsBuilder\Listener\AssetsCopyListener; -use SymfonyDocsBuilder\Listener\CopyImagesListener; -use SymfonyDocsBuilder\Listener\DuplicatedHeaderIdListener; +use Monolog\Logger; +use phpDocumentor\Guides\Cli\DependencyInjection\ContainerFactory; +use phpDocumentor\Guides\Code\DependencyInjection\CodeExtension; +use phpDocumentor\Guides\DependencyInjection\GuidesExtension; +use phpDocumentor\Guides\RestructuredText\DependencyInjection\ReStructuredTextExtension; +use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\EventDispatcher\EventDispatcher; +use SymfonyDocsBuilder\DependencyInjection\SymfonyExtension; -class DocsKernel extends Kernel +final class DocsKernel { - private $buildConfig; + public function __construct( + private Container $container, + ) { + } - public function __construct(BuildConfig $buildConfig, ?Configuration $configuration = null, $directives = [], $references = []) + /** @param list $extensions */ + public static function create(array $extensions = []): self { - parent::__construct($configuration, $directives, $references); + $containerFactory = new ContainerFactory([new SymfonyExtension(), self::createDefaultExtension(), new CodeExtension(), ...$extensions]); - $this->buildConfig = $buildConfig; - } + for ($i = 1; $i <= 4; ++$i) { + if (is_dir($vendor = \dirname(__DIR__, $i).'/vendor')) { + break; + } + } - public function initBuilder(Builder $builder): void - { - $this->initializeListeners( - $builder->getConfiguration()->getEventManager(), - $builder->getErrorManager() - ); + $containerFactory->loadExtensionConfig(GuidesExtension::class, [ + 'default_code_language' => 'php', + ]); + + $containerFactory->loadExtensionConfig(ReStructuredTextExtension::class, [ + 'code_language_labels' => [ + ['language' => 'caddy', 'label' => 'Caddy'], + ['language' => 'env', 'label' => 'Dotenv'], + ['language' => 'html+jinja', 'label' => 'Twig'], + ['language' => 'html+php', 'label' => 'PHP'], + ['language' => 'html+twig', 'label' => 'Twig'], + ['language' => 'jinja', 'label' => 'Twig'], + ['language' => 'php', 'label' => 'PHP'], + ['language' => 'php-annotations', 'label' => 'Annotations'], + ['language' => 'php-attributes', 'label' => 'Attributes'], + ['language' => 'php-standalone', 'label' => 'Standalone Use'], + ['language' => 'php-symfony', 'label' => 'Framework Use'], + ['language' => 'rst', 'label' => 'RST'], + ['language' => 'terminal', 'label' => 'Bash'], + ['language' => 'varnish3', 'label' => 'Varnish 3'], + ['language' => 'varnish4', 'label' => 'Varnish 4'], + ['language' => 'vcl', 'label' => 'VCL'], + ['language' => 'xml', 'label' => 'XML'], + ['language' => 'xml+php', 'label' => 'XML'], + ['language' => 'yaml', 'label' => 'YAML'], + ], + ]); - $builder->setScannerFinder($this->buildConfig->createFileFinder()); + $containerFactory->loadExtensionConfig(CodeExtension::class, [ + 'aliases' => [ + 'env' => 'bash', + 'html+jinja' => 'twig', + 'html+twig' => 'twig', + 'jinja' => 'twig', + 'html+php' => 'html', + 'xml+php' => 'xml', + 'php-annotations' => 'php', + 'php-attributes' => 'php', + 'terminal' => 'bash', + 'rst' => 'markdown', + 'php-standalone' => 'php', + 'php-symfony' => 'php', + 'varnish4' => 'c', + 'varnish3' => 'c', + 'vcl' => 'c', + ], + ]); + + $container = $containerFactory->create($vendor); + + return new self($container); } - private function initializeListeners(EventManager $eventManager, ErrorManager $errorManager) + /** + * @template T + * + * @param class-string $fqcn + * + * @return T + * + * @psalm-suppress InvalidReturnType + * @psalm-suppress InvalidReturnStatement + */ + public function get(string $fqcn): object { - $eventManager->addEventListener( - PreParseDocumentEvent::PRE_PARSE_DOCUMENT, - new AdmonitionListener() - ); + return $this->container->get($fqcn); + } - $eventManager->addEventListener( - PreParseDocumentEvent::PRE_PARSE_DOCUMENT, - new DuplicatedHeaderIdListener() - ); + private static function createDefaultExtension(): ExtensionInterface + { + return new class extends Extension { + #[\Override] + public function load(array $configs, ContainerBuilder $container): void + { + $container->register(Logger::class)->setArgument('$name', 'docs-builder'); + $container->setAlias(LoggerInterface::class, new Alias(Logger::class)); - $eventManager->addEventListener( - PreNodeRenderEvent::PRE_NODE_RENDER, - new CopyImagesListener($this->buildConfig, $errorManager) - ); + $container->register(EventDispatcher::class); + $container->setAlias(EventDispatcherInterface::class, new Alias(EventDispatcher::class)); + } - if (!$this->buildConfig->getSubdirectoryToBuild()) { - $eventManager->addEventListener( - [PostBuildRenderEvent::POST_BUILD_RENDER], - new AssetsCopyListener($this->buildConfig->getOutputDir()) - ); - } + #[\Override] + public function getAlias(): string + { + return 'docs-builder'; + } + }; } } diff --git a/src/Highlighter/SymfonyHighlighter.php b/src/Highlighter/SymfonyHighlighter.php new file mode 100644 index 00000000..9aefe0de --- /dev/null +++ b/src/Highlighter/SymfonyHighlighter.php @@ -0,0 +1,42 @@ +highlighter)($language, $code, $debugInformation); + + $code = $result->code; + if ('php' === $result->language) { + // highlight the $ in PHP variable names + $code = str_replace('$', '$', $code); + } + + if ('terminal' === $language) { + $code = preg_replace('/^\$ /m', '$ ', $code) ?? $code; + $code = preg_replace('/^C:\\\> /m', 'C:\> ', $code) ?? $code; + } + + return new HighlightResult($result->language, $code); + } +} diff --git a/src/Node/ExternalLinkNode.php b/src/Node/ExternalLinkNode.php new file mode 100644 index 00000000..ba2eea4c --- /dev/null +++ b/src/Node/ExternalLinkNode.php @@ -0,0 +1,31 @@ +title; + } +} diff --git a/src/NodeRenderer/CodeNodeRenderer.php b/src/NodeRenderer/CodeNodeRenderer.php new file mode 100644 index 00000000..e26ff4e3 --- /dev/null +++ b/src/NodeRenderer/CodeNodeRenderer.php @@ -0,0 +1,68 @@ + + */ +final class CodeNodeRenderer implements NodeRenderer +{ + public function __construct( + private TemplateRenderer $renderer, + private SymfonyHighlighter $higlighter, + ) { + } + + #[\Override] + public function supports(string $nodeFqcn): bool + { + return CodeNode::class === $nodeFqcn || is_a($nodeFqcn, CodeNode::class, true); + } + + #[\Override] + public function render(Node $node, RenderContext $renderContext): string + { + if (!$node instanceof CodeNode) { + throw new \LogicException(\sprintf('"%s" can only render code nodes, got "%s".', __CLASS__, get_debug_type($node))); + } + + $language = $node->getLanguage() ?? 'text'; + $highlight = ($this->higlighter)($language, $node->getValue(), $renderContext->getLoggerInformation()); + + $languages = array_unique([$language, $highlight->language]); + $code = $highlight->code; + + $codeLines = preg_split('/\R/', trim($code)); + \assert(\is_array($codeLines)); + $numOfLines = \count($codeLines); + $lineNumbers = implode("\n", range(1, $numOfLines)); + + return $this->renderer->renderTemplate( + $renderContext, + 'body/code.html.twig', + [ + 'languages' => $languages, + 'code' => rtrim($code), + 'line_numbers' => $lineNumbers, + 'loc' => $numOfLines, + 'node' => $node, + ] + ); + } +} diff --git a/src/NodeRenderer/MenuEntryRenderer.php b/src/NodeRenderer/MenuEntryRenderer.php new file mode 100644 index 00000000..7ba05454 --- /dev/null +++ b/src/NodeRenderer/MenuEntryRenderer.php @@ -0,0 +1,61 @@ + + */ +final class MenuEntryRenderer implements NodeRenderer +{ + public function __construct( + private TemplateRenderer $renderer, + private UrlGeneratorInterface $urlGenerator, + ) { + } + + #[\Override] + public function supports(string $nodeFqcn): bool + { + return MenuEntryNode::class === $nodeFqcn || is_a($nodeFqcn, MenuEntryNode::class, true); + } + + #[\Override] + public function render(Node $node, RenderContext $renderContext): string + { + if (!$node instanceof MenuEntryNode) { + throw new \LogicException(\sprintf('"%s" can only render menu entry nodes, got "%s".', __CLASS__, get_debug_type($node))); + } + + $url = $this->urlGenerator->generateCanonicalOutputUrl( + $renderContext, + $node->getUrl(), + $node instanceof SectionMenuEntryNode ? $node->getValue()?->getId() : null + ); + + return $this->renderer->renderTemplate( + $renderContext, + 'body/menu/menu-item.html.twig', + [ + 'url' => $url, + 'node' => $node, + ], + ); + } +} diff --git a/src/TextRole/ClassRole.php b/src/TextRole/ClassRole.php new file mode 100644 index 00000000..02e04f41 --- /dev/null +++ b/src/TextRole/ClassRole.php @@ -0,0 +1,50 @@ +replace('\\\\', '\\'); + + $url = \sprintf($this->buildConfig->getSymfonyRepositoryUrl(), $fqcn->replace('\\', '/').'.php'); + + return new ExternalLinkNode($url, (string) $fqcn->afterLast('\\'), (string) $fqcn); + } + + #[\Override] + public function getName(): string + { + return 'class'; + } + + #[\Override] + public function getAliases(): array + { + return []; + } +} diff --git a/src/TextRole/MethodRole.php b/src/TextRole/MethodRole.php new file mode 100644 index 00000000..5f96abac --- /dev/null +++ b/src/TextRole/MethodRole.php @@ -0,0 +1,51 @@ +replace('\\\\', '\\')->split('::', 2); + + $filename = \sprintf('%s.php#:~:text=%s', $fqcn->replace('\\', '/'), rawurlencode('function '.$method)); + $url = \sprintf($this->buildConfig->getSymfonyRepositoryUrl(), $filename); + + return new ExternalLinkNode($url, $method.'()', $fqcn.'::'.$method.'()'); + } + + #[\Override] + public function getName(): string + { + return 'method'; + } + + #[\Override] + public function getAliases(): array + { + return []; + } +} diff --git a/src/TextRole/NamespaceRole.php b/src/TextRole/NamespaceRole.php new file mode 100644 index 00000000..6dae6ad7 --- /dev/null +++ b/src/TextRole/NamespaceRole.php @@ -0,0 +1,50 @@ +replace('\\\\', '\\'); + + $url = \sprintf($this->buildConfig->getSymfonyRepositoryUrl(), $fqcn->replace('\\', '/')); + + return new ExternalLinkNode($url, (string) $fqcn->afterLast('\\'), (string) $fqcn); + } + + #[\Override] + public function getName(): string + { + return 'namespace'; + } + + #[\Override] + public function getAliases(): array + { + return []; + } +} diff --git a/src/TextRole/PhpClassRole.php b/src/TextRole/PhpClassRole.php new file mode 100644 index 00000000..ff32f55b --- /dev/null +++ b/src/TextRole/PhpClassRole.php @@ -0,0 +1,46 @@ +fqcn(...), ['is_safe' => ['html']]), + ]; + } + + #[\Override] + public function getFunctions(): array + { + return [ + new TwigFunction('dump', function (mixed ...$args) { dump(...$args); }), + ]; + } + + private function fqcn(string $fqcn): string + { + // some browsers can't break long properly, so we inject a + // `` (word-break HTML tag) after some characters to help break those + // We only do this for very long (4 or more \\) to not break short + // and common `` such as App\Entity\Something + if (substr_count($fqcn, '\\') >= 4) { + // breaking before the backslask is what Firefox browser does + $fqcn = str_replace('\\', '\\', $fqcn); + } + + return $fqcn; + } +} diff --git a/src/Twig/UrlExtension.php b/src/Twig/UrlExtension.php new file mode 100644 index 00000000..f1604b86 --- /dev/null +++ b/src/Twig/UrlExtension.php @@ -0,0 +1,45 @@ +isSafeUrl(...)), + ]; + } + + /* + * If the URL is considered safe, it's opened in the same browser tab; + * otherwise it's opened in a new tab and with some strict security options. + */ + private function isSafeUrl(string $url): bool + { + // The following are considered Symfony URLs: + // * https://symfony.com/[...] + // * https://[...].symfony.com/ (e.g. insight.symfony.com, etc.) + // * https://symfony.wip/[...] (used for internal/local development) + $url = u($url); + $isSymfonyUrl = $url->match('{^http(s)?://(.*\.)?symfony.(com|wip)}'); + $isRelativeUrl = !$url->startsWith('http://') && !$url->startsWith('https://'); + + return $isSymfonyUrl || $isRelativeUrl; + } +} diff --git a/tests/integration/HtmlIntegrationTest.php b/tests/integration/HtmlIntegrationTest.php new file mode 100644 index 00000000..2c1e8e2f --- /dev/null +++ b/tests/integration/HtmlIntegrationTest.php @@ -0,0 +1,120 @@ +get(DocBuilder::class)->buildString(file_get_contents($sourceFile)); + $generated = new \DOMDocument(); + $generated->loadHTML($generatedContents, \LIBXML_NOERROR); + $generated->preserveWhiteSpace = false; + $generatedHtml = self::sanitizeHTML($generated->saveHTML()); + + $expected = new \DOMDocument(); + $expectedContents = "\n\n\n".$expectedContents."\n\n"; + $expected->loadHTML($expectedContents, \LIBXML_NOERROR); + $expected->preserveWhiteSpace = false; + $expectedHtml = self::sanitizeHTML($expected->saveHTML()); + + $this->assertEquals($expectedHtml, $generatedHtml); + } catch (ExpectationFailedException $e) { + if (false !== $skip) { + $this->markTestIncomplete($skip); + } + + throw $e; + } + + $this->assertFalse($skip, 'Test passes while marked as SKIP.'); + } + + public static function provideBlocks(): iterable + { + foreach ((new Finder())->files()->in(__DIR__.'/fixtures/source/blocks') as $file) { + yield $file->getRelativePathname() => [$file->getRealPath(), __DIR__.'/fixtures/expected/blocks/'.str_replace('.rst', '.html', $file->getRelativePathname())]; + } + } + + #[DataProvider('provideProjects')] + public function testProjects(string $directory) + { + $buildEnvironment = new DynamicBuildEnvironment(new LocalFilesystemAdapter(__DIR__.'/fixtures/source/'.$directory)); + + $kernel = DocsKernel::create([new TestExtension()]); + $kernel->get(DocBuilder::class)->build($buildEnvironment); + + $expectedDirectory = __DIR__.'/fixtures/expected/'.$directory; + $skip = false; + if (file_exists($expectedDirectory.'/skip')) { + $skip = file_get_contents($expectedDirectory.'/skip'); + } + + try { + foreach ((new Finder())->files()->notName('skip')->in($expectedDirectory) as $file) { + $expected = self::sanitizeHTML($file->getContents()); + $actual = self::sanitizeHTML($buildEnvironment->getOutputFilesystem()->read($file->getRelativePathname())); + + $this->assertEquals($expected, $actual, 'File: '.$file->getRelativePathname()); + } + } catch (ExpectationFailedException $e) { + if (false !== $skip) { + $this->markTestIncomplete($skip); + } + + throw $e; + } + + $this->assertFalse($skip, 'Test passes while marked as SKIP.'); + } + + public static function provideProjects(): iterable + { + foreach ((new Finder())->directories()->in(__DIR__.'/fixtures/source')->depth(0) as $dir) { + if ('blocks' === $dir->getBasename()) { + continue; + } + + yield $dir->getBasename() => [$dir->getBasename()]; + } + } + + private static function sanitizeHTML(string $html): string + { + $html = implode("\n", array_map('trim', explode("\n", $html))); + $html = preg_replace('# +#', ' ', $html); + $html = preg_replace('#(? (?!\w)#', '>', $html); + $html = preg_replace('#\R+#', "\n", $html); + + $html = substr($html, strpos($html, '') + 6); + $html = substr($html, 0, strpos($html, '')); + + return trim($html); + } +} diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/bash.html b/tests/integration/fixtures/expected/blocks/code-blocks/bash.html new file mode 100644 index 00000000..499d0016 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/bash.html @@ -0,0 +1,6 @@ +
    +
    +
    1
    +
    git clone git@github.com:symfony/symfony.git
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/code-caption.html b/tests/integration/fixtures/expected/blocks/code-blocks/code-caption.html new file mode 100644 index 00000000..24d5b798 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/code-caption.html @@ -0,0 +1,27 @@ +
    +
    config/routes.php
    +
    +
    1
    +
    $foo = 'bar';
    +
    +
    + +
    +
    config/routes.php
    +
    +
    1
    +
    $foo = 'bar';
    +
    +
    + +
    +
    patch_file
    +
    +
    1
    +2
    +3
    +
    --- a/src/Controller/DefaultController.php
    +           +++ b/src/Controller/DefaultController.php
    +           @@ -2,7 +2,9 @@
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/diff.html b/tests/integration/fixtures/expected/blocks/code-blocks/diff.html new file mode 100644 index 00000000..f00f497a --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/diff.html @@ -0,0 +1,31 @@ +
    +
    +
    1
    +2
    +3
    +4
    +5
    +
    + Added line
    +            - Removed line
    +            Normal line
    +            - Removed line
    +            + Added line
    +
    +
    + +
    +
    +
    1
    +2
    +3
    +4
    +5
    +6
    +
     Normal line
    +            + Added line
    +            - Removed line
    +            Normal line
    +            - Removed line
    +            + Added line
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/html-php.html b/tests/integration/fixtures/expected/blocks/code-blocks/html-php.html new file mode 100644 index 00000000..e7b564e0 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/html-php.html @@ -0,0 +1,27 @@ +
    +
    +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +
    <!-- views/layout.php -->
    +<!doctype html>
    +<html>
    +    <head>
    +        <title>
    +            <?php echo 'title'; ?>
    +        </title>
    +    </head>
    +    <body>
    +        <?php echo 'body'; ?>
    +    </body>
    +</html>
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/html-twig.html b/tests/integration/fixtures/expected/blocks/code-blocks/html-twig.html new file mode 100644 index 00000000..6e17a7d9 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/html-twig.html @@ -0,0 +1,8 @@ +
    +
    +
    1
    +2
    +
    {# some code #}
    +<!-- some code -->
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/html.html b/tests/integration/fixtures/expected/blocks/code-blocks/html.html new file mode 100644 index 00000000..09d9b41d --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/html.html @@ -0,0 +1,5 @@ +
    +
    +
    1
    +
    <!-- some code -->
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/ini.html b/tests/integration/fixtures/expected/blocks/code-blocks/ini.html new file mode 100644 index 00000000..01600a98 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/ini.html @@ -0,0 +1,6 @@ +
    +
    +
    1
    +
    fetch = +refs/notes/*:refs/notes/*
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/php-annotations.html b/tests/integration/fixtures/expected/blocks/code-blocks/php-annotations.html new file mode 100644 index 00000000..d43ecf08 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/php-annotations.html @@ -0,0 +1,32 @@ +
    +
    +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    +12
    +13
    +14
    +
    // src/AppBundle/Entity/Transaction.php
    +namespace AppBundle\Entity;
    +
    +use Symfony\Component\Validator\Constraints as Assert;
    +
    +class Transaction
    +{
    +    /**
    +     * @Assert\Iban(
    +     *     message="This is not a valid International Bank Account Number (IBAN)."
    +     * )
    +     */
    +    protected $bankAccountNumber;
    +}
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/php.html b/tests/integration/fixtures/expected/blocks/code-blocks/php.html new file mode 100644 index 00000000..c005a13d --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/php.html @@ -0,0 +1,18 @@ +
    +
    +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +
    // config/routes.php
    +namespace Symfony\Component\Routing\Loader\Configurator;
    +
    +return function (RoutingConfigurator $routes) {
    +    $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us'])
    +        ->controller('App\Controller\CompanyController::about');
    +};
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/terminal.html b/tests/integration/fixtures/expected/blocks/code-blocks/terminal.html new file mode 100644 index 00000000..548e3078 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/terminal.html @@ -0,0 +1,31 @@ +
    +
    +
    1
    +
    git clone git@github.com:symfony/symfony.git
    +
    +
    +
    +
    +
    1
    +2
    +
    $ cowsay 'eat more chicken'
    +               $ cowsay 'mmmm'
    +
    +
    + +
    +
    +
    1
    +2
    +3
    +
    C:\> CIV
    +               # Civilization for DOS - my first computer game!
    +
    +
    + +
    +
    +
    1
    +
    $ git branch -D sessions-in-db || true
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/text.html b/tests/integration/fixtures/expected/blocks/code-blocks/text.html new file mode 100644 index 00000000..fe77dea1 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/text.html @@ -0,0 +1,6 @@ +
    +
    +
    1
    +
    some text with special chars < > " & and some text with special chars already escaped < > " &
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/twig.html b/tests/integration/fixtures/expected/blocks/code-blocks/twig.html new file mode 100644 index 00000000..fab139d4 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/twig.html @@ -0,0 +1,6 @@ +
    +
    +
    1
    +
    {# some code #}
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/xml.html b/tests/integration/fixtures/expected/blocks/code-blocks/xml.html new file mode 100644 index 00000000..02ffe4e8 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/xml.html @@ -0,0 +1,6 @@ +
    +
    +
    1
    +
    <!-- some code -->
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/code-blocks/yaml.html b/tests/integration/fixtures/expected/blocks/code-blocks/yaml.html new file mode 100644 index 00000000..1080576c --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/code-blocks/yaml.html @@ -0,0 +1,6 @@ +
    +
    +
    1
    +
    # some code
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/admonition.html b/tests/integration/fixtures/expected/blocks/directives/admonition.html new file mode 100644 index 00000000..ebdef057 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/admonition.html @@ -0,0 +1,6 @@ +
    +

    + Some Admonition +

    +

    Do you prefer admonitions? Well then... enjoy this one!

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/best-practice.html b/tests/integration/fixtures/expected/blocks/directives/best-practice.html new file mode 100644 index 00000000..cb2bfdb8 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/best-practice.html @@ -0,0 +1,6 @@ +
    +

    + Best Practice +

    +

    Use the bcrypt encoder for hashing your users' passwords.

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/caution.html b/tests/integration/fixtures/expected/blocks/directives/caution.html new file mode 100644 index 00000000..4a68d36f --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/caution.html @@ -0,0 +1,7 @@ +
    +

    + + Caution +

    +

    Using too many sidebars or caution directives can be distracting!

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/class.html b/tests/integration/fixtures/expected/blocks/directives/class.html new file mode 100644 index 00000000..9d8466c9 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/class.html @@ -0,0 +1,7 @@ +
      +
    • list-item-1
    • +
    • list-item-2
    • +
    • list-item-3
    • +
    + +

    some text

    diff --git a/tests/integration/fixtures/expected/blocks/directives/configuration-block.html b/tests/integration/fixtures/expected/blocks/directives/configuration-block.html new file mode 100644 index 00000000..aa101992 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/configuration-block.html @@ -0,0 +1,28 @@ +
    +
    + + +
    + +
    +
    +
    +
    1
    +
    # app/config/services.yml
    +
    +
    +
    + + +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/deprecated.html b/tests/integration/fixtures/expected/blocks/directives/deprecated.html new file mode 100644 index 00000000..8be1ed8b --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/deprecated.html @@ -0,0 +1,6 @@ +
    +

    + 5.4 +

    +

    The foobar option is deprecated since Symfony 5.4. Use barfoo instead.

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/note-code-block-nested.html b/tests/integration/fixtures/expected/blocks/directives/note-code-block-nested.html new file mode 100644 index 00000000..aa2e4263 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/note-code-block-nested.html @@ -0,0 +1,13 @@ +
    +

    + + Note +

    +

    test

    +
    +
    +
    1
    +
    // code
    +
    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/note.html b/tests/integration/fixtures/expected/blocks/directives/note.html new file mode 100644 index 00000000..0c215d96 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/note.html @@ -0,0 +1,7 @@ +
    +

    + + Note +

    +

    Sometimes we add notes. But not too often because they interrupt the flow.

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/screencast.html b/tests/integration/fixtures/expected/blocks/directives/screencast.html new file mode 100644 index 00000000..51cb7b45 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/screencast.html @@ -0,0 +1,19 @@ +
    +

    + + Screencast +

    +

    Do you prefer video tutorials? Check out the +Stellar Development with Symfony +screencast series.

    +
    + +
    +

    + + Screencast +

    +

    Do you prefer video tutorials? Check out the +Stellar Development with Symfony +screencast series.

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/seealso.html b/tests/integration/fixtures/expected/blocks/directives/seealso.html new file mode 100644 index 00000000..0e3899bb --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/seealso.html @@ -0,0 +1,7 @@ +
    +

    + + See also +

    +

    Also check out the homepage

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/sidebar-code-block-nested.html b/tests/integration/fixtures/expected/blocks/directives/sidebar-code-block-nested.html new file mode 100644 index 00000000..76f8612a --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/sidebar-code-block-nested.html @@ -0,0 +1,11 @@ +
    + +

    some text before code block

    +
    +
    +
    1
    +
    // some code
    +
    +
    +

    some text after code block

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/sidebar.html b/tests/integration/fixtures/expected/blocks/directives/sidebar.html new file mode 100644 index 00000000..bf3d1089 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/sidebar.html @@ -0,0 +1,9 @@ +
    + +

    some text inside sidebar

    +
    + +
    + +

    The full signature of the request() method is...

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/tip.html b/tests/integration/fixtures/expected/blocks/directives/tip.html new file mode 100644 index 00000000..fa813732 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/tip.html @@ -0,0 +1,7 @@ +
    +

    + + Tip +

    +

    This is a little tip about something! We an also talk about specific

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/topic.html b/tests/integration/fixtures/expected/blocks/directives/topic.html new file mode 100644 index 00000000..42965d64 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/topic.html @@ -0,0 +1,4 @@ +
    +

    Example

    +

    Here is a sample comment for a bug report that could be reproduced.

    +
    diff --git a/tests/integration/fixtures/expected/blocks/directives/versionadded.html b/tests/integration/fixtures/expected/blocks/directives/versionadded.html new file mode 100644 index 00000000..aadb68ed --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/directives/versionadded.html @@ -0,0 +1,6 @@ +
    +

    + 4.1 +

    +

    The foobar option was introduced in Symfony 4.1.

    +
    diff --git a/tests/integration/fixtures/expected/blocks/nodes/figure.html b/tests/integration/fixtures/expected/blocks/nodes/figure.html new file mode 100644 index 00000000..5a2b51bf --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/nodes/figure.html @@ -0,0 +1,22 @@ +
    + Symfony Logo +
    +

    I am a paragraph AFTER the figure. I should not be included as the +caption for the above figure.

    +
    + + +
    +

    But I am a caption for the figure above.

    +
    +
    + +

    Some images use a special CSS class to wrap a fake browser around them:

    +
    A typical exception page in the development environment +
    + +

    And RST figures use a different syntax to define their custom CSS classes:

    + +
    + / +
    diff --git a/tests/integration/fixtures/expected/blocks/nodes/list.html b/tests/integration/fixtures/expected/blocks/nodes/list.html new file mode 100644 index 00000000..f0f744b3 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/nodes/list.html @@ -0,0 +1,6 @@ +
      +
    • List item 1
    • +
    • List item 2
    • +
    • List item 3
    • +
    • List item 4
    • +
    diff --git a/tests/integration/fixtures/expected/blocks/nodes/literal.html b/tests/integration/fixtures/expected/blocks/nodes/literal.html new file mode 100644 index 00000000..1c12afae --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/nodes/literal.html @@ -0,0 +1,22 @@ +

    here is some php code from literal:

    +
    +
    +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +
    // config/routes.php
    +namespace Symfony\Component\Routing\Loader\Configurator;
    +
    +return function (RoutingConfigurator $routes) {
    +    $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us'])
    +        ->controller('App\Controller\CompanyController::about');
    +};
    +
    +
    +

    The CRUD controller of App\Entity\Example must implement +the EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface, +but you can also extend from the AbstractCrudController class.

    diff --git a/tests/integration/fixtures/expected/blocks/nodes/tables.html b/tests/integration/fixtures/expected/blocks/nodes/tables.html new file mode 100644 index 00000000..5c66ecc8 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/nodes/tables.html @@ -0,0 +1,181 @@ +

    Simple table with head:

    + +
    + + + + + + + + + + + + + + + + + + + + +
    Route pathIf the requested URL is /fooIf the requested URL is /foo/
    /fooIt matches (200 status response)It doesn't match (404 status response)
    /foo/It makes a 301 redirect to /foo/It matches (200 status response)
    +
    + +
    + + + + + + + + + + + + + + + + + +
    Columns separated by just 1 spaceAnother header
    xxxyyy
    xxxyyy
    +
    + +
    + + + + + + + + + + + + + + + + + +
    Header with a leading spaceAnother header
    xxxyyy
    xxxyyy
    +
    + +

    Simple table headless:

    + +
    + + + + + + + + + + + + + +
    /fooIt matches (200 status response)It doesn't match (404 status response)
    /foo/It makes a 301 redirect to /foo/It matches (200 status response)
    +
    + +
    + + + + + + + + + + + +
    Column with leading spaceyyy
    Another column with leading spaceyyy
    +
    + +

    Grid table:

    + +
    + + + + + + + + + + + + + + + +
    Cell 1Cell 2
    Cell 3Cell 4
    Cell 5Cell 6 +extra line
    +
    + +

    Grid table with head:

    + +
    + + + + + + + + + + + + + + + + + +
    Cell 1Cell 2
    Cell 3Cell 4
    Cell 5Cell 6 +extra line
    +
    + +

    Grid table with head and multi-line cells:

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Cell 1Cell 2
    Cell 3Cell 4
    Cell 5 +
      +
    • List item 1
    • +
    • List item 2
    • +
    • List item 3
    • +
    • List item 4
    • +
    +
    Cell 7Cell 8
    +
    diff --git a/tests/integration/fixtures/expected/blocks/nodes/title.html b/tests/integration/fixtures/expected/blocks/nodes/title.html new file mode 100644 index 00000000..2770260d --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/nodes/title.html @@ -0,0 +1,14 @@ +
    +

    Checking your Work Environment

    +

    Lorem ipsum dolor sit amet, consectetur adipisicing elit.

    + +
    +

    作業環境を確認する

    +

    Lorem ipsum dolor sit amet, consectetur adipisicing elit.

    +
    + +
    +

    Перевірка робочого середовища

    +

    Lorem ipsum dolor sit amet, consectetur adipisicing elit.

    +
    +
    diff --git a/tests/integration/fixtures/expected/blocks/references/reference-and-code.html b/tests/integration/fixtures/expected/blocks/references/reference-and-code.html new file mode 100644 index 00000000..e9d4cdaa --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/references/reference-and-code.html @@ -0,0 +1,3 @@ +

    Next, create the template used to render the field in the index and detail +CRUD pages.

    +

    More about CRUD pages.

    diff --git a/tests/integration/fixtures/expected/blocks/text-roles/class.html b/tests/integration/fixtures/expected/blocks/text-roles/class.html new file mode 100644 index 00000000..5f5e5305 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/text-roles/class.html @@ -0,0 +1 @@ +

    ContainerAwareHttpKernel

    diff --git a/tests/integration/fixtures/expected/blocks/text-roles/method.html b/tests/integration/fixtures/expected/blocks/text-roles/method.html new file mode 100644 index 00000000..cc632db0 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/text-roles/method.html @@ -0,0 +1 @@ +

    getCurrentRequest()

    diff --git a/tests/integration/fixtures/expected/blocks/text-roles/namespace.html b/tests/integration/fixtures/expected/blocks/text-roles/namespace.html new file mode 100644 index 00000000..b1416036 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/text-roles/namespace.html @@ -0,0 +1 @@ +

    HttpFoundation

    diff --git a/tests/integration/fixtures/expected/blocks/text-roles/php-class.html b/tests/integration/fixtures/expected/blocks/text-roles/php-class.html new file mode 100644 index 00000000..c3ce26f8 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/text-roles/php-class.html @@ -0,0 +1 @@ +

    ArrayAccess

    diff --git a/tests/integration/fixtures/expected/blocks/text-roles/php-function.html b/tests/integration/fixtures/expected/blocks/text-roles/php-function.html new file mode 100644 index 00000000..75f84181 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/text-roles/php-function.html @@ -0,0 +1 @@ +

    trigger_error()

    diff --git a/tests/integration/fixtures/expected/blocks/text-roles/php-method.html b/tests/integration/fixtures/expected/blocks/text-roles/php-method.html new file mode 100644 index 00000000..4a26d2d9 --- /dev/null +++ b/tests/integration/fixtures/expected/blocks/text-roles/php-method.html @@ -0,0 +1 @@ +

    Locale::getDefault()

    diff --git a/tests/integration/fixtures/expected/main/datetime.html b/tests/integration/fixtures/expected/main/datetime.html new file mode 100644 index 00000000..00f24d88 --- /dev/null +++ b/tests/integration/fixtures/expected/main/datetime.html @@ -0,0 +1,341 @@ + + + + + + +
    +

    DateTimeType Field

    +

    This field type allows the user to modify data that represents a specific + date and time (e.g. 1984-06-05 12:15:30).

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Underlying Data Typecan be DateTime, string, timestamp, or array (see the input option)
    Rendered assingle text box or three select fields
    Options + +
    Overridden options + +
    Parent typeFormType
    ClassDateTimeType
    RefA header + Test reference
    +
    +
    +

    Field Options

    +
    +

    The date_format Option

    +

    type: integer or string default: IntlDateFormatter::MEDIUM

    +

    Defines the format option that will be passed down to the date field. + for more details.

    +
    +

    + + Tip +

    +

    This is a little tip about something! We an also talk about specific + methods: doRequest(). + Or a namespace: Constraints. + Or a PHP function: parse_ini_file(). + Or a PHP method! Locale::getDefault().

    +
    +
    +
    +

    date_widget

    +

    Date widget!

    +
    +

    + + Note +

    +

    Sometimes we add notes. But not too often because they interrupt the flow. + FormType Documentation

    +
    +

    This is included documentation about the date_widget option.

    +
    +
    +

    placeholder

    +
    +

    + 2.6 +

    +

    The placeholder option was introduced in Symfony 2.6 and replaces + empty_value, which is available prior to 2.6. + FormType Documentation

    +
    +

    type: string | array

    +

    If your widget option is set to choice, then this field will be represented + as a series of select boxes. When the placeholder value is a string, + it will be used as the blank value of all select boxes:

    +
    +
    +
    1
    +2
    +3
    +4
    +5
    +
    use Symfony\Component\Form\Extension\Core\ Type\DateTimeType;
    +
    +$builder->add('startDateTime', DateTimeType::class, array(
    +    'placeholder' => 'Select a value',
    +));
    +
    +
    +
    +

    + + See also +

    +

    Also check out the homepage - Some Test Docs!. + FormType Documentation

    +
    +

    Custom classes for links are also cool:

    + +
    +
    +

    format

    +

    type: string default: Symfony\Component\Form\Extension\Core\Type\DateTimeType::HTML5_FORMAT

    +

    If the widget option is set to single_text, this option specifies + the format of the input, i.e. how Symfony will interpret the given input + as a datetime string. See Date/Time Format Syntax.

    +
    + +

    But do they really? They also get in the way!

    +
    +
    +

    + + Caution +

    +

    Using too many sidebars or caution directives can be distracting!

    +
    +
    +

    + Best Practice +

    +

    Use the bcrypt encoder for hashing your users' passwords.

    +
    +
    +
    +

    time_widget

    +

    type: string default: choice

    +

    Defines the widget option for the TimeType.

    +
    +
    +

    widget

    +

    type: string default: null

    +

    Defines the widget option for both the DateType. + and TimeType. This can be overridden + with the date_widget and time_widget options.

    +
    +
    +
    +

    Overridden Options

    +
    +

    by_reference

    +

    default: false

    +

    The DateTime classes are treated as immutable objects.

    +
    +
    +

    error_bubbling

    +

    default: false

    +

    We also support code blocks!

    +
    +
    +
    1
    +2
    +3
    +
    # app/config/parameters.yml
    +parameters:
    +    database_driver:   pdo_mysql
    +
    +
    +

    And configuration blocks:

    +
    +
    + + + +
    +
    +
    +
    +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +
    # app/config/config.yml
    +framework:
    +    secret:          '%secret%'
    +    router:          { resource: '%kernel.root_dir%/config/routing.yml' }
    +    # ...
    +
    +# ...
    +
    +
    +
    + + +
    +
    +
    +
    +

    Field Variables

    +
    + + + + + + + + + + + + + + + + + + + + +
    VariableTypeUsage
    widgetmixedThe value of the widget option
    typestringMultiple lines of text here, to show + that off
    +
    +
    +
    +

    Url checker errors

    +

    This is a 404 error. + And here is an invalid url invalid-url.

    +
    +
    + + diff --git a/tests/integration/fixtures/expected/main/form/form_type.html b/tests/integration/fixtures/expected/main/form/form_type.html new file mode 100644 index 00000000..ebbbf95c --- /dev/null +++ b/tests/integration/fixtures/expected/main/form/form_type.html @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/tests/integration/fixtures/expected/main/index.html b/tests/integration/fixtures/expected/main/index.html new file mode 100644 index 00000000..ed1f9eda --- /dev/null +++ b/tests/integration/fixtures/expected/main/index.html @@ -0,0 +1,24 @@ + + + + + + +
    +

    Some Test Docs!

    + + +
    + +

    A header

    +

    Some info...

    +
    +
    + + diff --git a/tests/integration/fixtures/expected/reference/index.html b/tests/integration/fixtures/expected/reference/index.html new file mode 100644 index 00000000..8d85aeb1 --- /dev/null +++ b/tests/integration/fixtures/expected/reference/index.html @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/tests/integration/fixtures/expected/toctree/index.html b/tests/integration/fixtures/expected/toctree/index.html new file mode 100644 index 00000000..b21e4d39 --- /dev/null +++ b/tests/integration/fixtures/expected/toctree/index.html @@ -0,0 +1,55 @@ + + + + + + +
    +

    Toctree

    +

    Simple

    +
    +
    +

    Simple, titles only

    +
    +
    +

    Simple, file from other directory

    +
    +
    +

    Glob

    +
    +
    +

    Glob, with explicit order

    +
    +
    +

    Hidden

    +
    + + diff --git a/tests/integration/fixtures/source/blocks/code-blocks/bash.rst b/tests/integration/fixtures/source/blocks/code-blocks/bash.rst new file mode 100644 index 00000000..e7c1213a --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/bash.rst @@ -0,0 +1,3 @@ + +.. code-block:: bash + git clone git@github.com:symfony/symfony.git diff --git a/tests/integration/fixtures/source/blocks/code-blocks/code-caption.rst b/tests/integration/fixtures/source/blocks/code-blocks/code-caption.rst new file mode 100644 index 00000000..3827262a --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/code-caption.rst @@ -0,0 +1,20 @@ + +.. code-block:: php + :caption: config/routes.php + + $foo = 'bar'; + + +.. code-block:: php + :caption: config/routes.php + :class: hide + + $foo = 'bar'; + +.. code-block:: diff + :caption: patch_file + :emphasize-lines: 1,2 + + --- a/src/Controller/DefaultController.php + +++ b/src/Controller/DefaultController.php + @@ -2,7 +2,9 @@ diff --git a/tests/integration/fixtures/source/blocks/code-blocks/diff.rst b/tests/integration/fixtures/source/blocks/code-blocks/diff.rst new file mode 100644 index 00000000..fce0f5f6 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/diff.rst @@ -0,0 +1,18 @@ + +.. code-block:: diff + + + Added line + - Removed line + Normal line + - Removed line + + Added line + + +.. code-block:: diff + + Normal line + + Added line + - Removed line + Normal line + - Removed line + + Added line diff --git a/tests/integration/fixtures/source/blocks/code-blocks/html-php.rst b/tests/integration/fixtures/source/blocks/code-blocks/html-php.rst new file mode 100644 index 00000000..10968df1 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/html-php.rst @@ -0,0 +1,14 @@ + +.. code-block:: html+php + + + + + + <?php echo 'title'; ?> + + + + + + diff --git a/tests/integration/fixtures/source/blocks/code-blocks/html-twig.rst b/tests/integration/fixtures/source/blocks/code-blocks/html-twig.rst new file mode 100644 index 00000000..11ab0fe3 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/html-twig.rst @@ -0,0 +1,4 @@ + +.. code-block:: html+twig + {# some code #} + diff --git a/tests/integration/fixtures/source/blocks/code-blocks/html.rst b/tests/integration/fixtures/source/blocks/code-blocks/html.rst new file mode 100644 index 00000000..f1c8d330 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/html.rst @@ -0,0 +1,3 @@ + +.. code-block:: html + diff --git a/tests/integration/fixtures/source/blocks/code-blocks/ini.rst b/tests/integration/fixtures/source/blocks/code-blocks/ini.rst new file mode 100644 index 00000000..d5733be2 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/ini.rst @@ -0,0 +1,3 @@ + +.. code-block:: ini + fetch = +refs/notes/*:refs/notes/* diff --git a/tests/integration/fixtures/source/blocks/code-blocks/php-annotations.rst b/tests/integration/fixtures/source/blocks/code-blocks/php-annotations.rst new file mode 100644 index 00000000..21511e7f --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/php-annotations.rst @@ -0,0 +1,16 @@ + +.. code-block:: php-annotations + // src/AppBundle/Entity/Transaction.php + namespace AppBundle\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Transaction + { + /** + * @Assert\Iban( + * message="This is not a valid International Bank Account Number (IBAN)." + * ) + */ + protected $bankAccountNumber; + } diff --git a/tests/integration/fixtures/source/blocks/code-blocks/php.rst b/tests/integration/fixtures/source/blocks/code-blocks/php.rst new file mode 100644 index 00000000..e9d65938 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/php.rst @@ -0,0 +1,9 @@ + +.. code-block:: php + // config/routes.php + namespace Symfony\Component\Routing\Loader\Configurator; + + return function (RoutingConfigurator $routes) { + $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us']) + ->controller('App\Controller\CompanyController::about'); + }; diff --git a/tests/integration/fixtures/source/blocks/code-blocks/terminal.rst b/tests/integration/fixtures/source/blocks/code-blocks/terminal.rst new file mode 100644 index 00000000..d68c238f --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/terminal.rst @@ -0,0 +1,19 @@ + +.. code-block:: terminal + git clone git@github.com:symfony/symfony.git + +.. code-block:: terminal + + $ cowsay 'eat more chicken' + $ cowsay 'mmmm' + +.. code-block:: terminal + + C:\> CIV + + # Civilization for DOS - my first computer game! + +.. code-block:: terminal + :class: hide + + $ git branch -D sessions-in-db || true diff --git a/tests/integration/fixtures/source/blocks/code-blocks/text.rst b/tests/integration/fixtures/source/blocks/code-blocks/text.rst new file mode 100644 index 00000000..50774bb1 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/text.rst @@ -0,0 +1,3 @@ + +.. code-block:: text + some text with special chars < > " & and some text with special chars already escaped < > " & diff --git a/tests/integration/fixtures/source/blocks/code-blocks/twig.rst b/tests/integration/fixtures/source/blocks/code-blocks/twig.rst new file mode 100644 index 00000000..01d06851 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/twig.rst @@ -0,0 +1,3 @@ + +.. code-block:: twig + {# some code #} diff --git a/tests/integration/fixtures/source/blocks/code-blocks/xml.rst b/tests/integration/fixtures/source/blocks/code-blocks/xml.rst new file mode 100644 index 00000000..c0fc2cd3 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/xml.rst @@ -0,0 +1,3 @@ + +.. code-block:: xml + diff --git a/tests/integration/fixtures/source/blocks/code-blocks/yaml.rst b/tests/integration/fixtures/source/blocks/code-blocks/yaml.rst new file mode 100644 index 00000000..45ce98d5 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/code-blocks/yaml.rst @@ -0,0 +1,3 @@ + +.. code-block:: yaml + # some code diff --git a/tests/integration/fixtures/source/blocks/directives/admonition.rst b/tests/integration/fixtures/source/blocks/directives/admonition.rst new file mode 100644 index 00000000..2127b640 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/admonition.rst @@ -0,0 +1,4 @@ +.. admonition:: Some Admonition + :class: some_admonition_class + + Do you prefer admonitions? Well then... enjoy this one! diff --git a/tests/integration/fixtures/source/blocks/directives/best-practice.rst b/tests/integration/fixtures/source/blocks/directives/best-practice.rst new file mode 100644 index 00000000..e1867485 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/best-practice.rst @@ -0,0 +1,4 @@ + +.. best-practice:: + + Use the bcrypt encoder for hashing your users' passwords. diff --git a/tests/integration/fixtures/source/blocks/directives/caution.rst b/tests/integration/fixtures/source/blocks/directives/caution.rst new file mode 100644 index 00000000..0b292fd9 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/caution.rst @@ -0,0 +1,3 @@ +.. caution:: + + Using too many sidebars or caution directives can be distracting! diff --git a/tests/integration/fixtures/source/blocks/directives/class.rst b/tests/integration/fixtures/source/blocks/directives/class.rst new file mode 100644 index 00000000..09b08fe8 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/class.rst @@ -0,0 +1,9 @@ +.. class:: a-class + +* list-item-1 +* list-item-2 +* list-item-3 + +.. class:: another-class + +some text diff --git a/tests/integration/fixtures/source/blocks/directives/configuration-block.rst b/tests/integration/fixtures/source/blocks/directives/configuration-block.rst new file mode 100644 index 00000000..001b615c --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/configuration-block.rst @@ -0,0 +1,10 @@ + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + + .. code-block:: php + + // config/routes.php diff --git a/tests/integration/fixtures/source/blocks/directives/deprecated.rst b/tests/integration/fixtures/source/blocks/directives/deprecated.rst new file mode 100644 index 00000000..fbb654c9 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/deprecated.rst @@ -0,0 +1,4 @@ + +.. deprecated:: 5.4 + + The ``foobar`` option is deprecated since Symfony 5.4. Use ``barfoo`` instead. diff --git a/tests/integration/fixtures/source/blocks/directives/note-code-block-nested.rst b/tests/integration/fixtures/source/blocks/directives/note-code-block-nested.rst new file mode 100644 index 00000000..1962e12e --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/note-code-block-nested.rst @@ -0,0 +1,8 @@ + +.. note:: + + test + + .. code-block:: php + + // code diff --git a/tests/integration/fixtures/source/blocks/directives/note.rst b/tests/integration/fixtures/source/blocks/directives/note.rst new file mode 100644 index 00000000..c8fce552 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/note.rst @@ -0,0 +1,4 @@ + +.. note:: + + Sometimes we add notes. But not too often because they interrupt the flow. diff --git a/tests/integration/fixtures/source/blocks/directives/screencast.rst b/tests/integration/fixtures/source/blocks/directives/screencast.rst new file mode 100644 index 00000000..e93b1ce1 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/screencast.rst @@ -0,0 +1,11 @@ +.. screencast:: + + Do you prefer video tutorials? Check out the + `Stellar Development with Symfony `_ + screencast series. + +.. admonition:: Screencast + + Do you prefer video tutorials? Check out the + `Stellar Development with Symfony `_ + screencast series. diff --git a/tests/integration/fixtures/source/blocks/directives/seealso.rst b/tests/integration/fixtures/source/blocks/directives/seealso.rst new file mode 100644 index 00000000..16d3a3b2 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/seealso.rst @@ -0,0 +1,4 @@ + +.. seealso:: + + Also check out the homepage diff --git a/tests/integration/fixtures/source/blocks/directives/sidebar-code-block-nested.rst b/tests/integration/fixtures/source/blocks/directives/sidebar-code-block-nested.rst new file mode 100644 index 00000000..080324b7 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/sidebar-code-block-nested.rst @@ -0,0 +1,10 @@ + +.. sidebar:: The sidebar's title + + some text before code block + + .. code-block:: php + + // some code + + some text after code block diff --git a/tests/integration/fixtures/source/blocks/directives/sidebar.rst b/tests/integration/fixtures/source/blocks/directives/sidebar.rst new file mode 100644 index 00000000..b1797631 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/sidebar.rst @@ -0,0 +1,8 @@ + +.. sidebar:: The sidebar's title + + some text inside sidebar + +.. sidebar:: More about the ``request()`` Method + + The full signature of the ``request()`` method is... diff --git a/tests/integration/fixtures/source/blocks/directives/tip.rst b/tests/integration/fixtures/source/blocks/directives/tip.rst new file mode 100644 index 00000000..baece7f8 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/tip.rst @@ -0,0 +1,4 @@ + +.. tip:: + + This is a little tip about something! We an also talk about specific diff --git a/tests/integration/fixtures/source/blocks/directives/topic.rst b/tests/integration/fixtures/source/blocks/directives/topic.rst new file mode 100644 index 00000000..f29b4efd --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/topic.rst @@ -0,0 +1,3 @@ +.. topic:: Example + + Here is a sample comment for a bug report that could be reproduced. diff --git a/tests/integration/fixtures/source/blocks/directives/versionadded.rst b/tests/integration/fixtures/source/blocks/directives/versionadded.rst new file mode 100644 index 00000000..9f3b5374 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/directives/versionadded.rst @@ -0,0 +1,4 @@ + +.. versionadded:: 4.1 + + The ``foobar`` option was introduced in Symfony 4.1. diff --git a/tests/integration/fixtures/source/blocks/nodes/figure.rst b/tests/integration/fixtures/source/blocks/nodes/figure.rst new file mode 100644 index 00000000..b1d6361f --- /dev/null +++ b/tests/integration/fixtures/source/blocks/nodes/figure.rst @@ -0,0 +1,24 @@ +.. figure:: images/logo.png + :alt: Symfony Logo + :width: 200px + +I am a paragraph AFTER the figure. I should not be included as the +caption for the above figure. + +.. figure:: images/logo.png + + But I am a caption *for* the figure above. + +Some images use a special CSS class to wrap a fake browser around them: + +.. image:: images/exceptions-in-dev-environment.png + :alt: A typical exception page in the development environment + :align: center + :class: some-class with-browser another-class + +And RST figures use a different syntax to define their custom CSS classes: + +.. figure:: images/logo.png + :alt: / + :align: center + :figclass: with-browser foo diff --git a/tests/integration/fixtures/source/blocks/nodes/list.rst b/tests/integration/fixtures/source/blocks/nodes/list.rst new file mode 100644 index 00000000..8b271db1 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/nodes/list.rst @@ -0,0 +1,5 @@ + +- List item 1 +- List item 2 +- List item 3 +- List item 4 diff --git a/tests/integration/fixtures/source/blocks/nodes/literal.rst b/tests/integration/fixtures/source/blocks/nodes/literal.rst new file mode 100644 index 00000000..43e65706 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/nodes/literal.rst @@ -0,0 +1,13 @@ +here is some php code from literal:: + + // config/routes.php + namespace Symfony\Component\Routing\Loader\Configurator; + + return function (RoutingConfigurator $routes) { + $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us']) + ->controller('App\Controller\CompanyController::about'); + }; + +The CRUD controller of ``App\Entity\Example`` must implement +the ``EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface``, +but you can also extend from the ``AbstractCrudController`` class. diff --git a/tests/integration/fixtures/source/blocks/nodes/tables.rst b/tests/integration/fixtures/source/blocks/nodes/tables.rst new file mode 100644 index 00000000..8bf9020d --- /dev/null +++ b/tests/integration/fixtures/source/blocks/nodes/tables.rst @@ -0,0 +1,71 @@ +Simple table with head: + +========== ======================================== ========================================== +Route path If the requested URL is /foo If the requested URL is /foo/ +========== ======================================== ========================================== +/foo It matches (200 status response) It doesn't match (404 status response) +/foo/ It makes a 301 redirect to /foo/ It matches (200 status response) +========== ======================================== ========================================== + +================================================== ========================================== +Columns separated by just 1 space Another header +================================================== ========================================== +xxx yyy +xxx yyy +================================================== ========================================== + +============================ ============================================ + Header with a leading space Another header +============================ ============================================ + xxx yyy + xxx yyy +============================ ============================================ + +Simple table headless: + +========== ======================================== ========================================== +/foo It matches (200 status response) It doesn't match (404 status response) +/foo/ It makes a 301 redirect to /foo/ It matches (200 status response) +========== ======================================== ========================================== + +================================== ==================================== + Column with leading space yyy + Another column with leading space yyy +================================== ==================================== + +Grid table: + ++--------+------------+ +| Cell 1 | Cell 2 | ++--------+------------+ +| Cell 3 | Cell 4 | ++--------+------------+ +| Cell 5 | Cell 6 | +| | extra line | ++--------+------------+ + +Grid table with head: + ++--------+------------+ +| Cell 1 | Cell 2 | ++========+============+ +| Cell 3 | Cell 4 | ++--------+------------+ +| Cell 5 | Cell 6 | +| | extra line | ++--------+------------+ + +Grid table with head and multi-line cells: + ++--------+---------------+ +| Cell 1 | Cell 2 | ++========+===============+ +| Cell 3 | Cell 4 | ++--------+---------------+ +| Cell 5 | - List item 1 | +| | - List item 2 | +| | - List item 3 | +| | - List item 4 | ++--------+---------------+ +| Cell 7 | Cell 8 | ++--------+---------------+ diff --git a/tests/integration/fixtures/source/blocks/nodes/title.rst b/tests/integration/fixtures/source/blocks/nodes/title.rst new file mode 100644 index 00000000..7014b146 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/nodes/title.rst @@ -0,0 +1,14 @@ +Checking your Work Environment +============================== + +Lorem ipsum dolor sit amet, consectetur adipisicing elit. + +作業環境を確認する +-------- + +Lorem ipsum dolor sit amet, consectetur adipisicing elit. + +Перевірка робочого середовища +----------------------------- + +Lorem ipsum dolor sit amet, consectetur adipisicing elit. diff --git a/tests/integration/fixtures/source/blocks/references/reference-and-code.rst b/tests/integration/fixtures/source/blocks/references/reference-and-code.rst new file mode 100644 index 00000000..b54e1f25 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/references/reference-and-code.rst @@ -0,0 +1,6 @@ +Next, create the template used to render the field in the ``index`` and ``detail`` +`CRUD pages`_. + +More about CRUD pages. + +.. _`CRUD pages`: https://symfony.com/doc/current/bundles/EasyAdminBundle/crud.html diff --git a/tests/integration/fixtures/source/blocks/text-roles/class.rst b/tests/integration/fixtures/source/blocks/text-roles/class.rst new file mode 100644 index 00000000..ca991ab0 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/text-roles/class.rst @@ -0,0 +1 @@ +:class:`Symfony\\Component\\HttpKernel\\DependencyInjection\\ContainerAwareHttpKernel` diff --git a/tests/integration/fixtures/source/blocks/text-roles/method.rst b/tests/integration/fixtures/source/blocks/text-roles/method.rst new file mode 100644 index 00000000..728f27d8 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/text-roles/method.rst @@ -0,0 +1 @@ +:method:`Symfony\\Component\\HttpFoundation\\RequestStack::getCurrentRequest` diff --git a/tests/integration/fixtures/source/blocks/text-roles/namespace.rst b/tests/integration/fixtures/source/blocks/text-roles/namespace.rst new file mode 100644 index 00000000..55cb253c --- /dev/null +++ b/tests/integration/fixtures/source/blocks/text-roles/namespace.rst @@ -0,0 +1 @@ +:namespace:`Symfony\\Component\\HttpFoundation` diff --git a/tests/integration/fixtures/source/blocks/text-roles/php-class.rst b/tests/integration/fixtures/source/blocks/text-roles/php-class.rst new file mode 100644 index 00000000..f20043dc --- /dev/null +++ b/tests/integration/fixtures/source/blocks/text-roles/php-class.rst @@ -0,0 +1 @@ +:phpclass:`ArrayAccess` diff --git a/tests/integration/fixtures/source/blocks/text-roles/php-function.rst b/tests/integration/fixtures/source/blocks/text-roles/php-function.rst new file mode 100644 index 00000000..fdbe50f2 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/text-roles/php-function.rst @@ -0,0 +1 @@ +:phpfunction:`trigger_error` diff --git a/tests/integration/fixtures/source/blocks/text-roles/php-method.rst b/tests/integration/fixtures/source/blocks/text-roles/php-method.rst new file mode 100644 index 00000000..e5b942b6 --- /dev/null +++ b/tests/integration/fixtures/source/blocks/text-roles/php-method.rst @@ -0,0 +1 @@ +:phpmethod:`Locale::getDefault` diff --git a/tests/integration/fixtures/source/main/_images/symfony-logo.png b/tests/integration/fixtures/source/main/_images/symfony-logo.png new file mode 100644 index 00000000..c1d221e5 Binary files /dev/null and b/tests/integration/fixtures/source/main/_images/symfony-logo.png differ diff --git a/tests/integration/fixtures/source/main/_includes/date_widget.rst.inc b/tests/integration/fixtures/source/main/_includes/date_widget.rst.inc new file mode 100644 index 00000000..e02cde99 --- /dev/null +++ b/tests/integration/fixtures/source/main/_includes/date_widget.rst.inc @@ -0,0 +1 @@ +This is included documentation about the ``date_widget`` option. diff --git a/tests/integration/fixtures/source/main/datetime.rst b/tests/integration/fixtures/source/main/datetime.rst new file mode 100644 index 00000000..a3e099c6 --- /dev/null +++ b/tests/integration/fixtures/source/main/datetime.rst @@ -0,0 +1,229 @@ +.. index:: + single: Forms; Fields; DateTimeType + +DateTimeType Field +================== + +This field type allows the user to modify data that represents a specific +date and time (e.g. ``1984-06-05 12:15:30``). + ++----------------------+-----------------------------------------------------------------------------+ +| Underlying Data Type | can be ``DateTime``, string, timestamp, or array (see the ``input`` option) | ++----------------------+-----------------------------------------------------------------------------+ +| Rendered as | single text box or three select fields | ++----------------------+-----------------------------------------------------------------------------+ +| Options | - `The date_format Option`_ | +| | - `date_widget`_ | +| | - `placeholder`_ | +| | - `format`_ | ++----------------------+-----------------------------------------------------------------------------+ +| Overridden options | - `by_reference`_ | +| | - `error_bubbling`_ | ++----------------------+-----------------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++----------------------+-----------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateTimeType` | ++----------------------+-----------------------------------------------------------------------------+ +| Ref | :ref:`reference-forms-type-date-format` | +| | :ref:`Test reference ` | ++----------------------+-----------------------------------------------------------------------------+ + +Field Options +------------- + +The date_format Option +~~~~~~~~~~~~~~~~~~~~~~ + +**type**: ``integer`` or ``string`` **default**: ``IntlDateFormatter::MEDIUM`` + +Defines the ``format`` option that will be passed down to the date field. +for more details. + +.. tip:: + + This is a little tip about something! We an also talk about specific + methods: :method:`Symfony\\Component\\BrowserKit\\Client::doRequest`. + Or a namespace: :namespace:`Symfony\\Component\\Validator\\Constraints`. + Or a PHP function: :phpfunction:`parse_ini_file`. + Or a PHP method! :phpmethod:`Locale::getDefault`. + +date_widget +~~~~~~~~~~~ + +Date widget! + +.. note:: + + Sometimes we add notes. But not too often because they interrupt the flow. + :ref:`internal-reference` + +.. include:: /_includes/date_widget.rst.inc + +placeholder +~~~~~~~~~~~ + +.. versionadded:: 2.6 + The ``placeholder`` option was introduced in Symfony 2.6 and replaces + ``empty_value``, which is available prior to 2.6. + :ref:`internal-reference` + +**type**: ``string`` | ``array`` + +If your widget option is set to ``choice``, then this field will be represented +as a series of ``select`` boxes. When the placeholder value is a string, +it will be used as the **blank value** of all select boxes:: + + use Symfony\Component\Form\Extension\Core\Type\DateTimeType; + + $builder->add('startDateTime', DateTimeType::class, array( + 'placeholder' => 'Select a value', + )); + +.. seealso:: + + Also check out the homepage - :doc:`/index`. + :ref:`internal-reference` + +Custom classes for links are also cool: + +.. class:: list-config-options + +* ``excluded_ajax_paths`` +* ``intercept_redirects`` +* ``position`` +* ``toolbar`` +* ``verbose`` +* :ref:`internal-reference` + +format +~~~~~~ + +**type**: ``string`` **default**: ``Symfony\Component\Form\Extension\Core\Type\DateTimeType::HTML5_FORMAT`` + +If the ``widget`` option is set to ``single_text``, this option specifies +the format of the input, i.e. how Symfony will interpret the given input +as a datetime string. See `Date/Time Format Syntax`_. + +.. sidebar:: Everyone loves sidebars + + But do they really? They also get in the way! + +.. caution:: + + Using too many sidebars or caution directives can be distracting! + +.. best-practice:: + + Use the bcrypt encoder for hashing your users' passwords. + +time_widget +~~~~~~~~~~~ + +**type**: ``string`` **default**: ``choice`` + +Defines the ``widget`` option for the ``TimeType``. + +widget +~~~~~~ + +**type**: ``string`` **default**: ``null`` + +Defines the ``widget`` option for both the ``DateType``. +and ``TimeType``. This can be overridden +with the `date_widget`_ and `time_widget`_ options. + +Overridden Options +------------------ + +by_reference +~~~~~~~~~~~~ + +**default**: ``false`` + +The ``DateTime`` classes are treated as immutable objects. + +error_bubbling +~~~~~~~~~~~~~~ + +**default**: ``false`` + +We also support code blocks! + +.. code-block:: yaml + + # app/config/parameters.yml + parameters: + database_driver: pdo_mysql + +And configuration blocks: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + framework: + secret: '%secret%' + router: { resource: '%kernel.root_dir%/config/routing.yml' } + # ... + + # ... + + .. code-block:: xml + + + + + + + + + + + + + + .. code-block:: php + + // app/config/config.php + $container->loadFromExtension('framework', array( + 'secret' => '%secret%', + 'router' => array( + 'resource' => '%kernel.root_dir%/config/routing.php', + ), + // ... + )); + + // ... + +Field Variables +--------------- + ++----------+------------+---------------------------------------+ +| Variable | Type | Usage | ++==========+============+=======================================+ +| widget | ``mixed`` | The value of the ``widget`` option | ++----------+------------+---------------------------------------+ +| type | ``string`` | Multiple lines of text here, to show | +| | | that off | ++----------+------------+---------------------------------------+ + +Url checker errors +------------------ + +This is a `404 error`_. +And here is an invalid url `invalid-url`_. + +.. _`RFC 3339`: https://tools.ietf.org/html/rfc3339 +.. _`Date/Time Format Syntax`: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax +.. _`404 error`: https://symfony.com/404 +.. _`invalid-url`: http://invalid-url diff --git a/tests/integration/fixtures/source/main/form/form_type.rst b/tests/integration/fixtures/source/main/form/form_type.rst new file mode 100644 index 00000000..c5d96fd9 --- /dev/null +++ b/tests/integration/fixtures/source/main/form/form_type.rst @@ -0,0 +1,6 @@ +FormType Documentation +====================== + +.. image:: /_images/symfony-logo.png + +.. _internal-reference: diff --git a/tests/integration/fixtures/source/main/index.rst b/tests/integration/fixtures/source/main/index.rst new file mode 100644 index 00000000..16a78508 --- /dev/null +++ b/tests/integration/fixtures/source/main/index.rst @@ -0,0 +1,17 @@ +Some Test Docs! +=============== + +.. image:: /_images/symfony-logo.png + +.. toctree:: + :maxdepth: 1 + + datetime + form/form_type + +.. _reference-forms-type-date-format: + +A header +-------- + +Some info... diff --git a/tests/integration/fixtures/source/reference/file.rst b/tests/integration/fixtures/source/reference/file.rst new file mode 100644 index 00000000..f3fdabff --- /dev/null +++ b/tests/integration/fixtures/source/reference/file.rst @@ -0,0 +1,4 @@ +File +==== + +.. _ref-test: diff --git a/tests/integration/fixtures/source/reference/index.rst b/tests/integration/fixtures/source/reference/index.rst new file mode 100644 index 00000000..b9f3ceb3 --- /dev/null +++ b/tests/integration/fixtures/source/reference/index.rst @@ -0,0 +1,11 @@ +A test for reference +==================== + +:doc:`A doc test ` + +:ref:`A ref test ` + +.. toctree:: + :hidden: + + file diff --git a/tests/integration/fixtures/source/toctree/directory/another_file.rst b/tests/integration/fixtures/source/toctree/directory/another_file.rst new file mode 100644 index 00000000..81ba92dd --- /dev/null +++ b/tests/integration/fixtures/source/toctree/directory/another_file.rst @@ -0,0 +1,8 @@ +Another file +============ + +Some text. + +.. _some_reference: + +And more text. diff --git a/tests/integration/fixtures/source/toctree/file.rst b/tests/integration/fixtures/source/toctree/file.rst new file mode 100644 index 00000000..1482f9a8 --- /dev/null +++ b/tests/integration/fixtures/source/toctree/file.rst @@ -0,0 +1,9 @@ +Title +===== + +foo + +Sub title +--------- + +foo diff --git a/tests/integration/fixtures/source/toctree/file1.rst b/tests/integration/fixtures/source/toctree/file1.rst new file mode 100644 index 00000000..181b6251 --- /dev/null +++ b/tests/integration/fixtures/source/toctree/file1.rst @@ -0,0 +1,4 @@ +Title 1 +======= + +foo diff --git a/tests/integration/fixtures/source/toctree/index.rst b/tests/integration/fixtures/source/toctree/index.rst new file mode 100644 index 00000000..b4acb308 --- /dev/null +++ b/tests/integration/fixtures/source/toctree/index.rst @@ -0,0 +1,44 @@ +Toctree +======= + +Simple + +.. toctree:: + + file + + +Simple, titles only + +.. toctree:: + :titlesonly: + + file + +Simple, file from other directory + +.. toctree:: + + directory/another_file + +Glob + +.. toctree:: + :glob: + + * + +Glob, with explicit order + +.. toctree:: + :glob: + + file1 + * + +Hidden + +.. toctree:: + :hidden: + + file diff --git a/tools/php-cs-fixer/composer.json b/tools/php-cs-fixer/composer.json new file mode 100644 index 00000000..b8381bb0 --- /dev/null +++ b/tools/php-cs-fixer/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "friendsofphp/php-cs-fixer": "^3.2" + } +} diff --git a/tools/php-cs-fixer/composer.lock b/tools/php-cs-fixer/composer.lock new file mode 100644 index 00000000..970734d4 --- /dev/null +++ b/tools/php-cs-fixer/composer.lock @@ -0,0 +1,2679 @@ +{ + "_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": "ea9e239a51e71b1e6b9c86391fc5365b", + "packages": [ + { + "name": "clue/ndjson-react", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2025-08-14T07:29:31+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.89.2", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "7569658f91e475ec93b99bd5964b059ad1336dcf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7569658f91e475ec93b99bd5964b059ad1336dcf", + "reference": "7569658f91e475ec93b99bd5964b059ad1336dcf", + "shasum": "" + }, + "require": { + "clue/ndjson-react": "^1.3", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.5", + "ext-filter": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.3", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.6", + "react/event-loop": "^1.5", + "react/socket": "^1.16", + "react/stream": "^1.4", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", + "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0", + "symfony/polyfill-mbstring": "^1.33", + "symfony/polyfill-php80": "^1.33", + "symfony/polyfill-php81": "^1.33", + "symfony/polyfill-php84": "^1.33", + "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2", + "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.7", + "infection/infection": "^0.31.0", + "justinrainbow/json-schema": "^6.5", + "keradus/cli-executor": "^2.2", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.9", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", + "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34", + "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2", + "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2" + }, + "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/" + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] + }, + "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.89.2" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2025-11-06T21:12:50+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/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/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.6", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-01-01T16:37:48+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", + "shasum": "" + }, + "require": { + "php": ">=7.1.0" + }, + "require-dev": { + "phpstan/phpstan": "1.12.28 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "support": { + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-08-19T18:57:03+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "support": { + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-07-26T10:38:09+00:00" + }, + { + "name": "react/stream", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "support": { + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:46+00:00" + }, + { + "name": "symfony/console", + "version": "v7.3.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.3.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-04T01:21:42+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.3.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.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": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^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/v7.3.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-13T11:49:31+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\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.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.3.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e9bcfd7837928ab656276fe00464092cc9e1826a", + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.3.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-05T09:52:27+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.3.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "9f696d2f1e340484b4683f7853b273abff94421f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/9f696d2f1e340484b4683f7853b273abff94421f", + "reference": "9f696d2f1e340484b4683f7853b273abff94421f", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.3.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-10-15T18:45:57+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v7.3.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d", + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "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/v7.3.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-08-05T10:16:07+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T09:58:17+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-php84", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-24T13:30:11+00:00" + }, + { + "name": "symfony/process", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b", + "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-11T10:12:26+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:30:57+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "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/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-02-24T10:49:57+00:00" + }, + { + "name": "symfony/string", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "f96476035142921000338bad71e5247fbc138872" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", + "reference": "f96476035142921000338bad71e5247fbc138872", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-11T14:36:48+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} diff --git a/tools/psalm/composer.json b/tools/psalm/composer.json new file mode 100644 index 00000000..d1c4a5a7 --- /dev/null +++ b/tools/psalm/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "vimeo/psalm": "^6.13" + } +} diff --git a/tools/psalm/composer.lock b/tools/psalm/composer.lock new file mode 100644 index 00000000..fece0e85 --- /dev/null +++ b/tools/psalm/composer.lock @@ -0,0 +1,3331 @@ +{ + "_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": "c35323044368851ea0a3468c5ca85ec7", + "packages": [ + { + "name": "amphp/amp", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/fa0ab33a6f47a82929c38d03ca47ebb71086a93f", + "reference": "fa0ab33a6f47a82929c38d03ca47ebb71086a93f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.23.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Future/functions.php", + "src/Internal/functions.php" + ], + "psr-4": { + "Amp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "https://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-08-27T21:42:00+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v2.1.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/55a6bd071aec26fa2a3e002618c20c35e3df1b46", + "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/parser": "^1.1", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2.3" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.22.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Internal/functions.php" + ], + "psr-4": { + "Amp\\ByteStream\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "https://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/v2.1.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-03-16T17:10:27+00:00" + }, + { + "name": "amphp/cache", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/cache.git", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/cache/zipball/46912e387e6aa94933b61ea1ead9cf7540b7797c", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Cache\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + } + ], + "description": "A fiber-aware cache API based on Amp and Revolt.", + "homepage": "https://amphp.org/cache", + "support": { + "issues": "https://github.com/amphp/cache/issues", + "source": "https://github.com/amphp/cache/tree/v2.0.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-19T03:38:06+00:00" + }, + { + "name": "amphp/dns", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/dns.git", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/dns/zipball/78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/process": "^2", + "daverandom/libdns": "^2.0.2", + "ext-filter": "*", + "ext-json": "*", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Dns\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Wright", + "email": "addr@daverandom.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Async DNS resolution for Amp.", + "homepage": "https://github.com/amphp/dns", + "keywords": [ + "amp", + "amphp", + "async", + "client", + "dns", + "resolve" + ], + "support": { + "issues": "https://github.com/amphp/dns/issues", + "source": "https://github.com/amphp/dns/tree/v2.4.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-01-19T15:43:40+00:00" + }, + { + "name": "amphp/parallel", + "version": "v2.3.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/parallel.git", + "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parallel/zipball/321b45ae771d9c33a068186b24117e3cd1c48dce", + "reference": "321b45ae771d9c33a068186b24117e3cd1c48dce", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/pipeline": "^1", + "amphp/process": "^2", + "amphp/serialization": "^1", + "amphp/socket": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" + }, + "type": "library", + "autoload": { + "files": [ + "src/Context/functions.php", + "src/Context/Internal/functions.php", + "src/Ipc/functions.php", + "src/Worker/functions.php" + ], + "psr-4": { + "Amp\\Parallel\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + } + ], + "description": "Parallel processing component for Amp.", + "homepage": "https://github.com/amphp/parallel", + "keywords": [ + "async", + "asynchronous", + "concurrent", + "multi-processing", + "multi-threading" + ], + "support": { + "issues": "https://github.com/amphp/parallel/issues", + "source": "https://github.com/amphp/parallel/tree/v2.3.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-08-27T21:55:40+00:00" + }, + { + "name": "amphp/parser", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/parser.git", + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parser/zipball/3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "shasum": "" + }, + "require": { + "php": ">=7.4" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Parser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A generator parser to make streaming parsers simple.", + "homepage": "https://github.com/amphp/parser", + "keywords": [ + "async", + "non-blocking", + "parser", + "stream" + ], + "support": { + "issues": "https://github.com/amphp/parser/issues", + "source": "https://github.com/amphp/parser/tree/v1.1.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-03-21T19:16:53+00:00" + }, + { + "name": "amphp/pipeline", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/pipeline.git", + "reference": "7b52598c2e9105ebcddf247fc523161581930367" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/pipeline/zipball/7b52598c2e9105ebcddf247fc523161581930367", + "reference": "7b52598c2e9105ebcddf247fc523161581930367", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "php": ">=8.1", + "revolt/event-loop": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Pipeline\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Asynchronous iterators and operators.", + "homepage": "https://amphp.org/pipeline", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "iterator", + "non-blocking" + ], + "support": { + "issues": "https://github.com/amphp/pipeline/issues", + "source": "https://github.com/amphp/pipeline/tree/v1.2.3" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-03-16T16:33:53+00:00" + }, + { + "name": "amphp/process", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/process.git", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/process/zipball/52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Process\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A fiber-aware process manager based on Amp and Revolt.", + "homepage": "https://amphp.org/process", + "support": { + "issues": "https://github.com/amphp/process/issues", + "source": "https://github.com/amphp/process/tree/v2.0.3" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-19T03:13:44+00:00" + }, + { + "name": "amphp/serialization", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/serialization.git", + "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/serialization/zipball/693e77b2fb0b266c3c7d622317f881de44ae94a1", + "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "phpunit/phpunit": "^9 || ^8 || ^7" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Serialization\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Serialization tools for IPC and data storage in PHP.", + "homepage": "https://github.com/amphp/serialization", + "keywords": [ + "async", + "asynchronous", + "serialization", + "serialize" + ], + "support": { + "issues": "https://github.com/amphp/serialization/issues", + "source": "https://github.com/amphp/serialization/tree/master" + }, + "time": "2020-03-25T21:39:07+00:00" + }, + { + "name": "amphp/socket", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/socket.git", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/socket/zipball/58e0422221825b79681b72c50c47a930be7bf1e1", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/dns": "^2", + "ext-openssl": "*", + "kelunik/certificate": "^1.1", + "league/uri": "^6.5 | ^7", + "league/uri-interfaces": "^2.3 | ^7", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "amphp/process": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Internal/functions.php", + "src/SocketAddress/functions.php" + ], + "psr-4": { + "Amp\\Socket\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@gmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.", + "homepage": "https://github.com/amphp/socket", + "keywords": [ + "amp", + "async", + "encryption", + "non-blocking", + "sockets", + "tcp", + "tls" + ], + "support": { + "issues": "https://github.com/amphp/socket/issues", + "source": "https://github.com/amphp/socket/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-21T14:33:03+00:00" + }, + { + "name": "amphp/sync", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/sync.git", + "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/sync/zipball/217097b785130d77cfcc58ff583cf26cd1770bf1", + "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/pipeline": "^1", + "amphp/serialization": "^1", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.23" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Sync\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + } + ], + "description": "Non-blocking synchronization primitives for PHP based on Amp and Revolt.", + "homepage": "https://github.com/amphp/sync", + "keywords": [ + "async", + "asynchronous", + "mutex", + "semaphore", + "synchronization" + ], + "support": { + "issues": "https://github.com/amphp/sync/issues", + "source": "https://github.com/amphp/sync/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-08-03T19:31:26+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "danog/advanced-json-rpc", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/danog/php-advanced-json-rpc.git", + "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/danog/php-advanced-json-rpc/zipball/aadb1c4068a88c3d0530cfe324b067920661efcb", + "reference": "aadb1c4068a88c3d0530cfe324b067920661efcb", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^5", + "php": ">=8.1", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "replace": { + "felixfbecker/php-advanced-json-rpc": "^3" + }, + "require-dev": { + "phpunit/phpunit": "^9" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + }, + { + "name": "Daniil Gentili", + "email": "daniil@daniil.it" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/danog/php-advanced-json-rpc/issues", + "source": "https://github.com/danog/php-advanced-json-rpc/tree/v3.2.2" + }, + "time": "2025-02-14T10:55:15+00:00" + }, + { + "name": "daverandom/libdns", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/DaveRandom/LibDNS.git", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "Required for IDN support" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "LibDNS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "DNS protocol implementation written in pure PHP", + "keywords": [ + "dns" + ], + "support": { + "issues": "https://github.com/DaveRandom/LibDNS/issues", + "source": "https://github.com/DaveRandom/LibDNS/tree/v2.1.0" + }, + "time": "2024-04-12T12:12:48+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + }, + "time": "2025-04-07T20:06:18+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.5.3", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/a9e113dbc7d849e35b8776da39edaf4313b7b6c9", + "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "^3.1", + "vimeo/psalm": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.3" + }, + "time": "2024-04-30T00:40:11+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2025-08-14T07:29:31+00:00" + }, + { + "name": "kelunik/certificate", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/kelunik/certificate.git", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">=7.0" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^6 | 7 | ^8 | ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kelunik\\Certificate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Access certificate details and transform between different formats.", + "keywords": [ + "DER", + "certificate", + "certificates", + "openssl", + "pem", + "x509" + ], + "support": { + "issues": "https://github.com/kelunik/certificate/issues", + "source": "https://github.com/kelunik/certificate/tree/v1.1.3" + }, + "time": "2023-02-03T21:26:53+00:00" + }, + { + "name": "league/uri", + "version": "7.5.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "81fb5145d2644324614cc532b28efd0215bda430" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", + "reference": "81fb5145d2644324614cc532b28efd0215bda430", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.5", + "php": "^8.1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", + "league/uri-components": "Needed to easily manipulate URI objects components", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.5.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:40:02+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:18:47+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v5.0.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c", + "reference": "8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v5.0.0" + }, + "time": "2024-09-08T10:20:00+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.6.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "3a454ca033b9e06b63282ce19562e892747449bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb", + "reference": "3a454ca033b9e06b63282ce19562e892747449bb", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2" + }, + "time": "2025-10-21T19:32:17+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.6.3", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9", + "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.3" + }, + "time": "2025-08-01T19:43:32+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" + }, + "time": "2024-11-09T15:12:26+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" + }, + "time": "2025-08-30T15:50:23+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "revolt/event-loop", + "version": "v1.0.7", + "source": { + "type": "git", + "url": "https://github.com/revoltphp/event-loop.git", + "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/09bf1bf7f7f574453efe43044b06fafe12216eb3", + "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.15" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Revolt\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "ceesjank@gmail.com" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Rock-solid event loop for concurrent PHP applications.", + "keywords": [ + "async", + "asynchronous", + "concurrency", + "event", + "event-loop", + "non-blocking", + "scheduler" + ], + "support": { + "issues": "https://github.com/revoltphp/event-loop/issues", + "source": "https://github.com/revoltphp/event-loop/tree/v1.0.7" + }, + "time": "2025-01-25T19:27:39+00:00" + }, + { + "name": "sebastian/diff", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:55:46+00:00" + }, + { + "name": "spatie/array-to-xml", + "version": "3.4.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/array-to-xml.git", + "reference": "6a740f39415aee8886aea10333403adc77d50791" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/6a740f39415aee8886aea10333403adc77d50791", + "reference": "6a740f39415aee8886aea10333403adc77d50791", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "pestphp/pest": "^1.21", + "spatie/pest-plugin-snapshots": "^1.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Spatie\\ArrayToXml\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://freek.dev", + "role": "Developer" + } + ], + "description": "Convert an array to xml", + "homepage": "https://github.com/spatie/array-to-xml", + "keywords": [ + "array", + "convert", + "xml" + ], + "support": { + "source": "https://github.com/spatie/array-to-xml/tree/3.4.1" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-11-12T10:32:50+00:00" + }, + { + "name": "symfony/console", + "version": "v7.3.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.3.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-04T01:21:42+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.3.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e9bcfd7837928ab656276fe00464092cc9e1826a", + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.3.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-05T09:52:27+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T09:58:17+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php84", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-24T13:30:11+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:30:57+00:00" + }, + { + "name": "symfony/string", + "version": "v7.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "f96476035142921000338bad71e5247fbc138872" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872", + "reference": "f96476035142921000338bad71e5247fbc138872", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-09-11T14:36:48+00:00" + }, + { + "name": "vimeo/psalm", + "version": "6.13.1", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "1e3b7f0a8ab32b23197b91107adc0a7ed8a05b51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/1e3b7f0a8ab32b23197b91107adc0a7ed8a05b51", + "reference": "1e3b7f0a8ab32b23197b91107adc0a7ed8a05b51", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/parallel": "^2.3", + "composer-runtime-api": "^2", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^2.0 || ^3.0", + "danog/advanced-json-rpc": "^3.1", + "dnoegel/php-xdg-base-dir": "^0.1.1", + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "felixfbecker/language-server-protocol": "^1.5.3", + "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", + "netresearch/jsonmapper": "^5.0", + "nikic/php-parser": "^5.0.0", + "php": "~8.1.31 || ~8.2.27 || ~8.3.16 || ~8.4.3", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0 || ^7.0", + "spatie/array-to-xml": "^2.17.0 || ^3.0", + "symfony/console": "^6.0 || ^7.0", + "symfony/filesystem": "~6.3.12 || ~6.4.3 || ^7.0.3", + "symfony/polyfill-php84": "^1.31.0" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "amphp/phpunit-util": "^3", + "bamarni/composer-bin-plugin": "^1.4", + "brianium/paratest": "^6.9", + "danog/class-finder": "^0.4.8", + "dg/bypass-finals": "^1.5", + "ext-curl": "*", + "mockery/mockery": "^1.5", + "nunomaduro/mock-final-classes": "^1.1", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpdoc-parser": "^1.6", + "phpunit/phpunit": "^9.6", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.19", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/process": "^6.0 || ^7.0" + }, + "suggest": { + "ext-curl": "In order to send data to shepherd", + "ext-igbinary": "^2.0.5 is required, used to serialize caching data" + }, + "bin": [ + "psalm", + "psalm-language-server", + "psalm-plugin", + "psalm-refactor", + "psalm-review", + "psalter" + ], + "type": "project", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev", + "dev-3.x": "3.x-dev", + "dev-4.x": "4.x-dev", + "dev-5.x": "5.x-dev", + "dev-6.x": "6.x-dev", + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\": "src/Psalm/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + }, + { + "name": "Daniil Gentili", + "email": "daniil@daniil.it" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php", + "static analysis" + ], + "support": { + "docs": "https://psalm.dev/docs", + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm" + }, + "time": "2025-08-06T10:10:28+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", + "php": "^7.2 || ^8.0" + }, + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" + }, + "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.12.1" + }, + "time": "2025-10-29T15:56:20+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +}