}
},
"require": {
- "cuyz/valinor": "^1.14.1",
+ "cuyz/valinor": "^1.14.2",
"dragonmantank/cron-expression": "^3.4.0",
"erusev/parsedown": "^1.7.4",
"ezyang/htmlpurifier": "^4.18",
"guzzlehttp/psr7": "^2.7.0",
"laminas/laminas-diactoros": "^3.5.0",
"laminas/laminas-httphandlerrunner": "^2.11.0",
- "laminas/laminas-progressbar": "^2.14",
+ "laminas/laminas-progressbar": "^2.14.1",
"minishlink/web-push": "^v9.0.1",
"nikic/fast-route": "2.0.0-beta1",
"paragonie/constant_time_encoding": "^3.0",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "c6d3e68e563d4b2ddb31505fc2d3b478",
+ "content-hash": "e28f08e0dd80e8d2c529f7e098d220ba",
"packages": [
{
"name": "brick/math",
},
{
"name": "cuyz/valinor",
- "version": "1.14.1",
+ "version": "1.14.2",
"source": {
"type": "git",
"url": "https://github.com/CuyZ/Valinor.git",
- "reference": "12033fccdcc6afa7e73b3e234e4d6656530f2bcb"
+ "reference": "1881c77d555b00c2f969dfbbc2c7dbd939ae97ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/CuyZ/Valinor/zipball/12033fccdcc6afa7e73b3e234e4d6656530f2bcb",
- "reference": "12033fccdcc6afa7e73b3e234e4d6656530f2bcb",
+ "url": "https://api.github.com/repos/CuyZ/Valinor/zipball/1881c77d555b00c2f969dfbbc2c7dbd939ae97ea",
+ "reference": "1881c77d555b00c2f969dfbbc2c7dbd939ae97ea",
"shasum": ""
},
"require": {
"infection/infection": "^0.27",
"marcocesarato/php-conventional-changelog": "^1.12",
"mikey179/vfsstream": "^1.6.10",
- "phpstan/phpstan": "^1.3",
- "phpstan/phpstan-phpunit": "^1.0",
- "phpstan/phpstan-strict-rules": "^1.0",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^10.5",
- "rector/rector": "^1.0",
+ "rector/rector": "^2.0",
"vimeo/psalm": "^5.0"
},
"type": "library",
],
"support": {
"issues": "https://github.com/CuyZ/Valinor/issues",
- "source": "https://github.com/CuyZ/Valinor/tree/1.14.1"
+ "source": "https://github.com/CuyZ/Valinor/tree/1.14.2"
},
"funding": [
{
"type": "github"
}
],
- "time": "2024-11-06T07:46:46+00:00"
+ "time": "2025-01-09T09:48:05+00:00"
},
{
"name": "dragonmantank/cron-expression",
},
{
"name": "laminas/laminas-progressbar",
- "version": "2.14.0",
+ "version": "2.14.1",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-progressbar.git",
- "reference": "cb87f8d9a252e9944a4a924b3a7ce1c6687c7007"
+ "reference": "f5180549455495dc10f4a5f34bfeef2013b141a4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-progressbar/zipball/cb87f8d9a252e9944a4a924b3a7ce1c6687c7007",
- "reference": "cb87f8d9a252e9944a4a924b3a7ce1c6687c7007",
+ "url": "https://api.github.com/repos/laminas/laminas-progressbar/zipball/f5180549455495dc10f4a5f34bfeef2013b141a4",
+ "reference": "f5180549455495dc10f4a5f34bfeef2013b141a4",
"shasum": ""
},
"require": {
"type": "community_bridge"
}
],
- "time": "2024-10-11T10:58:38+00:00"
+ "abandoned": true,
+ "time": "2024-12-05T16:32:56+00:00"
},
{
"name": "laminas/laminas-stdlib",
}
$installed = array();
+ $copiedLocalDir = false;
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
- $installed[] = self::$installedByVendor[$vendorDir] = $required;
- if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
- self::$installed = $installed[count($installed) - 1];
+ self::$installedByVendor[$vendorDir] = $required;
+ $installed[] = $required;
+ if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
+ self::$installed = $required;
+ $copiedLocalDir = true;
}
}
}
}
}
- if (self::$installed !== array()) {
+ if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
},
{
"name": "cuyz/valinor",
- "version": "1.14.1",
- "version_normalized": "1.14.1.0",
+ "version": "1.14.2",
+ "version_normalized": "1.14.2.0",
"source": {
"type": "git",
"url": "https://github.com/CuyZ/Valinor.git",
- "reference": "12033fccdcc6afa7e73b3e234e4d6656530f2bcb"
+ "reference": "1881c77d555b00c2f969dfbbc2c7dbd939ae97ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/CuyZ/Valinor/zipball/12033fccdcc6afa7e73b3e234e4d6656530f2bcb",
- "reference": "12033fccdcc6afa7e73b3e234e4d6656530f2bcb",
+ "url": "https://api.github.com/repos/CuyZ/Valinor/zipball/1881c77d555b00c2f969dfbbc2c7dbd939ae97ea",
+ "reference": "1881c77d555b00c2f969dfbbc2c7dbd939ae97ea",
"shasum": ""
},
"require": {
"infection/infection": "^0.27",
"marcocesarato/php-conventional-changelog": "^1.12",
"mikey179/vfsstream": "^1.6.10",
- "phpstan/phpstan": "^1.3",
- "phpstan/phpstan-phpunit": "^1.0",
- "phpstan/phpstan-strict-rules": "^1.0",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^10.5",
- "rector/rector": "^1.0",
+ "rector/rector": "^2.0",
"vimeo/psalm": "^5.0"
},
- "time": "2024-11-06T07:46:46+00:00",
+ "time": "2025-01-09T09:48:05+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
],
"support": {
"issues": "https://github.com/CuyZ/Valinor/issues",
- "source": "https://github.com/CuyZ/Valinor/tree/1.14.1"
+ "source": "https://github.com/CuyZ/Valinor/tree/1.14.2"
},
"funding": [
{
},
{
"name": "laminas/laminas-progressbar",
- "version": "2.14.0",
- "version_normalized": "2.14.0.0",
+ "version": "2.14.1",
+ "version_normalized": "2.14.1.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-progressbar.git",
- "reference": "cb87f8d9a252e9944a4a924b3a7ce1c6687c7007"
+ "reference": "f5180549455495dc10f4a5f34bfeef2013b141a4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-progressbar/zipball/cb87f8d9a252e9944a4a924b3a7ce1c6687c7007",
- "reference": "cb87f8d9a252e9944a4a924b3a7ce1c6687c7007",
+ "url": "https://api.github.com/repos/laminas/laminas-progressbar/zipball/f5180549455495dc10f4a5f34bfeef2013b141a4",
+ "reference": "f5180549455495dc10f4a5f34bfeef2013b141a4",
"shasum": ""
},
"require": {
"suggest": {
"laminas/laminas-session": "To support progressbar persistent"
},
- "time": "2024-10-11T10:58:38+00:00",
+ "time": "2024-12-05T16:32:56+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"type": "community_bridge"
}
],
+ "abandoned": true,
"install-path": "../laminas/laminas-progressbar"
},
{
"install-path": "../willdurand/negotiation"
}
],
- "dev": false,
+ "dev": true,
"dev-package-names": []
}
'name' => '__root__',
'pretty_version' => '6.1.x-dev',
'version' => '6.1.9999999.9999999-dev',
- 'reference' => 'd0f21942f2a92fa397acea1b42b2e552338c4f9a',
+ 'reference' => '7e305277c70cb69c4d566d99c44eef497f6614a1',
'type' => 'project',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
- 'dev' => false,
+ 'dev' => true,
),
'versions' => array(
'__root__' => array(
'pretty_version' => '6.1.x-dev',
'version' => '6.1.9999999.9999999-dev',
- 'reference' => 'd0f21942f2a92fa397acea1b42b2e552338c4f9a',
+ 'reference' => '7e305277c70cb69c4d566d99c44eef497f6614a1',
'type' => 'project',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
'dev_requirement' => false,
),
'cuyz/valinor' => array(
- 'pretty_version' => '1.14.1',
- 'version' => '1.14.1.0',
- 'reference' => '12033fccdcc6afa7e73b3e234e4d6656530f2bcb',
+ 'pretty_version' => '1.14.2',
+ 'version' => '1.14.2.0',
+ 'reference' => '1881c77d555b00c2f969dfbbc2c7dbd939ae97ea',
'type' => 'library',
'install_path' => __DIR__ . '/../cuyz/valinor',
'aliases' => array(),
'dev_requirement' => false,
),
'laminas/laminas-progressbar' => array(
- 'pretty_version' => '2.14.0',
- 'version' => '2.14.0.0',
- 'reference' => 'cb87f8d9a252e9944a4a924b3a7ce1c6687c7007',
+ 'pretty_version' => '2.14.1',
+ 'version' => '2.14.1.0',
+ 'reference' => 'f5180549455495dc10f4a5f34bfeef2013b141a4',
'type' => 'library',
'install_path' => __DIR__ . '/../laminas/laminas-progressbar',
'aliases' => array(),
"require-dev": {
"phpunit/phpunit": "^10.5",
"infection/infection": "^0.27",
- "phpstan/phpstan": "^1.3",
- "phpstan/phpstan-strict-rules": "^1.0",
- "phpstan/phpstan-phpunit": "^1.0",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
"friendsofphp/php-cs-fixer": "^3.4",
"marcocesarato/php-conventional-changelog": "^1.12",
"vimeo/psalm": "^5.0",
"mikey179/vfsstream": "^1.6.10",
- "rector/rector": "^1.0"
+ "rector/rector": "^2.0"
},
"autoload": {
"psr-4": {
return [
RuleErrorBuilder::message(
'Missing annotation `@api` or `@internal`.'
- )->build(),
+ )->identifier('valinor.api_or_internal_annotation')->build(),
];
}
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
-use PHPStan\Type\ClosureType;
-use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
$type = $scope->getType($arguments[0]->value);
- if ($type instanceof ClosureType) {
- $parameters = $type->getParameters();
- } elseif ($type instanceof ConstantArrayType) {
- $acceptors = $type->getCallableParametersAcceptors($scope);
+ if (! $type->isCallable()->yes()) {
+ return new MixedType();
+ }
- if (count($acceptors) !== 1) {
- return new MixedType();
- }
+ $acceptors = $type->getCallableParametersAcceptors($scope);
- $parameters = $acceptors[0]->getParameters();
- } else {
+ if (count($acceptors) !== 1) {
return new MixedType();
}
+ $parameters = $acceptors[0]->getParameters();
+
$builder = ConstantArrayTypeBuilder::createEmpty();
foreach ($parameters as $parameter) {
use PHPStan\PhpDoc\TypeStringResolver;
use PHPStan\PhpDocParser\Parser\ParserException;
use PHPStan\Reflection\MethodReflection;
-use PHPStan\Type\ClassStringType;
-use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
-use PHPStan\Type\Generic\GenericClassStringType;
use PHPStan\Type\MixedType;
-use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
+use function implode;
+
final class TreeMapperPHPStanExtension implements DynamicMethodReturnTypeExtension
{
public function __construct(private TypeStringResolver $resolver) {}
private function type(Type $type): Type
{
- if ($type instanceof GenericClassStringType) {
- return $type->getGenericType();
+ if ($type->isClassString()->yes()) {
+ return $type->getClassStringObjectType();
}
- if ($type instanceof ConstantStringType) {
- return $this->resolver->resolve($type->getValue());
- }
+ if ($type->isConstantValue()->yes()) {
+ $value = implode('', $type->getConstantScalarValues());
- if ($type instanceof ClassStringType) {
- return new ObjectWithoutClassType();
+ return $this->resolver->resolve($value);
}
return new MixedType();
class ValinorPsalmPlugin implements PluginEntryPointInterface
{
- public function __invoke(RegistrationInterface $api, SimpleXMLElement $config = null): void
+ public function __invoke(RegistrationInterface $api, ?SimpleXMLElement $config = null): void
{
require_once __DIR__ . '/Plugin/TreeMapperPsalmPlugin.php';
require_once __DIR__ . '/Plugin/ArgumentsMapperPsalmPlugin.php';
use CuyZ\Valinor\Definition\Attributes;
+use function array_map;
use function count;
use function implode;
use function is_array;
foreach ($attributes as $attribute) {
$class = $this->classDefinitionCompiler->compile($attribute->class);
- $arguments = $this->compileAttributeArguments($attribute->arguments);
+
+ if ($attribute->arguments === []) {
+ $arguments = '';
+ } else {
+ $arguments = implode(', ', array_map(
+ fn (mixed $argument) => $this->compileAttributeArguments($argument),
+ $attribute->arguments,
+ ));
+ }
$attributesListCode[] = <<<PHP
new \CuyZ\Valinor\Definition\AttributeDefinition(
return implode(', ', $attributesListCode);
}
- /**
- * @param array<mixed> $arguments
- */
- private function compileAttributeArguments(array $arguments): string
+ private function compileAttributeArguments(mixed $value): string
{
- if (count($arguments) === 0) {
- return '';
+ if (is_object($value)) {
+ return 'unserialize(' . var_export(serialize($value), true) . ')';
}
- $argumentsCode = [];
+ if (is_array($value)) {
+ $parts = [];
- foreach ($arguments as $argument) {
- if (is_object($argument)) {
- $argumentsCode[] = 'unserialize(' . var_export(serialize($argument), true) . ')';
- } elseif (is_array($argument)) {
- $argumentsCode[] = '[' . $this->compileAttributeArguments($argument) . ']';
- } else {
- $argumentsCode[] = var_export($argument, true);
+ foreach ($value as $key => $subValue) {
+ $parts[] = var_export($key, true) . ' => ' . $this->compileAttributeArguments($subValue);
}
+
+ return '[' . implode(', ', $parts) . ']';
}
- return implode(', ', $argumentsCode);
+ return var_export($value, true);
}
}
return array_values(array_map(
fn (ReflectionAttribute $attribute) => new AttributeDefinition(
$this->classDefinitionRepository->for(new NativeClassType($attribute->getName())),
- $attribute->getArguments(),
+ array_values($attribute->getArguments()),
),
$attributes,
));
public function for(ReflectionMethod $reflection, ReflectionTypeResolver $typeResolver): MethodDefinition
{
- /** @var non-empty-string $name */
$name = $reflection->name;
$signature = $reflection->getDeclaringClass()->name . '::' . $reflection->name . '()';
next($tokens);
- /** @var int|null $key / Somehow PHPStan does not properly infer the key */
$key = key($tokens);
+ // @phpstan-ignore identical.alwaysFalse (Somehow PHPStan does not properly infer the key)
if ($key === null) {
continue;
}
next($tokens);
}
- /** @var int|null $key / Somehow PHPStan does not properly infer the key */
$key = key($tokens);
+ // @phpstan-ignore notIdentical.alwaysTrue (Somehow PHPStan does not properly infer the key)
if ($key !== null) {
$aliases[$name] = $annotation->allAfter($key);
}
/** @var CacheInterface<mixed> */
public CacheInterface $cache;
- /** @var non-empty-array<non-empty-string> */
+ /** @var non-empty-list<non-empty-string> */
public array $supportedDateFormats = self::DEFAULT_SUPPORTED_DATETIME_FORMATS;
public bool $enableFlexibleCasting = false;
interface ArgumentsMapper
{
/**
- * @pure
- *
* @return array<string, mixed>
*
* @throws MappingError
*/
final class DateTimeFormatConstructor
{
- /** @var non-empty-array<non-empty-string> */
+ /** @var non-empty-list<non-empty-string> */
private array $formats;
/**
+ * @no-named-arguments
* @param non-empty-string $format
* @param non-empty-string ...$formats
*/
{
public function __construct(
private ObjectBuilderFactory $delegate,
- /** @var non-empty-array<non-empty-string> */
+ /** @var non-empty-list<non-empty-string> */
private array $supportedDateFormats,
private FunctionDefinitionRepository $functionDefinitionRepository
) {}
$arguments = new MethodArguments($parameters, $arguments);
try {
+ /** @var object */
return ($this->function->callback)(...$arguments);
} catch (Exception $exception) {
throw UserlandError::from($exception);
*/
final class PathMapping implements IteratorAggregate
{
- /** @var array<string, mixed> */
+ /** @var array<mixed> */
private array $source;
/**
use CuyZ\Valinor\Mapper\Tree\Message\NodeMessage;
-use function is_callable;
+use function is_string;
/**
* Can be used to customize the content of messages added during a mapping.
$target = $this->target($message);
if ($target) {
- return $message->withBody(is_callable($target) ? $target($message) : $target);
+ return $message->withBody(is_string($target) ? $target : $target($message));
}
return $message;
public function withTranslations(array $translations): self
{
$clone = clone $this;
+ // @phpstan-ignore assign.propertyType (PHPStan does not properly infer the return type of the function)
$clone->translations = array_replace_recursive($this->translations, $translations);
return $clone;
*/
public static function newError(string $body): self
{
+ /** @var self<ErrorMessage> $instance */
$instance = new self($body);
$instance->isError = true;
- /** @var self<ErrorMessage> */
return $instance;
}
- /**
- * @psalm-pure
- */
public static function from(Throwable $error): ErrorMessage
{
if ($error instanceof ErrorMessage) {
}
/**
- * @psalm-pure
- *
* @return MessageType&HasCode&HasParameters
*/
public function build(): Message&HasCode&HasParameters
public function body(): string
{
+ /** @var string */
return $this->message;
}
public function code(): string
{
+ /** @var string */
return $this->code;
}
use IteratorAggregate;
use function array_filter;
+use function array_values;
use function count;
/**
public function errors(): self
{
$clone = clone $this;
- $clone->messages = array_filter($clone->messages, fn (NodeMessage $message) => $message->isError());
+ $clone->messages = array_values(
+ array_filter($clone->messages, fn (NodeMessage $message) => $message->isError())
+ );
return $clone;
}
private bool $isValid = true;
- /** @var array<NodeMessage> */
+ /** @var list<NodeMessage> */
private array $messages = [];
/** @var array<self> */
}
/**
- * @return array<NodeMessage>
+ * @return list<NodeMessage>
*/
public function messages(): array
{
interface TreeMapper
{
/**
- * @pure
- *
* @template T of object
*
* @param string|class-string<T> $signature
private Settings $settings,
) {}
- /** @pure */
public function mapArguments(callable $callable, mixed $source): array
{
$function = $this->functionDefinitionRepository->for($callable);
private Settings $settings,
) {}
- /** @pure */
public function map(string $signature, mixed $source): mixed
{
$node = $this->node($signature, $source);
use Throwable;
use function array_unique;
+use function array_values;
use function is_callable;
/** @api */
* using the given source. These arguments can then be used to decide which
* implementation should be used.
*
- * The callback *must* be pure, its output must be deterministic.
- * @see https://en.wikipedia.org/wiki/Pure_function
- *
* Example:
*
* ```php
* ```
*
* @param interface-string|class-string $name
- * @psalm-param pure-callable $callback
*/
public function infer(string $name, callable $callback): self
{
* needs to be handled as well, the name of the class must be given to this
* method.
*
- * A constructor *must* be pure, its output must be deterministic.
- * @see https://en.wikipedia.org/wiki/Pure_function
- *
* ```php
* final class SomeClass
* {
* ]);
* ```
*
- * @psalm-param pure-callable|class-string ...$constructors
* @param callable|class-string ...$constructors
*/
public function registerConstructor(callable|string ...$constructors): self
public function supportDateFormats(string $format, string ...$formats): self
{
$clone = clone $this;
- $clone->settings->supportedDateFormats = array_unique([$format, ...$formats]);
+ $clone->settings->supportedDateFormats = array_values(array_unique([$format, ...$formats]));
return $clone;
}
/**
* @template T
- * @psalm-param pure-callable(T): T $callback
* @param callable(T): T $callback
*/
public function alter(callable $callback): self
* part of a query should never be allowed. Therefore, only an exhaustive
* list of carefully chosen exceptions should be filtered.
*
- * The filter callback *must* be pure, its output must be deterministic.
- * @see https://en.wikipedia.org/wiki/Pure_function
- *
* ```php
* final class SomeClass
* {
* ]);
* ```
*
- * @psalm-param pure-callable(Throwable): ErrorMessage $filter
* @param callable(Throwable): ErrorMessage $filter
*/
public function filterExceptions(callable $filter): self
* ->normalize('Hello world'); // HELLO WORLD?!
* ```
*
- * @psalm-param pure-callable|class-string $transformer
* @param callable|class-string $transformer
*/
public function registerTransformer(callable|string $transformer, int $priority = 0): self
use Generator;
use function array_is_list;
+use function assert;
use function fwrite;
use function is_array;
use function is_bool;
$isFirst = false;
if (! $isList) {
+ assert(is_scalar($key));
+
$key = json_encode((string)$key, $this->jsonEncodingOptions);
$chunk .= $key . ':';
final class JsonNormalizer implements Normalizer
{
private const ACCEPTABLE_JSON_OPTIONS = JSON_FORCE_OBJECT
- | JSON_HEX_QUOT
- | JSON_HEX_TAG
- | JSON_HEX_AMP
- | JSON_HEX_APOS
- | JSON_INVALID_UTF8_IGNORE
- | JSON_INVALID_UTF8_SUBSTITUTE
- | JSON_NUMERIC_CHECK
- | JSON_PRETTY_PRINT
- | JSON_PRESERVE_ZERO_FRACTION
- | JSON_UNESCAPED_LINE_TERMINATORS
- | JSON_UNESCAPED_SLASHES
- | JSON_UNESCAPED_UNICODE
- | JSON_THROW_ON_ERROR;
+ | JSON_HEX_QUOT
+ | JSON_HEX_TAG
+ | JSON_HEX_AMP
+ | JSON_HEX_APOS
+ | JSON_INVALID_UTF8_IGNORE
+ | JSON_INVALID_UTF8_SUBSTITUTE
+ | JSON_NUMERIC_CHECK
+ | JSON_PRETTY_PRINT
+ | JSON_PRESERVE_ZERO_FRACTION
+ | JSON_UNESCAPED_LINE_TERMINATORS
+ | JSON_UNESCAPED_SLASHES
+ | JSON_UNESCAPED_UNICODE
+ | JSON_THROW_ON_ERROR;
private RecursiveTransformer $transformer;
public function streamTo(mixed $resource): StreamNormalizer
{
// This check is there to help people that do not use static analyzers.
- // @phpstan-ignore-next-line
if (! is_resource($resource)) {
throw new RuntimeException('Expected a valid resource, got ' . get_debug_type($resource));
}
}
}
+ /** @var array-key */
return $key;
}
*/
public function transform(mixed $value, array $attributes, array $transformers, callable $defaultTransformer): mixed
{
+ /** @var array<mixed>|scalar|null */
return call_user_func(
$this->next($transformers, $value, $attributes, $defaultTransformer),
);
}
/**
- * @param array<string> $array
- * @return array<string>
+ * @param list<string> $array
+ * @return list<string>
*/
private function trimArrayTips(array $array): array
{
return $type;
}
- /** @phpstan-impure */
public function next(): Token
{
return $this->tokens[$this->peek + 1];
# laminas-progressbar
+> [!CAUTION]
+> This package is **abandoned** and will receive no further development.
+>
+> See the Technical Steering Committee [meeting minutes](https://github.com/laminas/technical-steering-committee/blob/main/meetings/minutes/2024-11-04-TSC-Minutes.md#archive--abandon-various-legacy-libraries).
+
> ## π·πΊ Π ΡΡΡΠΊΠΈΠΌ Π³ΡΠ°ΠΆΠ΄Π°Π½Π°ΠΌ
>
> ΠΡ, ΡΡΠ°ΡΡΠ½ΠΈΠΊΠΈ Laminas, ΡΠΎΠ΄ΠΈΠ»ΠΈΡΡ ΠΈ ΠΆΠΈΠ²Π΅ΠΌ Π² ΡΠ°Π·Π½ΡΡ
ΡΡΡΠ°Π½Π°Ρ
. Π£ ΠΌΠ½ΠΎΠ³ΠΈΡ
ΠΈΠ· Π½Π°Ρ Π΅ΡΡΡ Π΄ΡΡΠ·ΡΡ, ΡΠΎΠ΄ΡΡΠ²Π΅Π½Π½ΠΈΠΊΠΈ ΠΈ ΠΊΠΎΠ»Π»Π΅Π³ΠΈ ΠΊΠ°ΠΊ Π² Π ΠΎΡΡΠΈΠΈ, ΡΠ°ΠΊ ΠΈ Π² Π£ΠΊΡΠ°ΠΈΠ½Π΅. ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΠ· Π½Π°Ρ ΡΠΎΠ΄ΠΈΠ»ΠΈΡΡ Π² Π ΠΎΡΡΠΈΠΈ. ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΠ· Π½Π°Ρ ΠΆΠΈΠ²ΡΡ Π² Π ΠΎΡΡΠΈΠΈ. Π£ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
Π±Π°Π±ΡΡΠΊΠΈ ΠΈ Π΄Π΅Π΄ΡΡΠΊΠΈ ΡΡΠ°ΠΆΠ°Π»ΠΈΡΡ Ρ ΡΠ°ΡΠΈΡΡΠ°ΠΌΠΈ Π²ΠΎ ΠΡΠΎΡΠΎΠΉ ΠΌΠΈΡΠΎΠ²ΠΎΠΉ Π²ΠΎΠΉΠ½Π΅. ΠΠ΄Π΅ΡΡ Π½ΠΈΠΊΡΠΎ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠ°ΡΠΈΠ·ΠΌ.
>
> You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!"
-> This package is considered feature-complete, and is now in **security-only** maintenance mode, following a [decision by the Technical Steering Committee](https://github.com/laminas/technical-steering-committee/blob/2b55453e172a1b8c9c4c212be7cf7e7a58b9352c/meetings/minutes/2020-08-03-TSC-Minutes.md#vote-on-components-to-mark-as-security-only).
-> If you have a security issue, please [follow our security reporting guidelines](https://getlaminas.org/security/).
-> If you wish to take on the role of maintainer, please [nominate yourself](https://github.com/laminas/technical-steering-committee/issues/new?assignees=&labels=Nomination&template=Maintainer_Nomination.md&title=%5BNOMINATION%5D%5BMAINTAINER%5D%3A+%7Bname+of+person+being+nominated%7D)
-
-[![Build Status](https://github.com/laminas/laminas-progressbar/workflows/Continuous%20Integration/badge.svg)](https://github.com/laminas/laminas-progressbar/actions?query=workflow%3A"Continuous+Integration")
-
laminas-progressbar is a component to create and update progress bars in different
environments. It consists of a single backend, which outputs the progress through
one of the multiple adapters. On every update, it takes an absolute value and
## Documentation
Browse the documentation online at https://docs.laminas.dev/laminas-progressbar/
-
-## Support
-
-- [Issues](https://github.com/laminas/laminas-progressbar/issues/)
-- [Chat](https://laminas.dev/chat/)
-- [Forum](https://discourse.laminas.dev/)
"chat": "https://laminas.dev/chat",
"forum": "https://discourse.laminas.dev"
},
+ "abandoned": true,
"config": {
"sort-packages": true,
"platform": {