Skip to content
Snippets Groups Projects
Commit 0e4f41fd authored by Mateusz Charytoniuk's avatar Mateusz Charytoniuk
Browse files

feat: configuration variables

parent 82c93e2d
No related branches found
Tags v0.22.0
No related merge requests found
Showing
with 234 additions and 80 deletions
[app] [app]
env = development env = development
esbuild_metafile = esbuild-meta-app.json esbuild_metafile = %DM_ROOT%/esbuild-meta-app.json
scheme = https scheme = https
url = http://localhost:9501 url = http://localhost:9501
...@@ -15,6 +15,10 @@ default[log_queries] = false ...@@ -15,6 +15,10 @@ default[log_queries] = false
default[pool_prefill] = false default[pool_prefill] = false
default[pool_size] = 8 default[pool_size] = 8
[grpc]
grpc_php_plugin_bin = %DM_ROOT%/grpc_php_plugin
protoc_bin = /usr/bin/protoc
[llamacpp] [llamacpp]
host = 127.0.0.1 host = 127.0.0.1
port = 8081 port = 8081
...@@ -32,10 +36,10 @@ background_color = "#ffffff" ...@@ -32,10 +36,10 @@ background_color = "#ffffff"
theme_color = "#ffffff" theme_color = "#ffffff"
[oauth2] [oauth2]
encryption_key = oauth2/defuse.key encryption_key = %DM_ROOT%/oauth2/defuse.key
jwt_signing_key_passphrase = yourpassphrase jwt_signing_key_passphrase = yourpassphrase
jwt_signing_key_private = oauth2/private.key jwt_signing_key_private = %DM_ROOT%/oauth2/private.key
jwt_signing_key_public = oauth2/public.key jwt_signing_key_public = %DM_ROOT%/oauth2/public.key
session_key_authorization_request = oauth2.authorization_request session_key_authorization_request = oauth2.authorization_request
session_key_pkce = oauth2.pkce session_key_pkce = oauth2.pkce
session_key_state = oauth2.state session_key_state = oauth2.state
...@@ -61,25 +65,25 @@ cookie_name = dmsession ...@@ -61,25 +65,25 @@ cookie_name = dmsession
redis_connection_pool = default redis_connection_pool = default
[sqlite-vss] [sqlite-vss]
extension_vector0 = vector0.so extension_vector0 = %DM_ROOT%/vector0.so
extension_vss0 = vss0.so extension_vss0 = %DM_ROOT%/vss0.so
[static] [static]
base_url = https://resonance.distantmagic.com base_url = https://resonance.distantmagic.com
esbuild_metafile = esbuild-meta-docs.json esbuild_metafile = %DM_ROOT%/esbuild-meta-docs.json
input_directory = docs input_directory = docs
output_directory = docs/build output_directory = %DM_ROOT%/docs/build
sitemap = docs/build/sitemap.xml sitemap = %DM_ROOT%/docs/build/sitemap.xml
[swoole] [swoole]
host = 127.0.0.1 host = 127.0.0.1
port = 9501 port = 9501
log_level = SWOOLE_LOG_DEBUG log_level = SWOOLE_LOG_DEBUG
ssl_cert_file = ssl/origin.crt ssl_cert_file = %DM_ROOT%/ssl/origin.crt
ssl_key_file = ssl/origin.key ssl_key_file = %DM_ROOT%/ssl/origin.key
[translator] [translator]
base_directory = app/lang base_directory = %DM_APP_ROOT%/lang
default_primary_language = en default_primary_language = en
[websocket] [websocket]
......
...@@ -10,10 +10,15 @@ title: Changelog ...@@ -10,10 +10,15 @@ title: Changelog
# Changelog # Changelog
## v0.22.0
- Change: switch to absolute paths in {{docs/features/configuration/index}}
- Feature: interpolate some constants in {{docs/features/configuration/index}}
## v0.21.0 ## v0.21.0
- Feature: Doctrine {{docs/features/database/doctrine/events}} hooks - Feature: Doctrine {{docs/features/database/doctrine/events}} hooks
- Improvements: OpenAPI reads return types from `Can` - Improvement: OpenAPI reads return types from `Can`
{{docs/features/openapi/attributes/index}} {{docs/features/openapi/attributes/index}}
## v0.20.0 ## v0.20.0
......
...@@ -72,9 +72,9 @@ This is the default configuration file: ...@@ -72,9 +72,9 @@ This is the default configuration file:
```ini file:config.ini ```ini file:config.ini
[app] [app]
env = development env = development
esbuild_metafile = esbuild-meta-app.json esbuild_metafile = %DM_ROOT%/esbuild-meta-app.json
scheme = https scheme = https
url = https://resonance.distantmagic.com url = http://localhost:9501
[database] [database]
default[driver] = mysql default[driver] = mysql
...@@ -87,27 +87,31 @@ default[log_queries] = false ...@@ -87,27 +87,31 @@ default[log_queries] = false
default[pool_prefill] = false default[pool_prefill] = false
default[pool_size] = 8 default[pool_size] = 8
[grpc]
grpc_php_plugin_bin = %DM_ROOT%/grpc_php_plugin
protoc_bin = /usr/bin/protoc
[llamacpp] [llamacpp]
host = 127.0.0.1 host = 127.0.0.1
port = 8081 port = 8081
[mailer] [mailer]
default[transport_dsn] = smtp://localhost default[transport_dsn] = smtp://localhost
default[dkim_domain_name] = example.com ; default[dkim_domain_name] = example.com
default[dkim_selector] = resonance1 ; default[dkim_selector] = resonance1
default[dkim_signing_key_passphrase] = yourpassphrase ; default[dkim_signing_key_passphrase] = yourpassphrase
default[dkim_signing_key_private] = dkim/private.key ; default[dkim_signing_key_private] = dkim/private.key
default[dkim_signing_key_public] = dkim/public.key ; default[dkim_signing_key_public] = dkim/public.key
[manifest] [manifest]
background_color = "#ffffff" background_color = "#ffffff"
theme_color = "#ffffff" theme_color = "#ffffff"
[oauth2] [oauth2]
encryption_key = oauth2/defuse.key encryption_key = %DM_ROOT%/oauth2/defuse.key
jwt_signing_key_passphrase = yourpassphrase jwt_signing_key_passphrase = yourpassphrase
jwt_signing_key_private = oauth2/private.key jwt_signing_key_private = %DM_ROOT%/oauth2/private.key
jwt_signing_key_public = oauth2/public.key jwt_signing_key_public = %DM_ROOT%/oauth2/public.key
session_key_authorization_request = oauth2.authorization_request session_key_authorization_request = oauth2.authorization_request
session_key_pkce = oauth2.pkce session_key_pkce = oauth2.pkce
session_key_state = oauth2.state session_key_state = oauth2.state
...@@ -120,7 +124,7 @@ version = 0.0.0 ...@@ -120,7 +124,7 @@ version = 0.0.0
[redis] [redis]
default[db_index] = 0 default[db_index] = 0
default[host] = 127.0.0.1 default[host] = 127.0.0.1
default[password] = default[password] = null
default[port] = 6379 default[port] = 6379
default[prefix] = dm: default[prefix] = dm:
default[timeout] = 1 default[timeout] = 1
...@@ -133,25 +137,25 @@ cookie_name = dmsession ...@@ -133,25 +137,25 @@ cookie_name = dmsession
redis_connection_pool = default redis_connection_pool = default
[sqlite-vss] [sqlite-vss]
extension_vector0 = vector0.so extension_vector0 = %DM_ROOT%/vector0.so
extension_vss0 = vss0.so extension_vss0 = %DM_ROOT%/vss0.so
[static] [static]
base_url = https://resonance.distantmagic.com base_url = https://resonance.distantmagic.com
esbuild_metafile = esbuild-meta-docs.json esbuild_metafile = %DM_ROOT%/esbuild-meta-docs.json
input_directory = docs input_directory = docs
output_directory = docs/build output_directory = %DM_ROOT%/docs/build
sitemap = docs/build/sitemap.xml sitemap = %DM_ROOT%/docs/build/sitemap.xml
[swoole] [swoole]
host = 127.0.0.1 host = 127.0.0.1
port = 9501 port = 9501
log_level = SWOOLE_LOG_DEBUG log_level = SWOOLE_LOG_DEBUG
ssl_cert_file = ssl/origin.crt ssl_cert_file = %DM_ROOT%/ssl/origin.crt
ssl_key_file = ssl/origin.key ssl_key_file = %DM_ROOT%/ssl/origin.key
[translator] [translator]
base_directory = app/lang base_directory = %DM_APP_ROOT%/lang
default_primary_language = en default_primary_language = en
[websocket] [websocket]
...@@ -168,6 +172,17 @@ interpolation rules. For example: ...@@ -168,6 +172,17 @@ interpolation rules. For example:
path = ${PATH} path = ${PATH}
``` ```
### File Paths
For the sake of consistency, all file paths in the configuration file are
absolute.
### Interpolatable Constants
You can use `DM_APP_ROOT`, `DM_PUBLIC_ROOT`, `DM_RESONANCE_ROOT` and `DM_ROOT`
constants in your configuration file by inserting them with `%%` delimiters,
for example: `%DM_APP_ROOT%`.
### Configuration Providers ### Configuration Providers
You can extend `config.ini` by adding your configuration sections. Let's say You can extend `config.ini` by adding your configuration sections. Let's say
......
...@@ -9,6 +9,7 @@ use Distantmagic\Resonance\Attribute\RequiresPhpExtension; ...@@ -9,6 +9,7 @@ use Distantmagic\Resonance\Attribute\RequiresPhpExtension;
use Distantmagic\Resonance\Attribute\WantsFeature; use Distantmagic\Resonance\Attribute\WantsFeature;
use Distantmagic\Resonance\Command; use Distantmagic\Resonance\Command;
use Distantmagic\Resonance\Feature; use Distantmagic\Resonance\Feature;
use Distantmagic\Resonance\GrpcConfiguration;
use Nette\PhpGenerator\Printer; use Nette\PhpGenerator\Printer;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
...@@ -18,11 +19,14 @@ use Symfony\Component\Console\Output\OutputInterface; ...@@ -18,11 +19,14 @@ use Symfony\Component\Console\Output\OutputInterface;
description: 'Generate GRPC stubs' description: 'Generate GRPC stubs'
)] )]
#[RequiresPhpExtension('grpc')] #[RequiresPhpExtension('grpc')]
#[RequiresPhpExtension('protobuf')]
#[WantsFeature(Feature::Grpc)] #[WantsFeature(Feature::Grpc)]
final class GrpcGenerate extends Command final class GrpcGenerate extends Command
{ {
public function __construct(private readonly Printer $printer) public function __construct(
{ private readonly GrpcConfiguration $grpcConfiguration,
private readonly Printer $printer,
) {
parent::__construct(); parent::__construct();
} }
......
...@@ -4,9 +4,10 @@ declare(strict_types=1); ...@@ -4,9 +4,10 @@ declare(strict_types=1);
namespace Distantmagic\Resonance; namespace Distantmagic\Resonance;
use Dflydev\DotAccessData\Data;
readonly class ConfigurationFile readonly class ConfigurationFile
{ {
public function __construct(public Data $config) {} /**
* @param array<string,mixed> $config
*/
public function __construct(public array $config) {}
} }
...@@ -8,7 +8,7 @@ use Closure; ...@@ -8,7 +8,7 @@ use Closure;
use Distantmagic\Resonance\Attribute\RequiresPhpExtension; use Distantmagic\Resonance\Attribute\RequiresPhpExtension;
use Distantmagic\Resonance\DependencyInjectionContainerException\AmbiguousProvider; use Distantmagic\Resonance\DependencyInjectionContainerException\AmbiguousProvider;
use Distantmagic\Resonance\DependencyInjectionContainerException\DisabledFeatureProvider; use Distantmagic\Resonance\DependencyInjectionContainerException\DisabledFeatureProvider;
use Distantmagic\Resonance\DependencyInjectionContainerException\MissingPhpExtension; use Distantmagic\Resonance\DependencyInjectionContainerException\MissingPhpExtensions;
use Distantmagic\Resonance\DependencyInjectionContainerException\MissingProvider; use Distantmagic\Resonance\DependencyInjectionContainerException\MissingProvider;
use Ds\Map; use Ds\Map;
use Ds\Set; use Ds\Set;
...@@ -197,12 +197,12 @@ readonly class DependencyInjectionContainer ...@@ -197,12 +197,12 @@ readonly class DependencyInjectionContainer
} }
foreach ($dependencyProvider->grantsFeatures as $grantedFeature) { foreach ($dependencyProvider->grantsFeatures as $grantedFeature) {
if ($this->wantedFeatures->contains($grantedFeature)) { if (!$this->wantedFeatures->contains($grantedFeature)) {
return true; return false;
} }
} }
return false; return true;
} }
/** /**
...@@ -230,11 +230,20 @@ readonly class DependencyInjectionContainer ...@@ -230,11 +230,20 @@ readonly class DependencyInjectionContainer
$requiredPhpExtensions = $reflectionClassAttributeManager->findAttributes(RequiresPhpExtension::class); $requiredPhpExtensions = $reflectionClassAttributeManager->findAttributes(RequiresPhpExtension::class);
if (!$requiredPhpExtensions->isEmpty()) { if (!$requiredPhpExtensions->isEmpty()) {
/**
* @var list<non-empty-string>
*/
$missingExtensions = [];
foreach ($requiredPhpExtensions as $requiredPhpExtension) { foreach ($requiredPhpExtensions as $requiredPhpExtension) {
if (!extension_loaded($requiredPhpExtension->name)) { if (!extension_loaded($requiredPhpExtension->name)) {
throw new MissingPhpExtension($reflectionClass->name, $requiredPhpExtension->name); $missingExtensions[] = $requiredPhpExtension->name;
} }
} }
if (!empty($missingExtensions)) {
throw new MissingPhpExtensions($reflectionClass->name, $missingExtensions);
}
} }
$constructorReflection = $reflectionClass->getConstructor(); $constructorReflection = $reflectionClass->getConstructor();
...@@ -304,6 +313,13 @@ readonly class DependencyInjectionContainer ...@@ -304,6 +313,13 @@ readonly class DependencyInjectionContainer
$potentialSingletonProvider = $this->makeClassFromReflection($dependencyProvider->providerReflectionClass, $stack); $potentialSingletonProvider = $this->makeClassFromReflection($dependencyProvider->providerReflectionClass, $stack);
if ($potentialSingletonProvider instanceof SingletonProviderInterface) { if ($potentialSingletonProvider instanceof SingletonProviderInterface) {
if ($potentialSingletonProvider instanceof RegisterableInterface && !$potentialSingletonProvider->shouldRegister()) {
throw new DependencyInjectionContainerException(sprintf(
'"%s" service provider refused to register',
$potentialSingletonProvider::class,
));
}
$potentialSingleton = $potentialSingletonProvider->provide($this->singletons, $this->phpProjectFiles); $potentialSingleton = $potentialSingletonProvider->provide($this->singletons, $this->phpProjectFiles);
} else { } else {
$potentialSingleton = $potentialSingletonProvider; $potentialSingleton = $potentialSingletonProvider;
......
...@@ -7,22 +7,23 @@ namespace Distantmagic\Resonance\DependencyInjectionContainerException; ...@@ -7,22 +7,23 @@ namespace Distantmagic\Resonance\DependencyInjectionContainerException;
use Distantmagic\Resonance\DependencyInjectionContainerException; use Distantmagic\Resonance\DependencyInjectionContainerException;
use Throwable; use Throwable;
class MissingPhpExtension extends DependencyInjectionContainerException class MissingPhpExtensions extends DependencyInjectionContainerException
{ {
/** /**
* @param class-string $className * @param class-string $className
* @param non-empty-string $extensionName * @param non-empty-list<non-empty-string> $extensionNames
*/ */
public function __construct( public function __construct(
string $className, string $className,
string $extensionName, array $extensionNames,
?Throwable $previous = null, ?Throwable $previous = null,
) { ) {
parent::__construct( parent::__construct(
sprintf( sprintf(
'To use "%s" you need to install "%s" PHP extension.', 'To use "%s" you need to install "%s" PHP %s.',
$className, $className,
$extensionName, implode('", "', $extensionNames),
1 === count($extensionNames) ? 'extension' : 'extensions',
), ),
$previous $previous
); );
......
...@@ -26,7 +26,7 @@ readonly class EsbuildMetaBuilder ...@@ -26,7 +26,7 @@ readonly class EsbuildMetaBuilder
public function build( public function build(
string $esbuildMetafile, string $esbuildMetafile,
string $stripOutputPrefix = '', ?string $stripOutputPrefix = null,
): EsbuildMeta { ): EsbuildMeta {
if ($this->esbuildMetaCache->hasKey($esbuildMetafile)) { if ($this->esbuildMetaCache->hasKey($esbuildMetafile)) {
return $this->esbuildMetaCache->get($esbuildMetafile); return $this->esbuildMetaCache->get($esbuildMetafile);
...@@ -41,7 +41,7 @@ readonly class EsbuildMetaBuilder ...@@ -41,7 +41,7 @@ readonly class EsbuildMetaBuilder
private function doBuild( private function doBuild(
string $esbuildMetafile, string $esbuildMetafile,
string $stripOutputPrefix = '', ?string $stripOutputPrefix = null,
): EsbuildMeta { ): EsbuildMeta {
$esbuildMeta = new EsbuildMeta(); $esbuildMeta = new EsbuildMeta();
...@@ -68,7 +68,7 @@ readonly class EsbuildMetaBuilder ...@@ -68,7 +68,7 @@ readonly class EsbuildMetaBuilder
*/ */
private function entryPointImports( private function entryPointImports(
string $esbuildMetafile, string $esbuildMetafile,
string $stripOutputPrefix, ?string $stripOutputPrefix,
EsbuildMeta $esbuildMeta, EsbuildMeta $esbuildMeta,
): Generator { ): Generator {
foreach ($this->entryPointOutputs($esbuildMetafile, $stripOutputPrefix) as $filename => $output) { foreach ($this->entryPointOutputs($esbuildMetafile, $stripOutputPrefix) as $filename => $output) {
...@@ -77,8 +77,8 @@ readonly class EsbuildMetaBuilder ...@@ -77,8 +77,8 @@ readonly class EsbuildMetaBuilder
} }
$entryPointBasename = basename($output->entryPoint); $entryPointBasename = basename($output->entryPoint);
$esbuildMeta->registerEntryPoint($entryPointBasename, $filename); $esbuildMeta->registerEntryPoint($entryPointBasename, $filename);
if (!isset($output->imports)) { if (!isset($output->imports)) {
continue; continue;
} }
...@@ -101,7 +101,11 @@ readonly class EsbuildMetaBuilder ...@@ -101,7 +101,11 @@ readonly class EsbuildMetaBuilder
throw new LogicException('Expected "kind" and "path" import fields to be set.'); throw new LogicException('Expected "kind" and "path" import fields to be set.');
} }
yield $filename => $this->stripBaseDirectory($stripOutputPrefix, $import->path); yield $filename => $this->stripBaseDirectory(
$esbuildMetafile,
$stripOutputPrefix,
$import->path,
);
} }
} }
} }
...@@ -111,7 +115,7 @@ readonly class EsbuildMetaBuilder ...@@ -111,7 +115,7 @@ readonly class EsbuildMetaBuilder
*/ */
private function entryPointOutputs( private function entryPointOutputs(
string $esbuildMetafile, string $esbuildMetafile,
string $stripOutputPrefix, ?string $stripOutputPrefix,
): Generator { ): Generator {
$esbuildMeta = $this->getEsbuildMetaDecoded($esbuildMetafile); $esbuildMeta = $this->getEsbuildMetaDecoded($esbuildMetafile);
...@@ -129,7 +133,11 @@ readonly class EsbuildMetaBuilder ...@@ -129,7 +133,11 @@ readonly class EsbuildMetaBuilder
if (!is_string($output->entryPoint)) { if (!is_string($output->entryPoint)) {
continue; continue;
} }
yield $this->stripBaseDirectory($stripOutputPrefix, $filename) => $output; yield $this->stripBaseDirectory(
$esbuildMetafile,
$stripOutputPrefix,
$filename,
) => $output;
} }
} }
...@@ -166,12 +174,21 @@ readonly class EsbuildMetaBuilder ...@@ -166,12 +174,21 @@ readonly class EsbuildMetaBuilder
return $ret; return $ret;
} }
private function stripBaseDirectory(string $stripOutputPrefix, string $filename): string private function stripBaseDirectory(
{ string $esbuildMetafile,
if (!str_starts_with($filename, $stripOutputPrefix)) { ?string $stripOutputPrefix,
string $filename,
): string {
if (is_null($stripOutputPrefix)) {
return $filename;
}
$absoluteFilename = dirname($esbuildMetafile).'/'.$filename;
if (!str_starts_with($absoluteFilename, $stripOutputPrefix)) {
return $filename; return $filename;
} }
return substr($filename, strlen($stripOutputPrefix)); return substr($absoluteFilename, strlen($stripOutputPrefix));
} }
} }
<?php
declare(strict_types=1);
namespace Distantmagic\Resonance;
readonly class GrpcConfiguration
{
public function __construct() {}
}
...@@ -4,7 +4,6 @@ declare(strict_types=1); ...@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Distantmagic\Resonance\SingletonProvider; namespace Distantmagic\Resonance\SingletonProvider;
use Dflydev\DotAccessData\Data;
use Distantmagic\Resonance\Attribute\Singleton; use Distantmagic\Resonance\Attribute\Singleton;
use Distantmagic\Resonance\ConfigurationFile; use Distantmagic\Resonance\ConfigurationFile;
use Distantmagic\Resonance\PHPProjectFiles; use Distantmagic\Resonance\PHPProjectFiles;
...@@ -18,6 +17,13 @@ use RuntimeException; ...@@ -18,6 +17,13 @@ use RuntimeException;
#[Singleton(provides: ConfigurationFile::class)] #[Singleton(provides: ConfigurationFile::class)]
final readonly class ConfigurationFileProvider extends SingletonProvider final readonly class ConfigurationFileProvider extends SingletonProvider
{ {
private const INTERPOLATABLE_CONSTANTS = [
'DM_APP_ROOT',
'DM_PUBLIC_ROOT',
'DM_RESONANCE_ROOT',
'DM_ROOT',
];
public function provide(SingletonContainer $singletons, PHPProjectFiles $phpProjectFiles): ConfigurationFile public function provide(SingletonContainer $singletons, PHPProjectFiles $phpProjectFiles): ConfigurationFile
{ {
$filename = DM_ROOT.'/config.ini'; $filename = DM_ROOT.'/config.ini';
...@@ -31,9 +37,31 @@ final readonly class ConfigurationFileProvider extends SingletonProvider ...@@ -31,9 +37,31 @@ final readonly class ConfigurationFileProvider extends SingletonProvider
throw new RuntimeException('Unable to parse configuration file: '.$filename); throw new RuntimeException('Unable to parse configuration file: '.$filename);
} }
array_walk_recursive($iniConfig, $this->interpolateConstants(...));
/** /**
* @var array<string,mixed> $iniConfig * @var array<string,mixed> $iniConfig
*/ */
return new ConfigurationFile(new Data($iniConfig)); return new ConfigurationFile($iniConfig);
}
private function interpolateConstants(mixed &$value): void
{
if (!is_string($value)) {
return;
}
foreach (self::INTERPOLATABLE_CONSTANTS as $interpolatableConstant) {
$constantValue = constant($interpolatableConstant);
if (!is_string($constantValue) || empty($constantValue)) {
throw new RuntimeException(sprintf(
'You need to define "%s" constant in your constants.php file',
$interpolatableConstant,
));
}
$value = str_replace('%'.$interpolatableConstant.'%', $constantValue, $value);
}
} }
} }
...@@ -8,6 +8,7 @@ use Distantmagic\Resonance\ConfigurationFile; ...@@ -8,6 +8,7 @@ use Distantmagic\Resonance\ConfigurationFile;
use Distantmagic\Resonance\ConstraintSourceInterface; use Distantmagic\Resonance\ConstraintSourceInterface;
use Distantmagic\Resonance\ConstraintValidationException; use Distantmagic\Resonance\ConstraintValidationException;
use Distantmagic\Resonance\PHPProjectFiles; use Distantmagic\Resonance\PHPProjectFiles;
use Distantmagic\Resonance\RegisterableInterface;
use Distantmagic\Resonance\SingletonContainer; use Distantmagic\Resonance\SingletonContainer;
use Distantmagic\Resonance\SingletonProvider; use Distantmagic\Resonance\SingletonProvider;
...@@ -17,7 +18,7 @@ use Distantmagic\Resonance\SingletonProvider; ...@@ -17,7 +18,7 @@ use Distantmagic\Resonance\SingletonProvider;
* *
* @template-extends SingletonProvider<TObject> * @template-extends SingletonProvider<TObject>
*/ */
abstract readonly class ConfigurationProvider extends SingletonProvider implements ConstraintSourceInterface abstract readonly class ConfigurationProvider extends SingletonProvider implements ConstraintSourceInterface, RegisterableInterface
{ {
abstract protected function getConfigurationKey(): string; abstract protected function getConfigurationKey(): string;
...@@ -40,7 +41,7 @@ abstract readonly class ConfigurationProvider extends SingletonProvider implemen ...@@ -40,7 +41,7 @@ abstract readonly class ConfigurationProvider extends SingletonProvider implemen
/** /**
* @var mixed $data explicitly mixed for typechecks * @var mixed $data explicitly mixed for typechecks
*/ */
$data = $this->configurationFile->config->get($this->getConfigurationKey()); $data = $this->configurationFile->config[$this->getConfigurationKey()];
$constraintResult = $this->getConstraint()->validate($data); $constraintResult = $this->getConstraint()->validate($data);
...@@ -59,6 +60,9 @@ abstract readonly class ConfigurationProvider extends SingletonProvider implemen ...@@ -59,6 +60,9 @@ abstract readonly class ConfigurationProvider extends SingletonProvider implemen
public function shouldRegister(): bool public function shouldRegister(): bool
{ {
return $this->configurationFile->config->has($this->getConfigurationKey()); return array_key_exists(
$this->getConfigurationKey(),
$this->configurationFile->config,
);
} }
} }
...@@ -52,7 +52,7 @@ final readonly class ApplicationConfigurationProvider extends ConfigurationProvi ...@@ -52,7 +52,7 @@ final readonly class ApplicationConfigurationProvider extends ConfigurationProvi
return new ApplicationConfiguration( return new ApplicationConfiguration(
environment: Environment::from($validatedData['env']), environment: Environment::from($validatedData['env']),
esbuildMetafile: DM_ROOT.'/'.$validatedData['esbuild_metafile'], esbuildMetafile: $validatedData['esbuild_metafile'],
scheme: $validatedData['scheme'], scheme: $validatedData['scheme'],
url: $url, url: $url,
); );
......
<?php
declare(strict_types=1);
namespace Distantmagic\Resonance\SingletonProvider\ConfigurationProvider;
use Distantmagic\Resonance\Attribute\Singleton;
use Distantmagic\Resonance\Constraint;
use Distantmagic\Resonance\Constraint\ObjectConstraint;
use Distantmagic\Resonance\Constraint\StringConstraint;
use Distantmagic\Resonance\GrpcConfiguration;
use Distantmagic\Resonance\SingletonProvider\ConfigurationProvider;
/**
* @template-extends ConfigurationProvider<GrpcConfiguration, array{
* env: string,
* esbuild_metafile: non-empty-string,
* scheme: non-empty-string,
* url: non-empty-string,
* }>
*/
#[Singleton(provides: GrpcConfiguration::class)]
final readonly class GrpcConfigurationProvider extends ConfigurationProvider
{
public function getConstraint(): Constraint
{
return new ObjectConstraint(
properties: [
'protoc_bin' => new StringConstraint(),
],
);
}
protected function getConfigurationKey(): string
{
return 'grpc';
}
protected function provideConfiguration($validatedData): GrpcConfiguration
{
return new GrpcConfiguration(
);
}
}
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Distantmagic\Resonance\SingletonProvider\ConfigurationProvider; namespace Distantmagic\Resonance\SingletonProvider\ConfigurationProvider;
use Distantmagic\Resonance\Attribute\GrantsFeature;
use Distantmagic\Resonance\Attribute\Singleton; use Distantmagic\Resonance\Attribute\Singleton;
use Distantmagic\Resonance\Constraint; use Distantmagic\Resonance\Constraint;
use Distantmagic\Resonance\Constraint\EnumConstraint; use Distantmagic\Resonance\Constraint\EnumConstraint;
...@@ -11,6 +12,7 @@ use Distantmagic\Resonance\Constraint\IntegerConstraint; ...@@ -11,6 +12,7 @@ use Distantmagic\Resonance\Constraint\IntegerConstraint;
use Distantmagic\Resonance\Constraint\NumberConstraint; use Distantmagic\Resonance\Constraint\NumberConstraint;
use Distantmagic\Resonance\Constraint\ObjectConstraint; use Distantmagic\Resonance\Constraint\ObjectConstraint;
use Distantmagic\Resonance\Constraint\StringConstraint; use Distantmagic\Resonance\Constraint\StringConstraint;
use Distantmagic\Resonance\Feature;
use Distantmagic\Resonance\LlamaCppConfiguration; use Distantmagic\Resonance\LlamaCppConfiguration;
use Distantmagic\Resonance\SingletonProvider\ConfigurationProvider; use Distantmagic\Resonance\SingletonProvider\ConfigurationProvider;
...@@ -23,6 +25,7 @@ use Distantmagic\Resonance\SingletonProvider\ConfigurationProvider; ...@@ -23,6 +25,7 @@ use Distantmagic\Resonance\SingletonProvider\ConfigurationProvider;
* scheme: non-empty-string, * scheme: non-empty-string,
* }> * }>
*/ */
#[GrantsFeature(Feature::Grpc)]
#[Singleton(provides: LlamaCppConfiguration::class)] #[Singleton(provides: LlamaCppConfiguration::class)]
final readonly class LlamaCppConfigurationProvider extends ConfigurationProvider final readonly class LlamaCppConfigurationProvider extends ConfigurationProvider
{ {
......
...@@ -63,11 +63,11 @@ final readonly class OAuth2ConfigurationProvider extends ConfigurationProvider ...@@ -63,11 +63,11 @@ final readonly class OAuth2ConfigurationProvider extends ConfigurationProvider
return new OAuth2Configuration( return new OAuth2Configuration(
encryptionKey: Key::loadFromAsciiSafeString($encryptionKeyContent), encryptionKey: Key::loadFromAsciiSafeString($encryptionKeyContent),
jwtSigningKeyPrivate: new CryptKey( jwtSigningKeyPrivate: new CryptKey(
DM_ROOT.'/'.$validatedData['jwt_signing_key_private'], $validatedData['jwt_signing_key_private'],
$validatedData['jwt_signing_key_passphrase'], $validatedData['jwt_signing_key_passphrase'],
), ),
jwtSigningKeyPublic: new CryptKey( jwtSigningKeyPublic: new CryptKey(
DM_ROOT.'/'.$validatedData['jwt_signing_key_public'], $validatedData['jwt_signing_key_public'],
$validatedData['jwt_signing_key_passphrase'], $validatedData['jwt_signing_key_passphrase'],
), ),
sessionKeyAuthorizationRequest: $validatedData['session_key_authorization_request'], sessionKeyAuthorizationRequest: $validatedData['session_key_authorization_request'],
......
...@@ -45,10 +45,10 @@ final readonly class StaticPageConfigurationProvider extends ConfigurationProvid ...@@ -45,10 +45,10 @@ final readonly class StaticPageConfigurationProvider extends ConfigurationProvid
{ {
return new StaticPageConfiguration( return new StaticPageConfiguration(
baseUrl: $validatedData['base_url'], baseUrl: $validatedData['base_url'],
esbuildMetafile: DM_ROOT.'/'.$validatedData['esbuild_metafile'], esbuildMetafile: $validatedData['esbuild_metafile'],
inputDirectory: DM_ROOT.'/'.$validatedData['input_directory'], inputDirectory: $validatedData['input_directory'],
outputDirectory: DM_ROOT.'/'.$validatedData['output_directory'], outputDirectory: $validatedData['output_directory'],
sitemap: DM_ROOT.'/'.$validatedData['sitemap'], sitemap: $validatedData['sitemap'],
stripOutputPrefix: $validatedData['output_directory'].'/', stripOutputPrefix: $validatedData['output_directory'].'/',
); );
} }
......
...@@ -75,7 +75,7 @@ final readonly class MailerRepositoryProvider extends SingletonProvider ...@@ -75,7 +75,7 @@ final readonly class MailerRepositoryProvider extends SingletonProvider
return new DkimSigner( return new DkimSigner(
domainName: $transportConfiguration->dkimDomainName, domainName: $transportConfiguration->dkimDomainName,
passphrase: $transportConfiguration->dkimSigningKeyPassphrase, passphrase: $transportConfiguration->dkimSigningKeyPassphrase,
pk: 'file://'.DM_ROOT.'/'.$transportConfiguration->dkimSigningKeyPrivate, pk: 'file://'.$transportConfiguration->dkimSigningKeyPrivate,
selector: $transportConfiguration->dkimSelector, selector: $transportConfiguration->dkimSelector,
); );
} }
......
...@@ -4,6 +4,7 @@ declare(strict_types=1); ...@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Distantmagic\Resonance\SingletonProvider; namespace Distantmagic\Resonance\SingletonProvider;
use Distantmagic\Resonance\Attribute\RequiresPhpExtension;
use Distantmagic\Resonance\Attribute\Singleton; use Distantmagic\Resonance\Attribute\Singleton;
use Distantmagic\Resonance\PHPProjectFiles; use Distantmagic\Resonance\PHPProjectFiles;
use Distantmagic\Resonance\RedisConfiguration; use Distantmagic\Resonance\RedisConfiguration;
...@@ -16,6 +17,7 @@ use Swoole\Database\RedisPool; ...@@ -16,6 +17,7 @@ use Swoole\Database\RedisPool;
/** /**
* @template-extends SingletonProvider<RedisConnectionPoolRepository> * @template-extends SingletonProvider<RedisConnectionPoolRepository>
*/ */
#[RequiresPhpExtension('redis')]
#[Singleton(provides: RedisConnectionPoolRepository::class)] #[Singleton(provides: RedisConnectionPoolRepository::class)]
final readonly class RedisConnectionPoolRepositoryProvider extends SingletonProvider final readonly class RedisConnectionPoolRepositoryProvider extends SingletonProvider
{ {
......
...@@ -38,7 +38,7 @@ final readonly class TranslatorBridgeProvider extends SingletonProvider ...@@ -38,7 +38,7 @@ final readonly class TranslatorBridgeProvider extends SingletonProvider
->ignoreDotFiles(true) ->ignoreDotFiles(true)
->ignoreUnreadableDirs() ->ignoreUnreadableDirs()
->ignoreVCS(true) ->ignoreVCS(true)
->in(DM_ROOT.'/'.$this->translatorConfiguration->baseDirectory) ->in($this->translatorConfiguration->baseDirectory)
; ;
foreach ($translationFiles as $translationFile) { foreach ($translationFiles as $translationFile) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment