Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
7452c08
fix(auth): rename PHPDoc templates to T-prefix convention
xHeaven Feb 14, 2026
b66c44a
refactor(auth): remove unused Database dependency
xHeaven Feb 14, 2026
dad865e
fix(auth): remove unnecessary null-safe operators
xHeaven Feb 14, 2026
9178703
fix(auth): correct OAuth scopes fallback and state handling
xHeaven Feb 14, 2026
1088b91
fix(support): add TDefault generic to Arr first/last
xHeaven Feb 14, 2026
17ec8d5
fix(cache): correct PHPDoc annotations in Cache interface
xHeaven Feb 14, 2026
1583b2f
refactor(cache): remove unused dependency and redundant code
xHeaven Feb 14, 2026
59a710f
fix(cache): fix TestingCache property hook and add strict types
xHeaven Feb 14, 2026
20078aa
fix(cache): improve UserCacheInsightsProvider PHPDoc types
xHeaven Feb 14, 2026
f949a82
fix(support): add generic annotations to ManipulatesArray usage
xHeaven Feb 14, 2026
2854134
fix(support): improve type safety in Arr functions
xHeaven Feb 14, 2026
90f2977
fix(support): improve generic type annotations in Arr functions
xHeaven Feb 14, 2026
21a6cb1
refactor(command-bus): remove unused Console dependency
xHeaven Feb 14, 2026
e7bc174
fix(console): correct Process callback signature in TaskComponent
xHeaven Feb 14, 2026
8c897e3
refactor(console): remove unused ConsoleCommand dependency
xHeaven Feb 14, 2026
bac710a
fix(console): correct PHPDoc and return type annotations
xHeaven Feb 14, 2026
70e1e25
refactor(console): simplify config stub files
xHeaven Feb 14, 2026
6a9eb9c
fix(console): remove redundant assertions in ShellTest
xHeaven Feb 14, 2026
6c3dd18
refactor(phpstan): update baseline and config
xHeaven Feb 15, 2026
fb23b8f
chore: update phpstan command
xHeaven Feb 15, 2026
fa03110
refactor(container): add missing final keyword to fixtures
xHeaven Feb 15, 2026
f2c6112
refactor(auth): add mago-expect for test
xHeaven Feb 15, 2026
2f68586
refactor: extract class constants into backed enum
xHeaven Feb 15, 2026
f1137a7
refactor(core): remove unused Environment dependency
xHeaven Feb 15, 2026
c2ae59c
fix(core): correct PHPDoc type annotation
xHeaven Feb 15, 2026
3041dba
chore(phpstan): add container and core to scan paths
xHeaven Feb 15, 2026
55222f9
chore(phpstan): add cryptography to scan paths
xHeaven Feb 15, 2026
5e5e555
refactor(cryptography): fix PHPStan issues in tests
xHeaven Feb 15, 2026
821c429
chore(phpstan): add datetime to scan paths and disallow ld/lw
xHeaven Feb 15, 2026
8fd3e25
refactor(datetime): fix incorrect @throws on convenience methods
xHeaven Feb 15, 2026
dad2a58
fix(datetime): handle IntlCalendar edge cases for extreme year values
xHeaven Feb 15, 2026
d6e4aa8
chore(phpstan): update baseline for datetime runtime guards
xHeaven Feb 15, 2026
1ed06b0
refactor(debug): remove unused Highlighter dependency
xHeaven Feb 15, 2026
8f2a8ee
fix(debug): remove incompatible assertion in StacktraceTest
xHeaven Feb 15, 2026
ef7c074
chore(phpstan): add debug to scan paths and baseline
xHeaven Feb 15, 2026
2529df6
chore(phpstan): generalize Testing path exclusion in baseline
xHeaven Feb 15, 2026
7f356b9
refactor(event-bus): decouple FakeEventBus from GenericEventBus
xHeaven Feb 15, 2026
73c2fab
fix(event-bus): add missing type annotation in test
xHeaven Feb 15, 2026
3db2f52
chore(phpstan): add discovery and event-bus to scan paths
xHeaven Feb 15, 2026
02a688e
chore(phpstan): add generation to scan paths
xHeaven Feb 15, 2026
1023124
fix(generation): remove unnecessary phpstan-ignore annotations
xHeaven Feb 15, 2026
cc7aeab
fix(generation): correct type annotations in TypeScriptOutput
xHeaven Feb 15, 2026
6b7b780
fix(generation): add map for scalar types
xHeaven Feb 15, 2026
b078b59
chore(phpstan): add http to scan paths
xHeaven Feb 15, 2026
3ef3bfb
fix(http): correct type annotation in IsRequest::accepts
xHeaven Feb 15, 2026
c4bc9ca
fix(http): fix Cookie phpdoc, nullability, and parsing
xHeaven Feb 15, 2026
6a529e6
refactor(http): use FileSessionConfig in FileSessionManager
xHeaven Feb 15, 2026
cb2b086
chore(http): add todo
xHeaven Feb 15, 2026
0374134
chore(phpstan): add http-client, icon, and kv-store to scan paths
xHeaven Feb 15, 2026
59ee2e0
fix(icon): add type annotation for cache failure check
xHeaven Feb 15, 2026
cae26e4
fix(kv-store): add default arm to RedisExtensionWasMissing match
xHeaven Feb 15, 2026
56e1aa0
fix(kv-store): remove unnecessary array_filter in PredisClientTest
xHeaven Feb 15, 2026
8f56dd9
feat(kv-store): add persistentId option to RedisConfig
xHeaven Feb 15, 2026
0d17e70
fix(log): add missing LogChannel import to config PHPDocs
xHeaven Feb 15, 2026
fd7caac
fix(log): add missing $channels property to SlackLogConfig
xHeaven Feb 15, 2026
2f1f84e
fix(log): remove dead null coalesce on non-nullable $maxFiles
xHeaven Feb 15, 2026
ce05572
chore(phpstan): add log to scan paths
xHeaven Feb 15, 2026
1801351
chore(phpstan): add mail to scan paths
xHeaven Feb 15, 2026
0938510
fix(mail): correct PHPDoc type for MailerConfig::$transport
xHeaven Feb 15, 2026
243e8d2
fix(mail): add Attachment[] type to GenericEmail
xHeaven Feb 15, 2026
a6c3d91
fix(mail): remove nullsafe call on non-nullable EventBus
xHeaven Feb 15, 2026
75d5427
fix(mail): remove dead code in MailTester
xHeaven Feb 15, 2026
b1855d3
fix(mail): collapse redundant match arms in address helpers
xHeaven Feb 15, 2026
2aedd4c
fix(mail): add default arm to SMTP scheme match
xHeaven Feb 15, 2026
d141786
chore(phpstan): add mapper to scan paths
xHeaven Feb 15, 2026
3fcc0ae
fix(mapper): remove unused closure variable
xHeaven Feb 15, 2026
6e915bf
fix(mapper): correct @var annotation in ObjectFactory
xHeaven Feb 15, 2026
6d3cf07
fix(mapper): fix return type and PHPDoc in SerializerFactory
xHeaven Feb 15, 2026
a5141f2
fix(reflection): narrow EnumReflector and TypeReflector types
xHeaven Feb 15, 2026
7fa31f4
test(reflection): add EnumReflector constructor tests
xHeaven Feb 15, 2026
6f3eeef
fix(reflection): make TestAttribute class final
xHeaven Feb 15, 2026
9524b2a
chore(phpstan): add reflection to scan paths
xHeaven Feb 15, 2026
c59c2c4
fix(router): use native Throwable extension in ConvertsToResponse
xHeaven Feb 15, 2026
579ea51
fix(router): guard TEMPEST_START constant in DevelopmentException
xHeaven Feb 15, 2026
4f9c2ef
fix(router): check container before resolving MatchedRoute
xHeaven Feb 15, 2026
86d016e
fix(router): correct type annotations on without property
xHeaven Feb 15, 2026
3d80955
fix(router): remove unused RouteConfig and nullsafe access
xHeaven Feb 15, 2026
9cf1d00
fix(router): pass correct arity to controllerNotFound()
xHeaven Feb 15, 2026
a749193
chore(phpstan): add router to scan paths
xHeaven Feb 15, 2026
3f307de
chore(phpstan): add storage to scan paths
xHeaven Feb 15, 2026
31aee6f
fix(storage): update Azure adapter for new SDK API
xHeaven Feb 15, 2026
1cfde88
chore(phpstan): add support to scan paths
xHeaven Feb 15, 2026
9f4adee
fix(support): align removeValues and hasValue types
xHeaven Feb 15, 2026
0d20b01
fix(support): remove dead code in create_temporary_directory
xHeaven Feb 15, 2026
be37159
refactor(support): decouple debug methods from debug package
xHeaven Feb 15, 2026
6ab1fb4
fix(console): use hasKey for duplicate command detection
xHeaven Feb 15, 2026
35c439a
chore(phpstan): baseline exec() and phar require_once
xHeaven Feb 15, 2026
8c712e8
chore(phpstan): add validation to scan paths
xHeaven Feb 15, 2026
e72548f
fix(validation): correct PHPDoc types on Validator
xHeaven Feb 15, 2026
8002524
chore(phpstan): baseline IsEnum test type mismatch
xHeaven Feb 15, 2026
d7b925b
refactor(tests): use specific assertions in mapper tests
xHeaven Feb 15, 2026
2465383
fix(mapper): use configured format in DateTimeCaster
xHeaven Feb 15, 2026
749c97c
chore(phpstan): add view package to scan paths
xHeaven Feb 15, 2026
877c997
fix(view): remove dead PhpDataElement class
xHeaven Feb 15, 2026
733ad87
fix(view): resolve phpstan errors in view package
xHeaven Feb 15, 2026
dde7961
chore(phpstan): add vite packages to scan paths
xHeaven Feb 15, 2026
12dea15
fix(support): allow non-void return in Arr each() callback
xHeaven Feb 15, 2026
828e43f
fix(view): remove stale phpstan-ignore-next-line comments
xHeaven Feb 15, 2026
e886878
fix(process): resolve phpstan errors in process package
xHeaven Feb 15, 2026
b1663ac
chore(phpstan): add process package to scan paths
xHeaven Feb 15, 2026
66a1c75
chore(phpstan): baseline ProcessTester assertTrue calls
xHeaven Feb 15, 2026
a43cdf9
fix(upgrade): match Rector refactor() return type contract
xHeaven Feb 15, 2026
28d1088
fix(upgrade): remove disallowed dd() from RectorTester
xHeaven Feb 15, 2026
881f8c0
chore(phpstan): add upgrade package to scan paths
xHeaven Feb 15, 2026
51964d3
refactor(support): improve generics
xHeaven Feb 15, 2026
586115e
fix(intl): add missing imports for AST node types
xHeaven Feb 15, 2026
9f407ad
fix(intl): resolve type issues in MessageFormatter
xHeaven Feb 15, 2026
12275b2
fix(intl): fix parser optional check and catalog type
xHeaven Feb 15, 2026
120f196
fix(intl): cast exponent to int for array key usage
xHeaven Feb 15, 2026
0ebdf78
fix(intl): fix tests to use correct AST types
xHeaven Feb 15, 2026
561d0c8
fix(intl): generate type-safe plural rules matcher
xHeaven Feb 15, 2026
d5d55e5
chore(phpstan): add intl package to scan paths
xHeaven Feb 15, 2026
f14be46
style(support): reformat
xHeaven Feb 15, 2026
72be108
feat(phpstan): make phpstan understand Lazy and Inject
xHeaven Feb 15, 2026
adf2ff9
test(datetime): remove flaky tests
xHeaven Feb 15, 2026
492c1de
test(view): add a regression test for dynamic view component scoping
xHeaven Feb 16, 2026
96a3651
fix(database): narrow serializer return types to string
xHeaven Feb 16, 2026
6a75146
fix(database): fix return types
xHeaven Feb 16, 2026
5864ced
fix(database): add config property to Connection interface
xHeaven Feb 16, 2026
18bbd3d
fix(database): remove dead code in migration handling
xHeaven Feb 16, 2026
706a3d7
fix(database): fix property hook and redundant cast
xHeaven Feb 16, 2026
bb1c2f6
fix(database): fix type errors in SelectStatement::compile
xHeaven Feb 16, 2026
b739f4a
fix(database): fix where-clause mutations and generic types
xHeaven Feb 16, 2026
a0745d4
fix(database): preserve generic types
xHeaven Feb 16, 2026
96cd9e1
fix(database): narrow ask() result
xHeaven Feb 16, 2026
ad8b4ad
fix(database): fix callable PHPDoc
xHeaven Feb 16, 2026
adb5316
chore(phpstan): enable database package in analysis
xHeaven Feb 16, 2026
3dd61e9
fix: lock phpstan until fixed
xHeaven Feb 16, 2026
c5be004
refactor(database): add appendWhere helper
xHeaven Feb 16, 2026
6fdbebb
fix(database): improve generics
xHeaven Feb 16, 2026
a6d8b1f
test(database): add generics assertions
xHeaven Feb 16, 2026
1342663
refactor(database): improve more generics
xHeaven Feb 16, 2026
06302c7
refactor(database): improve generics for strings passed to query()
xHeaven Feb 16, 2026
a6aa54a
refactor(database): remove DatabaseConfig from Connection interface
xHeaven Feb 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0|^2.0",
"psr/log": "^3.0.0",
"rector/rector": "^2.3.2",
"rector/rector": "2.3.1",
"symfony/cache": "^7.3",
"symfony/filesystem": "^7.3",
"symfony/mailer": "^7.2.6",
Expand Down Expand Up @@ -74,7 +74,7 @@
"patrickbussmann/oauth2-apple": "^0.3",
"phpat/phpat": "^0.11.0",
"phpbench/phpbench": "84.x-dev",
"phpstan/phpstan": "2.1.38",
"phpstan/phpstan": "2.1.33",
"phpunit/phpunit": "^12.5.8",
"predis/predis": "^3.0.0",
"riskio/oauth2-auth0": "^2.4",
Expand Down Expand Up @@ -253,7 +253,7 @@
"test": "composer phpunit",
"test:stop": "composer phpunit -- --stop-on-error --stop-on-failure",
"lint": "vendor/bin/mago lint --potentially-unsafe --minimum-fail-level=note",
"phpstan": "vendor/bin/phpstan analyse src tests --memory-limit=1G",
"phpstan": "vendor/bin/phpstan analyse --memory-limit=1G",
"rector": "vendor/bin/rector process --no-ansi",
"merge": "php -d\"error_reporting = E_ALL & ~E_DEPRECATED\" vendor/bin/monorepo-builder merge",
"intl:plural": "./packages/intl/bin/plural-rules.php",
Expand Down
15 changes: 7 additions & 8 deletions packages/auth/src/AccessControl/AccessControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

