Skip to content

Releases: salient-labs/toolkit

v0.99.79

31 Mar 01:35
v0.99.79
1d30318
Compare
Choose a tag to compare

Added

Container

  • Add and implement ApplicationInterface methods:
    • hasOutputLog()
    • hasHarRecorder()
    • hasCache()
    • hasSync()

Changed

Container

  • Rename ApplicationInterface method exportHar() to recordHar()

v0.99.78

28 Mar 02:46
v0.99.78
139091e
Compare
Choose a tag to compare

Added

Console

  • Add and implement ConsoleInterface methods:
    • getTtyTarget()
    • removeEscapes()
    • removeTags()
  • Add and implement StreamTargetInterface method getUri()
  • In ConsoleInterface:
    • Add optional $debug parameters to registerStderrTarget() and registerStdioTargets()
    • Add optional $escapeNewlines parameter to escape()
    • Add optional $count parameter to exception()

Container

  • Allow closures to be bound to the container
  • Add $container parameter to HasBindings methods and allow them to return closures
  • Add $container parameter to getContextualBindings() and allow it to return parameter and unmapped services, closures and instances
  • Add and implement ApplicationInterface methods:
    • getVersion()
    • getVersionString()
    • reportVersion()

PHPStan

  • Add ContainerRule to report when calls to ContainerInterface::getAs() have an $id that isn't a subtype of $service

Changed

Console

  • Change default Console::info() prefix from to > to address inconsistent output width on some platforms
  • In ConsoleLogger, pass debug messages to Console::debug() so the caller is output
  • In StreamTarget::reopen(), don't throw an exception if the stream can't be reopened
  • Don't close targets when they are deregistered
  • Rename ConsoleInterface methods:
    • getLogger() -> logger()
    • setTargetPrefix() -> setPrefix()
    • printOut() -> printStdio()
    • getErrorCount() -> errors()
    • getWarningCount() -> warnings()
  • Remove $type parameters from print() methods in ConsoleInterface
  • Rename StreamTarget method fromPath() to more accurate fromFile()
  • Rename:
    • ConsoleFormatInterface -> FormatInterface
    • ConsoleFormatterInterface -> FormatterInterface
    • ConsoleMessageAttributesInterface -> MessageAttributesInterface
    • ConsoleMessageFormatInterface -> MessageFormatInterface
    • ConsoleTagAttributesInterface -> TagAttributesInterface
    • ConsoleTargetInterface -> TargetInterface
    • ConsoleTargetPrefixInterface -> HasPrefix
    • ConsoleTargetStreamInterface -> StreamTargetInterface
    • ConsoleFormat -> TtyFormat
    • ConsoleFormatter -> Formatter
    • ConsoleLoopbackFormat -> LoopbackFormat
    • ConsoleManPageFormat -> ManPageFormat
    • ConsoleMarkdownFormat -> MarkdownFormat
    • ConsoleMessageAttributes -> MessageAttributes
    • ConsoleMessageFormat -> MessageFormat
    • ConsoleMessageFormats -> MessageFormats
    • ConsolePrefixTarget -> AbstractTargetWithPrefix
    • ConsoleStreamTarget -> AbstractStreamTarget
    • ConsoleTag -> HasTag and add TAG_ prefix to the names of its constants
    • ConsoleTagAttributes -> TagAttributes
    • ConsoleTagFormats -> TagFormats
    • ConsoleTarget -> AbstractTarget
    • ConsoleTargetTypeFlag -> HasTargetFlag and add TARGET_ prefix to the names of its constants
  • Rename methods:
    • withUnescape() -> withRemoveEscapes()
    • getUnescape() -> removesEscapes()
    • withWrapAfterApply() -> withWrapAfterFormatting()
    • getWrapAfterApply() -> wrapsAfterFormatting()
  • Replace "dim" with "faint" in method names and documentation

Container

  • Remove $args parameters from bind(), bindIf(), singleton() and singletonIf()
  • Rename getName() -> getClass()
  • In getAs(), throw an exception if $id doesn't extend or implement $service
  • In providers(), map unmapped providers to themselves
  • Rename event and exception interfaces for consistency
  • Rename ArgumentsNotUsedException -> UnusedArgumentsException
  • Rename ServiceLifetime -> HasServiceLifetime and add LIFETIME_ prefix to the names of its constants
  • Rename ApplicationInterface methods:
    • getAppName() -> getName()
    • isProduction() -> isRunningInProduction()
    • registerSyncNamespace() -> sync() and start the entity store implicitly when called
    • getWorkingDirectory() -> getInitialWorkingDirectory()
    • setWorkingDirectory() -> setInitialWorkingDirectory() and remove nullability from parameter
  • In Application:
    • Always load .env files (previously, they were only loaded when running from source)
    • Write console messages to STDERR when running on the command line (previously, warnings and errors were written to STDERR and everything else was written to STDOUT by default)
    • Retrieve application name from configuration value "app.name" before falling back to script basename
    • Only stop cache and sync store instances started by the container

Removed

Cli

  • Remove redundant CliApplicationInterface methods reportVersion() and getVersionString()

Console

  • Remove ConsoleInterface methods:
    • getFormatter() (retrieve via getTtyTarget())
    • getWidth() (retrieve via getTtyTarget())
    • printStderr() (unused)
  • Remove FormatterInterface::withSpinnerState()
  • Remove StreamTargetInterface::getEol()
  • Remove StreamTarget::fromStream() in favour of a public constructor
  • Remove unused StreamTarget method getPath()

Container

  • Remove unused unbind() method
  • Remove implementation-specific resumeCache() method from ApplicationInterface
  • Remove implementation-specific arguments from startSync() method in ApplicationInterface

Fixed

Console

  • Fix issue where $msg2 is not indented when prefix width is 2
  • Fix issue where trailing carriage returns may not be preserved in LoopbackFormat, ManPageFormat and MarkdownFormat

Container

  • Fix issue where calling bind() with $class = null does not replace an existing binding to a different class
  • Fix issue where parameter bindings only work for untyped and scalar constructor parameters
  • Fix issue where objects cannot be bound to constructor parameters via contextual bindings
  • Fix addContextualBinding() issue where $class cannot be null
  • Fix inContextOf() issue where contextual callbacks are not used
  • Fix issue where Application::logOutput() can be called repeatedly

Core

  • Fix issue where methods that return $this from behind a facade return a facade-bound instance

Security

Console

  • Fix issue where StreamTarget::reopen() may not apply file permissions correctly in some log rotation scenarios

v0.99.77

04 Mar 10:23
v0.99.77
3ab8b11
Compare
Choose a tag to compare

Added

Utility

  • Add Reflect::getAllTraits(), with optional recursion into parents
  • Add Reflect::isMethodInClass()

Changed

PHPStan

  • Ignore static properties and properties ImmutableTrait methods cannot access in ImmutableTraitReadWritePropertiesExtension
  • Improve array argument unpacking in ArrExtendReturnTypeExtension, GetCoalesceReturnTypeExtension and StrCoalesceReturnTypeExtension

Utility

  • Optionally recurse into traits in Reflect::getTraitMethod()

Fixed

PHPStan

  • In ImmutableTraitRule:
    • Fix issue where inaccessible properties may not be reported
    • Fix issue where calls to ImmutableTrait methods are not detected when they override inherited methods or when ImmutableTrait is inserted by another trait
  • Fix ArrWhereNotNullReturnTypeExtension and ArrWhereNotEmptyReturnTypeExtension issues where:
    • iterable types may be returned
    • invalid key types may be returned
    • variadic arguments are not unpacked
  • Fix GetCoalesceRule issue where calls to Get::coalesce() are matched case-sensitively

Testing

  • Fix issue where MockTarget::write() may fail to write long messages to the (optional) underlying stream

v0.99.76

26 Feb 03:28
v0.99.76
a8ece0e
Compare
Choose a tag to compare

Added

Http

  • Add and implement exception interfaces:
    • HttpException
    • InvalidHeaderException
    • StreamException
    • StreamEncapsulationException

Sli

  • Add --constructor option to "generate builder" command

Changed

  • Rename methods across all Http and Curler classes:
    • getFirstHeaderLine() -> getFirstHeaderValue()
    • getLastHeaderLine() -> getLastHeaderValue()
    • getOneHeaderLine() -> getOnlyHeaderValue()

Collection

  • Extend Traversable instead of IteratorAggregate from CollectionInterface so inheritors can implement Iterator
  • Allow CollectionInterface::map() to return a collection of items of a different type
  • Return static<TKey|int,TValue> from CollectionInterface methods that add items without explicit keys

Core

  • Add $preserveKeys parameter to Arrayable::toArray()

Curler

  • In Curler (and CurlerInterface, if applicable):
    • Simplify __construct() and include it in the API
    • Don't replace user agent headers by default
    • Add hasUserAgent() method
    • In getPublicHttpHeaders(), always treat access token headers as sensitive
    • Only call Console::debug() if the global console service is loaded
    • Rename methods:
      • getCacheStore() -> getCache()
      • withCacheStore() -> withCache()
  • Rename event-related abstractions for consistency with exceptions:
    • CurlEventInterface -> CurlEvent
    • CurlRequestEventInterface -> CurlRequestEvent
    • CurlResponseEventInterface -> CurlResponseEvent
    • CurlerEventInterface -> CurlerEvent
    • ResponseCacheHitEventInterface -> ResponseCacheHitEvent
    • AbstractCurlerEvent -> CurlerEvent
    • AbstractCurlEvent -> CurlEvent

Iterator

  • Rename FluentIteratorInterface::nextWithValue() to getFirstWith()
  • In FluentIteratorTrait::getFirstWith():
    • Check properties exist before accessing them
    • Do not move to the next element after finding a match
  • Rename RecursiveFilesystemIterator to FileIterator and refactor
    • Return files and directories by default (previous behaviour was to return files, not directories)
    • Remove optional parameters and adopt one callback signature
    • Rename methods:
      • noDirs() -> files() (the previous files() method has been removed)
      • noFiles() -> directories()
      • matchRelative() -> relative()
      • doNotMatchRelative() -> notRelative()

Utility

  • In Get::array() and Get::list(), prefer iterator_to_array() when value is both Traversable and Arrayable
  • In Get::list() and Get::count(), use $preserveKeys = false with Arrayable values instead of array_values()

Removed

Iterator

  • Remove FileIterator methods dirs() and files()
  • Remove redundant FluentIteratorInterface::forEach() method
  • Remove unused MutableIterator interface
  • Remove unused MutableGraphIterator class
  • Remove unused RecursiveMutableGraphIterator class
  • Remove unnecessary RecursiveGraphIteratorTrait

v0.99.75

22 Feb 06:44
v0.99.75
7526e85
Compare
Choose a tag to compare

Achieved with the changes detailed below:

  • Completion of Core API review
  • Cleaner access to constants via classes that implement their interfaces
  • Progress towards decoupling the Core component from Container
  • Progress towards rewritten "sli generate" commands

Added

Core

  • Add Serializable interface
  • Add, implement and adopt InvalidDataException
  • Add, implement and adopt EventDispatcherInterface and EventListenerProviderInterface
  • Add Builder::getStaticConstructor() to allow use of a static method for instantiation instead of the constructor
  • Add MetricCollector::getMaxTimers() to provide maximum number of timers running simultaneously per group

Utility

  • Add File::eof() and File::select()
  • Add File::getIndentation()
  • Add Inflect::list(), with optional Oxford comma support
  • Add Reflect::getDeclaring(), Reflect::getFileName() and getNamespaceName()

Changed

  • Rename exception interfaces to reduce verbosity
  • Move Indentation to Salient\Utility\Support
  • Move MimeType to Salient\Contract\Http
  • Move SqlQuery to Salient\Db

Cache

  • Treat DateInterval TTLs like integers, i.e. delete the item if TTL is <= 0 seconds

Console

  • Rename:
    • ConsoleWriterInterface -> ConsoleInterface
    • ConsoleWriter -> Console
    • ConsoleMessageType -> HasMessageType
    • ConsoleMessageTypeGroup -> HasMessageTypes
  • Implement HasMessageLevel, HasMessageLevels, HasMessageType and HasMessageTypes from the Console facade

Core

  • Rename:
    • AbstractBuilder -> Builder
    • AbstractFacade -> Facade and move to Salient\Core\Facade
    • AbstractStore -> Store
    • AbstractStreamWrapper -> StreamWrapper
    • AbstractException -> Exception and move to Salient\Core\Exception
    • AbstractMultipleErrorException -> MultipleErrorException and move to Salient\Core\Exception
    • HasBuilder -> BuildableTrait
    • HasChainableMethods -> ChainableTrait
    • HasFacade -> FacadeAwareInstanceTrait
    • HasMutator -> ImmutableTrait
    • HasNormaliser -> NormalisableTrait
    • HasReadableProperties -> ReadableTrait
    • HasWritableProperties -> WritableTrait
    • JsonSchemaInterface -> HasJsonSchema
    • Process methods:
      • getText() -> getOutputAsText()
      • getNewText() -> getNewOutputAsText()
    • ProvidableEntityInterface -> ProviderEntityInterface and move to Salient\Core\Entity
    • ReadsProtectedProperties -> ReadableProtectedPropertiesTrait
    • SerializeRulesInterface methods:
      • getIncludeMeta() -> getDynamicProperties()
      • withIncludeMeta() -> withDynamicProperties()
    • UnloadsFacades -> FacadeAwareTrait
  • Rename, move to Salient\Contract and update constants:
    • EscapeSequence -> HasEscapeSequence
    • FileDescriptor -> HasFileDescriptor
    • ListConformity -> HasConformity
    • MessageLevel -> HasMessageLevel
    • MessageLevelGroup -> HasMessageLevels
    • TextComparisonAlgorithm -> HasTextComparisonFlag
    • TextComparisonFlag -> HasTextComparisonFlag
  • Move:
    • StoppableEventInterface -> Salient\Contract\Core\Event
    • EventDispatcher -> Salient\Core\Event
    • StoppableEventTrait -> Salient\Core\Event
    • FacadeInterface -> Salient\Contract\Core\Facade
    • FacadeAwareInterface -> Salient\Contract\Core\Facade
    • ArrayMapperInterface -> Salient\Contract\Core\Pipeline
    • DateFormatter -> Salient\Core\Date
    • DateFormatParser -> Salient\Core\Date
    • DateParser -> Salient\Core\Date
    • DotNetDateParser -> Salient\Core\Date
    • Providable -> Salient\Core\Entity
    • SerializeRulesInterface -> Salient\Core\Entity
    • ExceptionTrait -> Salient\Core\Exception
    • MultipleErrorExceptionTrait -> Salient\Core\Exception
    • AbstractEntity -> Salient\Core\Provider
    • AbstractProvider -> Salient\Core\Provider
    • ProviderContext -> Salient\Core\Provider
  • Don't accept a container when creating a builder (builders are tightly coupled with constructors, so no container is needed)
  • In Facade, only use Container if it is defined
  • Detect date properties and parameters via native type hints even if Temporal is not implemented
  • Refactor Facade::getService() for simplicity
  • Narrow Hierarchical return types to $this as needed
  • Refactor Normalisable::normaliseProperty() for clarity
  • Make $context a required parameter of Providable methods provide() and provideMultiple() and remove $provider accordingly
  • Refactor Providable::provideMultiple() for consistency with Constructible
  • Improve uninitialised property handling in TreeableTrait
  • Replace ConfigurationManager::getMany() with getMultiple()
  • Extend DateParserInterface from DateFormatterInterface
  • In DateParserInterface::parse(), specify that $timezone is ignored if $value has a timezone and update implementations accordingly
  • Deregister ErrorHandler when the facade it's running behind is unloaded
  • In MultipleErrorException:
    • Rename getMessageWithoutErrors() to getMessageOnly()
    • Add $console parameter to reportErrors()
  • In Process:
    • Improve robustness of stream handling
    • Always throw ProcessTerminatedBySignalException when a process is killed, not just when wait() is called
    • Add and throw ProcessDidNotTerminateException
    • Do not throw ProcessException for stream-related errors
  • Add ClassReflection and adopt instead of Introspector and IntrospectionClass where possible
    • Fix issue where reserved properties are ignored when getting "magic" properties
    • Fix issue where properties with asymmetric handling are not serialized, e.g. when a protected property is read via __get() and written via _setMyProperty()
    • Do not allow multiple properties or "magic" property methods to resolve to the same name after normalisation
    • Do not allow dynamic property properties to be serviced by "magic" property methods
    • Do not allow Treeable classes to return invalid parent/children properties

