From e9d1a9ccc1a27e39e3167d42c7953f044c936582 Mon Sep 17 00:00:00 2001 From: david-fairbanks42 Date: Sun, 10 Aug 2025 17:23:45 -0400 Subject: [PATCH] Updates to work with metadata service --- README.md | 2 +- app/Dates.php | 1 - app/Ec2Backup.php | 97 +++--- app/MachineDetails.php | 301 +++++++--------- app/functions.php | 58 ---- backup.php | 11 +- composer.json | 5 +- composer.lock | 756 ++++++++++++++++++++++++++++------------- metadata.php | 12 + 9 files changed, 709 insertions(+), 534 deletions(-) create mode 100644 metadata.php diff --git a/README.md b/README.md index ce43659..91a0c8c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ during the snapshot start which will break the database. ## Usage After the required configuration settings are set up in the `.env` file, simply executing `php backup.php` will perform the backup. The script has additional options such as `--no-prune` to prevent the script from removing old -snapshots. If the configuration setting `ENABLE` is set to `false` the script will no perform any actions. To override +snapshots. If the configuration setting `ENABLE` is set to `false` the script will not perform any actions. To override the `ENABLE` setting, `--force` can be used. The script will also respond to `--help` to outline the usage. ## Setup diff --git a/app/Dates.php b/app/Dates.php index e120d7a..47adf4b 100644 --- a/app/Dates.php +++ b/app/Dates.php @@ -13,7 +13,6 @@ use Carbon\Carbon; * Class Dates * * @author David Fairbanks - * @package Fairbanks\Kizarian\Utilities * @version 2.0 */ class Dates { diff --git a/app/Ec2Backup.php b/app/Ec2Backup.php index fd33f5f..a896fe0 100644 --- a/app/Ec2Backup.php +++ b/app/Ec2Backup.php @@ -2,7 +2,7 @@ /** * Ec2Backup.php * - * @copyright 2023 Fairbanks Publishing LLC + * @copyright 2025 Fairbanks Publishing LLC */ namespace App; @@ -10,21 +10,19 @@ namespace App; use Aws\Ec2\Ec2Client; /** - * Class Ec2Snapshot + * Class Ec2Backup * * @author David Fairbanks - * @version 2.0 + * @version 3.0 */ class Ec2Backup { - /** - * @var Ec2Client - */ private Ec2Client $ec2Client; - - /** - * @var boolean - */ + private array $options = [ + 'noPrune' => false, + 'force' => false, + 'dryRun' => false, + ]; private bool $enable = true; /** @@ -34,21 +32,26 @@ class Ec2Backup */ private int $maxBackupCount = 4; - public function __construct(Ec2Client $ec2Client) { + public function __construct(Ec2Client $ec2Client, array $options = []) + { $this->ec2Client = $ec2Client; + foreach ($this->options as $key => $default) { + if (array_key_exists($key, $options) && is_bool($options[$key])) { + $this->options[$key] = $options[$key]; + } + } $this->enable = boolean(config('ENABLE', true)); - $this->maxBackupCount = (int)config('MAX_SNAPSHOT_COUNT', 4); - if($this->maxBackupCount <= 0) + $this->maxBackupCount = (int) config('MAX_SNAPSHOT_COUNT', 4); + if ($this->maxBackupCount <= 0) { $this->maxBackupCount = 4; + } } - public function create(array $options=[]): void + public function create(): void { - $options = array_merge(['noPrune' => false, 'force' => false], $options); - - if (!$this->enable && !$options['force']) { + if (! $this->enable && ! $this->options['force']) { app_echo('EC2 Backup is disabled in environment'); return; } @@ -63,30 +66,31 @@ class Ec2Backup try { $machine = MachineDetails::getDetails(); - } catch(\Exception $e) { + } catch (\Exception $e) { app_echo("Error getting machine details: {$e->getMessage()}"); return; } - if ($machine['type'] != 'ec2') { - app_echo('Instance type is wrong to do an EC2 backup', $machine); + if ($machine->type != 'ec2') { + app_echo('Instance type is wrong to do an EC2 backup', (array) $machine); return; } - $volumes = $this->getVolumes($machine['instanceId']); - $tags = $this->getTags($machine['instanceId']); + $volumes = $this->getVolumes($machine->instanceId); + $tags = $this->getTags($machine->instanceId); foreach ($volumes as $volume) { - if ($options['noPrune']) { + if ($this->options['noPrune']) { $pruneWording = '(pruning disabled)'; } else { $pruneCount = $this->pruneBackups($volume['volumeId']); $pruneWording = "and pruned {$pruneCount} old snapshots"; } - $name = (isset($tags['Name'])) ? $tags['Name'] : $machine['instanceId']; - if (count($volumes) > 1) + $name = (isset($tags['Name'])) ? $tags['Name'] : $machine->instanceId; + if (count($volumes) > 1) { $name .= " ({$volume['device']})"; + } if ($this->backup(['volumeId' => $volume['volumeId'], 'name' => $name])) { app_echo("Successfully started snapshot for {$volume['volumeId']} {$pruneWording}"); @@ -101,16 +105,16 @@ class Ec2Backup try { $result = $this->ec2Client->describeVolumes( [ - 'DryRun' => false, + 'DryRun' => false, 'Filters' => [ [ - 'Name' => 'attachment.instance-id', + 'Name' => 'attachment.instance-id', 'Values' => [$instanceId] ] ] ] ); - } catch(\Exception $e) { + } catch (\Exception $e) { app_echo('Error getting volumes: ' . $e->getMessage()); return []; } @@ -131,16 +135,16 @@ class Ec2Backup try { $result = $this->ec2Client->describeTags( [ - 'DryRun' => false, + 'DryRun' => false, 'Filters' => [ [ - 'Name' => 'resource-id', + 'Name' => 'resource-id', 'Values' => [$instanceId] ] ] ] ); - } catch(\Exception $e) { + } catch (\Exception $e) { app_echo('Error getting instance tags: ' . $e->getMessage()); return []; } @@ -158,24 +162,25 @@ class Ec2Backup try { $result = $this->ec2Client->describeSnapshots( [ - 'DryRun' => false, + 'DryRun' => false, 'Filters' => [ [ - 'Name' => 'volume-id', + 'Name' => 'volume-id', 'Values' => [$volumeId], ] ] ] ); - } catch(\Exception $e) { + } catch (\Exception $e) { app_echo('Error getting current snapshots: ' . $e->getMessage()); return []; } $snapshots = []; foreach ($result['Snapshots'] as $snapshot) { - if ($snapshot['State'] != 'completed') + if ($snapshot['State'] != 'completed') { continue; + } $snapshots[$snapshot['SnapshotId']] = [ 'started' => Dates::makeCarbon($snapshot['StartTime']), @@ -184,7 +189,7 @@ class Ec2Backup ]; } - uasort($snapshots, function($a, $b) { + uasort($snapshots, function ($a, $b) { if ($a['started'] == $b['started']) { return 0; } else { @@ -204,7 +209,7 @@ class Ec2Backup } $prune = array_slice($backups, 0, count($backups) - $this->maxBackupCount); - if(empty($prune)) { + if (empty($prune)) { return 0; } @@ -213,11 +218,11 @@ class Ec2Backup try { $this->ec2Client->deleteSnapshot( [ - 'DryRun' => false, + 'DryRun' => $this->options['dryRun'], 'SnapshotId' => $snapshotId ] ); - } catch(\Exception $e) { + } catch (\Exception $e) { app_echo('Error pruning snapshot: ' . $e->getMessage()); continue; } @@ -230,7 +235,7 @@ class Ec2Backup public function backup(array $params): bool { - if (!isset($params['volumeId'])) { + if (! isset($params['volumeId'])) { app_echo('Volume ID is not set in backup parameters'); return false; } @@ -239,7 +244,7 @@ class Ec2Backup $tags = [['Key' => 'Name', 'Value' => $name]]; $snapTags = json_decode(config('TAGS', '[]'), true); - if (is_array($snapTags) && !empty($snapTags)) { + if (is_array($snapTags) && ! empty($snapTags)) { foreach ($snapTags as $key => $value) { $tags[] = ['Key' => $key, 'Value' => $value]; } @@ -248,18 +253,18 @@ class Ec2Backup try { $this->ec2Client->createSnapshot( [ - 'Description' => sprintf('%s Backup %s', $name, date('Y-m-d')), - 'DryRun' => false, + 'Description' => sprintf('%s Backup %s', $name, date('Y-m-d')), + 'DryRun' => $this->options['dryRun'], 'TagSpecifications' => [ [ 'ResourceType' => 'snapshot', - 'Tags' => $tags + 'Tags' => $tags ] ], - 'VolumeId' => $params['volumeId'] + 'VolumeId' => $params['volumeId'] ] ); - } catch(\Exception $e) { + } catch (\Exception $e) { app_echo($e->getMessage()); return false; } diff --git a/app/MachineDetails.php b/app/MachineDetails.php index 8b8357c..cd58b26 100644 --- a/app/MachineDetails.php +++ b/app/MachineDetails.php @@ -2,46 +2,38 @@ /** * MachineDetails.php * - * @copyright 2023 Fairbanks Publishing LLC + * @copyright 2025 Fairbanks Publishing LLC */ namespace App; +use Carbon\Carbon; +use Carbon\CarbonInterface; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; +use Exception; + /** * Class MachineDetails * * @author David Fairbanks - * @version 2.0 + * @version 3.0 */ class MachineDetails { - /** - * @var MachineDetails - */ protected static MachineDetails $instance; - /** - * @var array - */ - protected static array $details = [ - 'type' => null, - 'id' => null, - 'machineId' => null, - 'instanceId' => null, - 'region' => null, - 'publicIp' => null, - 'privateIp' => null, - ]; + protected string|null $type = null; + protected string|null $machineId = null; + protected string|null $instanceId = null; + protected string|null $region = null; + protected string|null $privateIp = null; + protected string|null $publicIp = null; - /** - * PHP config setting for default_socket_timeout to reset to after doing file_get_contents() - * @var int|null - */ - protected ?int $socketTimeout = null; + private Client|null $metadataServiceClient = null; + private string|null $metadataServiceToken = null; + private CarbonInterface|null $metadataServiceTokenDate = null; - /** - * @return MachineDetails - */ public static function getInstance(): MachineDetails { if (!isset(static::$instance)) { @@ -51,162 +43,75 @@ class MachineDetails return static::$instance; } - /** - * @return array - */ - public static function getDetails(): array + public static function getDetails(): object { - if(self::$instance === null) + if(! isset(self::$instance)) self::$instance = self::getInstance(); - return self::$details; + return self::$instance->get(); } - /** - * @return string|null - */ - public static function id(): ?string + public function get(): object { - if(self::$instance === null) - self::$instance = self::getInstance(); - - return self::$details['id']; - } - - /** - * @return string|null - */ - public static function machineId(): ?string - { - if(self::$instance === null) - self::$instance = self::getInstance(); - - return self::$details['machineId']; - } - - /** - * @return string - */ - public static function fullMachineId(): string - { - if(self::$instance === null) - self::$instance = self::getInstance(); - - $id = [ - config('MACHINE_TYPE'), - self::$details['region'], - self::$details['machineId'] + return (object) [ + 'type' => $this->type, + 'machineId' => $this->machineId, + 'instanceId' => $this->instanceId, + 'region' => $this->region, + 'privateIp' => $this->privateIp, + 'publicIp' => $this->publicIp, ]; - - return implode('-', array_unique(array_filter($id))); } - /** - * @return string|null - */ - public static function region(): ?string + public function publicIp(): string|null { - if(self::$instance === null) - self::$instance = self::getInstance(); - - return self::$details['region']; - } - - /** - * @return string|null - */ - public static function publicIp(): ?string - { - if(self::$instance === null) - self::$instance = self::getInstance(); - - if(self::$details['publicIp'] === null) { - self::$details['publicIp'] = match (self::$details['type']) { - 'ec2' => self::getEc2PublicIp(), - default => self::getLocalPublicIp(), - }; + if (! empty($this->publicIp)) { + return $this->publicIp; } - return self::$details['privateIp']; - } + $this->ensureMetadataService(); + if (empty($this->metadataServiceToken)) { + return null; + } - /** - * @return string|null - */ - public static function privateIp(): ?string - { - if(self::$instance === null) - self::$instance = self::getInstance(); + try { + $response = $this->metadataServiceClient->request( + 'GET', + 'meta-data/public-ipv4', + [ + 'headers' => [ + 'X-aws-ec2-metadata-token' => $this->metadataServiceToken, + ], + ] + ); - return self::$details['privateIp']; - } + $this->publicIp = $response->getBody()->getContents(); + } catch (GuzzleException|Exception $e) { + app_echo(get_class($e) . ' getting IMDS V2 instance details: ' . $e->getMessage()); + } - /* Private methods */ - - private static function getLocalPublicIp(): string - { - return '127.0.0.1'; - } - - private static function getEc2PublicIp(): false|string - { - if(self::$instance === null) - self::$instance = self::getInstance(); - - self::$instance->shortenTimeout(); - $ip = @file_get_contents('http://169.254.169.254/latest/meta-data/public-ipv4'); - self::$instance->resetTimeout(); - - return $ip; + return $this->publicIp; } private function __construct() { - $type = config('MACHINE_TYPE'); - if($type === null || empty($type)) { - $type = $this->determineMachineType(); - } - - switch($type) { - case 'ec2' : - self::$details['type'] = 'ec2'; - self::$details = array_merge(self::$details, $this->getEc2Data()); - break; - default : - self::$details['type'] = 'local'; - self::$details = array_merge(self::$details, $this->getLocalData()); + if ($this->isEc2()) { + $this->type = 'ec2'; + $this->instanceIdentity(); + } else { + $this->type = 'unknown'; } } - /** - * Make clone magic method private, so nobody can clone instance. - */ + private function isEc2(): bool + { + $uname = php_uname(); + + return preg_match('/ip-\d{2,3}-\d{1,3}-\d{1,3}-\d{1,3}\s.*-aws/', $uname); + } + private function __clone() {} - private function determineMachineType(): string - { - $this->shortenTimeout(); - $hostname = @file_get_contents('http://169.254.169.254/latest/meta-data/hostname'); - $this->resetTimeout(); - - if(strpos($hostname, 'ec2') !== false) { - return 'ec2'; - } else { - return 'local'; - } - } - - private function getLocalData(): array - { - return [ - 'id' => 'dev', - 'machineId' => 'dev', - 'region' => 'local', - 'publicIp' => '127.0.0.1', - 'privateIp' => '127.0.0.1', - ]; - } - - private function getEc2Data(): array + private function instanceIdentity(): void { /* * curl "http://169.254.169.254/latest/dynamic/instance-identity/document" @@ -228,40 +133,74 @@ class MachineDetails * } */ - $this->shortenTimeout(); - $json = @file_get_contents('http://169.254.169.254/latest/dynamic/instance-identity/document'); - $this->resetTimeout(); - - $data = json_decode($json, true); - - if(!is_array($data) || empty($data)) { - throw new \Exception('Invalid machine details from http://169.254.169.254. Assumption is this is not an EC2 instance.'); + $this->ensureMetadataService(); + if (empty($this->metadataServiceToken)) { + return; } - if(isset($data['instanceId'])) - $data['machineId'] = substr($data['instanceId'], 2); + try { + $response = $this->metadataServiceClient->request( + 'GET', + 'dynamic/instance-identity/document', + [ + 'headers' => [ + 'X-aws-ec2-metadata-token' => $this->metadataServiceToken, + ], + ] + ); - $out = []; - foreach(self::$details as $key => $v) { - $out[$key] = (isset($data[$key])) ? $data[$key] : $v; + $json = $response->getBody()->getContents(); + } catch (GuzzleException|Exception $e) { + app_echo(get_class($e) . ' getting IMDS V2 instance details: ' . $e->getMessage()); + + return; } - return $out; + $data = json_decode($json); + + $this->instanceId = $data->instanceId; + $this->region = $data->region; + $this->privateIp = $data->privateIp; + + if (! empty($data->instanceId)) { + $this->machineId = substr($data->instanceId, 2); + } } - private function shortenTimeout(): void + private function ensureMetadataService(): void { - if($this->socketTimeout === null) { - $this->socketTimeout = ini_get('default_socket_timeout'); + if ($this->metadataServiceClient === null) { + $this->metadataServiceClient = new Client(['base_uri' => 'http://169.254.169.254/latest/']); } - ini_set('default_socket_timeout', 2); - } + if ($this->metadataServiceToken !== null && $this->metadataServiceTokenDate !== null + && $this->metadataServiceTokenDate->isAfter(Carbon::now()->addSeconds(-60)) + ) { + return; + } - private function resetTimeout(): void - { - if($this->socketTimeout !== null) { - ini_set('default_socket_timeout', $this->socketTimeout); + $this->metadataServiceToken = null; + $this->metadataServiceTokenDate = Carbon::now(); + + // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-dynamic-data-retrieval.html + // https://stackoverflow.com/a/74334921/667613 + // TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` + // curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document + + try { + $response = $this->metadataServiceClient->request( + 'PUT', + 'api/token', + [ + 'headers' => [ + 'X-aws-ec2-metadata-token-ttl-seconds' => 60, + ], + ] + ); + + $this->metadataServiceToken = $response->getBody()->getContents(); + } catch (GuzzleException|Exception $e) { + app_echo(get_class($e) . ' getting IMDS V2 token: ' . $e->getMessage()); } } } diff --git a/app/functions.php b/app/functions.php index c6c2270..4277a16 100644 --- a/app/functions.php +++ b/app/functions.php @@ -5,64 +5,6 @@ * @copyright (c) 2018, Fairbanks Publishing */ -if(!function_exists('array_combine_safe')) { - /** - * Same affect as array_combine but does not error if the two arrays are different lengths - * - * @param array $keys - * @param array $values - * @param null $default - * - * @return array - */ - function array_combine_safe(array $keys = [], array $values = [], $default = null): array - { - if (empty($keys)) { - return []; - } - - $out = []; - - foreach ($keys as $index => $key) { - $out[$key] = (isset($values[$index])) ? $values[$index] : $default; - } - - return $out; - } -} - -if(!function_exists('array_limit_keys')) { - /** - * Filter input array to only have the keys provided - * - * Only ensures first level of supplied array - * - * @param array $keys - * @param array $input - * - * @return array - */ - function array_limit_keys(array $keys = [], array $input = []): array - { - if(empty($keys)) { - return []; - } - - //return array_filter($input, function($item) use ($keys) { - // return in_array($item, $keys); - //}, ARRAY_FILTER_USE_KEY); - - $out = []; - foreach ($keys as $key) { - if (array_key_exists($key, $input)) { - $out[$key] = $input[$key]; - } - } - - return $out; - } -} - if(!function_exists('boolean')) { /** * Convert value to boolean diff --git a/backup.php b/backup.php index f85bce9..fe53e2d 100644 --- a/backup.php +++ b/backup.php @@ -1,6 +1,6 @@ isset($arguments['f']) || isset($arguments['force']), - 'noPrune' => isset($arguments['p']) || isset($arguments['no-prune']) + 'noPrune' => isset($arguments['p']) || isset($arguments['no-prune']), + 'dryRun' => isset($arguments['dry-run']), ]; require_once(__DIR__ . '/vendor/autoload.php'); @@ -31,7 +33,7 @@ $dotenv->required('AWS_REGION')->notEmpty(); $dotenv->ifPresent('MAX_SNAPSHOT_COUNT')->isInteger(); $dotenv->ifPresent('ENABLE')->isBoolean(); -$ec2Client = new \Aws\Ec2\Ec2Client([ +$ec2Client = new Aws\Ec2\Ec2Client([ 'credentials' => [ 'key' => config('AWS_KEY'), 'secret' => config('AWS_SECRET') @@ -39,6 +41,5 @@ $ec2Client = new \Aws\Ec2\Ec2Client([ 'region' => config('AWS_REGION'), 'version' => config('AWS_VERSION', 'latest') ]); -$ec2Backup = new \App\Ec2Backup($ec2Client); - +$ec2Backup = new App\Ec2Backup($ec2Client, $options); $ec2Backup->create(); diff --git a/composer.json b/composer.json index 1f0657b..fdd689e 100644 --- a/composer.json +++ b/composer.json @@ -2,8 +2,9 @@ "require": { "php": "^8.2", "ext-json": "*", - "aws/aws-sdk-php": "^3.209", - "nesbot/carbon": "^2.68", + "aws/aws-sdk-php": "^3.308.0", + "guzzlehttp/guzzle": "^7.2", + "nesbot/carbon": "3.8.4.0", "vlucas/phpdotenv": "^5.5" }, "config": { diff --git a/composer.lock b/composer.lock index 5b3e00f..03cca82 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e3a5af54e16df030f3873775ec1cc3a0", + "content-hash": "67e0b88f8a272ab7600a3a0c1857391a", "packages": [ { "name": "aws/aws-crt-php", - "version": "v1.2.1", + "version": "v1.2.7", "source": { "type": "git", "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", - "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e", "shasum": "" }, "require": { @@ -56,54 +56,53 @@ ], "support": { "issues": "https://github.com/awslabs/aws-crt-php/issues", - "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.1" + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7" }, - "time": "2023-03-24T20:22:19+00:00" + "time": "2024-10-18T22:15:13+00:00" }, { "name": "aws/aws-sdk-php", - "version": "3.276.4", + "version": "3.351.3", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "80509b932c7e8e917a5026a89bd7af1f2b34ed59" + "reference": "7c58f4a8acd2230daad1ef23bceb9972e62bdf94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/80509b932c7e8e917a5026a89bd7af1f2b34ed59", - "reference": "80509b932c7e8e917a5026a89bd7af1f2b34ed59", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7c58f4a8acd2230daad1ef23bceb9972e62bdf94", + "reference": "7c58f4a8acd2230daad1ef23bceb9972e62bdf94", "shasum": "" }, "require": { - "aws/aws-crt-php": "^1.0.4", + "aws/aws-crt-php": "^1.2.3", "ext-json": "*", "ext-pcre": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", - "guzzlehttp/promises": "^1.4.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", - "mtdowling/jmespath.php": "^2.6", - "php": ">=5.5", - "psr/http-message": "^1.0" + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/promises": "^2.0", + "guzzlehttp/psr7": "^2.4.5", + "mtdowling/jmespath.php": "^2.8.0", + "php": ">=8.1", + "psr/http-message": "^2.0" }, "require-dev": { "andrewsville/php-token-reflection": "^1.4", "aws/aws-php-sns-message-validator": "~1.0", "behat/behat": "~3.0", - "composer/composer": "^1.10.22", + "composer/composer": "^2.7.8", "dms/phpunit-arraysubset-asserts": "^0.4.0", "doctrine/cache": "~1.4", "ext-dom": "*", "ext-openssl": "*", "ext-pcntl": "*", "ext-sockets": "*", - "nette/neon": "^2.3", - "paragonie/random_compat": ">= 2", - "phpunit/phpunit": "^4.8.35 || ^5.6.3 || ^9.5", - "psr/cache": "^1.0", - "psr/simple-cache": "^1.0", - "sebastian/comparator": "^1.2.3 || ^4.0", - "yoast/phpunit-polyfills": "^1.0" + "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5", + "psr/cache": "^2.0 || ^3.0", + "psr/simple-cache": "^2.0 || ^3.0", + "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0", + "symfony/filesystem": "^v6.4.0 || ^v7.1.0", + "yoast/phpunit-polyfills": "^2.0" }, "suggest": { "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", @@ -124,7 +123,10 @@ ], "psr-4": { "Aws\\": "src/" - } + }, + "exclude-from-classmap": [ + "src/data/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -149,32 +151,101 @@ "sdk" ], "support": { - "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", + "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.276.4" + "source": "https://github.com/aws/aws-sdk-php/tree/3.351.3" }, - "time": "2023-07-24T18:15:58+00:00" + "time": "2025-07-21T18:04:02+00:00" }, { - "name": "graham-campbell/result-type", - "version": "v1.1.1", + "name": "carbonphp/carbon-doctrine-types", + "version": "3.2.0", "source": { "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831" + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", - "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/dbal": "<4.0.0 || >=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.1" + "phpoption/phpoption": "^1.9.3" }, "require-dev": { - "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" }, "type": "library", "autoload": { @@ -203,7 +274,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" }, "funding": [ { @@ -215,26 +286,26 @@ "type": "tidelift" } ], - "time": "2023-02-25T20:23:15+00:00" + "time": "2024-07-20T21:45:45+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.7.0", + "version": "7.9.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -243,11 +314,11 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -325,7 +396,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.7.0" + "source": "https://github.com/guzzle/guzzle/tree/7.9.3" }, "funding": [ { @@ -341,33 +412,37 @@ "type": "tidelift" } ], - "time": "2023-05-21T14:04:53+00:00" + "time": "2025-03-27T13:37:11+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.3", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c", + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Promise\\": "src/" } @@ -404,7 +479,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.3" + "source": "https://github.com/guzzle/promises/tree/2.2.0" }, "funding": [ { @@ -420,20 +495,20 @@ "type": "tidelift" } ], - "time": "2023-05-21T12:31:43+00:00" + "time": "2025-03-27T13:27:01+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.5.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16", + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16", "shasum": "" }, "require": { @@ -447,9 +522,9 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -520,7 +595,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.5.0" + "source": "https://github.com/guzzle/psr7/tree/2.7.1" }, "funding": [ { @@ -536,29 +611,29 @@ "type": "tidelift" } ], - "time": "2023-04-17T16:11:26+00:00" + "time": "2025-03-27T12:30:47+00:00" }, { "name": "mtdowling/jmespath.php", - "version": "2.6.1", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", "shasum": "" }, "require": { - "php": "^5.4 || ^7.0 || ^8.0", + "php": "^7.2.5 || ^8.0", "symfony/polyfill-mbstring": "^1.17" }, "require-dev": { - "composer/xdebug-handler": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^7.5.15" + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.33" }, "bin": [ "bin/jp.php" @@ -566,7 +641,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -582,6 +657,11 @@ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", @@ -595,53 +675,53 @@ ], "support": { "issues": "https://github.com/jmespath/jmespath.php/issues", - "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1" + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" }, - "time": "2021-06-14T00:11:39+00:00" + "time": "2024-09-04T18:46:31+00:00" }, { "name": "nesbot/carbon", - "version": "2.68.1", + "version": "3.8.4", "source": { "type": "git", - "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da" + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "129700ed449b1f02d70272d2ac802357c8c30c58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4f991ed2a403c85efbc4f23eb4030063fdbe01da", - "reference": "4f991ed2a403c85efbc4f23eb4030063fdbe01da", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/129700ed449b1f02d70272d2ac802357c8c30c58", + "reference": "129700ed449b1f02d70272d2ac802357c8c30c58", "shasum": "" }, "require": { + "carbonphp/carbon-doctrine-types": "<100.0", "ext-json": "*", - "php": "^7.1.8 || ^8.0", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3 || ^7.0", "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + "symfony/translation": "^4.4.18 || ^5.2.1|| ^6.0 || ^7.0" + }, + "provide": { + "psr/clock-implementation": "1.0" }, "require-dev": { - "doctrine/dbal": "^2.0 || ^3.1.4", - "doctrine/orm": "^2.7", - "friendsofphp/php-cs-fixer": "^3.0", - "kylekatarnls/multi-tester": "^2.0", - "ondrejmirtes/better-reflection": "*", - "phpmd/phpmd": "^2.9", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.99 || ^1.7.14", - "phpunit/php-file-iterator": "^2.0.5 || ^3.0.6", - "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", - "squizlabs/php_codesniffer": "^3.4" + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.57.2", + "kylekatarnls/multi-tester": "^2.5.3", + "ondrejmirtes/better-reflection": "^6.25.0.4", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.11.2", + "phpunit/phpunit": "^10.5.20", + "squizlabs/php_codesniffer": "^3.9.0" }, "bin": [ "bin/carbon" ], "type": "library", "extra": { - "branch-alias": { - "dev-3.x": "3.x-dev", - "dev-master": "2.x-dev" - }, "laravel": { "providers": [ "Carbon\\Laravel\\ServiceProvider" @@ -651,6 +731,10 @@ "includes": [ "extension.neon" ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" } }, "autoload": { @@ -699,20 +783,20 @@ "type": "tidelift" } ], - "time": "2023-06-20T18:29:04+00:00" + "time": "2024-12-27T09:25:35+00:00" }, { "name": "phpoption/phpoption", - "version": "1.9.1", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e" + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e", - "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54", + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54", "shasum": "" }, "require": { @@ -720,13 +804,13 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12" + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" }, "type": "library", "extra": { "bamarni-bin": { "bin-links": true, - "forward-command": true + "forward-command": false }, "branch-alias": { "dev-master": "1.9-dev" @@ -762,7 +846,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.1" + "source": "https://github.com/schmittjoh/php-option/tree/1.9.3" }, "funding": [ { @@ -774,20 +858,68 @@ "type": "tidelift" } ], - "time": "2023-02-25T19:38:58+00:00" + "time": "2024-07-20T21:41:07+00:00" }, { - "name": "psr/http-client", - "version": "1.0.2", + "name": "psr/clock", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { @@ -824,26 +956,26 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" + "source": "https://github.com/php-fig/http-client" }, - "time": "2023-04-10T20:12:12+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "type": "library", @@ -867,7 +999,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -879,22 +1011,22 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2023-04-10T20:10:41+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { "name": "psr/http-message", - "version": "1.1", + "version": "2.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { @@ -903,7 +1035,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -918,7 +1050,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -932,9 +1064,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/1.1" + "source": "https://github.com/php-fig/http-message/tree/2.0" }, - "time": "2023-04-04T09:50:52+00:00" + "time": "2023-04-04T09:54:51+00:00" }, { "name": "ralouphie/getallheaders", @@ -981,17 +1113,91 @@ "time": "2019-03-08T08:55:37+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.3.0", + "name": "symfony/clock", + "version": "v7.3.0", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "url": "https://github.com/symfony/clock.git", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { @@ -999,12 +1205,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -1029,7 +1235,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" }, "funding": [ { @@ -1045,24 +1251,24 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -1072,12 +1278,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -1111,7 +1314,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" }, "funding": [ { @@ -1127,24 +1330,25 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -1154,12 +1358,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -1194,7 +1395,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" }, "funding": [ { @@ -1210,33 +1411,30 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -1277,7 +1475,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" }, "funding": [ { @@ -1293,54 +1491,132 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { - "name": "symfony/translation", - "version": "v6.3.0", + "name": "symfony/polyfill-php83", + "version": "v1.32.0", "source": { "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "f72b2cba8f79dd9d536f534f76874b58ad37876f" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f72b2cba8f79dd9d536f534f76874b58ad37876f", - "reference": "f72b2cba8f79dd9d536f534f76874b58ad37876f", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.3.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "241d5ac4910d256660238a7ecf250deba4c73063" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/241d5ac4910d256660238a7ecf250deba4c73063", + "reference": "241d5ac4910d256660238a7ecf250deba4c73063", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/translation-contracts": "^2.5|^3.0" }, "conflict": { - "symfony/config": "<5.4", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<5.4", + "nikic/php-parser": "<5.0", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<5.4", + "symfony/http-kernel": "<6.4", "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<5.4", - "symfony/yaml": "<5.4" + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { - "nikic/php-parser": "^4.13", + "nikic/php-parser": "^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/intl": "^5.4|^6.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^5.4|^6.0", + "symfony/routing": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0" + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1371,7 +1647,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.3.0" + "source": "https://github.com/symfony/translation/tree/v7.3.1" }, "funding": [ { @@ -1387,20 +1663,20 @@ "type": "tidelift" } ], - "time": "2023-05-19T12:46:45+00:00" + "time": "2025-06-27T19:55:54+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.3.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86" + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/02c24deb352fb0d79db5486c0c79905a85e37e86", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d", "shasum": "" }, "require": { @@ -1408,12 +1684,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -1449,7 +1725,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0" }, "funding": [ { @@ -1465,35 +1741,35 @@ "type": "tidelift" } ], - "time": "2023-05-30T17:17:10+00:00" + "time": "2024-09-27T08:32:26+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v5.5.0", + "version": "v5.6.2", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7" + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", - "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af", + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af", "shasum": "" }, "require": { "ext-pcre": "*", - "graham-campbell/result-type": "^1.0.2", - "php": "^7.1.3 || ^8.0", - "phpoption/phpoption": "^1.8", - "symfony/polyfill-ctype": "^1.23", - "symfony/polyfill-mbstring": "^1.23.1", - "symfony/polyfill-php80": "^1.23.1" + "graham-campbell/result-type": "^1.1.3", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.3", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.2", "ext-filter": "*", - "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25" + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" }, "suggest": { "ext-filter": "Required to use the boolean validator." @@ -1502,10 +1778,10 @@ "extra": { "bamarni-bin": { "bin-links": true, - "forward-command": true + "forward-command": false }, "branch-alias": { - "dev-master": "5.5-dev" + "dev-master": "5.6-dev" } }, "autoload": { @@ -1537,7 +1813,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0" + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2" }, "funding": [ { @@ -1549,19 +1825,19 @@ "type": "tidelift" } ], - "time": "2022-10-16T01:01:54+00:00" + "time": "2025-04-30T23:37:27+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "php": "^8.2", "ext-json": "*" }, - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/metadata.php b/metadata.php new file mode 100644 index 0000000..5589989 --- /dev/null +++ b/metadata.php @@ -0,0 +1,12 @@ +load(); +$dotenv->required('AWS_KEY')->notEmpty(); +$dotenv->required('AWS_SECRET')->notEmpty(); +$dotenv->required('AWS_REGION')->notEmpty(); + +$machine = App\MachineDetails::getDetails(); +echo json_encode($machine, JSON_PRETTY_PRINT) . PHP_EOL;