namespace Tempest\Auth\AccessControl;

use Tempest\Auth\Exceptions\AccessWasDenied;
use UnitEnum;

/**
* @template Subject of object
* @template Resource of object
* @template TSubject of object
* @template TResource of object
*/
interface AccessControl
{
/**
* Checks if the action is granted for the given resource and subject. If not, an exception is thrown.
*
* @template Resource of object
* @param UnitEnum|string $action An arbitrary action to check access for, e.g. 'view', 'edit', etc.
* @param Resource|class-string<Resource> $resource A model instance or class string of a model to check access for.
* @param null|Subject $subject An optional subject to check access against, e.g. a user or service account.
* @param TResource|class-string<TResource> $resource A model instance or class string of a model to check access for.
* @param null|TSubject $subject An optional subject to check access against, e.g. a user or service account.
*
* @throws AccessWasDenied
*/
Expand All @@ -25,10 +25,9 @@ public function ensureGranted(UnitEnum|string $action, object|string $resource,
/**
* Checks if the action is granted for the given resource and subject.
*
* @template Resource of object
* @param UnitEnum|string $action An arbitrary action to check access for, e.g. 'view', 'edit', etc.
* @param Resource|class-string<Resource> $resource A model instance or class string of a model to check access for.
* @param null|Subject $subject An optional subject to check access against, e.g. a user or service account.
* @param TResource|class-string<TResource> $resource A model instance or class string of a model to check access for.
* @param null|TSubject $subject An optional subject to check access against, e.g. a user or service account.
*/
public function isGranted(UnitEnum|string $action, object|string $resource, ?object $subject = null): AccessDecision;
}
12 changes: 5 additions & 7 deletions packages/auth/src/AccessControl/PolicyBasedAccessControl.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
use UnitEnum;

/**
* @template Subject of object
* @template Resource of object
* @implements AccessControl<Subject, Resource>
* @template TSubject of object
* @template TResource of object
* @implements AccessControl<TSubject, TResource>
*/
final readonly class PolicyBasedAccessControl implements AccessControl
{
Expand Down Expand Up @@ -119,11 +119,9 @@ private function ensureParameterAcceptsInput(?ParameterReflector $reflector, mix
return;
}

if (! ($type = $reflector?->getType())) {
return;
}
$type = $reflector->getType();

if ($type?->accepts($input)) {
if ($type->accepts($input)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
use Tempest\Container\Container;
use Tempest\Container\Initializer;
use Tempest\Container\Singleton;
use Tempest\Database\Database;

final class AuthenticatableResolverInitializer implements Initializer
{
#[Singleton]
public function initialize(Container $container): AuthenticatableResolver
{
return new DatabaseAuthenticatableResolver(
database: $container->get(Database::class),
);
return new DatabaseAuthenticatableResolver();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,15 @@

use Tempest\Auth\Exceptions\AuthenticatableModelWasInvalid;
use Tempest\Auth\Exceptions\ModelWasNotAuthenticatable;
use Tempest\Database\Database;

use function Tempest\Database\inspect;
use function Tempest\Database\query;

final readonly class DatabaseAuthenticatableResolver implements AuthenticatableResolver
{
public function __construct(
private Database $database,
) {}

public function resolve(int|string $id, string $class): ?Authenticatable
{
if (! is_a($class, Authenticatable::class, allow_string: true)) {
throw new ModelWasNotAuthenticatable($class);
}
$this->ensureClassIsAuthenticatable($class);

return query($class)->findById($id);
}
Expand All @@ -40,4 +33,11 @@ public function resolveId(Authenticatable $authenticatable): int|string

return $id;
}

private function ensureClassIsAuthenticatable(string $class): void
{
if (! is_a($class, Authenticatable::class, allow_string: true)) {
throw new ModelWasNotAuthenticatable($class);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
final class ModelWasNotAuthenticatable extends Exception implements AuthenticationException
{
public function __construct(
private readonly string $class,
string $class,
) {
parent::__construct(
sprintf('`%s` must be an instance of `%s`', $class, Authenticatable::class),
Expand Down
21 changes: 18 additions & 3 deletions packages/auth/src/OAuth/GenericOAuthClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ public function __construct(

public function buildAuthorizationUrl(array $scopes = [], array $options = []): string
{
if ($scopes === []) {
$scopes = $this->config->scopes;
}

return $this->provider->getAuthorizationUrl([
'scope' => $scopes ?? $this->config->scopes,
'scope' => $scopes,
'redirect_uri' => $this->uri->createUri($this->config->redirectTo),
...$options,
]);
Expand All @@ -71,16 +75,27 @@ public function createRedirect(array $scopes = [], array $options = []): Redirec

public function getState(): ?string
{
return $this->provider->getState();
return $this->provider->getState() ?: null;
}

public function requestAccessToken(string $code): AccessToken
{
try {
return $this->provider->getAccessToken('authorization_code', [
$token = $this->provider->getAccessToken('authorization_code', [
'code' => $code,
'redirect_uri' => $this->uri->createUri($this->config->redirectTo),
]);

if ($token instanceof AccessToken) {
return $token;
}

return new AccessToken([
...$token->getValues(),
'access_token' => $token->getToken(),
'refresh_token' => $token->getRefreshToken(),
'expires' => $token->getExpires(),
]);
} catch (IdentityProviderException $exception) {
throw OAuthTokenCouldNotBeRetrieved::fromProviderException($exception);
}
Expand Down
2 changes: 0 additions & 2 deletions packages/auth/src/OAuth/OAuthClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ public function fetchUser(AccessToken $token): OAuthUser;
/**
* Authenticates a user based on the given OAuth callback request.
*
* @template T of Authenticatable
*
* @param Closure(OAuthUser): T $map A callback that should return an authenticatable model from the given OAuthUser. Typically, the callback is also responsible for saving the user to the database.
*/
public function authenticate(Request $request, Closure $map): Authenticatable;
Expand Down
49 changes: 49 additions & 0 deletions packages/auth/tests/AuthenticationAndOAuthSafetyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Tempest\Auth\Tests;

use League\OAuth2\Client\Provider\GenericProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use ReflectionClass;
use ReflectionMethod;
use Tempest\Auth\Authentication\DatabaseAuthenticatableResolver;
use Tempest\Auth\Exceptions\ModelWasNotAuthenticatable;
use Tempest\Auth\OAuth\GenericOAuthClient;

final class AuthenticationAndOAuthSafetyTest extends TestCase
{
#[Test]
public function database_authenticatable_resolver_rejects_non_authenticatable_classes(): void
{
$resolver = new DatabaseAuthenticatableResolver();
$resolve = new ReflectionMethod($resolver, 'resolve');

$this->expectException(ModelWasNotAuthenticatable::class);

$resolve->invoke($resolver, 1, \stdClass::class);
}

#[Test]
public function generic_oauth_client_state_is_null_before_generating_authorization_url(): void
{
$provider = new GenericProvider([
'clientId' => 'client-id',
'clientSecret' => 'client-secret', // @mago-expect lint:no-literal-password
'redirectUri' => 'https://example.com/callback',
'urlAuthorize' => 'https://provider.test/authorize',
'urlAccessToken' => 'https://provider.test/token', // @mago-expect lint:no-literal-password
'urlResourceOwnerDetails' => 'https://provider.test/user',
]);

$reflection = new ReflectionClass(GenericOAuthClient::class);

/** @var GenericOAuthClient $client */
$client = $reflection->newInstanceWithoutConstructor();
$reflection->getProperty('provider')->setValue($client, $provider);

$this->assertNull($client->getState());
}
}
15 changes: 7 additions & 8 deletions packages/cache/src/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ public function put(Stringable|string $key, mixed $value, null|Duration|DateTime
/**
* Sets the specified keys to the specified values in the cache. Optionally, specify an expiration.
*
* @template TKey of array-key
* @template TKey of Stringable|string
* @template TValue
*
* @param iterable<TKey,TValue> $array
* @return array<TKey,CacheItemInterface>
* @param iterable<TKey,TValue> $values
* @return array<string,CacheItemInterface>
*/
public function putMany(iterable $values, null|Duration|DateTimeInterface $expiration = null): array;

Expand All @@ -53,11 +53,10 @@ public function get(Stringable|string $key): mixed;
/**
* Gets the values associated with the specified keys from the cache. If a key does not exist, null is returned for that key.
*
* @template TKey of array-key
* @template TValue
* @template TKey of Stringable|string
*
* @param iterable<TKey,TValue> $array
* @return array<TValue,mixed>
* @param iterable<array-key, TKey> $key
* @return array<string,mixed>
*/
public function getMany(iterable $key): array;

Expand All @@ -79,7 +78,7 @@ public function decrement(Stringable|string $key, int $by = 1): int;
/**
* If the specified key already exists in the cache, the value is returned and the `$callback` is not executed. Otherwise, the result of the callback is stored, then returned.
*
* @var null|Duration $stale Allow the value to be stale for the specified amount of time in addition to the time-to-live specified by `$expiration`. When a value is stale, it will still be returned as-is, but it will be refreshed in the background.
* @param null|Duration $stale Allow the value to be stale for the specified amount of time in addition to the time-to-live specified by `$expiration`. When a value is stale, it will still be returned as-is, but it will be refreshed in the background.
*/
public function resolve(Stringable|string $key, Closure $callback, null|Duration|DateTimeInterface $expiration = null, ?Duration $stale = null): mixed;

Expand Down
3 changes: 1 addition & 2 deletions packages/cache/src/Commands/CacheClearCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
private const string DEFAULT_CACHE = 'default';

public function __construct(
private Cache $cache,
private Container $container,
) {}

Expand Down Expand Up @@ -59,7 +58,7 @@ private function clearInternalCaches(bool $all = false): void
{
$caches = [ConfigCache::class, ViewCache::class, IconCache::class, DiscoveryCache::class];

if ($all === false && count($caches) > 1) {
if (! $all) {
$caches = $this->ask(
question: 'Which caches do you want to clear?',
options: $caches,
Expand Down
1 change: 0 additions & 1 deletion packages/cache/src/Commands/CacheStatusCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ public function __invoke(bool $internal = true): void

$this->console->header('User caches');

/** @var Cache $cache */
foreach ($caches as $cache) {
$this->console->keyValue(
key: $this->getCacheName($cache),
Expand Down
13 changes: 7 additions & 6 deletions packages/cache/src/InternalCacheInsightsProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Tempest\Core\DiscoveryCacheStrategy;
use Tempest\Core\Insight;
use Tempest\Core\InsightsProvider;
use Tempest\Core\InsightType;
use Tempest\Icon\IconCache;
use Tempest\View\ViewCache;

Expand All @@ -25,14 +26,14 @@ public function getInsights(): array
{
return [
'Discovery' => match ($this->discoveryCache->valid) {
false => new Insight('Invalid', Insight::ERROR),
false => new Insight('Invalid', InsightType::ERROR),
true => match ($this->discoveryCache->enabled) {
true => match ($this->discoveryCache->strategy) {
DiscoveryCacheStrategy::FULL => new Insight('Enabled', Insight::SUCCESS),
DiscoveryCacheStrategy::PARTIAL => new Insight('Enabled (partial)', Insight::SUCCESS),
DiscoveryCacheStrategy::FULL => new Insight('Enabled', InsightType::SUCCESS),
DiscoveryCacheStrategy::PARTIAL => new Insight('Enabled (partial)', InsightType::SUCCESS),
default => null, // INVALID and NONE are handled
},
false => new Insight('Disabled', Insight::WARNING),
false => new Insight('Disabled', InsightType::WARNING),
},
},
'Configuration' => $this->getInsight($this->configCache->enabled),
Expand All @@ -44,9 +45,9 @@ public function getInsights(): array
private function getInsight(bool $enabled): Insight
{
if ($enabled) {
return new Insight('ENABLED', Insight::SUCCESS);
return new Insight('ENABLED', InsightType::SUCCESS);
}

return new Insight('DISABLED', Insight::WARNING);
return new Insight('DISABLED', InsightType::WARNING);
}
}
10 changes: 7 additions & 3 deletions packages/cache/src/Testing/TestingCache.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

namespace Tempest\Cache\Testing;

use Closure;
Expand All @@ -18,9 +20,11 @@

final class TestingCache implements Cache
{
public bool $enabled {
get => $this->cache->enabled;
set => $this->cache->enabled = $value;
public bool $enabled = true {
set {
$this->cache->enabled = $value;
$this->enabled = $value;
}
}

private Cache $cache;
Expand Down
Loading
Loading