PHPDoc

  • Collect and propagate context data to allow expansion of relative class types like static, $this and self

PHPStan

  • Preserve key types when $preserveKeys = true is passed to Arr::flatten()
  • Handle optional keys in arrays passed to Arr::flatten()

Sli

  • Refactor "generate facade" command
    • Add new options:
      • --implement <interface>
      • --skip-deprecated (previous behaviour was to skip deprecated methods unconditionally)
    • Exclude @internal methods from facades
  • Build out PHPDoc tag handling and other abstractions in AbstractGenerateCommand

Sync

  • Extend ClassReflection from Reflection classes
  • Rename Reflection classes for consistency
  • Refactor SyncSerializeRulesInterface for consistency with SerializeRulesInterface
  • Rename SyncSerializeRulesInterface methods:
    • getIncludeCanonicalId() -> getCanonicalId()
    • withIncludeCanonicalId() -> withCanonicalId()
  • Rename SyncSerializeRulesBuilder methods:
    • includeMeta() -> dynamicProperties()
    • includeCanonicalId() -> canonicalId()
  • Do not extend AbstractEntity from AbstractSyncEntity
  • Remove Temporal from SyncEntityInterface and implement it in AbstractSyncEntity
  • Refactor SyncEntityProviderInterface::getResolver() and downstream implementations
    • Accept closures for $nameProperty and $weightProperty
    • Require $nameProperty closures to return string
    • Handle uninitialised properties and invalid values gracefully

Utility

  • Optionally preserve keys in Arr::pluck(), Arr::flatten() and Reflect::getNames()
  • In Test::isBuiltinType(), optionally exclude relative class types and/or the resource type, and remove soft-reserved types enum and numeric entirely

Removed

Core

  • Remove getB(), issetB(), unsetB() from BuilderInterface (implementation details are not needed in the contract)
  • Remove unused Exception::withExitStatus() method
  • Remove MultipleErrorExceptionTrait::getMetadata() to prevent errors being reported twice
  • Remove GraphInterface from API
  • Remove NormaliserFlag
  • Remove unused PipeInterface and related code
  • Remove unused Process::isTerminatedBySignal()
  • Remove unused WritesProtectedProperties trait
  • Remove date formatter caching from AbstractProvider
    • Remove final from AbstractProvider::getDateFormatter() and replace with a default implementation
    • Deprecate AbstractProvider::createDateFormatter() and make it final to force downstream implementation updates

PHPDoc

  • Remove $trackInheritance parameter from PHPDoc::forClass()

Sli

  • Remove support for setting properties via generated builders

Utility

  • Remove Indentation::from() (replaced with File::getIndentation())

Fixed

Core

  • Fix issue where a deregistered ErrorHandler cannot be re-registered and may still report errors on shutdown
  • Fix issue where multiple calls to ErrorHandler::deregister() may remove other error/exception handlers
  • Fix issue where timeout behaviour may be incorrect after calling Process::setTimeout()

PHPDoc

  • Do not inherit DocBlocks from private members of inherited classes
  • Fix issue where empty template maps are needlessly inherited

Utility

  • Fix Date::maybeSetTimezone() issue where +00:00, the timezone applied when timestamps are parsed, is not handled correctly
  • Add missing int<1,max> type to tab size in Indentation

v0.99.74

29 Jan 00:28
v0.99.74
78f33f4
Compare
Choose a tag to compare

Fixed

Utility

  • Fix regression in Str::expandLeadingTabs() where the indentation of the second line may be incorrect when $preserveLine1 is true

v0.99.73

28 Jan 12:22
v0.99.73
e409aa4
Compare
Choose a tag to compare

Changed

Utility

  • Rename Arr::isIndexed() to hasNumericKeys()
  • Make Date::immutable() argument optional
  • In Str::expandTabs() and expandLeadingTabs(), add support for strings with two or more different end-of-line sequences
  • In Str::expandLeadingTabs(), add support for an arbitrary combination of tabs and spaces at the start of each line

v0.99.72

27 Jan 06:15
v0.99.72
6ec6bc9
Compare
Choose a tag to compare

Added

Cli

  • Add overridable CliCommand::canRunAsRoot() method and fail with an exception if it returns false when running as root

Utility

  • Add Package::isInstalled() to public API
  • Add Sys::isRunningAsRoot()

Changed

Utility

  • Rename Json::stringify() to encode()
  • Rename Json::parseObjectAsArray to objectAsArray()
  • Rename Regex::quoteCharacterClass() to quoteCharacters()

Fixed

Cli

  • Fix issue where CliApplication::getVersionString() returns values like app dev-ef08c76d7c0e5563080e1276bccd2ca666ed85d8 (ef08c76d) PHP 8.3.6

Utility

  • Fix Get::copy() issue where private property values are not copied correctly if an extending class has a property with the same name
  • Fix Reflect::getAllProperties() issue where private properties in parent classes are not returned if an inheriting class has a property with the same name
  • Fix issue where Package::getPackagePath() doesn't use File::realpath() to return the canonical path
  • Fix issue where package versions like dev-ef08c76d7c0e...@ef08c76d may be returned

Security

Cli

  • Allow applications to run as root
  • Don't allow commands to run as root by default (see above)

v0.99.71

24 Jan 05:06
v0.99.71
9242909
Compare
Choose a tag to compare

Added

Utility

  • Add File methods rename() and symlink()
  • Add Regex::quote() for completeness

Changed

Utility

  • Improve Regex pattern consistency and readability
  • Add non-capturing groups to Regex patterns as needed for atomicity and to limit the scope of case sensitivity changes
  • Don't match leading and trailing whitespace in Regex patterns BOOLEAN_STRING and INTEGER_STRING

Removed

Utility

  • Remove unused Regex patterns PHP_UNION_TYPE, PHP_INTERSECTION_TYPE, PHP_DNF_SEGMENT, PHP_DNF_TYPE and PHP_FULL_TYPE

Security

Utility

  • Apply umask by default in File::create() and createDir()

v0.99.70

23 Jan 12:47
v0.99.70
e3a89c1
Compare
Choose a tag to compare

Changed

  • Adopt ReflectionClass<*> instead of ReflectionClass<object> to work around T not being covariant on PHPStan 2.1.2 + PHP 8.4

Polyfill

  • Remove dependency on salient/utils

Fixed

Polyfill

  • Fix issue where PhpToken doesn't tokenize binary strings like b"$foo" correctly
  • Fix issue where PhpToken fails if salient/sli is not installed

Security

Utility

  • Optionally honour umask in File::create() and createDir()