From 94ddbd85c520114c31e2ba713d977251b8ad1a41 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 10:00:31 +0200 Subject: [PATCH 1/9] install asyncAws s3 module --- composer.json | 3 +- composer.lock | 696 +- package-lock.json | 12651 ---------------- vendor/async-aws/core/CHANGELOG.md | 433 + vendor/async-aws/core/LICENSE | 21 + vendor/async-aws/core/README.md | 21 + vendor/async-aws/core/composer.json | 44 + vendor/async-aws/core/roave-bc-check.yaml | 3 + vendor/async-aws/core/src/AbstractApi.php | 358 + .../async-aws/core/src/AwsClientFactory.php | 631 + .../async-aws/core/src/AwsError/AwsError.php | 54 + .../AwsErrorFactoryFromResponseTrait.php | 16 + .../src/AwsError/AwsErrorFactoryInterface.php | 15 + .../src/AwsError/ChainAwsErrorFactory.php | 43 + .../src/AwsError/JsonRestAwsErrorFactory.php | 45 + .../src/AwsError/JsonRpcAwsErrorFactory.php | 42 + .../core/src/AwsError/XmlAwsErrorFactory.php | 54 + vendor/async-aws/core/src/Configuration.php | 266 + .../core/src/Credentials/CacheProvider.php | 48 + .../core/src/Credentials/ChainProvider.php | 84 + .../src/Credentials/ConfigurationProvider.php | 92 + .../src/Credentials/ContainerProvider.php | 80 + .../src/Credentials/CredentialProvider.php | 20 + .../core/src/Credentials/Credentials.php | 88 + .../core/src/Credentials/DateFromResult.php | 21 + .../core/src/Credentials/IniFileLoader.php | 110 + .../core/src/Credentials/IniFileProvider.php | 224 + .../core/src/Credentials/InstanceProvider.php | 158 + .../core/src/Credentials/NullProvider.php | 20 + .../core/src/Credentials/PsrCacheProvider.php | 73 + .../src/Credentials/SsoCacheFileLoader.php | 79 + .../src/Credentials/SymfonyCacheProvider.php | 71 + .../src/Credentials/WebIdentityProvider.php | 158 + .../src/EndpointDiscovery/EndpointCache.php | 126 + .../EndpointDiscovery/EndpointInterface.php | 10 + vendor/async-aws/core/src/EnvVar.php | 31 + .../core/src/Exception/Exception.php | 14 + .../src/Exception/Http/ClientException.php | 17 + .../core/src/Exception/Http/HttpException.php | 21 + .../src/Exception/Http/HttpExceptionTrait.php | 81 + .../src/Exception/Http/NetworkException.php | 17 + .../Exception/Http/RedirectionException.php | 17 + .../src/Exception/Http/ServerException.php | 17 + .../core/src/Exception/InvalidArgument.php | 9 + .../core/src/Exception/LogicException.php | 9 + .../core/src/Exception/MissingDependency.php | 16 + .../core/src/Exception/RuntimeException.php | 9 + .../core/src/Exception/UnexpectedValue.php | 9 + .../core/src/Exception/UnparsableResponse.php | 9 + .../core/src/Exception/UnsupportedRegion.php | 9 + .../src/HttpClient/AwsHttpClientFactory.php | 32 + .../core/src/HttpClient/AwsRetryStrategy.php | 73 + vendor/async-aws/core/src/Input.php | 36 + vendor/async-aws/core/src/Request.php | 215 + vendor/async-aws/core/src/RequestContext.php | 119 + vendor/async-aws/core/src/Response.php | 477 + vendor/async-aws/core/src/Result.php | 145 + vendor/async-aws/core/src/Signer/Signer.php | 19 + vendor/async-aws/core/src/Signer/SignerV4.php | 369 + .../core/src/Signer/SigningContext.php | 78 + .../core/src/Stream/CallableStream.php | 84 + .../core/src/Stream/FixedSizeStream.php | 90 + .../core/src/Stream/IterableStream.php | 70 + .../core/src/Stream/ReadOnceResultStream.php | 12 + .../core/src/Stream/RequestStream.php | 22 + .../core/src/Stream/ResourceStream.php | 105 + .../src/Stream/ResponseBodyResourceStream.php | 82 + .../core/src/Stream/ResponseBodyStream.php | 101 + .../core/src/Stream/ResultStream.php | 35 + .../core/src/Stream/RewindableStream.php | 97 + .../core/src/Stream/StreamFactory.php | 34 + .../core/src/Stream/StringStream.php | 68 + .../Sts/Exception/ExpiredTokenException.php | 13 + .../IDPCommunicationErrorException.php | 15 + .../Exception/IDPRejectedClaimException.php | 15 + .../InvalidIdentityTokenException.php | 13 + .../MalformedPolicyDocumentException.php | 12 + .../PackedPolicyTooLargeException.php | 22 + .../Sts/Exception/RegionDisabledException.php | 16 + .../core/src/Sts/Input/AssumeRoleRequest.php | 550 + .../AssumeRoleWithWebIdentityRequest.php | 320 + .../Sts/Input/GetCallerIdentityRequest.php | 58 + .../src/Sts/Result/AssumeRoleResponse.php | 110 + .../AssumeRoleWithWebIdentityResponse.php | 166 + .../Sts/Result/GetCallerIdentityResponse.php | 69 + vendor/async-aws/core/src/Sts/StsClient.php | 445 + .../src/Sts/ValueObject/AssumedRoleUser.php | 70 + .../core/src/Sts/ValueObject/Credentials.php | 96 + .../Sts/ValueObject/PolicyDescriptorType.php | 59 + .../src/Sts/ValueObject/ProvidedContext.php | 72 + .../core/src/Sts/ValueObject/Tag.php | 94 + .../src/Test/Http/SimpleMockedResponse.php | 91 + .../core/src/Test/ResultMockFactory.php | 290 + .../core/src/Test/SimpleResultStream.php | 53 + vendor/async-aws/core/src/Test/TestCase.php | 103 + vendor/async-aws/core/src/Waiter.php | 228 + vendor/async-aws/s3/CHANGELOG.md | 247 + vendor/async-aws/s3/LICENSE | 21 + vendor/async-aws/s3/README.md | 20 + vendor/async-aws/s3/composer.json | 36 + .../async-aws/s3/src/Enum/ArchiveStatus.php | 17 + .../async-aws/s3/src/Enum/BucketCannedACL.php | 21 + .../s3/src/Enum/BucketLocationConstraint.php | 69 + .../s3/src/Enum/ChecksumAlgorithm.php | 21 + vendor/async-aws/s3/src/Enum/ChecksumMode.php | 15 + vendor/async-aws/s3/src/Enum/EncodingType.php | 21 + vendor/async-aws/s3/src/Enum/Event.php | 70 + .../async-aws/s3/src/Enum/FilterRuleName.php | 17 + .../src/Enum/IntelligentTieringAccessTier.php | 17 + .../s3/src/Enum/MetadataDirective.php | 17 + .../async-aws/s3/src/Enum/ObjectCannedACL.php | 27 + .../s3/src/Enum/ObjectLockLegalHoldStatus.php | 17 + .../async-aws/s3/src/Enum/ObjectLockMode.php | 17 + .../async-aws/s3/src/Enum/ObjectOwnership.php | 33 + .../s3/src/Enum/ObjectStorageClass.php | 33 + .../s3/src/Enum/OptionalObjectAttributes.php | 15 + vendor/async-aws/s3/src/Enum/Permission.php | 23 + .../s3/src/Enum/ReplicationStatus.php | 21 + .../async-aws/s3/src/Enum/RequestCharged.php | 18 + vendor/async-aws/s3/src/Enum/RequestPayer.php | 22 + .../s3/src/Enum/ServerSideEncryption.php | 19 + vendor/async-aws/s3/src/Enum/StorageClass.php | 33 + .../s3/src/Enum/TaggingDirective.php | 17 + vendor/async-aws/s3/src/Enum/Type.php | 19 + .../BucketAlreadyExistsException.php | 13 + .../BucketAlreadyOwnedByYouException.php | 15 + .../Exception/InvalidObjectStateException.php | 50 + .../src/Exception/NoSuchBucketException.php | 12 + .../s3/src/Exception/NoSuchKeyException.php | 12 + .../src/Exception/NoSuchUploadException.php | 12 + .../ObjectNotInActiveTierErrorException.php | 12 + .../src/Input/AbortMultipartUploadRequest.php | 210 + .../Input/CompleteMultipartUploadRequest.php | 449 + .../s3/src/Input/CopyObjectRequest.php | 1267 ++ .../s3/src/Input/CreateBucketRequest.php | 337 + .../Input/CreateMultipartUploadRequest.php | 933 ++ .../s3/src/Input/DeleteBucketCorsRequest.php | 107 + .../s3/src/Input/DeleteBucketRequest.php | 107 + .../s3/src/Input/DeleteObjectRequest.php | 260 + .../src/Input/DeleteObjectTaggingRequest.php | 174 + .../s3/src/Input/DeleteObjectsRequest.php | 292 + .../s3/src/Input/GetBucketCorsRequest.php | 116 + .../src/Input/GetBucketEncryptionRequest.php | 107 + .../s3/src/Input/GetObjectAclRequest.php | 200 + .../s3/src/Input/GetObjectRequest.php | 633 + .../s3/src/Input/GetObjectTaggingRequest.php | 207 + .../s3/src/Input/HeadBucketRequest.php | 127 + .../s3/src/Input/HeadObjectRequest.php | 480 + .../s3/src/Input/ListBucketsRequest.php | 51 + .../src/Input/ListMultipartUploadsRequest.php | 329 + .../s3/src/Input/ListObjectsV2Request.php | 386 + .../s3/src/Input/ListPartsRequest.php | 347 + .../s3/src/Input/PutBucketCorsRequest.php | 223 + ...BucketNotificationConfigurationRequest.php | 170 + .../s3/src/Input/PutBucketTaggingRequest.php | 221 + .../s3/src/Input/PutObjectAclRequest.php | 497 + .../s3/src/Input/PutObjectRequest.php | 1178 ++ .../s3/src/Input/PutObjectTaggingRequest.php | 318 + .../s3/src/Input/UploadPartRequest.php | 557 + .../src/Result/AbortMultipartUploadOutput.php | 32 + .../s3/src/Result/BucketExistsWaiter.php | 49 + .../s3/src/Result/BucketNotExistsWaiter.php | 37 + .../Result/CompleteMultipartUploadOutput.php | 273 + .../s3/src/Result/CopyObjectOutput.php | 202 + .../s3/src/Result/CreateBucketOutput.php | 30 + .../Result/CreateMultipartUploadOutput.php | 251 + .../s3/src/Result/DeleteObjectOutput.php | 62 + .../src/Result/DeleteObjectTaggingOutput.php | 30 + .../s3/src/Result/DeleteObjectsOutput.php | 109 + .../s3/src/Result/GetBucketCorsOutput.php | 118 + .../src/Result/GetBucketEncryptionOutput.php | 51 + .../s3/src/Result/GetObjectAclOutput.php | 95 + .../s3/src/Result/GetObjectOutput.php | 621 + .../s3/src/Result/GetObjectTaggingOutput.php | 67 + .../s3/src/Result/HeadObjectOutput.php | 641 + .../s3/src/Result/ListBucketsOutput.php | 81 + .../src/Result/ListMultipartUploadsOutput.php | 402 + .../s3/src/Result/ListObjectsV2Output.php | 438 + .../s3/src/Result/ListPartsOutput.php | 352 + .../s3/src/Result/ObjectExistsWaiter.php | 41 + .../s3/src/Result/ObjectNotExistsWaiter.php | 37 + .../s3/src/Result/PutObjectAclOutput.php | 32 + .../s3/src/Result/PutObjectOutput.php | 259 + .../s3/src/Result/PutObjectTaggingOutput.php | 30 + .../s3/src/Result/UploadPartOutput.php | 206 + vendor/async-aws/s3/src/S3Client.php | 2651 ++++ .../async-aws/s3/src/Signer/SignerV4ForS3.php | 173 + .../src/ValueObject/AccessControlPolicy.php | 79 + .../s3/src/ValueObject/AwsObject.php | 169 + .../async-aws/s3/src/ValueObject/Bucket.php | 58 + .../s3/src/ValueObject/CORSConfiguration.php | 71 + .../async-aws/s3/src/ValueObject/CORSRule.php | 174 + .../s3/src/ValueObject/CommonPrefix.php | 43 + .../ValueObject/CompletedMultipartUpload.php | 60 + .../s3/src/ValueObject/CompletedPart.php | 157 + .../s3/src/ValueObject/CopyObjectResult.php | 132 + .../ValueObject/CreateBucketConfiguration.php | 61 + .../async-aws/s3/src/ValueObject/Delete.php | 86 + .../s3/src/ValueObject/DeletedObject.php | 88 + vendor/async-aws/s3/src/ValueObject/Error.php | 563 + .../ValueObject/EventBridgeConfiguration.php | 24 + .../s3/src/ValueObject/FilterRule.php | 82 + vendor/async-aws/s3/src/ValueObject/Grant.php | 80 + .../async-aws/s3/src/ValueObject/Grantee.php | 155 + .../s3/src/ValueObject/Initiator.php | 57 + .../LambdaFunctionConfiguration.php | 124 + .../s3/src/ValueObject/MultipartUpload.php | 140 + .../ValueObject/NotificationConfiguration.php | 129 + .../NotificationConfigurationFilter.php | 54 + .../s3/src/ValueObject/ObjectIdentifier.php | 83 + vendor/async-aws/s3/src/ValueObject/Owner.php | 79 + vendor/async-aws/s3/src/ValueObject/Part.php | 162 + .../s3/src/ValueObject/QueueConfiguration.php | 123 + .../s3/src/ValueObject/RestoreStatus.php | 72 + .../s3/src/ValueObject/S3KeyFilter.php | 56 + .../ServerSideEncryptionByDefault.php | 92 + .../ServerSideEncryptionConfiguration.php | 54 + .../ValueObject/ServerSideEncryptionRule.php | 63 + vendor/async-aws/s3/src/ValueObject/Tag.php | 77 + .../async-aws/s3/src/ValueObject/Tagging.php | 69 + .../s3/src/ValueObject/TopicConfiguration.php | 126 + vendor/autoload.php | 20 +- vendor/bin/jp.php | 120 +- vendor/bin/jp.php.bat | 5 + vendor/composer/ClassLoader.php | 208 +- vendor/composer/InstalledVersions.php | 359 + vendor/composer/autoload_classmap.php | 9 +- vendor/composer/autoload_files.php | 6 +- vendor/composer/autoload_namespaces.php | 2 +- vendor/composer/autoload_psr4.php | 14 +- vendor/composer/autoload_real.php | 60 +- vendor/composer/autoload_static.php | 73 +- vendor/composer/installed.json | 2343 ++- vendor/composer/installed.php | 257 + vendor/composer/platform_check.php | 26 + vendor/psr/cache/CHANGELOG.md | 16 + vendor/psr/cache/LICENSE.txt | 19 + vendor/psr/cache/README.md | 9 + vendor/psr/cache/composer.json | 25 + vendor/psr/cache/src/CacheException.php | 10 + vendor/psr/cache/src/CacheItemInterface.php | 105 + .../psr/cache/src/CacheItemPoolInterface.php | 138 + .../cache/src/InvalidArgumentException.php | 13 + vendor/psr/container/.gitignore | 3 + vendor/psr/container/LICENSE | 21 + vendor/psr/container/README.md | 13 + vendor/psr/container/composer.json | 22 + .../src/ContainerExceptionInterface.php | 10 + .../psr/container/src/ContainerInterface.php | 36 + .../src/NotFoundExceptionInterface.php | 10 + vendor/psr/log/LICENSE | 19 + vendor/psr/log/Psr/Log/AbstractLogger.php | 128 + .../log/Psr/Log/InvalidArgumentException.php | 7 + vendor/psr/log/Psr/Log/LogLevel.php | 18 + .../psr/log/Psr/Log/LoggerAwareInterface.php | 18 + vendor/psr/log/Psr/Log/LoggerAwareTrait.php | 26 + vendor/psr/log/Psr/Log/LoggerInterface.php | 125 + vendor/psr/log/Psr/Log/LoggerTrait.php | 142 + vendor/psr/log/Psr/Log/NullLogger.php | 30 + vendor/psr/log/Psr/Log/Test/DummyTest.php | 18 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 138 + vendor/psr/log/Psr/Log/Test/TestLogger.php | 147 + vendor/psr/log/README.md | 58 + vendor/psr/log/composer.json | 26 + .../symfony/http-client-contracts/.gitignore | 3 + .../http-client-contracts/CHANGELOG.md | 5 + .../http-client-contracts/ChunkInterface.php | 71 + .../Exception/ClientExceptionInterface.php | 21 + .../Exception/DecodingExceptionInterface.php | 21 + .../Exception/ExceptionInterface.php | 21 + .../Exception/HttpExceptionInterface.php | 24 + .../RedirectionExceptionInterface.php | 21 + .../Exception/ServerExceptionInterface.php | 21 + .../Exception/TimeoutExceptionInterface.php | 21 + .../Exception/TransportExceptionInterface.php | 21 + .../HttpClientInterface.php | 95 + vendor/symfony/http-client-contracts/LICENSE | 19 + .../symfony/http-client-contracts/README.md | 9 + .../ResponseInterface.php | 109 + .../ResponseStreamInterface.php | 26 + .../Test/Fixtures/web/index.php | 192 + .../Test/HttpClientTestCase.php | 1137 ++ .../Test/TestHttpServer.php | 46 + .../http-client-contracts/composer.json | 37 + vendor/symfony/http-client/AmpHttpClient.php | 181 + .../http-client/AsyncDecoratorTrait.php | 48 + vendor/symfony/http-client/CHANGELOG.md | 54 + .../symfony/http-client/CachingHttpClient.php | 152 + .../symfony/http-client/Chunk/DataChunk.php | 87 + .../symfony/http-client/Chunk/ErrorChunk.php | 140 + .../symfony/http-client/Chunk/FirstChunk.php | 28 + .../http-client/Chunk/InformationalChunk.php | 35 + .../symfony/http-client/Chunk/LastChunk.php | 28 + .../http-client/Chunk/ServerSentEvent.php | 79 + vendor/symfony/http-client/CurlHttpClient.php | 552 + .../DataCollector/HttpClientDataCollector.php | 176 + vendor/symfony/http-client/DecoratorTrait.php | 66 + .../DependencyInjection/HttpClientPass.php | 51 + .../http-client/EventSourceHttpClient.php | 159 + .../http-client/Exception/ClientException.php | 24 + .../Exception/EventSourceException.php | 21 + .../Exception/HttpExceptionTrait.php | 78 + .../Exception/InvalidArgumentException.php | 21 + .../http-client/Exception/JsonException.php | 23 + .../Exception/RedirectionException.php | 24 + .../http-client/Exception/ServerException.php | 24 + .../Exception/TimeoutException.php | 21 + .../Exception/TransportException.php | 21 + vendor/symfony/http-client/HttpClient.php | 79 + .../symfony/http-client/HttpClientTrait.php | 710 + vendor/symfony/http-client/HttpOptions.php | 331 + vendor/symfony/http-client/HttplugClient.php | 276 + .../symfony/http-client/Internal/AmpBody.php | 142 + .../http-client/Internal/AmpClientState.php | 217 + .../http-client/Internal/AmpListener.php | 183 + .../http-client/Internal/AmpResolver.php | 52 + .../symfony/http-client/Internal/Canary.php | 40 + .../http-client/Internal/ClientState.php | 26 + .../http-client/Internal/CurlClientState.php | 149 + .../symfony/http-client/Internal/DnsCache.php | 39 + .../http-client/Internal/HttplugWaitLoop.php | 145 + .../Internal/NativeClientState.php | 47 + .../http-client/Internal/PushedResponse.php | 41 + vendor/symfony/http-client/LICENSE | 19 + vendor/symfony/http-client/MockHttpClient.php | 124 + .../symfony/http-client/NativeHttpClient.php | 468 + .../NoPrivateNetworkHttpClient.php | 132 + vendor/symfony/http-client/Psr18Client.php | 248 + vendor/symfony/http-client/README.md | 27 + .../http-client/Response/AmpResponse.php | 460 + .../http-client/Response/AsyncContext.php | 195 + .../http-client/Response/AsyncResponse.php | 478 + .../Response/CommonResponseTrait.php | 185 + .../http-client/Response/CurlResponse.php | 473 + .../http-client/Response/HttplugPromise.php | 80 + .../http-client/Response/MockResponse.php | 343 + .../http-client/Response/NativeResponse.php | 376 + .../http-client/Response/ResponseStream.php | 54 + .../http-client/Response/StreamWrapper.php | 313 + .../Response/StreamableInterface.php | 35 + .../Response/TraceableResponse.php | 219 + .../Response/TransportResponseTrait.php | 312 + .../Retry/GenericRetryStrategy.php | 115 + .../Retry/RetryStrategyInterface.php | 36 + .../http-client/RetryableHttpClient.php | 171 + .../symfony/http-client/ScopingHttpClient.php | 131 + .../http-client/TraceableHttpClient.php | 120 + vendor/symfony/http-client/composer.json | 55 + vendor/symfony/polyfill-php73/LICENSE | 19 + vendor/symfony/polyfill-php73/Php73.php | 43 + vendor/symfony/polyfill-php73/README.md | 18 + .../Resources/stubs/JsonException.php | 16 + vendor/symfony/polyfill-php73/bootstrap.php | 31 + vendor/symfony/polyfill-php73/composer.json | 36 + vendor/symfony/polyfill-php80/LICENSE | 19 + vendor/symfony/polyfill-php80/Php80.php | 115 + vendor/symfony/polyfill-php80/PhpToken.php | 103 + vendor/symfony/polyfill-php80/README.md | 25 + .../Resources/stubs/Attribute.php | 31 + .../Resources/stubs/PhpToken.php | 16 + .../Resources/stubs/Stringable.php | 20 + .../Resources/stubs/UnhandledMatchError.php | 16 + .../Resources/stubs/ValueError.php | 16 + vendor/symfony/polyfill-php80/bootstrap.php | 42 + vendor/symfony/polyfill-php80/composer.json | 40 + vendor/symfony/service-contracts/.gitignore | 3 + .../service-contracts/Attribute/Required.php | 25 + .../Attribute/SubscribedService.php | 33 + vendor/symfony/service-contracts/CHANGELOG.md | 5 + vendor/symfony/service-contracts/LICENSE | 19 + vendor/symfony/service-contracts/README.md | 9 + .../service-contracts/ResetInterface.php | 30 + .../service-contracts/ServiceLocatorTrait.php | 128 + .../ServiceProviderInterface.php | 36 + .../ServiceSubscriberInterface.php | 53 + .../ServiceSubscriberTrait.php | 109 + .../Test/ServiceLocatorTest.php | 95 + .../symfony/service-contracts/composer.json | 42 + 378 files changed, 48983 insertions(+), 13551 deletions(-) delete mode 100644 package-lock.json create mode 100644 vendor/async-aws/core/CHANGELOG.md create mode 100644 vendor/async-aws/core/LICENSE create mode 100644 vendor/async-aws/core/README.md create mode 100644 vendor/async-aws/core/composer.json create mode 100644 vendor/async-aws/core/roave-bc-check.yaml create mode 100644 vendor/async-aws/core/src/AbstractApi.php create mode 100644 vendor/async-aws/core/src/AwsClientFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/AwsError.php create mode 100644 vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php create mode 100644 vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php create mode 100644 vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/Configuration.php create mode 100644 vendor/async-aws/core/src/Credentials/CacheProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/ChainProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/ConfigurationProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/ContainerProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/CredentialProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/Credentials.php create mode 100644 vendor/async-aws/core/src/Credentials/DateFromResult.php create mode 100644 vendor/async-aws/core/src/Credentials/IniFileLoader.php create mode 100644 vendor/async-aws/core/src/Credentials/IniFileProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/InstanceProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/NullProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/PsrCacheProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php create mode 100644 vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/WebIdentityProvider.php create mode 100644 vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php create mode 100644 vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php create mode 100644 vendor/async-aws/core/src/EnvVar.php create mode 100644 vendor/async-aws/core/src/Exception/Exception.php create mode 100644 vendor/async-aws/core/src/Exception/Http/ClientException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/HttpException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/HttpExceptionTrait.php create mode 100644 vendor/async-aws/core/src/Exception/Http/NetworkException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/RedirectionException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/ServerException.php create mode 100644 vendor/async-aws/core/src/Exception/InvalidArgument.php create mode 100644 vendor/async-aws/core/src/Exception/LogicException.php create mode 100644 vendor/async-aws/core/src/Exception/MissingDependency.php create mode 100644 vendor/async-aws/core/src/Exception/RuntimeException.php create mode 100644 vendor/async-aws/core/src/Exception/UnexpectedValue.php create mode 100644 vendor/async-aws/core/src/Exception/UnparsableResponse.php create mode 100644 vendor/async-aws/core/src/Exception/UnsupportedRegion.php create mode 100644 vendor/async-aws/core/src/HttpClient/AwsHttpClientFactory.php create mode 100644 vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php create mode 100644 vendor/async-aws/core/src/Input.php create mode 100644 vendor/async-aws/core/src/Request.php create mode 100644 vendor/async-aws/core/src/RequestContext.php create mode 100644 vendor/async-aws/core/src/Response.php create mode 100644 vendor/async-aws/core/src/Result.php create mode 100644 vendor/async-aws/core/src/Signer/Signer.php create mode 100644 vendor/async-aws/core/src/Signer/SignerV4.php create mode 100644 vendor/async-aws/core/src/Signer/SigningContext.php create mode 100644 vendor/async-aws/core/src/Stream/CallableStream.php create mode 100644 vendor/async-aws/core/src/Stream/FixedSizeStream.php create mode 100644 vendor/async-aws/core/src/Stream/IterableStream.php create mode 100644 vendor/async-aws/core/src/Stream/ReadOnceResultStream.php create mode 100644 vendor/async-aws/core/src/Stream/RequestStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResourceStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResponseBodyStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResultStream.php create mode 100644 vendor/async-aws/core/src/Stream/RewindableStream.php create mode 100644 vendor/async-aws/core/src/Stream/StreamFactory.php create mode 100644 vendor/async-aws/core/src/Stream/StringStream.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/IDPCommunicationErrorException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/IDPRejectedClaimException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/InvalidIdentityTokenException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/MalformedPolicyDocumentException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/PackedPolicyTooLargeException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/RegionDisabledException.php create mode 100644 vendor/async-aws/core/src/Sts/Input/AssumeRoleRequest.php create mode 100644 vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php create mode 100644 vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php create mode 100644 vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php create mode 100644 vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php create mode 100644 vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php create mode 100644 vendor/async-aws/core/src/Sts/StsClient.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/Credentials.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/Tag.php create mode 100644 vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php create mode 100644 vendor/async-aws/core/src/Test/ResultMockFactory.php create mode 100644 vendor/async-aws/core/src/Test/SimpleResultStream.php create mode 100644 vendor/async-aws/core/src/Test/TestCase.php create mode 100644 vendor/async-aws/core/src/Waiter.php create mode 100644 vendor/async-aws/s3/CHANGELOG.md create mode 100644 vendor/async-aws/s3/LICENSE create mode 100644 vendor/async-aws/s3/README.md create mode 100644 vendor/async-aws/s3/composer.json create mode 100644 vendor/async-aws/s3/src/Enum/ArchiveStatus.php create mode 100644 vendor/async-aws/s3/src/Enum/BucketCannedACL.php create mode 100644 vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php create mode 100644 vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php create mode 100644 vendor/async-aws/s3/src/Enum/ChecksumMode.php create mode 100644 vendor/async-aws/s3/src/Enum/EncodingType.php create mode 100644 vendor/async-aws/s3/src/Enum/Event.php create mode 100644 vendor/async-aws/s3/src/Enum/FilterRuleName.php create mode 100644 vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php create mode 100644 vendor/async-aws/s3/src/Enum/MetadataDirective.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectCannedACL.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectLockMode.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectOwnership.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectStorageClass.php create mode 100644 vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php create mode 100644 vendor/async-aws/s3/src/Enum/Permission.php create mode 100644 vendor/async-aws/s3/src/Enum/ReplicationStatus.php create mode 100644 vendor/async-aws/s3/src/Enum/RequestCharged.php create mode 100644 vendor/async-aws/s3/src/Enum/RequestPayer.php create mode 100644 vendor/async-aws/s3/src/Enum/ServerSideEncryption.php create mode 100644 vendor/async-aws/s3/src/Enum/StorageClass.php create mode 100644 vendor/async-aws/s3/src/Enum/TaggingDirective.php create mode 100644 vendor/async-aws/s3/src/Enum/Type.php create mode 100644 vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php create mode 100644 vendor/async-aws/s3/src/Exception/BucketAlreadyOwnedByYouException.php create mode 100644 vendor/async-aws/s3/src/Exception/InvalidObjectStateException.php create mode 100644 vendor/async-aws/s3/src/Exception/NoSuchBucketException.php create mode 100644 vendor/async-aws/s3/src/Exception/NoSuchKeyException.php create mode 100644 vendor/async-aws/s3/src/Exception/NoSuchUploadException.php create mode 100644 vendor/async-aws/s3/src/Exception/ObjectNotInActiveTierErrorException.php create mode 100644 vendor/async-aws/s3/src/Input/AbortMultipartUploadRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CopyObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CreateBucketRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteBucketRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetObjectAclRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/HeadBucketRequest.php create mode 100644 vendor/async-aws/s3/src/Input/HeadObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/ListBucketsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/ListObjectsV2Request.php create mode 100644 vendor/async-aws/s3/src/Input/ListPartsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutObjectAclRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/UploadPartRequest.php create mode 100644 vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php create mode 100644 vendor/async-aws/s3/src/Result/BucketExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php create mode 100644 vendor/async-aws/s3/src/Result/CopyObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/CreateBucketOutput.php create mode 100644 vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php create mode 100644 vendor/async-aws/s3/src/Result/DeleteObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php create mode 100644 vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetObjectAclOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php create mode 100644 vendor/async-aws/s3/src/Result/HeadObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ListBucketsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ListObjectsV2Output.php create mode 100644 vendor/async-aws/s3/src/Result/ListPartsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/PutObjectAclOutput.php create mode 100644 vendor/async-aws/s3/src/Result/PutObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php create mode 100644 vendor/async-aws/s3/src/Result/UploadPartOutput.php create mode 100644 vendor/async-aws/s3/src/S3Client.php create mode 100644 vendor/async-aws/s3/src/Signer/SignerV4ForS3.php create mode 100644 vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php create mode 100644 vendor/async-aws/s3/src/ValueObject/AwsObject.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Bucket.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CORSRule.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CommonPrefix.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CompletedPart.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Delete.php create mode 100644 vendor/async-aws/s3/src/ValueObject/DeletedObject.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Error.php create mode 100644 vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/FilterRule.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Grant.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Grantee.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Initiator.php create mode 100644 vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/MultipartUpload.php create mode 100644 vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Owner.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Part.php create mode 100644 vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/RestoreStatus.php create mode 100644 vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Tag.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Tagging.php create mode 100644 vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php create mode 100644 vendor/bin/jp.php.bat create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/installed.php create mode 100644 vendor/composer/platform_check.php create mode 100644 vendor/psr/cache/CHANGELOG.md create mode 100644 vendor/psr/cache/LICENSE.txt create mode 100644 vendor/psr/cache/README.md create mode 100644 vendor/psr/cache/composer.json create mode 100644 vendor/psr/cache/src/CacheException.php create mode 100644 vendor/psr/cache/src/CacheItemInterface.php create mode 100644 vendor/psr/cache/src/CacheItemPoolInterface.php create mode 100644 vendor/psr/cache/src/InvalidArgumentException.php create mode 100644 vendor/psr/container/.gitignore create mode 100644 vendor/psr/container/LICENSE create mode 100644 vendor/psr/container/README.md create mode 100644 vendor/psr/container/composer.json create mode 100644 vendor/psr/container/src/ContainerExceptionInterface.php create mode 100644 vendor/psr/container/src/ContainerInterface.php create mode 100644 vendor/psr/container/src/NotFoundExceptionInterface.php create mode 100644 vendor/psr/log/LICENSE create mode 100644 vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 vendor/psr/log/Psr/Log/Test/DummyTest.php create mode 100644 vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 vendor/psr/log/Psr/Log/Test/TestLogger.php create mode 100644 vendor/psr/log/README.md create mode 100644 vendor/psr/log/composer.json create mode 100644 vendor/symfony/http-client-contracts/.gitignore create mode 100644 vendor/symfony/http-client-contracts/CHANGELOG.md create mode 100644 vendor/symfony/http-client-contracts/ChunkInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/HttpClientInterface.php create mode 100644 vendor/symfony/http-client-contracts/LICENSE create mode 100644 vendor/symfony/http-client-contracts/README.md create mode 100644 vendor/symfony/http-client-contracts/ResponseInterface.php create mode 100644 vendor/symfony/http-client-contracts/ResponseStreamInterface.php create mode 100644 vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php create mode 100644 vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php create mode 100644 vendor/symfony/http-client-contracts/Test/TestHttpServer.php create mode 100644 vendor/symfony/http-client-contracts/composer.json create mode 100644 vendor/symfony/http-client/AmpHttpClient.php create mode 100644 vendor/symfony/http-client/AsyncDecoratorTrait.php create mode 100644 vendor/symfony/http-client/CHANGELOG.md create mode 100644 vendor/symfony/http-client/CachingHttpClient.php create mode 100644 vendor/symfony/http-client/Chunk/DataChunk.php create mode 100644 vendor/symfony/http-client/Chunk/ErrorChunk.php create mode 100644 vendor/symfony/http-client/Chunk/FirstChunk.php create mode 100644 vendor/symfony/http-client/Chunk/InformationalChunk.php create mode 100644 vendor/symfony/http-client/Chunk/LastChunk.php create mode 100644 vendor/symfony/http-client/Chunk/ServerSentEvent.php create mode 100644 vendor/symfony/http-client/CurlHttpClient.php create mode 100644 vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php create mode 100644 vendor/symfony/http-client/DecoratorTrait.php create mode 100644 vendor/symfony/http-client/DependencyInjection/HttpClientPass.php create mode 100644 vendor/symfony/http-client/EventSourceHttpClient.php create mode 100644 vendor/symfony/http-client/Exception/ClientException.php create mode 100644 vendor/symfony/http-client/Exception/EventSourceException.php create mode 100644 vendor/symfony/http-client/Exception/HttpExceptionTrait.php create mode 100644 vendor/symfony/http-client/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/http-client/Exception/JsonException.php create mode 100644 vendor/symfony/http-client/Exception/RedirectionException.php create mode 100644 vendor/symfony/http-client/Exception/ServerException.php create mode 100644 vendor/symfony/http-client/Exception/TimeoutException.php create mode 100644 vendor/symfony/http-client/Exception/TransportException.php create mode 100644 vendor/symfony/http-client/HttpClient.php create mode 100644 vendor/symfony/http-client/HttpClientTrait.php create mode 100644 vendor/symfony/http-client/HttpOptions.php create mode 100644 vendor/symfony/http-client/HttplugClient.php create mode 100644 vendor/symfony/http-client/Internal/AmpBody.php create mode 100644 vendor/symfony/http-client/Internal/AmpClientState.php create mode 100644 vendor/symfony/http-client/Internal/AmpListener.php create mode 100644 vendor/symfony/http-client/Internal/AmpResolver.php create mode 100644 vendor/symfony/http-client/Internal/Canary.php create mode 100644 vendor/symfony/http-client/Internal/ClientState.php create mode 100644 vendor/symfony/http-client/Internal/CurlClientState.php create mode 100644 vendor/symfony/http-client/Internal/DnsCache.php create mode 100644 vendor/symfony/http-client/Internal/HttplugWaitLoop.php create mode 100644 vendor/symfony/http-client/Internal/NativeClientState.php create mode 100644 vendor/symfony/http-client/Internal/PushedResponse.php create mode 100644 vendor/symfony/http-client/LICENSE create mode 100644 vendor/symfony/http-client/MockHttpClient.php create mode 100644 vendor/symfony/http-client/NativeHttpClient.php create mode 100644 vendor/symfony/http-client/NoPrivateNetworkHttpClient.php create mode 100644 vendor/symfony/http-client/Psr18Client.php create mode 100644 vendor/symfony/http-client/README.md create mode 100644 vendor/symfony/http-client/Response/AmpResponse.php create mode 100644 vendor/symfony/http-client/Response/AsyncContext.php create mode 100644 vendor/symfony/http-client/Response/AsyncResponse.php create mode 100644 vendor/symfony/http-client/Response/CommonResponseTrait.php create mode 100644 vendor/symfony/http-client/Response/CurlResponse.php create mode 100644 vendor/symfony/http-client/Response/HttplugPromise.php create mode 100644 vendor/symfony/http-client/Response/MockResponse.php create mode 100644 vendor/symfony/http-client/Response/NativeResponse.php create mode 100644 vendor/symfony/http-client/Response/ResponseStream.php create mode 100644 vendor/symfony/http-client/Response/StreamWrapper.php create mode 100644 vendor/symfony/http-client/Response/StreamableInterface.php create mode 100644 vendor/symfony/http-client/Response/TraceableResponse.php create mode 100644 vendor/symfony/http-client/Response/TransportResponseTrait.php create mode 100644 vendor/symfony/http-client/Retry/GenericRetryStrategy.php create mode 100644 vendor/symfony/http-client/Retry/RetryStrategyInterface.php create mode 100644 vendor/symfony/http-client/RetryableHttpClient.php create mode 100644 vendor/symfony/http-client/ScopingHttpClient.php create mode 100644 vendor/symfony/http-client/TraceableHttpClient.php create mode 100644 vendor/symfony/http-client/composer.json create mode 100644 vendor/symfony/polyfill-php73/LICENSE create mode 100644 vendor/symfony/polyfill-php73/Php73.php create mode 100644 vendor/symfony/polyfill-php73/README.md create mode 100644 vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php create mode 100644 vendor/symfony/polyfill-php73/bootstrap.php create mode 100644 vendor/symfony/polyfill-php73/composer.json create mode 100644 vendor/symfony/polyfill-php80/LICENSE create mode 100644 vendor/symfony/polyfill-php80/Php80.php create mode 100644 vendor/symfony/polyfill-php80/PhpToken.php create mode 100644 vendor/symfony/polyfill-php80/README.md create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php create mode 100644 vendor/symfony/polyfill-php80/bootstrap.php create mode 100644 vendor/symfony/polyfill-php80/composer.json create mode 100644 vendor/symfony/service-contracts/.gitignore create mode 100644 vendor/symfony/service-contracts/Attribute/Required.php create mode 100644 vendor/symfony/service-contracts/Attribute/SubscribedService.php create mode 100644 vendor/symfony/service-contracts/CHANGELOG.md create mode 100644 vendor/symfony/service-contracts/LICENSE create mode 100644 vendor/symfony/service-contracts/README.md create mode 100644 vendor/symfony/service-contracts/ResetInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceLocatorTrait.php create mode 100644 vendor/symfony/service-contracts/ServiceProviderInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceSubscriberInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceSubscriberTrait.php create mode 100644 vendor/symfony/service-contracts/Test/ServiceLocatorTest.php create mode 100644 vendor/symfony/service-contracts/composer.json diff --git a/composer.json b/composer.json index 17bd7f3d2..b95e7e1fd 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "yoast/phpunit-polyfills": "dev-main" }, "require": { - "aws/aws-sdk-php": "^3.235" + "aws/aws-sdk-php": "^3.235", + "async-aws/s3": "^2.0" }, "scripts": { "pre-autoload-dump": "Aws\\Script\\Composer\\Composer::removeUnusedServices" diff --git a/composer.lock b/composer.lock index 102d3f949..aef52451a 100644 --- a/composer.lock +++ b/composer.lock @@ -1,11 +1,139 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "796127396252780d637c7e6db70edfc6", + "content-hash": "14ce5f2993b144fc5b52fd63402a4b23", "packages": [ + { + "name": "async-aws/core", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/core.git", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/core/zipball/e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/http-client": "^4.4.16 || ^5.1.7 || ^6.0 || ^7.0", + "symfony/http-client-contracts": "^1.1.8 || ^2.0 || ^3.0", + "symfony/service-contracts": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "async-aws/s3": "<1.1", + "symfony/http-client": "5.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.20-dev" + } + }, + "autoload": { + "psr-4": { + "AsyncAws\\Core\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Core package to integrate with AWS. This is a lightweight AWS SDK provider by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "sdk", + "sts" + ], + "support": { + "source": "https://github.com/async-aws/core/tree/1.20.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-08-07T20:00:50+00:00" + }, + { + "name": "async-aws/s3", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/s3.git", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/s3/zipball/1486ae6592a8f870da60dfc29bfc98390c7b9092", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092", + "shasum": "" + }, + "require": { + "async-aws/core": "^1.9", + "ext-dom": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "psr-4": { + "AsyncAws\\S3\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "S3 client, part of the AWS SDK provided by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "s3", + "sdk" + ], + "support": { + "source": "https://github.com/async-aws/s3/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-08-07T20:00:50+00:00" + }, { "name": "aws/aws-crt-php", "version": "v1.2.1", @@ -477,6 +605,103 @@ ], "time": "2021-06-14T00:11:39+00:00" }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "time": "2021-03-05T17:36:06+00:00" + }, { "name": "psr/http-client", "version": "1.0.2", @@ -628,6 +853,56 @@ ], "time": "2023-04-04T09:50:52+00:00" }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, { "name": "ralouphie/getallheaders", "version": "3.0.3", @@ -718,6 +993,175 @@ "homepage": "https://symfony.com", "time": "2022-01-02T09:53:40+00:00" }, + { + "name": "symfony/http-client", + "version": "v5.4.26", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/19d48ef7f38e5057ed1789a503cd3eccef039bce", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.4", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "2.4" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "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": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v5.4.26" + }, + "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": "2023-07-03T12:14:50+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "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": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.2" + }, + "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": "2022-04-12T15:48:08+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.27.0", @@ -783,6 +1227,251 @@ "shim" ], "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.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": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.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": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, + "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": "2022-05-30T19:17:29+00:00" } ], "packages-dev": [ @@ -2422,5 +3111,6 @@ "platform-dev": [], "platform-overrides": { "php": "7.3.5" - } + }, + "plugin-api-version": "2.3.0" } diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index c910a49db..000000000 --- a/package-lock.json +++ /dev/null @@ -1,12651 +0,0 @@ -{ - "name": "fv-wordpress-flowplayer", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "fv-wordpress-flowplayer", - "version": "1.0.0", - "hasInstallScript": true, - "license": "GPL-3.0", - "devDependencies": { - "@babel/core": "^7.17.9", - "@babel/preset-env": "^7.16.11", - "gulp": "^4.0.2", - "gulp-autoprefixer": "^8.0.0", - "gulp-babel": "^8.0.0", - "gulp-clean-css": "^4.3.0", - "gulp-concat": "^2.6.1", - "gulp-rename": "^2.0.0", - "gulp-sort": "^2.0.0", - "gulp-sourcemaps": "^3.0.0", - "gulp-uglify": "^3.0.2", - "gulp-wp-pot": "^2.5.0", - "gulp-zip": "^5.1.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", - "dev": true, - "dependencies": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-babel/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - ], - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "node_modules/gulp-sourcemaps/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "dependencies": { - "glob-stream": "^6.1.0", - "vinyl-sourcemap": "^1.1.0", - "to-through": "^2.0.0", - "resolve-options": "^1.1.0", - "pumpify": "^1.3.5", - "remove-bom-buffer": "^3.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "fs-mkdirp-stream": "^1.0.0", - "object.assign": "^4.0.4", - "value-or-function": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "readable-stream": "^2.3.3", - "vinyl": "^2.0.0", - "is-valid-glob": "^1.0.0", - "through2": "^2.0.0", - "graceful-fs": "^4.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@gulp-sourcemaps/identity-map/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chokidar/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "node_modules/glob-stream/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", - "dev": true, - "dependencies": { - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "dependencies": { - "flush-write-stream": "^1.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/each-props/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-uglify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", - "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "extend-shallow": "^3.0.2", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "isobject": "^3.0.1", - "make-error-cause": "^1.1.1", - "safe-buffer": "^5.1.2", - "through2": "^2.0.0", - "uglify-js": "^3.0.5", - "vinyl-sourcemaps-apply": "^0.2.0" - } - }, - "node_modules/unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "dependencies": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "node_modules/matched": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", - "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", - "dev": true, - "dependencies": { - "glob": "^7.1.6", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", - "dev": true, - "dependencies": { - "buffer-equal": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", - "dev": true, - "dependencies": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/matchdep/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "extraneous": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/fs-mkdirp-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/gulp-wp-pot": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/gulp-wp-pot/-/gulp-wp-pot-2.5.0.tgz", - "integrity": "sha512-3IIVEsgAaRFi4DWv5hRZcM7VEsCtGD4ZxgPL8qPdX+yrSpwD8I2+Q1cP3olXhn7KLJsnGSNuqor5sxo97H5pmQ==", - "dev": true, - "dependencies": { - "plugin-error": "^1.0.1", - "vinyl": "^2.2.1", - "wp-pot": "^1.9.6" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/remove-bom-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-uglify/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "dependencies": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/gulp-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", - "integrity": "sha512-MyTel3FXOdh1qhw1yKhpimQrAmur9q1X0ZigLmCOxouQD+BD3za9/89O+HfbgBQvvh4igEbp0/PUWO+VqGYG1g==", - "dev": true, - "dependencies": { - "through2": "^2.0.1" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/array-initial/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "dependencies": { - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==", - "dev": true, - "dependencies": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "dependencies": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/micromatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==", - "dev": true, - "dependencies": { - "sparkles": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/gulp-concat/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-sourcemaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz", - "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==", - "dev": true, - "dependencies": { - "@gulp-sourcemaps/identity-map": "^2.0.1", - "@gulp-sourcemaps/map-sources": "^1.0.0", - "acorn": "^6.4.1", - "convert-source-map": "^1.0.0", - "css": "^3.0.0", - "debug-fabulous": "^1.0.0", - "detect-newline": "^2.0.0", - "graceful-fs": "^4.0.0", - "source-map": "^0.6.0", - "strip-bom-string": "^1.0.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-clean-css": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz", - "integrity": "sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg==", - "dev": true, - "dependencies": { - "clean-css": "4.2.3", - "plugin-error": "1.0.1", - "through2": "3.0.1", - "vinyl-sourcemaps-apply": "0.2.1" - } - }, - "node_modules/gulp-uglify/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "dev": true, - "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@gulp-sourcemaps/map-sources/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "dependencies": { - "once": "^1.3.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "dependencies": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - } - }, - "node_modules/glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "dependencies": { - "sparkles": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", - "dev": true, - "dependencies": { - "sver-compat": "^1.5.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/liftoff/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/gulp-uglify/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "dependencies": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "node_modules/php-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.1.2.tgz", - "integrity": "sha512-RRCMK/bCKYPLRhlpfMlVVVsaIesuW+X6UxRqWjm7dTAmTZk8PvD6hCmG/RVeDzse7iqYWJwLJeqEbaGLC+aHeQ==", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/plugin-error/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.1" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/plugin-error/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "dependencies": { - "ansi-wrap": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "dependencies": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/split-string/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/gulp-zip": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.1.0.tgz", - "integrity": "sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw==", - "dev": true, - "dependencies": { - "get-stream": "^5.2.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "vinyl": "^2.1.0", - "yazl": "^2.5.1" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "gulp": ">=4" - }, - "peerDependenciesMeta": { - "gulp": { - "optional": true - } - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/micromatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "dependencies": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/gulp-uglify/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", - "dev": true, - "dependencies": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/plugin-error/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "node_modules/@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-sourcemap/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/glob-stream/node_modules/glob-parent": { - "version": "^6.0.1", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "node_modules/fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://www.patreon.com/infusion" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/to-through/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@gulp-sourcemaps/identity-map/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "^6.0.1", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "dependencies": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "dependencies": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-rename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz", - "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/gulp-clean-css/node_modules/through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "dev": true, - "dependencies": { - "readable-stream": "2 || 3" - } - }, - "node_modules/vinyl-fs/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", - "dev": true, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", - "dev": true, - "dependencies": { - "each-props": "^1.3.2", - "is-plain-object": "^5.0.0" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/nanomatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", - "dev": true, - "dependencies": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "dependencies": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/gulp-autoprefixer": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-8.0.0.tgz", - "integrity": "sha512-sVR++PIaXpa81p52dmmA/jt50bw0egmylK5mjagfgOJ8uLDGaF9tHyzvetkY9Uo0gBZUS5sVqN3kX/GlUKOyog==", - "dev": true, - "dependencies": { - "autoprefixer": "^10.2.6", - "fancy-log": "^1.3.3", - "plugin-error": "^1.0.1", - "postcss": "^8.3.0", - "through2": "^4.0.2", - "vinyl-sourcemaps-apply": "^0.2.1" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "gulp": ">=4" - }, - "peerDependenciesMeta": { - "gulp": { - "optional": true - } - } - }, - "node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true, - "optional": true - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", - "dev": true, - "dependencies": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "dependencies": { - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "semver": "^6.3.0", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "core-js-compat": "^3.25.1", - "@babel/compat-data": "^7.20.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/preset-modules": "^0.1.5", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/types": "^7.20.2", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-reserved-words": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "dependencies": { - "path-root-regex": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/gulp-sort/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha512-4TO2Y3HkBnis4c0dxhAgD/jprySYLACf7nwN6V0HAHDx59g12WlRpUmFy1bRHamjGUEEBrEvCq6SUpsEE2lhUg==", - "dev": true, - "dependencies": { - "make-error": "^1.2.0" - } - }, - "node_modules/path-sort": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-sort/-/path-sort-0.1.0.tgz", - "integrity": "sha512-70MSq7edKtbODYKkqXYzSMQxtYMjDgP3K6D15Fu4KUvpyBPlxDWPvv8JI9GjNDF2K5baPHFEtlg818dOmf2ifg==", - "dev": true - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/snapdragon/node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/micromatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "node_modules/async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", - "dev": true, - "dependencies": { - "source-map": "^0.5.1" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/through2-filter/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-zip/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/@gulp-sourcemaps/identity-map/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", - "dev": true, - "dependencies": { - "async-done": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/fined/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", - "dev": true, - "dependencies": { - "glogg": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "dependencies": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-last/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha512-a2scActrQrDBpBbR3WUZGyGS1JEPLg5PZJdIa7/Bi3GuKAmPYDK6SFhy/NZq5R8KsKKFvtfR0fakbUCcKGCCjg==", - "dev": true, - "dependencies": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp-babel": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-8.0.0.tgz", - "integrity": "sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ==", - "dev": true, - "dependencies": { - "plugin-error": "^1.0.1", - "replace-ext": "^1.0.0", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "dependencies": { - "kind-of": "^5.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/make-iterator/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/debug-fabulous/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "dependencies": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.1" - } - }, - "node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/@gulp-sourcemaps/identity-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", - "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==", - "dev": true, - "dependencies": { - "acorn": "^6.4.1", - "normalize-path": "^3.0.0", - "postcss": "^7.0.16", - "source-map": "^0.6.0", - "through2": "^3.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/nanomatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "dependencies": { - "yargs": "^7.1.0", - "v8flags": "^3.2.0", - "ansi-colors": "^1.0.1", - "color-support": "^1.1.3", - "copy-props": "^2.0.1", - "replace-homedir": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "fancy-log": "^1.3.2", - "matchdep": "^2.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "isobject": "^3.0.1", - "archy": "^1.0.0", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "mute-stdout": "^1.0.0", - "array-sort": "^1.0.0", - "concat-stream": "^1.6.0", - "liftoff": "^3.1.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", - "dev": true, - "dependencies": { - "value-or-function": "^3.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/wp-pot": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/wp-pot/-/wp-pot-1.10.2.tgz", - "integrity": "sha512-NJ9+dsSilghAYMiuGdURJSbKFf9Z2mH+P6ojT8Nw1Pp8KuwvHdRTFTYK73THlYzohUEXlQGpvKkz+mJb8K1ToA==", - "dev": true, - "dependencies": { - "espree": "^9.3.1", - "matched": "^5.0.1", - "path-sort": "^0.1.0", - "php-parser": "^3.0.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.2" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", - "dev": true - }, - "@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - } - }, - "@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "requires": { - "@babel/types": "^7.20.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - } - }, - "@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", - "dev": true - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.10" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@gulp-sourcemaps/identity-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", - "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==", - "dev": true, - "requires": { - "acorn": "^6.4.1", - "normalize-path": "^3.0.0", - "postcss": "^7.0.16", - "source-map": "^0.6.0", - "through2": "^3.0.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==", - "dev": true, - "requires": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - } - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - } - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^6.0.1", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "dependencies": { - "glob-parent": { - "version": "^6.0.1", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - } - } - }, - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true - }, - "copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", - "dev": true, - "requires": { - "each-props": "^1.3.2", - "is-plain-object": "^5.0.0" - } - }, - "core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "dev": true, - "requires": { - "browserslist": "^4.21.4" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "requires": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true - } - } - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^6.0.1", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "glob-parent": { - "version": "^6.0.1", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - } - }, - "gulp-autoprefixer": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-8.0.0.tgz", - "integrity": "sha512-sVR++PIaXpa81p52dmmA/jt50bw0egmylK5mjagfgOJ8uLDGaF9tHyzvetkY9Uo0gBZUS5sVqN3kX/GlUKOyog==", - "dev": true, - "requires": { - "autoprefixer": "^10.2.6", - "fancy-log": "^1.3.3", - "plugin-error": "^1.0.1", - "postcss": "^8.3.0", - "through2": "^4.0.2", - "vinyl-sourcemaps-apply": "^0.2.1" - } - }, - "gulp-babel": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-8.0.0.tgz", - "integrity": "sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ==", - "dev": true, - "requires": { - "plugin-error": "^1.0.1", - "replace-ext": "^1.0.0", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-clean-css": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz", - "integrity": "sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg==", - "dev": true, - "requires": { - "clean-css": "4.2.3", - "plugin-error": "1.0.1", - "through2": "3.0.1", - "vinyl-sourcemaps-apply": "0.2.1" - }, - "dependencies": { - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "dev": true, - "requires": { - "readable-stream": "2 || 3" - } - } - } - }, - "gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha512-a2scActrQrDBpBbR3WUZGyGS1JEPLg5PZJdIa7/Bi3GuKAmPYDK6SFhy/NZq5R8KsKKFvtfR0fakbUCcKGCCjg==", - "dev": true, - "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-rename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz", - "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==", - "dev": true - }, - "gulp-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", - "integrity": "sha512-MyTel3FXOdh1qhw1yKhpimQrAmur9q1X0ZigLmCOxouQD+BD3za9/89O+HfbgBQvvh4igEbp0/PUWO+VqGYG1g==", - "dev": true, - "requires": { - "through2": "^2.0.1" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-sourcemaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz", - "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==", - "dev": true, - "requires": { - "@gulp-sourcemaps/identity-map": "^2.0.1", - "@gulp-sourcemaps/map-sources": "^1.0.0", - "acorn": "^6.4.1", - "convert-source-map": "^1.0.0", - "css": "^3.0.0", - "debug-fabulous": "^1.0.0", - "detect-newline": "^2.0.0", - "graceful-fs": "^4.0.0", - "source-map": "^0.6.0", - "strip-bom-string": "^1.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-uglify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", - "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "extend-shallow": "^3.0.2", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "isobject": "^3.0.1", - "make-error-cause": "^1.1.1", - "safe-buffer": "^5.1.2", - "through2": "^2.0.0", - "uglify-js": "^3.0.5", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-wp-pot": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/gulp-wp-pot/-/gulp-wp-pot-2.5.0.tgz", - "integrity": "sha512-3IIVEsgAaRFi4DWv5hRZcM7VEsCtGD4ZxgPL8qPdX+yrSpwD8I2+Q1cP3olXhn7KLJsnGSNuqor5sxo97H5pmQ==", - "dev": true, - "requires": { - "plugin-error": "^1.0.1", - "vinyl": "^2.2.1", - "wp-pot": "^1.9.6" - } - }, - "gulp-zip": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.1.0.tgz", - "integrity": "sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw==", - "dev": true, - "requires": { - "get-stream": "^5.2.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "vinyl": "^2.1.0", - "yazl": "^2.5.1" - }, - "dependencies": { - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha512-4TO2Y3HkBnis4c0dxhAgD/jprySYLACf7nwN6V0HAHDx59g12WlRpUmFy1bRHamjGUEEBrEvCq6SUpsEE2lhUg==", - "dev": true, - "requires": { - "make-error": "^1.2.0" - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "matched": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", - "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", - "dev": true, - "requires": { - "glob": "^7.1.6", - "picomatch": "^2.2.1" - } - }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true, - "optional": true - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true - }, - "path-sort": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-sort/-/path-sort-0.1.0.tgz", - "integrity": "sha512-70MSq7edKtbODYKkqXYzSMQxtYMjDgP3K6D15Fu4KUvpyBPlxDWPvv8JI9GjNDF2K5baPHFEtlg818dOmf2ifg==", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "php-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.1.2.tgz", - "integrity": "sha512-RRCMK/bCKYPLRhlpfMlVVVsaIesuW+X6UxRqWjm7dTAmTZk8PvD6hCmG/RVeDzse7iqYWJwLJeqEbaGLC+aHeQ==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true - }, - "postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", - "dev": true, - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - } - }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true - } - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true - }, - "source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - } - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "dev": true - }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true - }, - "undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", - "dev": true - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", - "dev": true - }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", - "dev": true, - "requires": { - "source-map": "^0.5.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "wp-pot": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/wp-pot/-/wp-pot-1.10.2.tgz", - "integrity": "sha512-NJ9+dsSilghAYMiuGdURJSbKFf9Z2mH+P6ojT8Nw1Pp8KuwvHdRTFTYK73THlYzohUEXlQGpvKkz+mJb8K1ToA==", - "dev": true, - "requires": { - "espree": "^9.3.1", - "matched": "^5.0.1", - "path-sort": "^0.1.0", - "php-parser": "^3.0.3" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.1" - } - }, - "yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3" - } - } - } -} \ No newline at end of file diff --git a/vendor/async-aws/core/CHANGELOG.md b/vendor/async-aws/core/CHANGELOG.md new file mode 100644 index 000000000..ccf1ee19a --- /dev/null +++ b/vendor/async-aws/core/CHANGELOG.md @@ -0,0 +1,433 @@ +# Change Log + +## 1.20.0 + +### Added + +- Support for LocationService +- Support for hostPrefix in requests +- AWS api-change: API updates for the AWS Security Token Service +- Support for SSO credentials +- Avoid overriding the exception message with the raw message + +### Changed + +- Improve parameter type and return type in phpdoc + +## 1.19.0 + +### Added + +- Support for Symfony 7 +- Support for Athena +- Support for MediaConvert +- Support for IMDS v2 authentication +- Support for using endpoint discovery with parameters passed in the query string or the path + +### Fixed + +- Fix potential malformed URI in discovered endpoints + +## 1.18.1 + +### Changed + +- AWS enhancement: Documentation updates. +- Fix deprecation by adding return type on reset methods + +## 1.18.0 + +### Added + +- Support for Scheduler + +## 1.17.0 + +### Added + +- Support for Iot Data + +## 1.16.0 + +### Added + +- Support for endpoint discovery +- Support for Iot Core + +## 1.15.0 + +### Added + +- Support for CodeBuild +- Support for CodeCommit +- Support for TimestreamQuery +- Support for TimestreamWrite +- AWS enhancement: Documentation updates. +- Reverted the automated decoration of the injected HttpClient +- Added an AwsHttpClientFactory to help people creating retryable clients +- Add 403 errors in the list of potential retryiable operations + +### Changed + +- Set default value to `false` for the `sendChunkedBody` option. + +## 1.14.0 + +### Added + +- Make the injected HttpClient decorated by our `RetryableHttpClient` +- Support for KMS + +### Fixed + +- Issue with symfony http-client when posting empty payload + +## 1.13.0 + +### Added + +- AWS api-change: Added `us-iso-west-1` region +- AWS api-change: Used regional endpoint for `us` regions +- AWS enhancement: Documentation updates. +- Support for AppSync +- Support for XRay + +## 1.12.0 + +### Added + +- Support for Firehose +- Support for ElastiCache +- Support for CloudWatchClient +- Support for psr/log 2.0 and 3.0 + +## 1.11.0 + +### Added + +- Support for StepFunctions +- Support for Kinesis +- Support for SecretsManager +- Support for Symfony contracts v3 +- AWS enhancement: Documentation updates for AWS Security Token Service. + +### Fixed + +- Wrap the HttpClient's decoding exception in UnparsableResponse. + +## 1.10.0 + +### Added + +- AWS enhancement: STS now supports assume role with Web Identity using JWT token length upto 20000 characters +- AWS api-change: This release adds the SourceIdentity parameter that can be set when assuming a role. +- Support for Symfony 6 + +## 1.9.2 + +### Fixed + +- Support for psr/cache v2 and v3 +- Fix forming signature with multiple spaces + +## 1.9.1 + +### Fixed + +- Make sure mocked results have a response with `Response::$bodyDownloaded = true`. + +## 1.9.0 + +### Added + +- Changed case of object's properties to camelCase. +- Added documentation in class headers. +- Removed `final` from `ClientException` and `ServerException`. +- Make Responses thrown Business Exception when AwsErrorCode <-> Exception class mapping provided through RequestContext. +- Added domain exceptions. +- Improved Aws Error parsing by using specialized AwsErrorFactory. + +### Fixed + +- Exception thrown twice by waiters. + +## 1.8.0 + +### Added + +- Added option `sendChunkedBody` dedicated to S3. + +## 1.7.2 + +- Make sure we can get credentials even if the cache storage fails +- Clear `realpath` cache to make sure we get the latest credentials token + +## 1.7.1 + +### Fixed + +- Fix for an edge case where aws config file could be a directory +- Fix when AWS profile name is only digits + +## 1.7.0 + +### Added + +- A `AwsRetryStrategy` to define what HTTP request we retry +- Support for Elastic Container Registry (ECR) in `AwsClientFactory` +- Read "region" from ini files. +- Support for hard coded `roleArn` in `ConfigurationProvider` +- Added exception `AsyncAws\Core\Exception\UnexpectedValue` and `AsyncAws\Core\Exception\UnparsableResponse` + +### Fixed + +- Merge configuration if a profile is spread out over multiple files. Ie if `[profile company]` is defined in both `~/.aws/config` and `~/.aws/credentials`. +- All exceptions thrown must extend `AsyncAws\Core\Exception\Exception` + +## 1.6.0 + +### Added + +- Support for Rekognition in `AwsClientFactory` + +## 1.5.0 + +### Added + +- Support for `debug` configuration option to log HTTP requests and responses +- Use Symfony `RetryableHttpClient` when available. + +### Fixed + +- Allow signing request with non-standard region when using custom endpoint? +- Fix unresolved Env Variable in some php configuration + +## 1.4.2 + +### Fixed + +- Fixed logic in `AbstractApi::getSigner()` when passing `@region` to an API operation + +## 1.4.1 + +### Fixed + +- Make sure passing `@region` to an API operation has effect. +- Check that both AWS access id and secret exists before using them. + +## 1.4.0 + +### Added + +- Allow to pass additional content to `ResultMockFactory::createFailing()` + +## 1.3.0 + +### Added + +- Support for PHP 8 +- Added second parameter `$preferredChunkSize` to `StreamFactory::create()` +- Support for CloudFront in `AwsClientFactory` +- Support for RdsDataService in `AwsClientFactory` + +### Fixed + +- Allows non-AWS regions when using custom endpoints + +### Changed + +- Add more context to error logs +- Log level for 404 responses changed to "info". + +## 1.2.0 + +### Added + +- Support for EventBridge in `AwsClientFactory` +- Support for IAM in `AwsClientFactory` +- Add a `PsrCacheProvider` and `SymfonyCacheProvider` to persists crendentials in a cache pool +- Add a `Credential::adjustExpireDate` method for adjusting the time according to the time difference with AWS clock +- Support for global and regional endpoints +- Add a `Configuration::optionExists` to allow third parties to check if an option is available (needed by libraries supporting several versions of core) + +### Deprecation + +- Clients extending `AbstractApi` should override `getEndpointMetata`. The method will be abstract in 2.0 +- Custom endpoints should not contain `%region%` and `%service` placeholder. They won't be replaced anymore in 2.0 +- Protected methods `getServiceCode`, `getSignatureVersion` and `getSignatureScopeName` of AbstractApi are deprecated and will be removed in 2.0 + +### Fixed + +- Fix signing of requests with a header containing a date (like `expires` in `S3`). +- Fix thread safety regarding env vars by using `$_SERVER` instead of `getenv()`. + +## 1.1.0 + +### Added + +- Support for ECS Credentials Provider +- Support for Cognito Identity Provider client in `AwsClientFactory` +- Support for Cloud Watch Log client in `AwsClientFactory` + +### Fixed + +- Fixed invalid chunking of request with large body for most clients but S3. This version removed the invalid code from SignerV4 to make sure requests are not chunked. +- Use camelCase for all getter methods. + +## 1.0.0 + +### Added + +- Support for CodeDeploy client in `AwsClientFactory` + +### Fixed + +- Handle Aws Error type in JsonRest error responses + +## 0.5.4 + +### Added + +- Logging on HTTP exceptions. + +## 0.5.3 + +### Added + +- Support for SSM client in `AwsClientFactory` +- Support for Waiters in `ResultMockFactory` + +## 0.5.2 + +### Fixed + +- Add support for `Content-Type: application/x-amz-json-1.1` in test case. + +## 0.5.1 + +### Added + +- Add `Configuration::isDefault` methods. + +### Fixed + +- Allow mocking of Results classes named "*Result" + +## 0.5.0 + +### Added + +- Add support for multiregion via `@region` input parameter. +- DynamoDB support. +- `ResultMockFactory` was updated with `createFailing()` and support for pagination. +- `AbstractApi::presign()`. +- `Result::wait()` for multiplexing downloads. +- Interface `AsyncAws\Core\Input`. +- `AsyncAws\Core\Stream\ResponseBodyResourceStream` and `AsyncAws\Core\Stream\ResponseBodyStream`. +- Internal `AsyncAws\Core\Response` to encapsulate the HTTP client. +- Internal `AsyncAws\Core\RequestContext`. +- Internal `AsyncAws\Core\Stream\RewindableStream`. + +### Removed + +- The input's `validate()` function was merged with the `request()` function. +- `Configuration::isDefault()`. +- Protected property `AbstractApi::$logger`. +- `AsyncAws\Core\StreamableBody` in favor of `AsyncAws\Core\Stream\ResponseBodyStream`. + +### Changed + +- Exceptions will contain more information from the HTTP response. +- Moved STS value objects to a dedicated namespace. +- The `AsyncAws\Core\Sts\Input\*` and `AsyncAws\Core\Sts\ValueObject*` classes are marked final. +- Using `DateTimeImmutable` instead of `DateTimeInterface`. +- Protected properties `AbstractApi::$httpClient`, `AbstractApi::$configuration` and `AbstractApi::$credentialProvider` are now private. +- `AbstractApi::getResponse()` has new signature. New optional second argument `?RequestContext $context = null` and the return type is `AsyncAws\Core\Response`. +- The `CredentialProvider`s and `Configuration` are now `final`. +- Renamed `AsyncAws\Core\Stream\Stream` to `AsyncAws\Core\Stream\RequestStream`. +- Renamed `AsyncAws\Core\StreamableBodyInterface` to `AsyncAws\Core\Stream\ResultStream`. +- The `ResultStream::getChunks()` now returns a iterable of string. + +### Fixed + +- Bugfix in `WebIdentityProvider` + +## 0.4.0 + +### Added + +- Test class `AsyncAws\Core\Test\SimpleStreamableBody` + +### Changed + +- Moved `AsyncAws\Core\Signer\Request` to `AsyncAws\Core\Request`. +- Added constructor argument to `AsyncAws\Core\Request::__construct()` to support query parameters. +- Renamed `AsyncAws\Core\Request::getUrl()` to `AsyncAws\Core\Request::getEndpoint()` +- Class `AsyncAws\Core\Stream\StreamFactory` is not internal anymore. +- Removed `requestBody()`, `requestHeaders()`, `requestQuery()` and `requestUri()` input classes. They are replaced with `request()`. + +### Removed + +- Public `AbstractApi::request()` was removed. +- Protected function `AbstractApi::getEndpoint()` was made private. + +### Fixed + +- Fix Instance Provider Role fetching + +## 0.3.3 + +### Added + +- Added a `ResultMockFactory` to helps creating tests + +### Fixed + +- Http method is replaced by PUT in REST calls + +## 0.3.2 + +### Fixed + +- `Configuration` don't mix anymore attributes injected by php array and env variables. + +## 0.3.1 + +### Added + +- `AbstractApi::getConfiguration()` + +### Fixed + +- Make sure `Configuration::create(['foo'=>null])` is using the default value of "foo". + +## 0.3.0 + +### Added + +- Requests can now be streamed +- Streamable request accepts iterable alongside string, callable, resource +- Support for getting credentials from Web Identity or OpenID Connect Federation. (`WebIdentityProvider`) + +### Changed + +- Rename namespace `Signers` into `Signer`. + +## 0.2.0 + +### Added + +- Class `AsyncAws\Core\Credentials\NullProvider` +- Methods `AwsClient::cloudFormation()`, `AwsClient::lambda()`, `AwsClient::sns()` +- Protected methods `Result::registerPrefetch()` and `Result::unregisterPrefetch()` +- Timeout parameter to `InstanceProvider::__construct()` + +### Changed + +- Removed `AwsClient` and replaced it with `AwsClientFactory` +- Class `AsyncAws\Core\Signer\Request` is marked as internal +- Make sure behavior of calling `Result::resolve()` is consistent + +## 0.1.0 + +First version diff --git a/vendor/async-aws/core/LICENSE b/vendor/async-aws/core/LICENSE new file mode 100644 index 000000000..191fcfb40 --- /dev/null +++ b/vendor/async-aws/core/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Jérémy Derussé, Tobias Nyholm + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/async-aws/core/README.md b/vendor/async-aws/core/README.md new file mode 100644 index 000000000..f1188d7bf --- /dev/null +++ b/vendor/async-aws/core/README.md @@ -0,0 +1,21 @@ +# AsyncAws Core + +![](https://github.com/async-aws/core/workflows/Tests/badge.svg?branch=master) +![](https://github.com/async-aws/core/workflows/BC%20Check/badge.svg?branch=master) + +The repository contains shared classes between all AWS services. It also contains +the STS client to handle authentication. + +## Install + +```cli +composer require async-aws/core +``` + +## Documentation + +See https://async-aws.com for documentation. + +## Contribute + +Contributions are welcome and appreciated. Please read https://async-aws.com/contribute/ diff --git a/vendor/async-aws/core/composer.json b/vendor/async-aws/core/composer.json new file mode 100644 index 000000000..dbc0851c5 --- /dev/null +++ b/vendor/async-aws/core/composer.json @@ -0,0 +1,44 @@ +{ + "name": "async-aws/core", + "description": "Core package to integrate with AWS. This is a lightweight AWS SDK provider by AsyncAws.", + "license": "MIT", + "type": "library", + "keywords": [ + "aws", + "amazon", + "sdk", + "async-aws", + "sts" + ], + "require": { + "php": "^7.2.5 || ^8.0", + "ext-SimpleXML": "*", + "ext-hash": "*", + "ext-json": "*", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/http-client": "^4.4.16 || ^5.1.7 || ^6.0 || ^7.0", + "symfony/http-client-contracts": "^1.1.8 || ^2.0 || ^3.0", + "symfony/service-contracts": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "async-aws/s3": "<1.1", + "symfony/http-client": "5.2.0" + }, + "autoload": { + "psr-4": { + "AsyncAws\\Core\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "AsyncAws\\Core\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.20-dev" + } + } +} diff --git a/vendor/async-aws/core/roave-bc-check.yaml b/vendor/async-aws/core/roave-bc-check.yaml new file mode 100644 index 000000000..2fbae213d --- /dev/null +++ b/vendor/async-aws/core/roave-bc-check.yaml @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - '#ReflectionClass "PHPUnit\\Framework\\TestCase" could not be found in the located source#' diff --git a/vendor/async-aws/core/src/AbstractApi.php b/vendor/async-aws/core/src/AbstractApi.php new file mode 100644 index 000000000..ad48a6912 --- /dev/null +++ b/vendor/async-aws/core/src/AbstractApi.php @@ -0,0 +1,358 @@ + + * @author Jérémy Derussé + */ +abstract class AbstractApi +{ + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * @var Configuration + */ + private $configuration; + + /** + * @var CredentialProvider + */ + private $credentialProvider; + + /** + * @var array + */ + private $signers; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var AwsErrorFactoryInterface + */ + private $awsErrorFactory; + + /** + * @var EndpointCache + */ + private $endpointCache; + + /** + * @param Configuration|array $configuration + */ + public function __construct($configuration = [], ?CredentialProvider $credentialProvider = null, ?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null) + { + if (\is_array($configuration)) { + $configuration = Configuration::create($configuration); + } elseif (!$configuration instanceof Configuration) { + throw new InvalidArgument(sprintf('First argument to "%s::__construct()" must be an array or an instance of "%s"', static::class, Configuration::class)); + } + + $this->logger = $logger ?? new NullLogger(); + $this->awsErrorFactory = $this->getAwsErrorFactory(); + $this->endpointCache = new EndpointCache(); + if (!isset($httpClient)) { + $httpClient = HttpClient::create(); + if (class_exists(RetryableHttpClient::class)) { + /** @psalm-suppress MissingDependency */ + $httpClient = new RetryableHttpClient( + $httpClient, + new AwsRetryStrategy(AwsRetryStrategy::DEFAULT_RETRY_STATUS_CODES, 1000, 2.0, 0, 0.1, $this->awsErrorFactory), + 3, + $this->logger + ); + } + } + $this->httpClient = $httpClient; + $this->configuration = $configuration; + $this->credentialProvider = $credentialProvider ?? new CacheProvider(ChainProvider::createDefaultChain($this->httpClient, $this->logger)); + } + + final public function getConfiguration(): Configuration + { + return $this->configuration; + } + + final public function presign(Input $input, ?\DateTimeImmutable $expires = null): string + { + $request = $input->request(); + $request->setEndpoint($this->getEndpoint($request->getUri(), $request->getQuery(), $input->getRegion())); + + if (null !== $credentials = $this->credentialProvider->getCredentials($this->configuration)) { + $this->getSigner($input->getRegion())->presign($request, $credentials, new RequestContext(['expirationDate' => $expires])); + } + + return $request->getEndpoint(); + } + + /** + * @deprecated + */ + protected function getServiceCode(): string + { + throw new LogicException(sprintf('The method "%s" should not be called. The Client "%s" must implement the "%s" method.', __FUNCTION__, \get_class($this), 'getEndpointMetadata')); + } + + /** + * @deprecated + */ + protected function getSignatureVersion(): string + { + throw new LogicException(sprintf('The method "%s" should not be called. The Client "%s" must implement the "%s" method.', __FUNCTION__, \get_class($this), 'getEndpointMetadata')); + } + + /** + * @deprecated + */ + protected function getSignatureScopeName(): string + { + throw new LogicException(sprintf('The method "%s" should not be called. The Client "%s" must implement the "%s" method.', __FUNCTION__, \get_class($this), 'getEndpointMetadata')); + } + + final protected function getResponse(Request $request, ?RequestContext $context = null): Response + { + $request->setEndpoint($this->getDiscoveredEndpoint($request->getUri(), $request->getQuery(), $context ? $context->getRegion() : null, $context ? $context->usesEndpointDiscovery() : false, $context ? $context->requiresEndpointDiscovery() : false)); + + if (null !== $credentials = $this->credentialProvider->getCredentials($this->configuration)) { + $this->getSigner($context ? $context->getRegion() : null)->sign($request, $credentials, $context ?? new RequestContext()); + } + + $length = $request->getBody()->length(); + if (null !== $length && !$request->hasHeader('content-length')) { + $request->setHeader('content-length', (string) $length); + } + + // Some servers (like testing Docker Images) does not support `Transfer-Encoding: chunked` requests. + // The body is converted into string to prevent curl using `Transfer-Encoding: chunked` unless it really has to. + if (($requestBody = $request->getBody()) instanceof StringStream) { + $requestBody = $requestBody->stringify(); + } + + $response = $this->httpClient->request( + $request->getMethod(), + $request->getEndpoint(), + [ + 'headers' => $request->getHeaders(), + ] + (0 === $length ? [] : ['body' => $requestBody]) + ); + + if ($debug = filter_var($this->configuration->get('debug'), \FILTER_VALIDATE_BOOLEAN)) { + $this->logger->debug('AsyncAws HTTP request sent: {method} {endpoint}', [ + 'method' => $request->getMethod(), + 'endpoint' => $request->getEndpoint(), + 'headers' => json_encode($request->getHeaders()), + 'body' => 0 === $length ? null : $requestBody, + ]); + } + + return new Response($response, $this->httpClient, $this->logger, $this->awsErrorFactory, $this->endpointCache, $request, $debug, $context ? $context->getExceptionMapping() : []); + } + + /** + * @return array + */ + protected function getSignerFactories(): array + { + return [ + 'v4' => static function (string $service, string $region) { + return new SignerV4($service, $region); + }, + ]; + } + + protected function getAwsErrorFactory(): AwsErrorFactoryInterface + { + return new ChainAwsErrorFactory(); + } + + /** + * Returns the AWS endpoint metadata for the given region. + * When user did not provide a region, the client have to either return a global endpoint or fallback to + * the Configuration::DEFAULT_REGION constant. + * + * This implementation is a BC layer for client that does not require core:^1.2. + * + * @param ?string $region region provided by the user (without fallback to a default region) + * + * @return array{endpoint: string, signRegion: string, signService: string, signVersions: string[]} + */ + protected function getEndpointMetadata(?string $region): array + { + /** @psalm-suppress TooManyArguments */ + trigger_deprecation('async-aws/core', '1.2', 'Extending "%s"" without overriding "%s" is deprecated. This method will be abstract in version 2.0.', __CLASS__, __FUNCTION__); + + /** @var string $endpoint */ + $endpoint = $this->configuration->get('endpoint'); + /** @var string $region */ + $region = $region ?? $this->configuration->get('region'); + + return [ + 'endpoint' => strtr($endpoint, [ + '%region%' => $region, + '%service%' => $this->getServiceCode(), + ]), + 'signRegion' => $region, + 'signService' => $this->getSignatureScopeName(), + 'signVersions' => [$this->getSignatureVersion()], + ]; + } + + /** + * Build the endpoint full uri. + * + * @param string $uri or path + * @param array $query parameters that should go in the query string + * @param ?string $region region provided by the user in the `@region` parameter of the Input + */ + protected function getEndpoint(string $uri, array $query, ?string $region): string + { + $region = $region ?? ($this->configuration->isDefault('region') ? null : $this->configuration->get('region')); + if (!$this->configuration->isDefault('endpoint')) { + /** @var string $endpoint */ + $endpoint = $this->configuration->get('endpoint'); + } else { + $metadata = $this->getEndpointMetadata($region); + $endpoint = $metadata['endpoint']; + } + + if (false !== strpos($endpoint, '%region%') || false !== strpos($endpoint, '%service%')) { + /** @psalm-suppress TooManyArguments */ + trigger_deprecation('async-aws/core', '1.2', 'providing an endpoint with placeholder is deprecated and will be ignored in version 2.0. Provide full endpoint instead.'); + + $endpoint = strtr($endpoint, [ + '%region%' => $region ?? $this->configuration->get('region'), + '%service%' => $this->getServiceCode(), // if people provides a custom endpoint 'http://%service%.localhost/ + ]); + } + + $endpoint .= $uri; + if ([] === $query) { + return $endpoint; + } + + return $endpoint . (false === strpos($endpoint, '?') ? '?' : '&') . http_build_query($query, '', '&', \PHP_QUERY_RFC3986); + } + + /** + * @return EndpointInterface[] + */ + protected function discoverEndpoints(?string $region): array + { + throw new LogicException(sprintf('The Client "%s" must implement the "%s" method.', \get_class($this), 'discoverEndpoints')); + } + + /** + * @param array $query + * + * @return string + */ + private function getDiscoveredEndpoint(string $uri, array $query, ?string $region, bool $usesEndpointDiscovery, bool $requiresEndpointDiscovery) + { + if (!$this->configuration->isDefault('endpoint')) { + return $this->getEndpoint($uri, $query, $region); + } + + $usesEndpointDiscovery = $requiresEndpointDiscovery || ($usesEndpointDiscovery && filter_var($this->configuration->get(Configuration::OPTION_ENDPOINT_DISCOVERY_ENABLED), \FILTER_VALIDATE_BOOLEAN)); + if (!$usesEndpointDiscovery) { + return $this->getEndpoint($uri, $query, $region); + } + + // 1. use an active endpoints + if (null === $endpoint = $this->endpointCache->getActiveEndpoint($region)) { + $previous = null; + + try { + // 2. call API to fetch new endpoints + $endpoints = $this->discoverEndpoints($region); + $this->endpointCache->addEndpoints($region, $endpoints); + + // 3. use active endpoints that has just been injected + $endpoint = $this->endpointCache->getActiveEndpoint($region); + } catch (\Exception $previous) { + } + + // 4. if endpoint is still null, fallback to expired endpoint + if (null === $endpoint && null === $endpoint = $this->endpointCache->getExpiredEndpoint($region)) { + if ($requiresEndpointDiscovery) { + throw new RuntimeException(sprintf('The Client "%s" failed to fetch the endpoint.', \get_class($this)), 0, $previous); + } + + return $this->getEndpoint($uri, $query, $region); + } + } + + $endpoint .= $uri; + if (empty($query)) { + return $endpoint; + } + + return $endpoint . (false === strpos($endpoint, '?') ? '?' : '&') . http_build_query($query); + } + + /** + * @param ?string $region region provided by the user in the `@region` parameter of the Input + */ + private function getSigner(?string $region): Signer + { + /** @var string $region */ + $region = $region ?? ($this->configuration->isDefault('region') ? null : $this->configuration->get('region')); + if (!isset($this->signers[$region])) { + $factories = $this->getSignerFactories(); + $factory = null; + if ($this->configuration->isDefault('endpoint') || $this->configuration->isDefault('region')) { + $metadata = $this->getEndpointMetadata($region); + } else { + // Allow non-aws region with custom endpoint + $metadata = $this->getEndpointMetadata(Configuration::DEFAULT_REGION); + $metadata['signRegion'] = $region; + } + + foreach ($metadata['signVersions'] as $signatureVersion) { + if (isset($factories[$signatureVersion])) { + $factory = $factories[$signatureVersion]; + + break; + } + } + + if (null === $factory) { + throw new InvalidArgument(sprintf('None of the signatures "%s" is implemented.', implode(', ', $metadata['signVersions']))); + } + + $this->signers[$region] = $factory($metadata['signService'], $metadata['signRegion']); + } + + /** @psalm-suppress PossiblyNullArrayOffset */ + return $this->signers[$region]; + } +} diff --git a/vendor/async-aws/core/src/AwsClientFactory.php b/vendor/async-aws/core/src/AwsClientFactory.php new file mode 100644 index 000000000..5ff2b0981 --- /dev/null +++ b/vendor/async-aws/core/src/AwsClientFactory.php @@ -0,0 +1,631 @@ + + */ +class AwsClientFactory +{ + /** + * @var array + */ + private $serviceCache; + + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * @var Configuration + */ + private $configuration; + + /** + * @var CredentialProvider + */ + private $credentialProvider; + + /** + * @var LoggerInterface|null + */ + private $logger; + + /** + * @param Configuration|array $configuration + */ + public function __construct($configuration = [], ?CredentialProvider $credentialProvider = null, ?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null) + { + if (\is_array($configuration)) { + $configuration = Configuration::create($configuration); + } elseif (!$configuration instanceof Configuration) { + throw new InvalidArgument(sprintf('Second argument to "%s::__construct()" must be an array or an instance of "%s"', __CLASS__, Configuration::class)); + } + + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->logger = $logger ?? new NullLogger(); + $this->configuration = $configuration; + $this->credentialProvider = $credentialProvider ?? new CacheProvider(ChainProvider::createDefaultChain($this->httpClient, $this->logger)); + } + + public function appSync(): AppSyncClient + { + if (!class_exists(AppSyncClient::class)) { + throw MissingDependency::create('async-aws/app-sync', 'AppSync'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new AppSyncClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudFormation(): CloudFormationClient + { + if (!class_exists(CloudFormationClient::class)) { + throw MissingDependency::create('async-aws/cloud-formation', 'CloudFormation'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudFormationClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudFront(): CloudFrontClient + { + if (!class_exists(CloudFrontClient::class)) { + throw MissingDependency::create('async-aws/cloud-front', 'CloudFront'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudFrontClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudWatch(): CloudWatchClient + { + if (!class_exists(CloudWatchClient::class)) { + throw MissingDependency::create('async-aws/cloud-watch', 'CloudWatch'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudWatchClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudWatchLogs(): CloudWatchLogsClient + { + if (!class_exists(CloudWatchLogsClient::class)) { + throw MissingDependency::create('async-aws/cloud-watch-logs', 'CloudWatchLogs'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudWatchLogsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function codeBuild(): CodeBuildClient + { + if (!class_exists(CodeBuildClient::class)) { + throw MissingDependency::create('async-aws/code-build', 'CodeBuild'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CodeBuildClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function codeCommit(): CodeCommitClient + { + if (!class_exists(CodeCommitClient::class)) { + throw MissingDependency::create('async-aws/code-commit', 'CodeCommit'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CodeCommitClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function codeDeploy(): CodeDeployClient + { + if (!class_exists(CodeDeployClient::class)) { + throw MissingDependency::create('async-aws/code-deploy', 'CodeDeploy'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CodeDeployClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function comprehend(): ComprehendClient + { + if (!class_exists(ComprehendClient::class)) { + throw MissingDependency::create('async-aws/comprehend', 'ComprehendClient'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new ComprehendClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function dynamoDb(): DynamoDbClient + { + if (!class_exists(DynamoDbClient::class)) { + throw MissingDependency::create('async-aws/dynamo-db', 'DynamoDb'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new DynamoDbClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function ecr(): EcrClient + { + if (!class_exists(EcrClient::class)) { + throw MissingDependency::create('async-aws/ecr', 'ECR'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new EcrClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function elastiCache(): ElastiCacheClient + { + if (!class_exists(ElastiCacheClient::class)) { + throw MissingDependency::create('async-aws/elasti-cache', 'ElastiCache'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new ElastiCacheClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function eventBridge(): EventBridgeClient + { + if (!class_exists(EventBridgeClient::class)) { + throw MissingDependency::create('async-aws/event-bridge', 'EventBridge'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new EventBridgeClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function firehose(): FirehoseClient + { + if (!class_exists(FirehoseClient::class)) { + throw MissingDependency::create('async-aws/firehose', 'Firehose'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new FirehoseClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function iam(): IamClient + { + if (!class_exists(IamClient::class)) { + throw MissingDependency::create('async-aws/iam', 'IAM'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new IamClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function iot(): IotClient + { + if (!class_exists(IotClient::class)) { + throw MissingDependency::create('async-aws/iot', 'Iot'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new IotClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function iotData(): IotDataClient + { + if (!class_exists(IotDataClient::class)) { + throw MissingDependency::create('async-aws/iot-data', 'IotData'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new IotDataClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function kinesis(): KinesisClient + { + if (!class_exists(KinesisClient::class)) { + throw MissingDependency::create('aws/kinesis', 'Kinesis'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new KinesisClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function kms(): KmsClient + { + if (!class_exists(KmsClient::class)) { + throw MissingDependency::create('aws/kms', 'Kms'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new KmsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function lambda(): LambdaClient + { + if (!class_exists(LambdaClient::class)) { + throw MissingDependency::create('async-aws/lambda', 'Lambda'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new LambdaClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function locationService(): LocationServiceClient + { + if (!class_exists(LocationServiceClient::class)) { + throw MissingDependency::create('async-aws/location-service', 'LocationService'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new LocationServiceClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function mediaConvert(): MediaConvertClient + { + if (!class_exists(MediaConvertClient::class)) { + throw MissingDependency::create('async-aws/media-convert', 'MediaConvert'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new MediaConvertClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function rdsDataService(): RdsDataServiceClient + { + if (!class_exists(RdsDataServiceClient::class)) { + throw MissingDependency::create('async-aws/rds-data-service', 'RdsDataService'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new RdsDataServiceClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function rekognition(): RekognitionClient + { + if (!class_exists(RekognitionClient::class)) { + throw MissingDependency::create('aws/rekognition', 'Rekognition'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new RekognitionClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function route53(): Route53Client + { + if (!class_exists(Route53Client::class)) { + throw MissingDependency::create('aws/route53', 'Route53'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new Route53Client($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function s3(): S3Client + { + if (!class_exists(S3Client::class)) { + throw MissingDependency::create('async-aws/s3', 'S3'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new S3Client($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function scheduler(): SchedulerClient + { + if (!class_exists(SchedulerClient::class)) { + throw MissingDependency::create('async-aws/scheduler', 'Scheduler'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SchedulerClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function secretsManager(): SecretsManagerClient + { + if (!class_exists(SecretsManagerClient::class)) { + throw MissingDependency::create('async-aws/secret-manager', 'SecretsManager'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SecretsManagerClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function ses(): SesClient + { + if (!class_exists(SesClient::class)) { + throw MissingDependency::create('async-aws/ses', 'SES'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SesClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sns(): SnsClient + { + if (!class_exists(SnsClient::class)) { + throw MissingDependency::create('async-aws/sns', 'SNS'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SnsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sqs(): SqsClient + { + if (!class_exists(SqsClient::class)) { + throw MissingDependency::create('async-aws/sqs', 'SQS'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SqsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function ssm(): SsmClient + { + if (!class_exists(SsmClient::class)) { + throw MissingDependency::create('async-aws/ssm', 'SSM'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SsmClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sso(): SsoClient + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SsoClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sts(): StsClient + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new StsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function stepFunctions(): StepFunctionsClient + { + if (!class_exists(StepFunctionsClient::class)) { + throw MissingDependency::create('async-aws/step-functions', 'StepFunctions'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new StepFunctionsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function timestreamQuery(): TimestreamQueryClient + { + if (!class_exists(TimestreamQueryClient::class)) { + throw MissingDependency::create('async-aws/timestream-query', 'TimestreamQuery'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new TimestreamQueryClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function timestreamWrite(): TimestreamWriteClient + { + if (!class_exists(TimestreamWriteClient::class)) { + throw MissingDependency::create('async-aws/timestream-write', 'TimestreamWrite'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new TimestreamWriteClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function translate(): TranslateClient + { + if (!class_exists(TranslateClient::class)) { + throw MissingDependency::create('async-aws/translate', 'Translate'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new TranslateClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function xRay(): XRayClient + { + if (!class_exists(XRayClient::class)) { + throw MissingDependency::create('async-aws/x-ray', 'XRay'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new XRayClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cognitoIdentityProvider(): CognitoIdentityProviderClient + { + if (!class_exists(CognitoIdentityProviderClient::class)) { + throw MissingDependency::create('aws/cognito-identity-provider', 'CognitoIdentityProvider'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CognitoIdentityProviderClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function athena(): AthenaClient + { + if (!class_exists(AthenaClient::class)) { + throw MissingDependency::create('async-aws/athena', 'Athena'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new AthenaClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } +} diff --git a/vendor/async-aws/core/src/AwsError/AwsError.php b/vendor/async-aws/core/src/AwsError/AwsError.php new file mode 100644 index 000000000..126735473 --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/AwsError.php @@ -0,0 +1,54 @@ +code = $code; + $this->message = $message; + $this->type = $type; + $this->detail = $detail; + } + + public function getCode(): ?string + { + return $this->code; + } + + public function getMessage(): ?string + { + return $this->message; + } + + public function getType(): ?string + { + return $this->type; + } + + public function getDetail(): ?string + { + return $this->detail; + } +} diff --git a/vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php new file mode 100644 index 000000000..51782845d --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php @@ -0,0 +1,16 @@ +getContent(false); + $headers = $response->getHeaders(false); + + return $this->createFromContent($content, $headers); + } +} diff --git a/vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php new file mode 100644 index 000000000..d3e6c4536 --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php @@ -0,0 +1,15 @@ +> $headers + */ + public function createFromContent(string $content, array $headers): AwsError; +} diff --git a/vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php new file mode 100644 index 000000000..75080c9eb --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php @@ -0,0 +1,43 @@ +factories = $factories ?? [ + new JsonRestAwsErrorFactory(), + new JsonRpcAwsErrorFactory(), + new XmlAwsErrorFactory(), + ]; + } + + public function createFromContent(string $content, array $headers): AwsError + { + $e = null; + foreach ($this->factories as $factory) { + try { + return $factory->createFromContent($content, $headers); + } catch (UnparsableResponse $e) { + } + } + + throw new UnparsableResponse('Failed to parse AWS error: ' . $content, 0, $e); + } +} diff --git a/vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php new file mode 100644 index 000000000..1af77d9b7 --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php @@ -0,0 +1,45 @@ + $body + * @param array> $headers + */ + private static function parseJson(array $body, array $headers): AwsError + { + $code = null; + $type = $body['type'] ?? $body['Type'] ?? null; + if ($type) { + $type = strtolower($type); + } + $message = $body['message'] ?? $body['Message'] ?? null; + if (isset($headers['x-amzn-errortype'][0])) { + $code = explode(':', $headers['x-amzn-errortype'][0], 2)[0]; + } + + if (null !== $code) { + return new AwsError($code, $message, $type, null); + } + + throw new UnexpectedValue('JSON does not contains AWS Error'); + } +} diff --git a/vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php new file mode 100644 index 000000000..bf774be4d --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php @@ -0,0 +1,42 @@ + $body + * @param array> $headers + */ + private static function parseJson(array $body, array $headers): AwsError + { + $code = null; + $message = $body['message'] ?? $body['Message'] ?? null; + if (isset($body['__type'])) { + $parts = explode('#', $body['__type'], 2); + $code = $parts[1] ?? $parts[0]; + } + + if (null !== $code || null !== $message) { + return new AwsError($code, $message, null, null); + } + + throw new UnexpectedValue('JSON does not contains AWS Error'); + } +} diff --git a/vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php new file mode 100644 index 000000000..6a152f92f --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php @@ -0,0 +1,54 @@ +Error->count()) { + return new AwsError( + $xml->Error->Code->__toString(), + $xml->Error->Message->__toString(), + $xml->Error->Type->__toString(), + $xml->Error->Detail->__toString() + ); + } + + if (1 === $xml->Code->count() && 1 === $xml->Message->count()) { + return new AwsError( + $xml->Code->__toString(), + $xml->Message->__toString(), + null, + null + ); + } + + throw new UnexpectedValue('XML does not contains AWS Error'); + } +} diff --git a/vendor/async-aws/core/src/Configuration.php b/vendor/async-aws/core/src/Configuration.php new file mode 100644 index 000000000..66f7530a4 --- /dev/null +++ b/vendor/async-aws/core/src/Configuration.php @@ -0,0 +1,266 @@ + + * @author Jérémy Derussé + */ +final class Configuration +{ + public const DEFAULT_REGION = 'us-east-1'; + + public const OPTION_REGION = 'region'; + public const OPTION_DEBUG = 'debug'; + public const OPTION_PROFILE = 'profile'; + public const OPTION_ACCESS_KEY_ID = 'accessKeyId'; + public const OPTION_SECRET_ACCESS_KEY = 'accessKeySecret'; + public const OPTION_SESSION_TOKEN = 'sessionToken'; + public const OPTION_SHARED_CREDENTIALS_FILE = 'sharedCredentialsFile'; + public const OPTION_SHARED_CONFIG_FILE = 'sharedConfigFile'; + public const OPTION_ENDPOINT = 'endpoint'; + public const OPTION_ROLE_ARN = 'roleArn'; + public const OPTION_WEB_IDENTITY_TOKEN_FILE = 'webIdentityTokenFile'; + public const OPTION_ROLE_SESSION_NAME = 'roleSessionName'; + public const OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI = 'containerCredentialsRelativeUri'; + public const OPTION_ENDPOINT_DISCOVERY_ENABLED = 'endpointDiscoveryEnabled'; + + // S3 specific option + public const OPTION_PATH_STYLE_ENDPOINT = 'pathStyleEndpoint'; + public const OPTION_SEND_CHUNKED_BODY = 'sendChunkedBody'; + + private const AVAILABLE_OPTIONS = [ + self::OPTION_REGION => true, + self::OPTION_DEBUG => true, + self::OPTION_PROFILE => true, + self::OPTION_ACCESS_KEY_ID => true, + self::OPTION_SECRET_ACCESS_KEY => true, + self::OPTION_SESSION_TOKEN => true, + self::OPTION_SHARED_CREDENTIALS_FILE => true, + self::OPTION_SHARED_CONFIG_FILE => true, + self::OPTION_ENDPOINT => true, + self::OPTION_ROLE_ARN => true, + self::OPTION_WEB_IDENTITY_TOKEN_FILE => true, + self::OPTION_ROLE_SESSION_NAME => true, + self::OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI => true, + self::OPTION_ENDPOINT_DISCOVERY_ENABLED => true, + self::OPTION_PATH_STYLE_ENDPOINT => true, + self::OPTION_SEND_CHUNKED_BODY => true, + ]; + + // Put fallback options into groups to avoid mixing of provided config and environment variables + private const FALLBACK_OPTIONS = [ + [self::OPTION_REGION => ['AWS_REGION', 'AWS_DEFAULT_REGION']], + [self::OPTION_PROFILE => ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']], + [ + self::OPTION_ACCESS_KEY_ID => ['AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY'], + self::OPTION_SECRET_ACCESS_KEY => ['AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_KEY'], + self::OPTION_SESSION_TOKEN => 'AWS_SESSION_TOKEN', + ], + [self::OPTION_SHARED_CREDENTIALS_FILE => 'AWS_SHARED_CREDENTIALS_FILE'], + [self::OPTION_SHARED_CONFIG_FILE => 'AWS_CONFIG_FILE'], + [ + self::OPTION_ROLE_ARN => 'AWS_ROLE_ARN', + self::OPTION_WEB_IDENTITY_TOKEN_FILE => 'AWS_WEB_IDENTITY_TOKEN_FILE', + self::OPTION_ROLE_SESSION_NAME => 'AWS_ROLE_SESSION_NAME', + ], + [self::OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI => 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'], + [self::OPTION_ENDPOINT_DISCOVERY_ENABLED => ['AWS_ENDPOINT_DISCOVERY_ENABLED', 'AWS_ENABLE_ENDPOINT_DISCOVERY']], + ]; + + private const DEFAULT_OPTIONS = [ + self::OPTION_REGION => self::DEFAULT_REGION, + self::OPTION_DEBUG => 'false', + self::OPTION_PROFILE => 'default', + self::OPTION_SHARED_CREDENTIALS_FILE => '~/.aws/credentials', + self::OPTION_SHARED_CONFIG_FILE => '~/.aws/config', + // https://docs.aws.amazon.com/general/latest/gr/rande.html + self::OPTION_ENDPOINT => 'https://%service%.%region%.amazonaws.com', + self::OPTION_PATH_STYLE_ENDPOINT => 'false', + self::OPTION_SEND_CHUNKED_BODY => 'false', + self::OPTION_ENDPOINT_DISCOVERY_ENABLED => 'false', + ]; + + /** + * @var array + */ + private $data = []; + + /** + * @var array + */ + private $userData = []; + + /** + * @param array $options + */ + public static function create(array $options): self + { + if (0 < \count($invalidOptions = array_diff_key($options, self::AVAILABLE_OPTIONS))) { + throw new InvalidArgument(sprintf('Invalid option(s) "%s" passed to "%s::%s". ', implode('", "', array_keys($invalidOptions)), __CLASS__, __METHOD__)); + } + + // Force each option to be string or null + $options = array_map(static function ($value) { + return null !== $value ? (string) $value : $value; + }, $options); + + $configuration = new self(); + $options = self::parseEnvironmentVariables($options); + self::populateConfiguration($configuration, $options); + $iniOptions = self::parseIniFiles($configuration); + self::populateConfiguration($configuration, $iniOptions); + + return $configuration; + } + + public static function optionExists(string $optionName): bool + { + return isset(self::AVAILABLE_OPTIONS[$optionName]); + } + + /** + * @param self::OPTION_* $name + * + * @psalm-return ( + * $name is + * self::OPTION_REGION + * |self::OPTION_DEBUG + * |self::OPTION_PROFILE + * |self::OPTION_SHARED_CREDENTIALS_FILE + * |self::OPTION_SHARED_CONFIG_FILE + * |self::OPTION_ENDPOINT + * |self::OPTION_PATH_STYLE_ENDPOINT + * |self::OPTION_SEND_CHUNKED_BODY + * ? string + * : ?string + * ) + */ + public function get(string $name): ?string + { + if (!isset(self::AVAILABLE_OPTIONS[$name])) { + throw new InvalidArgument(sprintf('Invalid option "%s" passed to "%s::%s". ', $name, __CLASS__, __METHOD__)); + } + + return $this->data[$name] ?? null; + } + + /** + * @param self::OPTION_* $name + */ + public function has(string $name): bool + { + if (!isset(self::AVAILABLE_OPTIONS[$name])) { + throw new InvalidArgument(sprintf('Invalid option "%s" passed to "%s::%s". ', $name, __CLASS__, __METHOD__)); + } + + return isset($this->data[$name]); + } + + /** + * @param self::OPTION_* $name + */ + public function isDefault(string $name): bool + { + if (!isset(self::AVAILABLE_OPTIONS[$name])) { + throw new InvalidArgument(sprintf('Invalid option "%s" passed to "%s::%s". ', $name, __CLASS__, __METHOD__)); + } + + return empty($this->userData[$name]); + } + + /** + * @param array $options + * + * @return array + */ + private static function parseEnvironmentVariables(array $options): array + { + foreach (self::FALLBACK_OPTIONS as $fallbackGroup) { + // prevent mixing env variables with config keys + foreach ($fallbackGroup as $option => $envVariableNames) { + if (isset($options[$option])) { + continue 2; + } + } + + foreach ($fallbackGroup as $option => $envVariableNames) { + // Read environment files + $envVariableNames = (array) $envVariableNames; + foreach ($envVariableNames as $envVariableName) { + if (null !== $envVariableValue = EnvVar::get($envVariableName)) { + $options[$option] = $envVariableValue; + + break; + } + } + } + } + + return $options; + } + + /** + * Look for "region" in the configured ini files. + * + * @return array + */ + private static function parseIniFiles(Configuration $configuration): array + { + $options = []; + if (!$configuration->isDefault(self::OPTION_REGION)) { + return $options; + } + + $profilesData = (new IniFileLoader())->loadProfiles([ + $configuration->get(self::OPTION_SHARED_CREDENTIALS_FILE), + $configuration->get(self::OPTION_SHARED_CONFIG_FILE), + ]); + + if (empty($profilesData)) { + return $options; + } + + /** @var string $profile */ + $profile = $configuration->get(Configuration::OPTION_PROFILE); + if (isset($profilesData[$profile]['region'])) { + $options[self::OPTION_REGION] = $profilesData[$profile]['region']; + } + + return $options; + } + + /** + * Add array options to the configuration object. + * + * @param array $options + */ + private static function populateConfiguration(Configuration $configuration, array $options): void + { + foreach ($options as $key => $value) { + if (null !== $value) { + $configuration->userData[$key] = true; + } + } + + // If we have not applied default before + if (empty($configuration->data)) { + foreach (self::DEFAULT_OPTIONS as $optionTrigger => $defaultValue) { + if (isset($options[$optionTrigger])) { + continue; + } + + $options[$optionTrigger] = $defaultValue; + } + } + + $configuration->data = array_merge($configuration->data, $options); + } +} diff --git a/vendor/async-aws/core/src/Credentials/CacheProvider.php b/vendor/async-aws/core/src/Credentials/CacheProvider.php new file mode 100644 index 000000000..428e62e47 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/CacheProvider.php @@ -0,0 +1,48 @@ + + */ +final class CacheProvider implements CredentialProvider, ResetInterface +{ + /** + * @var array + */ + private $cache = []; + + /** + * @var CredentialProvider + */ + private $decorated; + + public function __construct(CredentialProvider $decorated) + { + $this->decorated = $decorated; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $key = spl_object_hash($configuration); + if (!\array_key_exists($key, $this->cache) || (null !== $this->cache[$key] && $this->cache[$key]->isExpired())) { + $this->cache[$key] = $this->decorated->getCredentials($configuration); + } + + return $this->cache[$key]; + } + + public function reset(): void + { + $this->cache = []; + } +} diff --git a/vendor/async-aws/core/src/Credentials/ChainProvider.php b/vendor/async-aws/core/src/Credentials/ChainProvider.php new file mode 100644 index 000000000..abc46f032 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/ChainProvider.php @@ -0,0 +1,84 @@ + + */ +final class ChainProvider implements CredentialProvider, ResetInterface +{ + /** + * @var iterable + */ + private $providers; + + /** + * @var array + */ + private $lastSuccessfulProvider = []; + + /** + * @param iterable $providers + */ + public function __construct(iterable $providers) + { + $this->providers = $providers; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $key = spl_object_hash($configuration); + if (\array_key_exists($key, $this->lastSuccessfulProvider)) { + if (null === $provider = $this->lastSuccessfulProvider[$key]) { + return null; + } + + return $provider->getCredentials($configuration); + } + + foreach ($this->providers as $provider) { + if (null !== $credentials = $provider->getCredentials($configuration)) { + $this->lastSuccessfulProvider[$key] = $provider; + + return $credentials; + } + } + + $this->lastSuccessfulProvider[$key] = null; + + return null; + } + + public function reset(): void + { + $this->lastSuccessfulProvider = []; + } + + public static function createDefaultChain(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null): CredentialProvider + { + $httpClient = $httpClient ?? HttpClient::create(); + $logger = $logger ?? new NullLogger(); + + return new ChainProvider([ + new ConfigurationProvider(), + new WebIdentityProvider($logger, null, $httpClient), + new IniFileProvider($logger, null, $httpClient), + new ContainerProvider($httpClient, $logger), + new InstanceProvider($httpClient, $logger), + ]); + } +} diff --git a/vendor/async-aws/core/src/Credentials/ConfigurationProvider.php b/vendor/async-aws/core/src/Credentials/ConfigurationProvider.php new file mode 100644 index 000000000..3dca53444 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/ConfigurationProvider.php @@ -0,0 +1,92 @@ + + */ +final class ConfigurationProvider implements CredentialProvider +{ + use DateFromResult; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface|null + */ + private $httpClient; + + public function __construct(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null) + { + $this->logger = $logger ?? new NullLogger(); + $this->httpClient = $httpClient; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $accessKeyId = $configuration->get(Configuration::OPTION_ACCESS_KEY_ID); + $secretAccessKeyId = $configuration->get(Configuration::OPTION_SECRET_ACCESS_KEY); + + if (null === $accessKeyId || null === $secretAccessKeyId) { + return null; + } + + $credentials = new Credentials( + $accessKeyId, + $secretAccessKeyId, + $configuration->get(Configuration::OPTION_SESSION_TOKEN) + ); + + $roleArn = $configuration->get(Configuration::OPTION_ROLE_ARN); + if (null !== $roleArn) { + $region = $configuration->get(Configuration::OPTION_REGION); + $roleSessionName = $configuration->get(Configuration::OPTION_ROLE_SESSION_NAME); + + return $this->getCredentialsFromRole($credentials, $region, $roleArn, $roleSessionName); + } + + /** @psalm-suppress PossiblyNullArgument */ + return $credentials; + } + + private function getCredentialsFromRole(Credentials $credentials, string $region, string $roleArn, ?string $roleSessionName = null): ?Credentials + { + $roleSessionName = $roleSessionName ?? uniqid('async-aws-', true); + $stsClient = new StsClient(['region' => $region], $credentials, $this->httpClient); + $result = $stsClient->assumeRole([ + 'RoleArn' => $roleArn, + 'RoleSessionName' => $roleSessionName, + ]); + + try { + if (null === $credentials = $result->getCredentials()) { + throw new RuntimeException('The AsumeRole response does not contains credentials'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from assumed role: {exception}".', ['exception' => $e]); + + return null; + } + + return new Credentials( + $credentials->getAccessKeyId(), + $credentials->getSecretAccessKey(), + $credentials->getSessionToken(), + Credentials::adjustExpireDate($credentials->getExpiration(), $this->getDateFromResult($result)) + ); + } +} diff --git a/vendor/async-aws/core/src/Credentials/ContainerProvider.php b/vendor/async-aws/core/src/Credentials/ContainerProvider.php new file mode 100644 index 000000000..6b31e545a --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/ContainerProvider.php @@ -0,0 +1,80 @@ +logger = $logger ?? new NullLogger(); + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->timeout = $timeout; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $relativeUri = $configuration->get(Configuration::OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI); + // introduces an early exit if the env variable is not set. + if (empty($relativeUri)) { + return null; + } + + // fetch credentials from ecs endpoint + try { + $response = $this->httpClient->request('GET', self::ENDPOINT . $relativeUri, ['timeout' => $this->timeout]); + $result = $response->toArray(); + } catch (DecodingExceptionInterface $e) { + $this->logger->info('Failed to decode Credentials.', ['exception' => $e]); + + return null; + } catch (TransportExceptionInterface|HttpExceptionInterface $e) { + $this->logger->info('Failed to fetch Profile from Instance Metadata.', ['exception' => $e]); + + return null; + } + + if (null !== $date = $response->getHeaders(false)['date'][0] ?? null) { + $date = new \DateTimeImmutable($date); + } + + return new Credentials( + $result['AccessKeyId'], + $result['SecretAccessKey'], + $result['Token'], + Credentials::adjustExpireDate(new \DateTimeImmutable($result['Expiration']), $date) + ); + } +} diff --git a/vendor/async-aws/core/src/Credentials/CredentialProvider.php b/vendor/async-aws/core/src/Credentials/CredentialProvider.php new file mode 100644 index 000000000..a160fbd4a --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/CredentialProvider.php @@ -0,0 +1,20 @@ + + */ +interface CredentialProvider +{ + /** + * Return a Credential when possible. Return null otherwise. + */ + public function getCredentials(Configuration $configuration): ?Credentials; +} diff --git a/vendor/async-aws/core/src/Credentials/Credentials.php b/vendor/async-aws/core/src/Credentials/Credentials.php new file mode 100644 index 000000000..acd2a8052 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/Credentials.php @@ -0,0 +1,88 @@ + + */ +final class Credentials implements CredentialProvider +{ + private const EXPIRATION_DRIFT = 30; + + /** + * @var string + */ + private $accessKeyId; + + /** + * @var string + */ + private $secretKey; + + /** + * @var string|null + */ + private $sessionToken; + + /** + * @var \DateTimeImmutable|null + */ + private $expireDate; + + public function __construct( + string $accessKeyId, + string $secretKey, + ?string $sessionToken = null, + ?\DateTimeImmutable $expireDate = null + ) { + $this->accessKeyId = $accessKeyId; + $this->secretKey = $secretKey; + $this->sessionToken = $sessionToken; + $this->expireDate = $expireDate; + } + + public function getAccessKeyId(): string + { + return $this->accessKeyId; + } + + public function getSecretKey(): string + { + return $this->secretKey; + } + + public function getSessionToken(): ?string + { + return $this->sessionToken; + } + + public function getExpireDate(): ?\DateTimeImmutable + { + return $this->expireDate; + } + + public function isExpired(): bool + { + return null !== $this->expireDate && new \DateTimeImmutable() >= $this->expireDate; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + return $this->isExpired() ? null : $this; + } + + public static function adjustExpireDate(\DateTimeImmutable $expireDate, ?\DateTimeImmutable $reference = null): \DateTimeImmutable + { + if (null !== $reference) { + $expireDate = (new \DateTimeImmutable())->add($reference->diff($expireDate)); + } + + return $expireDate->sub(new \DateInterval(sprintf('PT%dS', self::EXPIRATION_DRIFT))); + } +} diff --git a/vendor/async-aws/core/src/Credentials/DateFromResult.php b/vendor/async-aws/core/src/Credentials/DateFromResult.php new file mode 100644 index 000000000..513ba13b0 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/DateFromResult.php @@ -0,0 +1,21 @@ +info()['response']; + if (null !== $date = $response->getHeaders(false)['date'][0] ?? null) { + return new \DateTimeImmutable($date); + } + + return null; + } +} diff --git a/vendor/async-aws/core/src/Credentials/IniFileLoader.php b/vendor/async-aws/core/src/Credentials/IniFileLoader.php new file mode 100644 index 000000000..df45ed73b --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/IniFileLoader.php @@ -0,0 +1,110 @@ + + */ +final class IniFileLoader +{ + public const KEY_REGION = 'region'; + public const KEY_ACCESS_KEY_ID = 'aws_access_key_id'; + public const KEY_SECRET_ACCESS_KEY = 'aws_secret_access_key'; + public const KEY_SESSION_TOKEN = 'aws_session_token'; + public const KEY_ROLE_ARN = 'role_arn'; + public const KEY_ROLE_SESSION_NAME = 'role_session_name'; + public const KEY_SOURCE_PROFILE = 'source_profile'; + public const KEY_WEB_IDENTITY_TOKEN_FILE = 'web_identity_token_file'; + public const KEY_SSO_START_URL = 'sso_start_url'; + public const KEY_SSO_REGION = 'sso_region'; + public const KEY_SSO_ACCOUNT_ID = 'sso_account_id'; + public const KEY_SSO_ROLE_NAME = 'sso_role_name'; + + /** + * @var LoggerInterface + */ + private $logger; + + public function __construct(?LoggerInterface $logger = null) + { + $this->logger = $logger ?? new NullLogger(); + } + + /** + * @param string[] $filepaths + * + * @return array> + */ + public function loadProfiles(array $filepaths): array + { + $profilesData = []; + $homeDir = null; + foreach ($filepaths as $filepath) { + if ('' === $filepath) { + continue; + } + if ('~' === $filepath[0]) { + $homeDir = $homeDir ?? $this->getHomeDir(); + $filepath = $homeDir . substr($filepath, 1); + } + if (!is_readable($filepath) || !is_file($filepath)) { + continue; + } + + foreach ($this->parseIniFile($filepath) as $name => $profile) { + $name = preg_replace('/^profile /', '', (string) $name); + if (!isset($profilesData[$name])) { + $profilesData[$name] = array_map('trim', $profile); + } else { + foreach ($profile as $k => $v) { + if (!isset($profilesData[$name][$k])) { + $profilesData[$name][$k] = trim($v); + } + } + } + } + } + + return $profilesData; + } + + private function getHomeDir(): string + { + // On Linux/Unix-like systems, use the HOME environment variable + if (null !== $homeDir = EnvVar::get('HOME')) { + return $homeDir; + } + + // Get the HOMEDRIVE and HOMEPATH values for Windows hosts + $homeDrive = EnvVar::get('HOMEDRIVE'); + $homePath = EnvVar::get('HOMEPATH'); + + return ($homeDrive && $homePath) ? $homeDrive . $homePath : '/'; + } + + /** + * @return array + */ + private function parseIniFile(string $filepath): array + { + if (false === $data = parse_ini_string( + preg_replace('/^#/m', ';', file_get_contents($filepath)), + true, + \INI_SCANNER_RAW + )) { + $this->logger->warning('The ini file {path} is invalid.', ['path' => $filepath]); + + return []; + } + + return $data; + } +} diff --git a/vendor/async-aws/core/src/Credentials/IniFileProvider.php b/vendor/async-aws/core/src/Credentials/IniFileProvider.php new file mode 100644 index 000000000..c8476c49d --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/IniFileProvider.php @@ -0,0 +1,224 @@ + + */ +final class IniFileProvider implements CredentialProvider +{ + use DateFromResult; + + /** + * @var IniFileLoader + */ + private $iniFileLoader; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface|null + */ + private $httpClient; + + public function __construct(?LoggerInterface $logger = null, ?IniFileLoader $iniFileLoader = null, ?HttpClientInterface $httpClient = null) + { + $this->logger = $logger ?? new NullLogger(); + $this->iniFileLoader = $iniFileLoader ?? new IniFileLoader($this->logger); + $this->httpClient = $httpClient; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $profilesData = $this->iniFileLoader->loadProfiles([ + $configuration->get(Configuration::OPTION_SHARED_CREDENTIALS_FILE), + $configuration->get(Configuration::OPTION_SHARED_CONFIG_FILE), + ]); + if (empty($profilesData)) { + return null; + } + + /** @var string $profile */ + $profile = $configuration->get(Configuration::OPTION_PROFILE); + + return $this->getCredentialsFromProfile($profilesData, $profile); + } + + /** + * @param array> $profilesData + * @param array $circularCollector + */ + private function getCredentialsFromProfile(array $profilesData, string $profile, array $circularCollector = []): ?Credentials + { + if (isset($circularCollector[$profile])) { + $this->logger->warning('Circular reference detected when loading "{profile}". Already loaded {previous_profiles}', ['profile' => $profile, 'previous_profiles' => array_keys($circularCollector)]); + + return null; + } + $circularCollector[$profile] = true; + + if (!isset($profilesData[$profile])) { + $this->logger->warning('Profile "{profile}" not found.', ['profile' => $profile]); + + return null; + } + + $profileData = $profilesData[$profile]; + if (isset($profileData[IniFileLoader::KEY_ACCESS_KEY_ID], $profileData[IniFileLoader::KEY_SECRET_ACCESS_KEY])) { + return new Credentials( + $profileData[IniFileLoader::KEY_ACCESS_KEY_ID], + $profileData[IniFileLoader::KEY_SECRET_ACCESS_KEY], + $profileData[IniFileLoader::KEY_SESSION_TOKEN] ?? null + ); + } + + if (isset($profileData[IniFileLoader::KEY_ROLE_ARN])) { + return $this->getCredentialsFromRole($profilesData, $profileData, $profile, $circularCollector); + } + + if (isset($profileData[IniFileLoader::KEY_SSO_START_URL])) { + if (class_exists(SsoClient::class)) { + return $this->getCredentialsFromLegacySso($profileData, $profile); + } + + $this->logger->warning('The profile "{profile}" contains SSO (legacy) config but the "async-aws/sso" package is not installed. Try running "composer require async-aws/sso".', ['profile' => $profile]); + + return null; + } + + $this->logger->info('No credentials found for profile "{profile}".', ['profile' => $profile]); + + return null; + } + + /** + * @param array> $profilesData + * @param array $profileData + * @param array $circularCollector + */ + private function getCredentialsFromRole(array $profilesData, array $profileData, string $profile, array $circularCollector = []): ?Credentials + { + $roleArn = (string) ($profileData[IniFileLoader::KEY_ROLE_ARN] ?? ''); + $roleSessionName = (string) ($profileData[IniFileLoader::KEY_ROLE_SESSION_NAME] ?? uniqid('async-aws-', true)); + if (null === $sourceProfileName = $profileData[IniFileLoader::KEY_SOURCE_PROFILE] ?? null) { + $this->logger->warning('The source profile is not defined in Role "{profile}".', ['profile' => $profile]); + + return null; + } + + $sourceCredentials = $this->getCredentialsFromProfile($profilesData, $sourceProfileName, $circularCollector); + if (null === $sourceCredentials) { + $this->logger->warning('The source profile "{profile}" does not contains valid credentials.', ['profile' => $profile]); + + return null; + } + + $stsClient = new StsClient( + isset($profilesData[$sourceProfileName][IniFileLoader::KEY_REGION]) ? ['region' => $profilesData[$sourceProfileName][IniFileLoader::KEY_REGION]] : [], + $sourceCredentials, + $this->httpClient + ); + $result = $stsClient->assumeRole([ + 'RoleArn' => $roleArn, + 'RoleSessionName' => $roleSessionName, + ]); + + try { + if (null === $credentials = $result->getCredentials()) { + throw new RuntimeException('The AssumeRole response does not contains credentials'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from assumed role in profile "{profile}: {exception}".', ['profile' => $profile, 'exception' => $e]); + + return null; + } + + return new Credentials( + $credentials->getAccessKeyId(), + $credentials->getSecretAccessKey(), + $credentials->getSessionToken(), + Credentials::adjustExpireDate($credentials->getExpiration(), $this->getDateFromResult($result)) + ); + } + + /** + * @param array $profileData + */ + private function getCredentialsFromLegacySso(array $profileData, string $profile): ?Credentials + { + if (!isset( + $profileData[IniFileLoader::KEY_SSO_START_URL], + $profileData[IniFileLoader::KEY_SSO_REGION], + $profileData[IniFileLoader::KEY_SSO_ACCOUNT_ID], + $profileData[IniFileLoader::KEY_SSO_ROLE_NAME] + )) { + $this->logger->warning('Profile "{profile}" does not contains required legacy SSO config.', ['profile' => $profile]); + + return null; + } + + $ssoCacheFileLoader = new SsoCacheFileLoader($this->logger); + $tokenData = $ssoCacheFileLoader->loadSsoCacheFile($profileData[IniFileLoader::KEY_SSO_START_URL]); + + if ([] === $tokenData) { + return null; + } + + $ssoClient = new SsoClient( + ['region' => $profileData[IniFileLoader::KEY_SSO_REGION]], + new NullProvider(), // no credentials required as we provide an access token via the role credentials request + $this->httpClient + ); + $result = $ssoClient->getRoleCredentials([ + 'accessToken' => $tokenData[SsoCacheFileLoader::KEY_ACCESS_TOKEN], + 'accountId' => $profileData[IniFileLoader::KEY_SSO_ACCOUNT_ID], + 'roleName' => $profileData[IniFileLoader::KEY_SSO_ROLE_NAME], + ]); + + try { + if (null === $credentials = $result->getRoleCredentials()) { + throw new RuntimeException('The RoleCredentials response does not contains credentials'); + } + if (null === $accessKeyId = $credentials->getAccessKeyId()) { + throw new RuntimeException('The RoleCredentials response does not contain an accessKeyId'); + } + if (null === $secretAccessKey = $credentials->getSecretAccessKey()) { + throw new RuntimeException('The RoleCredentials response does not contain a secretAccessKey'); + } + if (null === $sessionToken = $credentials->getSessionToken()) { + throw new RuntimeException('The RoleCredentials response does not contain a sessionToken'); + } + if (null === $expiration = $credentials->getExpiration()) { + throw new RuntimeException('The RoleCredentials response does not contain an expiration'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from role credentials in profile "{profile}: {exception}".', ['profile' => $profile, 'exception' => $e]); + + return null; + } + + return new Credentials( + $accessKeyId, + $secretAccessKey, + $sessionToken, + (new \DateTimeImmutable())->setTimestamp($expiration) + ); + } +} diff --git a/vendor/async-aws/core/src/Credentials/InstanceProvider.php b/vendor/async-aws/core/src/Credentials/InstanceProvider.php new file mode 100644 index 000000000..033e8c8e5 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/InstanceProvider.php @@ -0,0 +1,158 @@ + + */ +final class InstanceProvider implements CredentialProvider +{ + private const TOKEN_ENDPOINT = 'http://169.254.169.254/latest/api/token'; + private const METADATA_ENDPOINT = 'http://169.254.169.254/latest/meta-data/iam/security-credentials'; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * @var float + */ + private $timeout; + + /** + * @var int + */ + private $tokenTtl; + + public function __construct(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null, float $timeout = 1.0, int $tokenTtl = 21600) + { + $this->logger = $logger ?? new NullLogger(); + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->timeout = $timeout; + $this->tokenTtl = $tokenTtl; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $token = $this->getToken(); + $headers = []; + + if (null !== $token) { + $headers = ['X-aws-ec2-metadata-token' => $token]; + } + + try { + // Fetch current Profile + $response = $this->httpClient->request('GET', self::METADATA_ENDPOINT, [ + 'timeout' => $this->timeout, + 'headers' => $headers, + ]); + $profile = $response->getContent(); + + // Fetch credentials from profile + $response = $this->httpClient->request('GET', self::METADATA_ENDPOINT . '/' . $profile, [ + 'timeout' => $this->timeout, + 'headers' => $headers, + ]); + $result = $this->toArray($response); + + if ('Success' !== $result['Code']) { + $this->logger->info('Unexpected instance profile.', ['response_code' => $result['Code']]); + + return null; + } + } catch (DecodingExceptionInterface $e) { + $this->logger->info('Failed to decode Credentials.', ['exception' => $e]); + + return null; + } catch (TransportExceptionInterface|HttpExceptionInterface $e) { + $this->logger->info('Failed to fetch Profile from Instance Metadata.', ['exception' => $e]); + + return null; + } + + if (null !== $date = $response->getHeaders(false)['date'][0] ?? null) { + $date = new \DateTimeImmutable($date); + } + + return new Credentials( + $result['AccessKeyId'], + $result['SecretAccessKey'], + $result['Token'], + Credentials::adjustExpireDate(new \DateTimeImmutable($result['Expiration']), $date) + ); + } + + /** + * Copy of Symfony\Component\HttpClient\Response::toArray without assertion on Content-Type header. + * + * @return array + */ + private function toArray(ResponseInterface $response): array + { + if ('' === $content = $response->getContent(true)) { + throw new TransportException('Response body is empty.'); + } + + try { + $content = json_decode($content, true, 512, \JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0)); + } catch (\JsonException $e) { + /** @psalm-suppress all */ + throw new JsonException(sprintf('%s for "%s".', $e->getMessage(), $response->getInfo('url')), $e->getCode()); + } + + if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error()) { + /** @psalm-suppress InvalidArgument */ + throw new JsonException(sprintf('%s for "%s".', json_last_error_msg(), $response->getInfo('url')), json_last_error()); + } + + if (!\is_array($content)) { + /** @psalm-suppress InvalidArgument */ + throw new JsonException(sprintf('JSON content was expected to decode to an array, %s returned for "%s".', \gettype($content), $response->getInfo('url'))); + } + + return $content; + } + + private function getToken(): ?string + { + try { + $response = $this->httpClient->request('PUT', self::TOKEN_ENDPOINT, + [ + 'timeout' => $this->timeout, + 'headers' => ['X-aws-ec2-metadata-token-ttl-seconds' => $this->tokenTtl], + ] + ); + + return $response->getContent(); + } catch (TransportExceptionInterface|HttpExceptionInterface $e) { + $this->logger->info('Failed to fetch metadata token for IMDSv2, fallback to IMDSv1.', ['exception' => $e]); + + return null; + } + } +} diff --git a/vendor/async-aws/core/src/Credentials/NullProvider.php b/vendor/async-aws/core/src/Credentials/NullProvider.php new file mode 100644 index 000000000..b6399216e --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/NullProvider.php @@ -0,0 +1,20 @@ + + */ +final class NullProvider implements CredentialProvider +{ + public function getCredentials(Configuration $configuration): ?Credentials + { + return null; + } +} diff --git a/vendor/async-aws/core/src/Credentials/PsrCacheProvider.php b/vendor/async-aws/core/src/Credentials/PsrCacheProvider.php new file mode 100644 index 000000000..7dd0a0421 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/PsrCacheProvider.php @@ -0,0 +1,73 @@ + + */ +final class PsrCacheProvider implements CredentialProvider +{ + /** + * @var CacheItemPoolInterface + */ + private $cache; + + /** + * @var CredentialProvider + */ + private $decorated; + + /** + * @var LoggerInterface|null + */ + private $logger; + + public function __construct(CredentialProvider $decorated, CacheItemPoolInterface $cache, ?LoggerInterface $logger = null) + { + $this->decorated = $decorated; + $this->cache = $cache; + $this->logger = $logger; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + try { + return $this->getFromCache($configuration); + } catch (CacheException $e) { + if (null !== $this->logger) { + $this->logger->error('Failed to get AWS credentials from cache.', ['exception' => $e]); + } + + return $this->decorated->getCredentials($configuration); + } + } + + /** + * @throws CacheException + */ + private function getFromCache(Configuration $configuration): ?Credentials + { + $item = $this->cache->getItem('AsyncAws.Credentials.' . sha1(serialize([$configuration, \get_class($this->decorated)]))); + if (!$item->isHit()) { + $item->set($credential = $this->decorated->getCredentials($configuration)); + + if (null !== $credential && null !== $exp = $credential->getExpireDate()) { + $item->expiresAt($exp); + $this->cache->save($item); + } + } + + return $item->get(); + } +} diff --git a/vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php b/vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php new file mode 100644 index 000000000..756476835 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php @@ -0,0 +1,79 @@ +logger = $logger ?? new NullLogger(); + } + + /** + * @return array + */ + public function loadSsoCacheFile(string $ssoStartUrl): array + { + $filepath = sprintf('%s/.aws/sso/cache/%s.json', $this->getHomeDir(), sha1($ssoStartUrl)); + + if (false === ($contents = @file_get_contents($filepath))) { + $this->logger->warning('The sso cache file {path} is not readable.', ['path' => $filepath]); + + return []; + } + + $tokenData = json_decode($contents, true); + if (!isset($tokenData[self::KEY_ACCESS_TOKEN], $tokenData[self::KEY_EXPIRES_AT])) { + $this->logger->warning('Token file at {path} must contain an accessToken and an expiresAt.', ['path' => $filepath]); + + return []; + } + + try { + $expiration = (new \DateTimeImmutable($tokenData[self::KEY_EXPIRES_AT])); + } catch (\Exception $e) { + $this->logger->warning('Cached SSO credentials returned an invalid expiresAt value.'); + + return []; + } + + if ($expiration < new \DateTimeImmutable()) { + $this->logger->warning('Cached SSO credentials returned an invalid expiresAt value.'); + + return []; + } + + return $tokenData; + } + + private function getHomeDir(): string + { + // On Linux/Unix-like systems, use the HOME environment variable + if (null !== $homeDir = EnvVar::get('HOME')) { + return $homeDir; + } + + // Get the HOMEDRIVE and HOMEPATH values for Windows hosts + $homeDrive = EnvVar::get('HOMEDRIVE'); + $homePath = EnvVar::get('HOMEPATH'); + + return ($homeDrive && $homePath) ? $homeDrive . $homePath : '/'; + } +} diff --git a/vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php b/vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php new file mode 100644 index 000000000..e3bfe25c3 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php @@ -0,0 +1,71 @@ + + */ +final class SymfonyCacheProvider implements CredentialProvider +{ + /** + * @var CacheInterface + */ + private $cache; + + /** + * @var CredentialProvider + */ + private $decorated; + + /** + * @var LoggerInterface|null + */ + private $logger; + + public function __construct(CredentialProvider $decorated, CacheInterface $cache, ?LoggerInterface $logger = null) + { + $this->decorated = $decorated; + $this->cache = $cache; + $this->logger = $logger; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $provider = $this->decorated; + $closure = \Closure::fromCallable(static function (ItemInterface $item) use ($configuration, $provider) { + $credential = $provider->getCredentials($configuration); + + if (null !== $credential && null !== $exp = $credential->getExpireDate()) { + $item->expiresAt($exp); + } else { + $item->expiresAfter(0); + } + + return $credential; + }); + + try { + return $this->cache->get('AsyncAws.Credentials.' . sha1(serialize([$configuration, \get_class($this->decorated)])), $closure); + } catch (CacheException $e) { + if (null !== $this->logger) { + $this->logger->error('Failed to get AWS credentials from cache.', ['exception' => $e]); + } + + return $provider->getCredentials($configuration); + } + } +} diff --git a/vendor/async-aws/core/src/Credentials/WebIdentityProvider.php b/vendor/async-aws/core/src/Credentials/WebIdentityProvider.php new file mode 100644 index 000000000..f05485e66 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/WebIdentityProvider.php @@ -0,0 +1,158 @@ + + */ +final class WebIdentityProvider implements CredentialProvider +{ + use DateFromResult; + + /** + * @var IniFileLoader + */ + private $iniFileLoader; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface|null + */ + private $httpClient; + + public function __construct(?LoggerInterface $logger = null, ?IniFileLoader $iniFileLoader = null, ?HttpClientInterface $httpClient = null) + { + $this->logger = $logger ?? new NullLogger(); + $this->iniFileLoader = $iniFileLoader ?? new IniFileLoader($this->logger); + $this->httpClient = $httpClient; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $roleArn = $configuration->get(Configuration::OPTION_ROLE_ARN); + $tokenFile = $configuration->get(Configuration::OPTION_WEB_IDENTITY_TOKEN_FILE); + + if ($tokenFile && $roleArn) { + return $this->getCredentialsFromRole( + $roleArn, + $tokenFile, + $configuration->get(Configuration::OPTION_ROLE_SESSION_NAME), + $configuration->get(Configuration::OPTION_REGION) + ); + } + + $profilesData = $this->iniFileLoader->loadProfiles([ + $configuration->get(Configuration::OPTION_SHARED_CREDENTIALS_FILE), + $configuration->get(Configuration::OPTION_SHARED_CONFIG_FILE), + ]); + if (empty($profilesData)) { + return null; + } + + /** @var string $profile */ + $profile = $configuration->get(Configuration::OPTION_PROFILE); + if (!isset($profilesData[$profile])) { + $this->logger->warning('Profile "{profile}" not found.', ['profile' => $profile]); + + return null; + } + + $profileData = $profilesData[$profile]; + $roleArn = $profileData[IniFileLoader::KEY_ROLE_ARN] ?? null; + $tokenFile = $profileData[IniFileLoader::KEY_WEB_IDENTITY_TOKEN_FILE] ?? null; + + if (null !== $roleArn && null !== $tokenFile) { + return $this->getCredentialsFromRole( + $roleArn, + $tokenFile, + $profileData[IniFileLoader::KEY_ROLE_SESSION_NAME] ?? null, + $profileData[IniFileLoader::KEY_REGION] ?? $configuration->get(Configuration::OPTION_REGION) + ); + } + + return null; + } + + private function getCredentialsFromRole(string $roleArn, string $tokenFile, ?string $sessionName, ?string $region): ?Credentials + { + $sessionName = $sessionName ?? uniqid('async-aws-', true); + if (!preg_match("/^\w\:|^\/|^\\\/", $tokenFile)) { + $this->logger->warning('WebIdentityTokenFile "{tokenFile}" must be an absolute path.', ['tokenFile' => $tokenFile]); + } + + try { + $token = $this->getTokenFileContent($tokenFile); + } catch (\Exception $e) { + $this->logger->warning('"Error reading WebIdentityTokenFile "{tokenFile}.', ['tokenFile' => $tokenFile, 'exception' => $e]); + + return null; + } + + $stsClient = new StsClient(['region' => $region], new NullProvider(), $this->httpClient); + $result = $stsClient->assumeRoleWithWebIdentity([ + 'RoleArn' => $roleArn, + 'RoleSessionName' => $sessionName, + 'WebIdentityToken' => $token, + ]); + + try { + if (null === $credentials = $result->getCredentials()) { + throw new RuntimeException('The AssumeRoleWithWebIdentity response does not contains credentials'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from assumed role: {exception}".', ['exception' => $e]); + + return null; + } + + return new Credentials( + $credentials->getAccessKeyId(), + $credentials->getSecretAccessKey(), + $credentials->getSessionToken(), + Credentials::adjustExpireDate($credentials->getExpiration(), $this->getDateFromResult($result)) + ); + } + + /** + * @see https://github.com/async-aws/aws/issues/900 + * @see https://github.com/aws/aws-sdk-php/issues/2014 + * @see https://github.com/aws/aws-sdk-php/pull/2043 + */ + private function getTokenFileContent(string $tokenFile): string + { + $token = @file_get_contents($tokenFile); + + if (false !== $token) { + return $token; + } + + $tokenDir = \dirname($tokenFile); + $tokenLink = readlink($tokenFile); + clearstatcache(true, $tokenDir . \DIRECTORY_SEPARATOR . $tokenLink); + clearstatcache(true, $tokenDir . \DIRECTORY_SEPARATOR . \dirname($tokenLink)); + clearstatcache(true, $tokenFile); + + if (false === $token = file_get_contents($tokenFile)) { + throw new RuntimeException('Failed to read data'); + } + + return $token; + } +} diff --git a/vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php b/vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php new file mode 100644 index 000000000..e659e4900 --- /dev/null +++ b/vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php @@ -0,0 +1,126 @@ + + * + * @internal + */ +class EndpointCache +{ + /** + * @var array> + */ + private $endpoints = []; + + /** + * @var array> + */ + private $expired = []; + + /** + * @param EndpointInterface[] $endpoints + */ + public function addEndpoints(?string $region, array $endpoints): void + { + $now = time(); + + if (null === $region) { + $region = ''; + } + if (!isset($this->endpoints[$region])) { + $this->endpoints[$region] = []; + } + + foreach ($endpoints as $endpoint) { + $this->endpoints[$region][$this->sanitizeEndpoint($endpoint->getAddress())] = $now + ($endpoint->getCachePeriodInMinutes() * 60); + } + arsort($this->endpoints[$region]); + } + + public function removeEndpoint(string $endpoint): void + { + $endpoint = $this->sanitizeEndpoint($endpoint); + foreach ($this->endpoints as &$endpoints) { + unset($endpoints[$endpoint]); + } + unset($endpoints); + foreach ($this->expired as &$endpoints) { + unset($endpoints[$endpoint]); + } + + unset($endpoints); + } + + public function getActiveEndpoint(?string $region): ?string + { + if (null === $region) { + $region = ''; + } + $now = time(); + + foreach ($this->endpoints[$region] ?? [] as $endpoint => $expiresAt) { + if ($expiresAt < $now) { + $this->expired[$region] = \array_slice($this->expired[$region] ?? [], -100); // keep only the last 100 items + unset($this->endpoints[$region][$endpoint]); + $this->expired[$region][$endpoint] = $expiresAt; + + continue; + } + + return $endpoint; + } + + return null; + } + + public function getExpiredEndpoint(?string $region): ?string + { + if (null === $region) { + $region = ''; + } + if (empty($this->expired[$region])) { + return null; + } + + return array_key_last($this->expired[$region]); + } + + private function sanitizeEndpoint(string $address): string + { + $parsed = parse_url($address); + + // parse_url() will correctly parse full URIs with schemes + if (isset($parsed['host'])) { + return rtrim(sprintf( + '%s://%s/%s', + $parsed['scheme'] ?? 'https', + $parsed['host'], + ltrim($parsed['path'] ?? '/', '/') + ), '/'); + } + + // parse_url() will put host & path in 'path' if scheme is not provided + if (isset($parsed['path'])) { + $split = explode('/', $parsed['path'], 2); + $parsed['host'] = $split[0]; + if (isset($split[1])) { + $parsed['path'] = $split[1]; + } else { + $parsed['path'] = ''; + } + + return rtrim(sprintf( + '%s://%s/%s', + $parsed['scheme'] ?? 'https', + $parsed['host'], + ltrim($parsed['path'], '/') + ), '/'); + } + + throw new LogicException(sprintf('The supplied endpoint "%s" is invalid.', $address)); + } +} diff --git a/vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php b/vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php new file mode 100644 index 000000000..d46e2f340 --- /dev/null +++ b/vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php @@ -0,0 +1,10 @@ + + * + * @internal + */ +final class EnvVar +{ + public static function get(string $name): ?string + { + if (isset($_ENV[$name])) { + // variable_order = *E*GPCS + return (string) $_ENV[$name]; + } elseif (isset($_SERVER[$name]) && !\is_array($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + // fastcgi_param, env var, ... + return (string) $_SERVER[$name]; + } elseif (false === $env = getenv($name)) { + // getenv not thread safe + return null; + } + + return $env; + } +} diff --git a/vendor/async-aws/core/src/Exception/Exception.php b/vendor/async-aws/core/src/Exception/Exception.php new file mode 100644 index 000000000..87b8074e9 --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Exception.php @@ -0,0 +1,14 @@ + + */ +interface Exception extends \Throwable +{ +} diff --git a/vendor/async-aws/core/src/Exception/Http/ClientException.php b/vendor/async-aws/core/src/Exception/Http/ClientException.php new file mode 100644 index 000000000..5ffbe0227 --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/ClientException.php @@ -0,0 +1,17 @@ + + */ +class ClientException extends \RuntimeException implements ClientExceptionInterface, HttpException +{ + use HttpExceptionTrait; +} diff --git a/vendor/async-aws/core/src/Exception/Http/HttpException.php b/vendor/async-aws/core/src/Exception/Http/HttpException.php new file mode 100644 index 000000000..cc5f6e64f --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/HttpException.php @@ -0,0 +1,21 @@ + + * @author Tobias Nyholm + * @author Jérémy Derussé + * + * @internal + */ +trait HttpExceptionTrait +{ + /** + * @var ResponseInterface + */ + private $response; + + /** + * @var ?AwsError + */ + private $awsError; + + public function __construct(ResponseInterface $response, ?AwsError $awsError = null) + { + $this->response = $response; + /** @var int $code */ + $code = $response->getInfo('http_code'); + /** @var string $url */ + $url = $response->getInfo('url'); + + $message = sprintf('HTTP %d returned for "%s".', $code, $url); + if (null !== $this->awsError = $awsError) { + $message .= <<awsError->getCode()} +Message: {$this->awsError->getMessage()} +Type: {$this->awsError->getType()} +Detail: {$this->awsError->getDetail()} + +TEXT; + } + + parent::__construct($message, $code); + + $this->populateResult($response); + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } + + public function getAwsCode(): ?string + { + return $this->awsError ? $this->awsError->getCode() : null; + } + + public function getAwsType(): ?string + { + return $this->awsError ? $this->awsError->getType() : null; + } + + public function getAwsMessage(): ?string + { + return $this->awsError ? $this->awsError->getMessage() : null; + } + + public function getAwsDetail(): ?string + { + return $this->awsError ? $this->awsError->getDetail() : null; + } + + protected function populateResult(ResponseInterface $response): void + { + } +} diff --git a/vendor/async-aws/core/src/Exception/Http/NetworkException.php b/vendor/async-aws/core/src/Exception/Http/NetworkException.php new file mode 100644 index 000000000..9c893ddde --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/NetworkException.php @@ -0,0 +1,17 @@ + + */ +class NetworkException extends \RuntimeException implements Exception, TransportExceptionInterface +{ +} diff --git a/vendor/async-aws/core/src/Exception/Http/RedirectionException.php b/vendor/async-aws/core/src/Exception/Http/RedirectionException.php new file mode 100644 index 000000000..c1443b98c --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/RedirectionException.php @@ -0,0 +1,17 @@ + + */ +final class RedirectionException extends \RuntimeException implements HttpException, RedirectionExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/async-aws/core/src/Exception/Http/ServerException.php b/vendor/async-aws/core/src/Exception/Http/ServerException.php new file mode 100644 index 000000000..baf6560f8 --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/ServerException.php @@ -0,0 +1,17 @@ + + */ +class ServerException extends \RuntimeException implements HttpException, ServerExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/async-aws/core/src/Exception/InvalidArgument.php b/vendor/async-aws/core/src/Exception/InvalidArgument.php new file mode 100644 index 000000000..46604d57a --- /dev/null +++ b/vendor/async-aws/core/src/Exception/InvalidArgument.php @@ -0,0 +1,9 @@ + + */ +class AwsHttpClientFactory +{ + public static function createRetryableClient(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null): HttpClientInterface + { + if (null === $httpClient) { + $httpClient = HttpClient::create(); + } + if (class_exists(RetryableHttpClient::class)) { + /** @psalm-suppress MissingDependency */ + $httpClient = new RetryableHttpClient( + $httpClient, + new AwsRetryStrategy(), + 3, + $logger + ); + } + + return $httpClient; + } +} diff --git a/vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php b/vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php new file mode 100644 index 000000000..d779f6f80 --- /dev/null +++ b/vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php @@ -0,0 +1,73 @@ + + */ +class AwsRetryStrategy extends GenericRetryStrategy +{ + // Override Symfony default options for a better integration of AWS servers. + public const DEFAULT_RETRY_STATUS_CODES = [0, 423, 425, 429, 500, 502, 503, 504, 507, 510]; + + /** + * @var AwsErrorFactoryInterface + */ + private $awsErrorFactory; + + /** + * @param array $statusCodes + */ + public function __construct(array $statusCodes = self::DEFAULT_RETRY_STATUS_CODES, int $delayMs = 1000, float $multiplier = 2.0, int $maxDelayMs = 0, float $jitter = 0.1, ?AwsErrorFactoryInterface $awsErrorFactory = null) + { + parent::__construct($statusCodes, $delayMs, $multiplier, $maxDelayMs, $jitter); + $this->awsErrorFactory = $awsErrorFactory ?? new ChainAwsErrorFactory(); + } + + public function shouldRetry(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): ?bool + { + if (parent::shouldRetry($context, $responseContent, $exception)) { + return true; + } + + if (!\in_array($context->getStatusCode(), [400, 403], true)) { + return false; + } + + if (null === $responseContent) { + return null; // null mean no decision taken and need to be called again with the body + } + + try { + $error = $this->awsErrorFactory->createFromContent($responseContent, $context->getHeaders()); + } catch (UnparsableResponse $e) { + return false; + } + + return \in_array($error->getCode(), [ + 'RequestLimitExceeded', + 'Throttling', + 'ThrottlingException', + 'ThrottledException', + 'LimitExceededException', + 'PriorRequestNotComplete', + 'ProvisionedThroughputExceededException', + 'RequestThrottled', + 'SlowDown', + 'BandwidthLimitExceeded', + 'RequestThrottledException', + 'RetryableThrottlingException', + 'TooManyRequestsException', + 'IDPCommunicationError', + 'EC2ThrottledException', + 'TransactionInProgressException', + ], true); + } +} diff --git a/vendor/async-aws/core/src/Input.php b/vendor/async-aws/core/src/Input.php new file mode 100644 index 000000000..2c360d94e --- /dev/null +++ b/vendor/async-aws/core/src/Input.php @@ -0,0 +1,36 @@ + + */ +abstract class Input +{ + /** + * @var string|null + */ + public $region; + + /** + * @param array{'@region'?: ?string,...} $input + */ + protected function __construct(array $input) + { + $this->region = $input['@region'] ?? null; + } + + public function setRegion(?string $region): void + { + $this->region = $region; + } + + public function getRegion(): ?string + { + return $this->region; + } + + abstract public function request(): Request; +} diff --git a/vendor/async-aws/core/src/Request.php b/vendor/async-aws/core/src/Request.php new file mode 100644 index 000000000..52eac4dde --- /dev/null +++ b/vendor/async-aws/core/src/Request.php @@ -0,0 +1,215 @@ + + */ +final class Request +{ + /** + * @var string + */ + private $method; + + /** + * @var string + */ + private $uri; + + /** + * @var array + */ + private $headers; + + /** + * @var RequestStream + */ + private $body; + + /** + * @var string|null + */ + private $queryString; + + /** + * @var array + */ + private $query; + + /** + * @var string + */ + private $endpoint; + + /** + * @var string + */ + private $hostPrefix; + + /** + * @var array{scheme: string, host: string, port: int|null}|null + */ + private $parsed; + + /** + * @param array $query + * @param array $headers + */ + public function __construct(string $method, string $uri, array $query, array $headers, RequestStream $body, string $hostPrefix = '') + { + $this->method = $method; + $this->uri = $uri; + $this->headers = []; + foreach ($headers as $key => $value) { + $this->headers[strtolower($key)] = (string) $value; + } + $this->body = $body; + $this->query = $query; + $this->hostPrefix = $hostPrefix; + $this->endpoint = ''; + } + + public function getMethod(): string + { + return $this->method; + } + + public function setMethod(string $method): void + { + $this->method = $method; + } + + public function getUri(): string + { + return $this->uri; + } + + public function hasHeader(string $name): bool + { + return \array_key_exists(strtolower($name), $this->headers); + } + + public function setHeader(string $name, string $value): void + { + $this->headers[strtolower($name)] = $value; + } + + /** + * @return array + */ + public function getHeaders(): array + { + return $this->headers; + } + + public function getHeader(string $name): ?string + { + return $this->headers[strtolower($name)] ?? null; + } + + public function removeHeader(string $name): void + { + unset($this->headers[strtolower($name)]); + } + + public function getBody(): RequestStream + { + return $this->body; + } + + public function setBody(RequestStream $body): void + { + $this->body = $body; + } + + public function hasQueryAttribute(string $name): bool + { + return \array_key_exists($name, $this->query); + } + + public function removeQueryAttribute(string $name): void + { + unset($this->query[$name]); + $this->queryString = null; + $this->endpoint = ''; + } + + public function setQueryAttribute(string $name, string $value): void + { + $this->query[$name] = $value; + $this->queryString = null; + $this->endpoint = ''; + } + + public function getQueryAttribute(string $name): ?string + { + return $this->query[$name] ?? null; + } + + /** + * @return array + */ + public function getQuery(): array + { + return $this->query; + } + + public function getHostPrefix(): string + { + return $this->hostPrefix; + } + + public function setHostPrefix(string $hostPrefix): void + { + $this->hostPrefix = $hostPrefix; + $this->endpoint = ''; + } + + public function getEndpoint(): string + { + if (empty($this->endpoint)) { + if (null === $this->parsed) { + throw new LogicException('Request::$endpoint must be set before using it.'); + } + + $this->endpoint = $this->parsed['scheme'] . '://' . $this->hostPrefix . $this->parsed['host'] . (isset($this->parsed['port']) ? ':' . $this->parsed['port'] : '') . $this->uri . ($this->query ? (false === strpos($this->uri, '?') ? '?' : '&') . $this->getQueryString() : ''); + } + + return $this->endpoint; + } + + public function setEndpoint(string $endpoint): void + { + if (null !== $this->parsed) { + throw new LogicException('Request::$endpoint cannot be changed after it has a value.'); + } + + $parsed = parse_url($endpoint); + + if (false === $parsed || !isset($parsed['scheme'], $parsed['host'])) { + throw new InvalidArgument(sprintf('The endpoint "%s" is invalid.', $endpoint)); + } + + $this->parsed = ['scheme' => $parsed['scheme'], 'host' => $parsed['host'], 'port' => $parsed['port'] ?? null]; + + $this->queryString = $parsed['query'] ?? ''; + parse_str($parsed['query'] ?? '', $this->query); + $this->uri = $parsed['path'] ?? '/'; + } + + private function getQueryString(): string + { + if (null === $this->queryString) { + $this->queryString = http_build_query($this->query, '', '&', \PHP_QUERY_RFC3986); + } + + return $this->queryString; + } +} diff --git a/vendor/async-aws/core/src/RequestContext.php b/vendor/async-aws/core/src/RequestContext.php new file mode 100644 index 000000000..9d5226eb9 --- /dev/null +++ b/vendor/async-aws/core/src/RequestContext.php @@ -0,0 +1,119 @@ + + */ +final class RequestContext +{ + public const AVAILABLE_OPTIONS = [ + 'region' => true, + 'operation' => true, + 'expirationDate' => true, + 'currentDate' => true, + 'exceptionMapping' => true, + 'usesEndpointDiscovery' => true, + 'requiresEndpointDiscovery' => true, + ]; + + /** + * @var string|null + */ + private $operation; + + /** + * @var bool + */ + private $usesEndpointDiscovery = false; + + /** + * @var bool + */ + private $requiresEndpointDiscovery = false; + + /** + * @var string|null + */ + private $region; + + /** + * @var \DateTimeImmutable|null + */ + private $expirationDate; + + /** + * @var \DateTimeImmutable|null + */ + private $currentDate; + + /** + * @var array> + */ + private $exceptionMapping = []; + + /** + * @param array{ + * operation?: null|string, + * region?: null|string, + * expirationDate?: null|\DateTimeImmutable, + * currentDate?: null|\DateTimeImmutable, + * exceptionMapping?: array>, + * usesEndpointDiscovery?: bool, + * requiresEndpointDiscovery?: bool, + * } $options + */ + public function __construct(array $options = []) + { + if (0 < \count($invalidOptions = array_diff_key($options, self::AVAILABLE_OPTIONS))) { + throw new InvalidArgument(sprintf('Invalid option(s) "%s" passed to "%s". ', implode('", "', array_keys($invalidOptions)), __METHOD__)); + } + + foreach ($options as $property => $value) { + $this->$property = $value; + } + } + + public function getOperation(): ?string + { + return $this->operation; + } + + public function getRegion(): ?string + { + return $this->region; + } + + public function getExpirationDate(): ?\DateTimeImmutable + { + return $this->expirationDate; + } + + public function getCurrentDate(): ?\DateTimeImmutable + { + return $this->currentDate; + } + + /** + * @return array> + */ + public function getExceptionMapping(): array + { + return $this->exceptionMapping; + } + + public function usesEndpointDiscovery(): bool + { + return $this->usesEndpointDiscovery; + } + + public function requiresEndpointDiscovery(): bool + { + return $this->requiresEndpointDiscovery; + } +} diff --git a/vendor/async-aws/core/src/Response.php b/vendor/async-aws/core/src/Response.php new file mode 100644 index 000000000..b58ade040 --- /dev/null +++ b/vendor/async-aws/core/src/Response.php @@ -0,0 +1,477 @@ + + */ +final class Response +{ + /** + * @var ResponseInterface + */ + private $httpResponse; + + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * A Result can be resolved many times. This variable contains the last resolve result. + * Null means that the result has never been resolved. Array contains material to create an exception. + * + * @var bool|HttpException|NetworkException|(callable(): (HttpException|NetworkException))|null + */ + private $resolveResult; + + /** + * A flag that indicated that the body have been downloaded. + * + * @var bool + */ + private $bodyDownloaded = false; + + /** + * A flag that indicated that the body started being downloaded. + * + * @var bool + */ + private $streamStarted = false; + + /** + * A flag that indicated that an exception has been thrown to the user. + * + * @var bool + */ + private $didThrow = false; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var AwsErrorFactoryInterface + */ + private $awsErrorFactory; + + /** + * @var ?EndpointCache + */ + private $endpointCache; + + /** + * @var ?Request + */ + private $request; + + /** + * @var bool + */ + private $debug; + + /** + * @var array> + */ + private $exceptionMapping; + + /** + * @param array> $exceptionMapping + */ + public function __construct(ResponseInterface $response, HttpClientInterface $httpClient, LoggerInterface $logger, ?AwsErrorFactoryInterface $awsErrorFactory = null, ?EndpointCache $endpointCache = null, ?Request $request = null, bool $debug = false, array $exceptionMapping = []) + { + $this->httpResponse = $response; + $this->httpClient = $httpClient; + $this->logger = $logger; + $this->awsErrorFactory = $awsErrorFactory ?? new ChainAwsErrorFactory(); + $this->endpointCache = $endpointCache; + $this->request = $request; + $this->debug = $debug; + $this->exceptionMapping = $exceptionMapping; + } + + public function __destruct() + { + if (null === $this->resolveResult || !$this->didThrow) { + $this->resolve(); + } + } + + /** + * Make sure the actual request is executed. + * + * @param float|null $timeout Duration in seconds before aborting. When null wait + * until the end of execution. Using 0 means non-blocking + * + * @return bool whether the request is executed or not + * + * @throws NetworkException + * @throws HttpException + */ + public function resolve(?float $timeout = null): bool + { + if (null !== $this->resolveResult) { + return $this->getResolveStatus(); + } + + try { + if (null === $timeout) { + $this->httpResponse->getStatusCode(); + } else { + foreach ($this->httpClient->stream($this->httpResponse, $timeout) as $chunk) { + if ($chunk->isTimeout()) { + return false; + } + if ($chunk->isFirst()) { + break; + } + } + } + + $this->defineResolveStatus(); + } catch (TransportExceptionInterface $e) { + $this->resolveResult = new NetworkException('Could not contact remote server.', 0, $e); + } + + if (true === $this->debug) { + $httpStatusCode = $this->httpResponse->getInfo('http_code'); + if (0 === $httpStatusCode) { + // Network exception + $this->logger->debug('AsyncAws HTTP request could not be sent due network issues'); + } else { + $this->logger->debug('AsyncAws HTTP response received with status code {status_code}', [ + 'status_code' => $httpStatusCode, + 'headers' => json_encode($this->httpResponse->getHeaders(false)), + 'body' => $this->httpResponse->getContent(false), + ]); + $this->bodyDownloaded = true; + } + } + + return $this->getResolveStatus(); + } + + /** + * Make sure all provided requests are executed. + * + * @param self[] $responses + * @param float|null $timeout Duration in seconds before aborting. When null wait + * until the end of execution. Using 0 means non-blocking + * @param bool $downloadBody Wait until receiving the entire response body or only the first bytes + * + * @return iterable + * + * @throws NetworkException + * @throws HttpException + */ + final public static function wait(iterable $responses, ?float $timeout = null, bool $downloadBody = false): iterable + { + /** @var self[] $responseMap */ + $responseMap = []; + $indexMap = []; + $httpResponses = []; + $httpClient = null; + foreach ($responses as $index => $response) { + if (null !== $response->resolveResult && (true !== $response->resolveResult || !$downloadBody || $response->bodyDownloaded)) { + yield $index => $response; + + continue; + } + + if (null === $httpClient) { + $httpClient = $response->httpClient; + } elseif ($httpClient !== $response->httpClient) { + throw new LogicException('Unable to wait for the given results, they all have to be created with the same HttpClient'); + } + $httpResponses[] = $response->httpResponse; + $indexMap[$hash = spl_object_id($response->httpResponse)] = $index; + $responseMap[$hash] = $response; + } + + // no response provided (or all responses already resolved) + if (empty($httpResponses)) { + return; + } + + if (null === $httpClient) { + throw new InvalidArgument('At least one response should have contain an Http Client'); + } + + foreach ($httpClient->stream($httpResponses, $timeout) as $httpResponse => $chunk) { + $hash = spl_object_id($httpResponse); + $response = $responseMap[$hash] ?? null; + // Check if null, just in case symfony yield an unexpected response. + if (null === $response) { + continue; + } + + // index could be null if already yield + $index = $indexMap[$hash] ?? null; + + try { + if ($chunk->isTimeout()) { + // Receiving a timeout mean all responses are inactive. + break; + } + } catch (TransportExceptionInterface $e) { + // Exception is stored as an array, because storing an instance of \Exception will create a circular + // reference and prevent `__destruct` being called. + $response->resolveResult = new NetworkException('Could not contact remote server.', 0, $e); + + if (null !== $index) { + unset($indexMap[$hash]); + yield $index => $response; + if (empty($indexMap)) { + // early exit if all statusCode are known. We don't have to wait for all responses + return; + } + } + } + + if (!$response->streamStarted && '' !== $chunk->getContent()) { + $response->streamStarted = true; + } + + if ($chunk->isLast()) { + $response->bodyDownloaded = true; + if (null !== $index && $downloadBody) { + unset($indexMap[$hash]); + yield $index => $response; + } + } + if ($chunk->isFirst()) { + $response->defineResolveStatus(); + if (null !== $index && !$downloadBody) { + unset($indexMap[$hash]); + yield $index => $response; + } + } + + if (empty($indexMap)) { + // early exit if all statusCode are known. We don't have to wait for all responses + return; + } + } + } + + /** + * Returns info on the current request. + * + * @return array{ + * resolved: bool, + * body_downloaded: bool, + * response: \Symfony\Contracts\HttpClient\ResponseInterface, + * status: int, + * } + */ + public function info(): array + { + return [ + 'resolved' => null !== $this->resolveResult, + 'body_downloaded' => $this->bodyDownloaded, + 'response' => $this->httpResponse, + 'status' => (int) $this->httpResponse->getInfo('http_code'), + ]; + } + + public function cancel(): void + { + $this->httpResponse->cancel(); + $this->resolveResult = false; + } + + /** + * @return array> + * + * @throws NetworkException + * @throws HttpException + */ + public function getHeaders(): array + { + $this->resolve(); + + return $this->httpResponse->getHeaders(false); + } + + /** + * @throws NetworkException + * @throws HttpException + */ + public function getContent(): string + { + $this->resolve(); + + try { + return $this->httpResponse->getContent(false); + } finally { + $this->bodyDownloaded = true; + } + } + + /** + * @return array + * + * @throws NetworkException + * @throws UnparsableResponse + * @throws HttpException + */ + public function toArray(): array + { + $this->resolve(); + + try { + return $this->httpResponse->toArray(false); + } catch (DecodingExceptionInterface $e) { + throw new UnparsableResponse('Could not parse response as array', 0, $e); + } finally { + $this->bodyDownloaded = true; + } + } + + public function getStatusCode(): int + { + return $this->httpResponse->getStatusCode(); + } + + /** + * @throws NetworkException + * @throws HttpException + */ + public function toStream(): ResultStream + { + $this->resolve(); + + if (\is_callable([$this->httpResponse, 'toStream'])) { + return new ResponseBodyResourceStream($this->httpResponse->toStream()); + } + + if ($this->streamStarted) { + throw new RuntimeException('Can not create a ResultStream because the body started being downloaded. The body was started to be downloaded in Response::wait()'); + } + + try { + return new ResponseBodyStream($this->httpClient->stream($this->httpResponse)); + } finally { + $this->bodyDownloaded = true; + } + } + + /** + * In PHP < 7.4, a reference to the arguments is present in the stackTrace of the exception. + * This creates a Circular reference: Response -> resolveResult -> Exception -> stackTrace -> Response. + * This mean, that calling `unset($response)` does not call the `__destruct` method and does not throw the + * remaining exception present in `resolveResult`. The `__destruct` method will be called once the garbage collector + * will detect the loop. + * That's why this method does not creates exception here, but creates closure instead that will be resolved right + * before throwing the exception. + */ + private function defineResolveStatus(): void + { + try { + $statusCode = $this->httpResponse->getStatusCode(); + } catch (TransportExceptionInterface $e) { + $this->resolveResult = static function () use ($e): NetworkException { + return new NetworkException('Could not contact remote server.', 0, $e); + }; + + return; + } + + if (300 <= $statusCode) { + try { + $awsError = $this->awsErrorFactory->createFromResponse($this->httpResponse); + if ($this->request && $this->endpointCache && (400 === $statusCode || 'InvalidEndpointException' === $awsError->getCode())) { + $this->endpointCache->removeEndpoint($this->request->getEndpoint()); + } + } catch (UnparsableResponse $e) { + $awsError = null; + } + + if ((null !== $awsCode = ($awsError ? $awsError->getCode() : null)) && isset($this->exceptionMapping[$awsCode])) { + $exceptionClass = $this->exceptionMapping[$awsCode]; + } elseif (500 <= $statusCode) { + $exceptionClass = ServerException::class; + } elseif (400 <= $statusCode) { + $exceptionClass = ClientException::class; + } else { + $exceptionClass = RedirectionException::class; + } + + $httpResponse = $this->httpResponse; + $this->resolveResult = static function () use ($exceptionClass, $httpResponse, $awsError): HttpException { + return new $exceptionClass($httpResponse, $awsError); + }; + + return; + } + + $this->resolveResult = true; + } + + private function getResolveStatus(): bool + { + if (\is_bool($this->resolveResult)) { + return $this->resolveResult; + } + + if (\is_callable($this->resolveResult)) { + $this->resolveResult = ($this->resolveResult)(); + } + + $code = null; + $message = null; + $context = ['exception' => $this->resolveResult]; + if ($this->resolveResult instanceof HttpException) { + /** @var int $code */ + $code = $this->httpResponse->getInfo('http_code'); + /** @var string $url */ + $url = $this->httpResponse->getInfo('url'); + $context['aws_code'] = $this->resolveResult->getAwsCode(); + $context['aws_message'] = $this->resolveResult->getAwsMessage(); + $context['aws_type'] = $this->resolveResult->getAwsType(); + $context['aws_detail'] = $this->resolveResult->getAwsDetail(); + $message = sprintf('HTTP %d returned for "%s".', $code, $url); + } + + if ($this->resolveResult instanceof Exception) { + $this->logger->log( + 404 === $code ? LogLevel::INFO : LogLevel::ERROR, + $message ?? $this->resolveResult->getMessage(), + $context + ); + $this->didThrow = true; + + throw $this->resolveResult; + } + + throw new RuntimeException('Unexpected resolve state'); + } +} diff --git a/vendor/async-aws/core/src/Result.php b/vendor/async-aws/core/src/Result.php new file mode 100644 index 000000000..fb57737b3 --- /dev/null +++ b/vendor/async-aws/core/src/Result.php @@ -0,0 +1,145 @@ +response = $response; + $this->awsClient = $awsClient; + $this->input = $request; + } + + public function __destruct() + { + while (!empty($this->prefetchResults)) { + array_shift($this->prefetchResults)->cancel(); + } + } + + /** + * Make sure the actual request is executed. + * + * @param float|null $timeout Duration in seconds before aborting. When null wait until the end of execution. + * + * @return bool whether the request is executed or not + * + * @throws NetworkException + * @throws HttpException + */ + final public function resolve(?float $timeout = null): bool + { + return $this->response->resolve($timeout); + } + + /** + * Make sure all provided requests are executed. + * This only work if the http responses are produced by the same HTTP client. + * See https://symfony.com/doc/current/components/http_client.html#multiplexing-responses. + * + * @param self[] $results + * @param float|null $timeout Duration in seconds before aborting. When null wait + * until the end of execution. Using 0 means non-blocking + * @param bool $downloadBody Wait until receiving the entire response body or only the first bytes + * + * @return iterable + * + * @throws NetworkException + * @throws HttpException + */ + final public static function wait(iterable $results, ?float $timeout = null, bool $downloadBody = false): iterable + { + $resultMap = []; + $responses = []; + foreach ($results as $index => $result) { + $responses[$index] = $result->response; + $resultMap[$index] = $result; + } + + foreach (Response::wait($responses, $timeout, $downloadBody) as $index => $response) { + yield $index => $resultMap[$index]; + } + } + + /** + * Returns info on the current request. + * + * @return array{ + * resolved: bool, + * body_downloaded: bool, + * response: \Symfony\Contracts\HttpClient\ResponseInterface, + * status: int, + * } + */ + final public function info(): array + { + return $this->response->info(); + } + + final public function cancel(): void + { + $this->response->cancel(); + } + + final protected function registerPrefetch(self $result): void + { + $this->prefetchResults[spl_object_id($result)] = $result; + } + + final protected function unregisterPrefetch(self $result): void + { + unset($this->prefetchResults[spl_object_id($result)]); + } + + final protected function initialize(): void + { + if ($this->initialized) { + return; + } + + $this->resolve(); + $this->initialized = true; + $this->populateResult($this->response); + } + + protected function populateResult(Response $response): void + { + } +} diff --git a/vendor/async-aws/core/src/Signer/Signer.php b/vendor/async-aws/core/src/Signer/Signer.php new file mode 100644 index 000000000..7ce4ed5d2 --- /dev/null +++ b/vendor/async-aws/core/src/Signer/Signer.php @@ -0,0 +1,19 @@ + + */ +interface Signer +{ + public function sign(Request $request, Credentials $credentials, RequestContext $context): void; + + public function presign(Request $request, Credentials $credentials, RequestContext $context): void; +} diff --git a/vendor/async-aws/core/src/Signer/SignerV4.php b/vendor/async-aws/core/src/Signer/SignerV4.php new file mode 100644 index 000000000..a407df599 --- /dev/null +++ b/vendor/async-aws/core/src/Signer/SignerV4.php @@ -0,0 +1,369 @@ + + */ +class SignerV4 implements Signer +{ + private const ALGORITHM_REQUEST = 'AWS4-HMAC-SHA256'; + + private const BLACKLIST_HEADERS = [ + 'cache-control' => true, + 'content-type' => true, + 'content-length' => true, + 'expect' => true, + 'max-forwards' => true, + 'pragma' => true, + 'range' => true, + 'te' => true, + 'if-match' => true, + 'if-none-match' => true, + 'if-modified-since' => true, + 'if-unmodified-since' => true, + 'if-range' => true, + 'accept' => true, + 'authorization' => true, + 'proxy-authorization' => true, + 'from' => true, + 'referer' => true, + 'user-agent' => true, + 'x-amzn-trace-id' => true, + 'aws-sdk-invocation-id' => true, + 'aws-sdk-retry' => true, + ]; + + /** + * @var string + */ + private $scopeName; + + /** + * @var string + */ + private $region; + + public function __construct(string $scopeName, string $region) + { + $this->scopeName = $scopeName; + $this->region = $region; + } + + public function presign(Request $request, Credentials $credentials, RequestContext $context): void + { + $now = $context->getCurrentDate() ?? new \DateTimeImmutable(); + + // Signer date have to be UTC https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html + $now = $now->setTimezone(new \DateTimeZone('UTC')); + $expires = $context->getExpirationDate() ?? $now->add(new \DateInterval('PT1H')); + + $this->handleSignature($request, $credentials, $now, $expires, true); + } + + public function sign(Request $request, Credentials $credentials, RequestContext $context): void + { + $now = $context->getCurrentDate() ?? new \DateTimeImmutable(); + + // Signer date have to be UTC https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html + $now = $now->setTimezone(new \DateTimeZone('UTC')); + + $this->handleSignature($request, $credentials, $now, $now, false); + } + + protected function buildBodyDigest(Request $request, bool $isPresign): string + { + if ($request->hasHeader('x-amz-content-sha256')) { + /** @var string $hash */ + $hash = $request->getHeader('x-amz-content-sha256'); + } else { + $body = $request->getBody(); + if ($body instanceof ReadOnceResultStream) { + $request->setBody($body = RewindableStream::create($body)); + } + + $hash = $request->getBody()->hash(); + } + + if ('UNSIGNED-PAYLOAD' === $hash) { + $request->setHeader('x-amz-content-sha256', $hash); + } + + return $hash; + } + + protected function convertBodyToStream(SigningContext $context): void + { + $request = $context->getRequest(); + $request->setBody(StringStream::create($request->getBody())); + } + + protected function buildCanonicalPath(Request $request): string + { + $doubleEncoded = rawurlencode(ltrim($request->getUri(), '/')); + + return '/' . str_replace('%2F', '/', $doubleEncoded); + } + + private function handleSignature(Request $request, Credentials $credentials, \DateTimeImmutable $now, \DateTimeImmutable $expires, bool $isPresign): void + { + $this->removePresign($request); + $this->sanitizeHostForHeader($request); + $this->assignAmzQueryValues($request, $credentials, $isPresign); + + $this->buildTime($request, $now, $expires, $isPresign); + $credentialScope = $this->buildCredentialString($request, $credentials, $now, $isPresign); + $context = new SigningContext( + $request, + $now, + implode('/', $credentialScope), + $this->buildSigningKey($credentials, $credentialScope) + ); + if ($isPresign) { + // Should be called before `buildBodyDigest` because this method may alter the body + $this->convertBodyToQuery($request); + } else { + $this->convertBodyToStream($context); + } + + $bodyDigest = $this->buildBodyDigest($request, $isPresign); + + if ($isPresign) { + // Should be called after `buildBodyDigest` because this method may remove the header `x-amz-content-sha256` + $this->convertHeaderToQuery($request); + } + + $canonicalHeaders = $this->buildCanonicalHeaders($request, $isPresign); + $canonicalRequest = $this->buildCanonicalRequest($request, $canonicalHeaders, $bodyDigest); + $stringToSign = $this->buildStringToSign($context->getNow(), $context->getCredentialString(), $canonicalRequest); + $context->setSignature($signature = $this->buildSignature($stringToSign, $context->getSigningKey())); + + if ($isPresign) { + $request->setQueryAttribute('X-Amz-Signature', $signature); + } else { + $request->setHeader('authorization', sprintf( + '%s Credential=%s/%s, SignedHeaders=%s, Signature=%s', + self::ALGORITHM_REQUEST, + $credentials->getAccessKeyId(), + implode('/', $credentialScope), + implode(';', array_keys($canonicalHeaders)), + $signature + )); + } + } + + private function removePresign(Request $request): void + { + $request->removeQueryAttribute('X-Amz-Algorithm'); + $request->removeQueryAttribute('X-Amz-Signature'); + $request->removeQueryAttribute('X-Amz-Security-Token'); + $request->removeQueryAttribute('X-Amz-Date'); + $request->removeQueryAttribute('X-Amz-Expires'); + $request->removeQueryAttribute('X-Amz-Credential'); + $request->removeQueryAttribute('X-Amz-SignedHeaders'); + } + + private function sanitizeHostForHeader(Request $request): void + { + if (false === $parsedUrl = parse_url($request->getEndpoint())) { + throw new InvalidArgument(sprintf('The endpoint "%s" is invalid.', $request->getEndpoint())); + } + + if (!isset($parsedUrl['host'])) { + return; + } + + $host = $parsedUrl['host']; + if (isset($parsedUrl['port'])) { + $host .= ':' . $parsedUrl['port']; + } + + $request->setHeader('host', $host); + } + + private function assignAmzQueryValues(Request $request, Credentials $credentials, bool $isPresign): void + { + if ($isPresign) { + $request->setQueryAttribute('X-Amz-Algorithm', self::ALGORITHM_REQUEST); + if (null !== $sessionToken = $credentials->getSessionToken()) { + $request->setQueryAttribute('X-Amz-Security-Token', $sessionToken); + } + + return; + } + + if (null !== $sessionToken = $credentials->getSessionToken()) { + $request->setHeader('x-amz-security-token', $sessionToken); + } + } + + private function buildTime(Request $request, \DateTimeImmutable $now, \DateTimeImmutable $expires, bool $isPresign): void + { + if ($isPresign) { + $duration = $expires->getTimestamp() - $now->getTimestamp(); + if ($duration > 604800) { + throw new InvalidArgument('The expiration date of presigned URL must be less than one week'); + } + if ($duration < 0) { + throw new InvalidArgument('The expiration date of presigned URL must be in the future'); + } + + $request->setQueryAttribute('X-Amz-Date', $now->format('Ymd\THis\Z')); + $request->setQueryAttribute('X-Amz-Expires', (string) $duration); + } else { + $request->setHeader('X-Amz-Date', $now->format('Ymd\THis\Z')); + } + } + + /** + * @return string[] + */ + private function buildCredentialString(Request $request, Credentials $credentials, \DateTimeImmutable $now, bool $isPresign): array + { + $credentialScope = [$now->format('Ymd'), $this->region, $this->scopeName, 'aws4_request']; + + if ($isPresign) { + $request->setQueryAttribute('X-Amz-Credential', $credentials->getAccessKeyId() . '/' . implode('/', $credentialScope)); + } + + return $credentialScope; + } + + private function convertHeaderToQuery(Request $request): void + { + foreach ($request->getHeaders() as $name => $value) { + if ('x-amz' === substr($name, 0, 5)) { + $request->setQueryAttribute($name, $value); + } + + if (isset(self::BLACKLIST_HEADERS[$name])) { + $request->removeHeader($name); + } + } + $request->removeHeader('x-amz-content-sha256'); + } + + private function convertBodyToQuery(Request $request): void + { + if ('POST' !== $request->getMethod()) { + return; + } + + $request->setMethod('GET'); + if ('application/x-www-form-urlencoded' === $request->getHeader('Content-Type')) { + parse_str($request->getBody()->stringify(), $params); + foreach ($params as $name => $value) { + $request->setQueryAttribute($name, $value); + } + } + + $request->removeHeader('content-type'); + $request->removeHeader('content-length'); + $request->setBody(StringStream::create('')); + } + + /** + * @return array + */ + private function buildCanonicalHeaders(Request $request, bool $isPresign): array + { + // Case-insensitively aggregate all of the headers. + $canonicalHeaders = []; + foreach ($request->getHeaders() as $key => $value) { + $key = strtolower($key); + if (isset(self::BLACKLIST_HEADERS[$key])) { + continue; + } + + $canonicalHeaders[$key] = $key . ':' . preg_replace('/\s+/', ' ', $value); + } + ksort($canonicalHeaders); + + if ($isPresign) { + $request->setQueryAttribute('X-Amz-SignedHeaders', implode(';', array_keys($canonicalHeaders))); + } + + return $canonicalHeaders; + } + + /** + * @param array $canonicalHeaders + */ + private function buildCanonicalRequest(Request $request, array $canonicalHeaders, string $bodyDigest): string + { + return implode("\n", [ + $request->getMethod(), + $this->buildCanonicalPath($request), + $this->buildCanonicalQuery($request), + implode("\n", array_values($canonicalHeaders)), + '', // empty line after headers + implode(';', array_keys($canonicalHeaders)), + $bodyDigest, + ]); + } + + private function buildCanonicalQuery(Request $request): string + { + $query = $request->getQuery(); + + unset($query['X-Amz-Signature']); + if (!$query) { + return ''; + } + + ksort($query); + $encodedQuery = []; + foreach ($query as $key => $values) { + if (!\is_array($values)) { + $encodedQuery[] = rawurlencode($key) . '=' . rawurlencode($values); + + continue; + } + + sort($values); + foreach ($values as $value) { + $encodedQuery[] = rawurlencode($key) . '=' . rawurlencode($value); + } + } + + return implode('&', $encodedQuery); + } + + private function buildStringToSign(\DateTimeImmutable $now, string $credentialString, string $canonicalRequest): string + { + return implode("\n", [ + self::ALGORITHM_REQUEST, + $now->format('Ymd\THis\Z'), + $credentialString, + hash('sha256', $canonicalRequest), + ]); + } + + /** + * @param string[] $credentialScope + */ + private function buildSigningKey(Credentials $credentials, array $credentialScope): string + { + $signingKey = 'AWS4' . $credentials->getSecretKey(); + foreach ($credentialScope as $scopePart) { + $signingKey = hash_hmac('sha256', $scopePart, $signingKey, true); + } + + return $signingKey; + } + + private function buildSignature(string $stringToSign, string $signingKey): string + { + return hash_hmac('sha256', $stringToSign, $signingKey); + } +} diff --git a/vendor/async-aws/core/src/Signer/SigningContext.php b/vendor/async-aws/core/src/Signer/SigningContext.php new file mode 100644 index 000000000..f012806b1 --- /dev/null +++ b/vendor/async-aws/core/src/Signer/SigningContext.php @@ -0,0 +1,78 @@ + + */ +final class SigningContext +{ + /** + * @var Request + */ + private $request; + + /** + * @var \DateTimeImmutable + */ + private $now; + + /** + * @var string + */ + private $credentialString; + + /** + * @var string + */ + private $signingKey; + + /** + * @var string + */ + private $signature = ''; + + public function __construct( + Request $request, + \DateTimeImmutable $now, + string $credentialString, + string $signingKey + ) { + $this->request = $request; + $this->now = $now; + $this->credentialString = $credentialString; + $this->signingKey = $signingKey; + } + + public function getRequest(): Request + { + return $this->request; + } + + public function getNow(): \DateTimeImmutable + { + return $this->now; + } + + public function getCredentialString(): string + { + return $this->credentialString; + } + + public function getSigningKey(): string + { + return $this->signingKey; + } + + public function getSignature(): string + { + return $this->signature; + } + + public function setSignature(string $signature): void + { + $this->signature = $signature; + } +} diff --git a/vendor/async-aws/core/src/Stream/CallableStream.php b/vendor/async-aws/core/src/Stream/CallableStream.php new file mode 100644 index 000000000..76111e9c0 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/CallableStream.php @@ -0,0 +1,84 @@ + + * + * @internal + */ +final class CallableStream implements ReadOnceResultStream, RequestStream +{ + /** + * @var callable(int): string + */ + private $content; + + /** + * @var int + */ + private $chunkSize; + + /** + * @param callable(int): string $content + */ + private function __construct(callable $content, int $chunkSize = 64 * 1024) + { + $this->content = $content; + $this->chunkSize = $chunkSize; + } + + /** + * @param self|callable(int): string $content + */ + public static function create($content, int $chunkSize = 64 * 1024): CallableStream + { + if ($content instanceof self) { + return $content; + } + if (\is_callable($content)) { + return new self($content, $chunkSize); + } + + throw new InvalidArgument(sprintf('Expect content to be a "callable". "%s" given.', \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): ?int + { + return null; + } + + public function stringify(): string + { + return implode('', iterator_to_array($this)); + } + + public function getIterator(): \Traversable + { + while (true) { + if (!\is_string($data = ($this->content)($this->chunkSize))) { + throw new InvalidArgument(sprintf('The return value of content callback must be a string, %s returned.', \is_object($data) ? \get_class($data) : \gettype($data))); + } + if ('' === $data) { + break; + } + + yield $data; + } + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + $ctx = hash_init($algo); + foreach ($this as $chunk) { + hash_update($ctx, $chunk); + } + + return hash_final($ctx, $raw); + } +} diff --git a/vendor/async-aws/core/src/Stream/FixedSizeStream.php b/vendor/async-aws/core/src/Stream/FixedSizeStream.php new file mode 100644 index 000000000..a0021c039 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/FixedSizeStream.php @@ -0,0 +1,90 @@ + + */ +final class FixedSizeStream implements RequestStream +{ + /** + * @var RequestStream + */ + private $content; + + /** + * @var int + */ + private $chunkSize; + + private function __construct(RequestStream $content, int $chunkSize = 64 * 1024) + { + $this->content = $content; + $this->chunkSize = $chunkSize; + } + + public static function create(RequestStream $content, int $chunkSize = 64 * 1024): FixedSizeStream + { + if ($content instanceof self) { + if ($content->chunkSize === $chunkSize) { + return $content; + } + + return new self($content->content, $chunkSize); + } + + return new self($content, $chunkSize); + } + + public function length(): ?int + { + return $this->content->length(); + } + + public function stringify(): string + { + return $this->content->stringify(); + } + + public function getIterator(): \Traversable + { + // This algorithm do not use string concatenation nor substr, to reuse the same ZVAL et reduce memory footprint. + $chunk = ''; + foreach ($this->content as $buffer) { + if (!\is_string($buffer)) { + throw new InvalidArgument(sprintf('The return value of content callback must be a string, %s returned.', \is_object($buffer) ? \get_class($buffer) : \gettype($buffer))); + } + + $chunk .= $nextBytes = substr($buffer, 0, $this->chunkSize - \strlen($chunk)); + $bufferPosition = \strlen($nextBytes); + + if (\strlen($chunk) < $this->chunkSize) { + // The chunk does not have yet the expected size. Let's fetching new data + continue; + } + + yield $chunk; + while (\strlen($buffer) - $bufferPosition >= $this->chunkSize) { + // The buffer is bigger than the expected size. Let's flushing it. + yield substr($buffer, $bufferPosition, $this->chunkSize); + $bufferPosition += $this->chunkSize; + } + + // Here we can substr the buffer because the remaining size is smaller that chunkSize + $chunk = substr($buffer, $bufferPosition); + } + + if ('' !== $chunk) { + yield $chunk; + } + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + return $this->content->hash($algo, $raw); + } +} diff --git a/vendor/async-aws/core/src/Stream/IterableStream.php b/vendor/async-aws/core/src/Stream/IterableStream.php new file mode 100644 index 000000000..f77407506 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/IterableStream.php @@ -0,0 +1,70 @@ + + */ +final class IterableStream implements ReadOnceResultStream, RequestStream +{ + /** + * @var iterable + */ + private $content; + + /** + * @param iterable $content + */ + private function __construct(iterable $content) + { + $this->content = $content; + } + + /** + * @param self|iterable $content + */ + public static function create($content): IterableStream + { + if ($content instanceof self) { + return $content; + } + if (is_iterable($content)) { + return new self($content); + } + + throw new InvalidArgument(sprintf('Expect content to be an iterable. "%s" given.', \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): ?int + { + return null; + } + + public function stringify(): string + { + if ($this->content instanceof \Traversable) { + return implode('', iterator_to_array($this->content)); + } + + return implode('', iterator_to_array((function () {yield from $this->content; })())); + } + + public function getIterator(): \Traversable + { + yield from $this->content; + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + $ctx = hash_init($algo); + foreach ($this->content as $chunk) { + hash_update($ctx, $chunk); + } + + return hash_final($ctx, $raw); + } +} diff --git a/vendor/async-aws/core/src/Stream/ReadOnceResultStream.php b/vendor/async-aws/core/src/Stream/ReadOnceResultStream.php new file mode 100644 index 000000000..b1fa03ac0 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ReadOnceResultStream.php @@ -0,0 +1,12 @@ + + * + * @extends \IteratorAggregate + */ +interface RequestStream extends \IteratorAggregate +{ + /** + * Length in bytes. + */ + public function length(): ?int; + + public function stringify(): string; + + public function hash(string $algo = 'sha256', bool $raw = false): string; +} diff --git a/vendor/async-aws/core/src/Stream/ResourceStream.php b/vendor/async-aws/core/src/Stream/ResourceStream.php new file mode 100644 index 000000000..0e863e4f7 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResourceStream.php @@ -0,0 +1,105 @@ + + * + * @internal + */ +final class ResourceStream implements RequestStream +{ + /** + * @var resource + */ + private $content; + + /** + * @var int + */ + private $chunkSize; + + /** + * @param resource $content + */ + private function __construct($content, int $chunkSize = 64 * 1024) + { + $this->content = $content; + $this->chunkSize = $chunkSize; + } + + /** + * @param self|resource $content + */ + public static function create($content, int $chunkSize = 64 * 1024): ResourceStream + { + if ($content instanceof self) { + return $content; + } + if (\is_resource($content)) { + if (!stream_get_meta_data($content)['seekable']) { + throw new InvalidArgument(sprintf('The give body is not seekable.')); + } + + return new self($content, $chunkSize); + } + + throw new InvalidArgument(sprintf('Expect content to be a "resource". "%s" given.', \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): ?int + { + return fstat($this->content)['size'] ?? null; + } + + public function stringify(): string + { + if (-1 === fseek($this->content, 0)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + return stream_get_contents($this->content); + } + + public function getIterator(): \Traversable + { + if (-1 === fseek($this->content, 0)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + while (!feof($this->content)) { + yield fread($this->content, $this->chunkSize); + } + } + + /** + * @return resource + */ + public function getResource() + { + return $this->content; + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + $pos = ftell($this->content); + + if ($pos > 0 && -1 === fseek($this->content, 0)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + $ctx = hash_init($algo); + hash_update_stream($ctx, $this->content); + $out = hash_final($ctx, $raw); + + if (-1 === fseek($this->content, $pos)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + return $out; + } +} diff --git a/vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php b/vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php new file mode 100644 index 000000000..00ce21a2d --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php @@ -0,0 +1,82 @@ + + */ +class ResponseBodyResourceStream implements ResultStream +{ + /** + * @var resource + */ + private $resource; + + /** + * @param resource $resource + */ + public function __construct($resource) + { + $this->resource = $resource; + } + + public function __toString(): string + { + return $this->getContentAsString(); + } + + /** + * {@inheritdoc} + */ + public function getChunks(): iterable + { + $pos = ftell($this->resource); + if (0 !== $pos && !rewind($this->resource)) { + throw new RuntimeException('The stream is not rewindable'); + } + + try { + while (!feof($this->resource)) { + yield fread($this->resource, 64 * 1024); + } + } finally { + fseek($this->resource, $pos); + } + } + + /** + * {@inheritdoc} + */ + public function getContentAsString(): string + { + $pos = ftell($this->resource); + + try { + if (!rewind($this->resource)) { + throw new RuntimeException('Failed to rewind the stream'); + } + + return stream_get_contents($this->resource); + } finally { + fseek($this->resource, $pos); + } + } + + /** + * {@inheritdoc} + */ + public function getContentAsResource() + { + if (!rewind($this->resource)) { + throw new RuntimeException('Failed to rewind the stream'); + } + + return $this->resource; + } +} diff --git a/vendor/async-aws/core/src/Stream/ResponseBodyStream.php b/vendor/async-aws/core/src/Stream/ResponseBodyStream.php new file mode 100644 index 000000000..138c56570 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResponseBodyStream.php @@ -0,0 +1,101 @@ + + * @author Jérémy Derussé + */ +class ResponseBodyStream implements ResultStream +{ + /** + * @var ResponseStreamInterface + */ + private $responseStream; + + /** + * @var ResponseBodyResourceStream|null + */ + private $fallback; + + /** + * @var bool + */ + private $partialRead = false; + + public function __construct(ResponseStreamInterface $responseStream) + { + $this->responseStream = $responseStream; + } + + public function __toString(): string + { + return $this->getContentAsString(); + } + + /** + * {@inheritdoc} + */ + public function getChunks(): iterable + { + if (null !== $this->fallback) { + yield from $this->fallback->getChunks(); + + return; + } + if ($this->partialRead) { + throw new LogicException(sprintf('You can not call "%s". Another process doesn\'t reading "getChunks" till the end.', __METHOD__)); + } + + $resource = fopen('php://temp', 'rb+'); + foreach ($this->responseStream as $chunk) { + $this->partialRead = true; + $chunkContent = $chunk->getContent(); + fwrite($resource, $chunkContent); + yield $chunkContent; + } + + $this->fallback = new ResponseBodyResourceStream($resource); + $this->partialRead = false; + } + + /** + * {@inheritdoc} + */ + public function getContentAsString(): string + { + if (null === $this->fallback) { + // Use getChunks() to read stream content to $this->fallback + foreach ($this->getChunks() as $chunk) { + } + \assert(null !== $this->fallback); + } + + return $this->fallback->getContentAsString(); + } + + /** + * {@inheritdoc} + */ + public function getContentAsResource() + { + if (null === $this->fallback) { + // Use getChunks() to read stream content to $this->fallback + foreach ($this->getChunks() as $chunk) { + } + \assert(null !== $this->fallback); + } + + return $this->fallback->getContentAsResource(); + } +} diff --git a/vendor/async-aws/core/src/Stream/ResultStream.php b/vendor/async-aws/core/src/Stream/ResultStream.php new file mode 100644 index 000000000..754662375 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResultStream.php @@ -0,0 +1,35 @@ +getBody()->getChunks() as $chunk) { + * fwrite($fileHandler, $chunk); + * } + * + * @return iterable + */ + public function getChunks(): iterable; + + /** + * Download content into a temporary resource and return a string. + */ + public function getContentAsString(): string; + + /** + * Download content into a resource and then return that resource. + * + * @return resource + */ + public function getContentAsResource(); +} diff --git a/vendor/async-aws/core/src/Stream/RewindableStream.php b/vendor/async-aws/core/src/Stream/RewindableStream.php new file mode 100644 index 000000000..44f015dcd --- /dev/null +++ b/vendor/async-aws/core/src/Stream/RewindableStream.php @@ -0,0 +1,97 @@ + + */ +final class RewindableStream implements RequestStream +{ + /** + * @var RequestStream + */ + private $content; + + /** + * @var RequestStream|null + */ + private $fallback; + + private function __construct(RequestStream $content) + { + $this->content = $content; + } + + public static function create(RequestStream $content): RewindableStream + { + if ($content instanceof self) { + return $content; + } + + return new self($content); + } + + public function length(): ?int + { + if (null !== $this->fallback) { + return $this->fallback->length(); + } + + return $this->content->length(); + } + + public function stringify(): string + { + if (null !== $this->fallback) { + return $this->fallback->stringify(); + } + + return implode('', iterator_to_array($this)); + } + + public function getIterator(): \Traversable + { + if (null !== $this->fallback) { + yield from $this->fallback; + + return; + } + + $resource = fopen('php://temp', 'r+b'); + $this->fallback = ResourceStream::create($resource); + + foreach ($this->content as $chunk) { + fwrite($resource, $chunk); + yield $chunk; + } + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + if (null !== $this->fallback) { + return $this->fallback->hash($algo, $raw); + } + + $ctx = hash_init($algo); + foreach ($this as $chunk) { + hash_update($ctx, $chunk); + } + + return hash_final($ctx, $raw); + } + + public function read(): void + { + // Use getIterator() to read stream content to $this->fallback + foreach ($this as $chunk) { + } + } +} diff --git a/vendor/async-aws/core/src/Stream/StreamFactory.php b/vendor/async-aws/core/src/Stream/StreamFactory.php new file mode 100644 index 000000000..658a7f33e --- /dev/null +++ b/vendor/async-aws/core/src/Stream/StreamFactory.php @@ -0,0 +1,34 @@ + + */ +class StreamFactory +{ + /** + * @param string|resource|(callable(int): string)|iterable|null $content + */ + public static function create($content, int $preferredChunkSize = 64 * 1024): RequestStream + { + if (null === $content || \is_string($content)) { + return StringStream::create($content ?? ''); + } + if (\is_callable($content)) { + return CallableStream::create($content, $preferredChunkSize); + } + if (is_iterable($content)) { + return IterableStream::create($content); + } + if (\is_resource($content)) { + return ResourceStream::create($content, $preferredChunkSize); + } + + throw new InvalidArgument(sprintf('Unexpected content type "%s".', \is_object($content) ? \get_class($content) : \gettype($content))); + } +} diff --git a/vendor/async-aws/core/src/Stream/StringStream.php b/vendor/async-aws/core/src/Stream/StringStream.php new file mode 100644 index 000000000..550fd63b1 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/StringStream.php @@ -0,0 +1,68 @@ + + * + * @internal + */ +final class StringStream implements RequestStream +{ + /** + * @var string + */ + private $content; + + /** + * @var int|null + */ + private $lengthCache; + + private function __construct(string $content) + { + $this->content = $content; + } + + /** + * @param RequestStream|string $content + */ + public static function create($content): StringStream + { + if ($content instanceof self) { + return $content; + } + if ($content instanceof RequestStream) { + return new self($content->stringify()); + } + if (\is_string($content)) { + return new self($content); + } + + throw new InvalidArgument(sprintf('Expect content to be a "%s" or as "string". "%s" given.', RequestStream::class, \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): int + { + return $this->lengthCache ?? $this->lengthCache = \strlen($this->content); + } + + public function stringify(): string + { + return $this->content; + } + + public function getIterator(): \Traversable + { + yield $this->content; + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + return hash($algo, $this->content, $raw); + } +} diff --git a/vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php b/vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php new file mode 100644 index 000000000..ccbd4dd0b --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php @@ -0,0 +1,13 @@ + An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * Passing policies to this operation returns new temporary credentials. The resulting session's permissions are the + * intersection of the role's identity-based policy and the session policies. You can use the role's temporary + * credentials in subsequent Amazon Web Services API calls to access resources in the account that owns the role. You + * cannot use session policies to grant more permissions than those allowed by the identity-based policy of the role + * that is being assumed. For more information, see Session Policies [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var PolicyDescriptorType[]|null + */ + private $policyArns; + + /** + * An IAM policy in JSON format that you want to use as an inline session policy. + * + * This parameter is optional. Passing policies to this operation returns new temporary credentials. The resulting + * session's permissions are the intersection of the role's identity-based policy and the session policies. You can use + * the role's temporary credentials in subsequent Amazon Web Services API calls to access resources in the account that + * owns the role. You cannot use session policies to grant more permissions than those allowed by the identity-based + * policy of the role that is being assumed. For more information, see Session Policies [^1] in the *IAM User Guide*. + * + * The plaintext that you use for both inline and managed session policies can't exceed 2,048 characters. The JSON + * policy characters can be any ASCII character from the space character to the end of the valid character list (\u0020 + * through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage return (\u000D) characters. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var string|null + */ + private $policy; + + /** + * The duration, in seconds, of the role session. The value specified can range from 900 seconds (15 minutes) up to the + * maximum session duration set for the role. The maximum session duration setting can have a value from 1 hour to 12 + * hours. If you specify a value higher than this setting or the administrator setting (whichever is lower), the + * operation fails. For example, if you specify a session duration of 12 hours, but your administrator set the maximum + * session duration to 6 hours, your operation fails. + * + * Role chaining limits your Amazon Web Services CLI or Amazon Web Services API role session to a maximum of one hour. + * When you use the `AssumeRole` API operation to assume a role, you can specify the duration of your role session with + * the `DurationSeconds` parameter. You can specify a parameter value of up to 43200 seconds (12 hours), depending on + * the maximum session duration setting for your role. However, if you assume a role using role chaining and provide a + * `DurationSeconds` parameter value greater than one hour, the operation fails. To learn how to view the maximum value + * for your role, see View the Maximum Session Duration Setting for a Role [^1] in the *IAM User Guide*. + * + * By default, the value is set to `3600` seconds. + * + * > The `DurationSeconds` parameter is separate from the duration of a console session that you might request using the + * > returned credentials. The request to the federation endpoint for a console sign-in token takes a `SessionDuration` + * > parameter that specifies the maximum length of the console session. For more information, see Creating a URL that + * > Enables Federated Users to Access the Amazon Web Services Management Console [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html + * + * @var int|null + */ + private $durationSeconds; + + /** + * A list of session tags that you want to pass. Each session tag consists of a key name and an associated value. For + * more information about session tags, see Tagging Amazon Web Services STS Sessions [^1] in the *IAM User Guide*. + * + * This parameter is optional. You can pass up to 50 session tags. The plaintext session tag keys can’t exceed 128 + * characters, and the values can’t exceed 256 characters. For these and additional limits, see IAM and STS Character + * Limits [^2] in the *IAM User Guide*. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * You can pass a session tag with the same key as a tag that is already attached to the role. When you do, session tags + * override a role tag with the same key. + * + * Tag key–value pairs are not case sensitive, but case is preserved. This means that you cannot have separate + * `Department` and `department` tag keys. Assume that the role has the `Department`=`Marketing` tag and you pass the + * `department`=`engineering` session tag. `Department` and `department` are not saved as separate tags, and the session + * tag passed in the request takes precedence over the role tag. + * + * Additionally, if you used temporary credentials to perform this operation, the new session inherits any transitive + * session tags from the calling session. If you pass a session tag with the same key as an inherited tag, the operation + * fails. To view the inherited tags for a session, see the CloudTrail logs. For more information, see Viewing Session + * Tags in CloudTrail [^3] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length + * [^3]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_ctlogs + * + * @var Tag[]|null + */ + private $tags; + + /** + * A list of keys for session tags that you want to set as transitive. If you set a tag key as transitive, the + * corresponding key and value passes to subsequent sessions in a role chain. For more information, see Chaining Roles + * with Session Tags [^1] in the *IAM User Guide*. + * + * This parameter is optional. When you set session tags as transitive, the session policy and session tags packed + * binary limit is not affected. + * + * If you choose not to specify a transitive tag key, then no tags are passed from this session to any subsequent + * sessions. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining + * + * @var string[]|null + */ + private $transitiveTagKeys; + + /** + * A unique identifier that might be required when you assume a role in another account. If the administrator of the + * account to which the role belongs provided you with an external ID, then provide that value in the `ExternalId` + * parameter. This value can be any string, such as a passphrase or account number. A cross-account role is usually set + * up to trust everyone in an account. Therefore, the administrator of the trusting account might send an external ID to + * the administrator of the trusted account. That way, only someone with the ID can assume the role, rather than + * everyone in the account. For more information about the external ID, see How to Use an External ID When Granting + * Access to Your Amazon Web Services Resources to a Third Party [^1] in the *IAM User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@:/- + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html + * + * @var string|null + */ + private $externalId; + + /** + * The identification number of the MFA device that is associated with the user who is making the `AssumeRole` call. + * Specify this value if the trust policy of the role being assumed includes a condition that requires MFA + * authentication. The value is either the serial number for a hardware device (such as `GAHT12345678`) or an Amazon + * Resource Name (ARN) for a virtual device (such as `arn:aws:iam::123456789012:mfa/user`). + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@- + * + * @var string|null + */ + private $serialNumber; + + /** + * The value provided by the MFA device, if the trust policy of the role being assumed requires MFA. (In other words, if + * the policy includes a condition that tests for MFA). If the role being assumed requires MFA and if the `TokenCode` + * value is missing or expired, the `AssumeRole` call returns an "access denied" error. + * + * The format for this parameter, as described by its regex pattern, is a sequence of six numeric digits. + * + * @var string|null + */ + private $tokenCode; + + /** + * The source identity specified by the principal that is calling the `AssumeRole` operation. + * + * You can require users to specify a source identity when they assume a role. You do this by using the + * `sts:SourceIdentity` condition key in a role trust policy. You can use source identity information in CloudTrail logs + * to determine who took actions with a role. You can use the `aws:SourceIdentity` condition key to further control + * access to Amazon Web Services resources based on the value of source identity. For more information about using + * source identity, see Monitor and control actions taken with assumed roles [^1] in the *IAM User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@-. You cannot use + * a value that begins with the text `aws:`. This prefix is reserved for Amazon Web Services internal use. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html + * + * @var string|null + */ + private $sourceIdentity; + + /** + * Reserved for future use. + * + * @var ProvidedContext[]|null + */ + private $providedContexts; + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * Tags?: array, + * TransitiveTagKeys?: string[], + * ExternalId?: string, + * SerialNumber?: string, + * TokenCode?: string, + * SourceIdentity?: string, + * ProvidedContexts?: array, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->roleArn = $input['RoleArn'] ?? null; + $this->roleSessionName = $input['RoleSessionName'] ?? null; + $this->policyArns = isset($input['PolicyArns']) ? array_map([PolicyDescriptorType::class, 'create'], $input['PolicyArns']) : null; + $this->policy = $input['Policy'] ?? null; + $this->durationSeconds = $input['DurationSeconds'] ?? null; + $this->tags = isset($input['Tags']) ? array_map([Tag::class, 'create'], $input['Tags']) : null; + $this->transitiveTagKeys = $input['TransitiveTagKeys'] ?? null; + $this->externalId = $input['ExternalId'] ?? null; + $this->serialNumber = $input['SerialNumber'] ?? null; + $this->tokenCode = $input['TokenCode'] ?? null; + $this->sourceIdentity = $input['SourceIdentity'] ?? null; + $this->providedContexts = isset($input['ProvidedContexts']) ? array_map([ProvidedContext::class, 'create'], $input['ProvidedContexts']) : null; + parent::__construct($input); + } + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * Tags?: array, + * TransitiveTagKeys?: string[], + * ExternalId?: string, + * SerialNumber?: string, + * TokenCode?: string, + * SourceIdentity?: string, + * ProvidedContexts?: array, + * '@region'?: string|null, + * }|AssumeRoleRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDurationSeconds(): ?int + { + return $this->durationSeconds; + } + + public function getExternalId(): ?string + { + return $this->externalId; + } + + public function getPolicy(): ?string + { + return $this->policy; + } + + /** + * @return PolicyDescriptorType[] + */ + public function getPolicyArns(): array + { + return $this->policyArns ?? []; + } + + /** + * @return ProvidedContext[] + */ + public function getProvidedContexts(): array + { + return $this->providedContexts ?? []; + } + + public function getRoleArn(): ?string + { + return $this->roleArn; + } + + public function getRoleSessionName(): ?string + { + return $this->roleSessionName; + } + + public function getSerialNumber(): ?string + { + return $this->serialNumber; + } + + public function getSourceIdentity(): ?string + { + return $this->sourceIdentity; + } + + /** + * @return Tag[] + */ + public function getTags(): array + { + return $this->tags ?? []; + } + + public function getTokenCode(): ?string + { + return $this->tokenCode; + } + + /** + * @return string[] + */ + public function getTransitiveTagKeys(): array + { + return $this->transitiveTagKeys ?? []; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/x-www-form-urlencoded']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = http_build_query(['Action' => 'AssumeRole', 'Version' => '2011-06-15'] + $this->requestBody(), '', '&', \PHP_QUERY_RFC1738); + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setDurationSeconds(?int $value): self + { + $this->durationSeconds = $value; + + return $this; + } + + public function setExternalId(?string $value): self + { + $this->externalId = $value; + + return $this; + } + + public function setPolicy(?string $value): self + { + $this->policy = $value; + + return $this; + } + + /** + * @param PolicyDescriptorType[] $value + */ + public function setPolicyArns(array $value): self + { + $this->policyArns = $value; + + return $this; + } + + /** + * @param ProvidedContext[] $value + */ + public function setProvidedContexts(array $value): self + { + $this->providedContexts = $value; + + return $this; + } + + public function setRoleArn(?string $value): self + { + $this->roleArn = $value; + + return $this; + } + + public function setRoleSessionName(?string $value): self + { + $this->roleSessionName = $value; + + return $this; + } + + public function setSerialNumber(?string $value): self + { + $this->serialNumber = $value; + + return $this; + } + + public function setSourceIdentity(?string $value): self + { + $this->sourceIdentity = $value; + + return $this; + } + + /** + * @param Tag[] $value + */ + public function setTags(array $value): self + { + $this->tags = $value; + + return $this; + } + + public function setTokenCode(?string $value): self + { + $this->tokenCode = $value; + + return $this; + } + + /** + * @param string[] $value + */ + public function setTransitiveTagKeys(array $value): self + { + $this->transitiveTagKeys = $value; + + return $this; + } + + private function requestBody(): array + { + $payload = []; + if (null === $v = $this->roleArn) { + throw new InvalidArgument(sprintf('Missing parameter "RoleArn" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleArn'] = $v; + if (null === $v = $this->roleSessionName) { + throw new InvalidArgument(sprintf('Missing parameter "RoleSessionName" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleSessionName'] = $v; + if (null !== $v = $this->policyArns) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["PolicyArns.member.$index.$bodyKey"] = $bodyValue; + } + } + } + if (null !== $v = $this->policy) { + $payload['Policy'] = $v; + } + if (null !== $v = $this->durationSeconds) { + $payload['DurationSeconds'] = $v; + } + if (null !== $v = $this->tags) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["Tags.member.$index.$bodyKey"] = $bodyValue; + } + } + } + if (null !== $v = $this->transitiveTagKeys) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + $payload["TransitiveTagKeys.member.$index"] = $mapValue; + } + } + if (null !== $v = $this->externalId) { + $payload['ExternalId'] = $v; + } + if (null !== $v = $this->serialNumber) { + $payload['SerialNumber'] = $v; + } + if (null !== $v = $this->tokenCode) { + $payload['TokenCode'] = $v; + } + if (null !== $v = $this->sourceIdentity) { + $payload['SourceIdentity'] = $v; + } + if (null !== $v = $this->providedContexts) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["ProvidedContexts.member.$index.$bodyKey"] = $bodyValue; + } + } + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php b/vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php new file mode 100644 index 000000000..c2eeb101b --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php @@ -0,0 +1,320 @@ + An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * Passing policies to this operation returns new temporary credentials. The resulting session's permissions are the + * intersection of the role's identity-based policy and the session policies. You can use the role's temporary + * credentials in subsequent Amazon Web Services API calls to access resources in the account that owns the role. You + * cannot use session policies to grant more permissions than those allowed by the identity-based policy of the role + * that is being assumed. For more information, see Session Policies [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var PolicyDescriptorType[]|null + */ + private $policyArns; + + /** + * An IAM policy in JSON format that you want to use as an inline session policy. + * + * This parameter is optional. Passing policies to this operation returns new temporary credentials. The resulting + * session's permissions are the intersection of the role's identity-based policy and the session policies. You can use + * the role's temporary credentials in subsequent Amazon Web Services API calls to access resources in the account that + * owns the role. You cannot use session policies to grant more permissions than those allowed by the identity-based + * policy of the role that is being assumed. For more information, see Session Policies [^1] in the *IAM User Guide*. + * + * The plaintext that you use for both inline and managed session policies can't exceed 2,048 characters. The JSON + * policy characters can be any ASCII character from the space character to the end of the valid character list (\u0020 + * through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage return (\u000D) characters. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var string|null + */ + private $policy; + + /** + * The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum + * session duration setting for the role. This setting can have a value from 1 hour to 12 hours. If you specify a value + * higher than this setting, the operation fails. For example, if you specify a session duration of 12 hours, but your + * administrator set the maximum session duration to 6 hours, your operation fails. To learn how to view the maximum + * value for your role, see View the Maximum Session Duration Setting for a Role [^1] in the *IAM User Guide*. + * + * By default, the value is set to `3600` seconds. + * + * > The `DurationSeconds` parameter is separate from the duration of a console session that you might request using the + * > returned credentials. The request to the federation endpoint for a console sign-in token takes a `SessionDuration` + * > parameter that specifies the maximum length of the console session. For more information, see Creating a URL that + * > Enables Federated Users to Access the Amazon Web Services Management Console [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html + * + * @var int|null + */ + private $durationSeconds; + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * WebIdentityToken?: string, + * ProviderId?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->roleArn = $input['RoleArn'] ?? null; + $this->roleSessionName = $input['RoleSessionName'] ?? null; + $this->webIdentityToken = $input['WebIdentityToken'] ?? null; + $this->providerId = $input['ProviderId'] ?? null; + $this->policyArns = isset($input['PolicyArns']) ? array_map([PolicyDescriptorType::class, 'create'], $input['PolicyArns']) : null; + $this->policy = $input['Policy'] ?? null; + $this->durationSeconds = $input['DurationSeconds'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * WebIdentityToken?: string, + * ProviderId?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * '@region'?: string|null, + * }|AssumeRoleWithWebIdentityRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDurationSeconds(): ?int + { + return $this->durationSeconds; + } + + public function getPolicy(): ?string + { + return $this->policy; + } + + /** + * @return PolicyDescriptorType[] + */ + public function getPolicyArns(): array + { + return $this->policyArns ?? []; + } + + public function getProviderId(): ?string + { + return $this->providerId; + } + + public function getRoleArn(): ?string + { + return $this->roleArn; + } + + public function getRoleSessionName(): ?string + { + return $this->roleSessionName; + } + + public function getWebIdentityToken(): ?string + { + return $this->webIdentityToken; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/x-www-form-urlencoded']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = http_build_query(['Action' => 'AssumeRoleWithWebIdentity', 'Version' => '2011-06-15'] + $this->requestBody(), '', '&', \PHP_QUERY_RFC1738); + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setDurationSeconds(?int $value): self + { + $this->durationSeconds = $value; + + return $this; + } + + public function setPolicy(?string $value): self + { + $this->policy = $value; + + return $this; + } + + /** + * @param PolicyDescriptorType[] $value + */ + public function setPolicyArns(array $value): self + { + $this->policyArns = $value; + + return $this; + } + + public function setProviderId(?string $value): self + { + $this->providerId = $value; + + return $this; + } + + public function setRoleArn(?string $value): self + { + $this->roleArn = $value; + + return $this; + } + + public function setRoleSessionName(?string $value): self + { + $this->roleSessionName = $value; + + return $this; + } + + public function setWebIdentityToken(?string $value): self + { + $this->webIdentityToken = $value; + + return $this; + } + + private function requestBody(): array + { + $payload = []; + if (null === $v = $this->roleArn) { + throw new InvalidArgument(sprintf('Missing parameter "RoleArn" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleArn'] = $v; + if (null === $v = $this->roleSessionName) { + throw new InvalidArgument(sprintf('Missing parameter "RoleSessionName" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleSessionName'] = $v; + if (null === $v = $this->webIdentityToken) { + throw new InvalidArgument(sprintf('Missing parameter "WebIdentityToken" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['WebIdentityToken'] = $v; + if (null !== $v = $this->providerId) { + $payload['ProviderId'] = $v; + } + if (null !== $v = $this->policyArns) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["PolicyArns.member.$index.$bodyKey"] = $bodyValue; + } + } + } + if (null !== $v = $this->policy) { + $payload['Policy'] = $v; + } + if (null !== $v = $this->durationSeconds) { + $payload['DurationSeconds'] = $v; + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php b/vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php new file mode 100644 index 000000000..88b804afc --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php @@ -0,0 +1,58 @@ + 'application/x-www-form-urlencoded']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = http_build_query(['Action' => 'GetCallerIdentity', 'Version' => '2011-06-15'] + $this->requestBody(), '', '&', \PHP_QUERY_RFC1738); + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + private function requestBody(): array + { + $payload = []; + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php b/vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php new file mode 100644 index 000000000..cb4ac1cd2 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php @@ -0,0 +1,110 @@ + The size of the security token that STS API operations return is not fixed. We strongly recommend that you make no + * > assumptions about the maximum size. + * + * @var Credentials|null + */ + private $credentials; + + /** + * The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers that you can use to refer to the + * resulting temporary security credentials. For example, you can reference these credentials as a principal in a + * resource-based policy by using the ARN or assumed role ID. The ARN and ID include the `RoleSessionName` that you + * specified when you called `AssumeRole`. + * + * @var AssumedRoleUser|null + */ + private $assumedRoleUser; + + /** + * A percentage value that indicates the packed size of the session policies and session tags combined passed in the + * request. The request fails if the packed size is greater than 100 percent, which means the policies and tags exceeded + * the allowed space. + * + * @var int|null + */ + private $packedPolicySize; + + /** + * The source identity specified by the principal that is calling the `AssumeRole` operation. + * + * You can require users to specify a source identity when they assume a role. You do this by using the + * `sts:SourceIdentity` condition key in a role trust policy. You can use source identity information in CloudTrail logs + * to determine who took actions with a role. You can use the `aws:SourceIdentity` condition key to further control + * access to Amazon Web Services resources based on the value of source identity. For more information about using + * source identity, see Monitor and control actions taken with assumed roles [^1] in the *IAM User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@- + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html + * + * @var string|null + */ + private $sourceIdentity; + + public function getAssumedRoleUser(): ?AssumedRoleUser + { + $this->initialize(); + + return $this->assumedRoleUser; + } + + public function getCredentials(): ?Credentials + { + $this->initialize(); + + return $this->credentials; + } + + public function getPackedPolicySize(): ?int + { + $this->initialize(); + + return $this->packedPolicySize; + } + + public function getSourceIdentity(): ?string + { + $this->initialize(); + + return $this->sourceIdentity; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $data = $data->AssumeRoleResult; + + $this->credentials = !$data->Credentials ? null : new Credentials([ + 'AccessKeyId' => (string) $data->Credentials->AccessKeyId, + 'SecretAccessKey' => (string) $data->Credentials->SecretAccessKey, + 'SessionToken' => (string) $data->Credentials->SessionToken, + 'Expiration' => new \DateTimeImmutable((string) $data->Credentials->Expiration), + ]); + $this->assumedRoleUser = !$data->AssumedRoleUser ? null : new AssumedRoleUser([ + 'AssumedRoleId' => (string) $data->AssumedRoleUser->AssumedRoleId, + 'Arn' => (string) $data->AssumedRoleUser->Arn, + ]); + $this->packedPolicySize = ($v = $data->PackedPolicySize) ? (int) (string) $v : null; + $this->sourceIdentity = ($v = $data->SourceIdentity) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php b/vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php new file mode 100644 index 000000000..6eb109477 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php @@ -0,0 +1,166 @@ + The size of the security token that STS API operations return is not fixed. We strongly recommend that you make no + * > assumptions about the maximum size. + * + * @var Credentials|null + */ + private $credentials; + + /** + * The unique user identifier that is returned by the identity provider. This identifier is associated with the + * `WebIdentityToken` that was submitted with the `AssumeRoleWithWebIdentity` call. The identifier is typically unique + * to the user and the application that acquired the `WebIdentityToken` (pairwise identifier). For OpenID Connect ID + * tokens, this field contains the value returned by the identity provider as the token's `sub` (Subject) claim. + * + * @var string|null + */ + private $subjectFromWebIdentityToken; + + /** + * The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers that you can use to refer to the + * resulting temporary security credentials. For example, you can reference these credentials as a principal in a + * resource-based policy by using the ARN or assumed role ID. The ARN and ID include the `RoleSessionName` that you + * specified when you called `AssumeRole`. + * + * @var AssumedRoleUser|null + */ + private $assumedRoleUser; + + /** + * A percentage value that indicates the packed size of the session policies and session tags combined passed in the + * request. The request fails if the packed size is greater than 100 percent, which means the policies and tags exceeded + * the allowed space. + * + * @var int|null + */ + private $packedPolicySize; + + /** + * The issuing authority of the web identity token presented. For OpenID Connect ID tokens, this contains the value of + * the `iss` field. For OAuth 2.0 access tokens, this contains the value of the `ProviderId` parameter that was passed + * in the `AssumeRoleWithWebIdentity` request. + * + * @var string|null + */ + private $provider; + + /** + * The intended audience (also known as client ID) of the web identity token. This is traditionally the client + * identifier issued to the application that requested the web identity token. + * + * @var string|null + */ + private $audience; + + /** + * The value of the source identity that is returned in the JSON web token (JWT) from the identity provider. + * + * You can require users to set a source identity value when they assume a role. You do this by using the + * `sts:SourceIdentity` condition key in a role trust policy. That way, actions that are taken with the role are + * associated with that user. After the source identity is set, the value cannot be changed. It is present in the + * request for all actions that are taken by the role and persists across chained role [^1] sessions. You can configure + * your identity provider to use an attribute associated with your users, like user name or email, as the source + * identity when calling `AssumeRoleWithWebIdentity`. You do this by adding a claim to the JSON web token. To learn more + * about OIDC tokens and claims, see Using Tokens with User Pools [^2] in the *Amazon Cognito Developer Guide*. For more + * information about using source identity, see Monitor and control actions taken with assumed roles [^3] in the *IAM + * User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@- + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts#iam-term-role-chaining + * [^2]: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html + * [^3]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html + * + * @var string|null + */ + private $sourceIdentity; + + public function getAssumedRoleUser(): ?AssumedRoleUser + { + $this->initialize(); + + return $this->assumedRoleUser; + } + + public function getAudience(): ?string + { + $this->initialize(); + + return $this->audience; + } + + public function getCredentials(): ?Credentials + { + $this->initialize(); + + return $this->credentials; + } + + public function getPackedPolicySize(): ?int + { + $this->initialize(); + + return $this->packedPolicySize; + } + + public function getProvider(): ?string + { + $this->initialize(); + + return $this->provider; + } + + public function getSourceIdentity(): ?string + { + $this->initialize(); + + return $this->sourceIdentity; + } + + public function getSubjectFromWebIdentityToken(): ?string + { + $this->initialize(); + + return $this->subjectFromWebIdentityToken; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $data = $data->AssumeRoleWithWebIdentityResult; + + $this->credentials = !$data->Credentials ? null : new Credentials([ + 'AccessKeyId' => (string) $data->Credentials->AccessKeyId, + 'SecretAccessKey' => (string) $data->Credentials->SecretAccessKey, + 'SessionToken' => (string) $data->Credentials->SessionToken, + 'Expiration' => new \DateTimeImmutable((string) $data->Credentials->Expiration), + ]); + $this->subjectFromWebIdentityToken = ($v = $data->SubjectFromWebIdentityToken) ? (string) $v : null; + $this->assumedRoleUser = !$data->AssumedRoleUser ? null : new AssumedRoleUser([ + 'AssumedRoleId' => (string) $data->AssumedRoleUser->AssumedRoleId, + 'Arn' => (string) $data->AssumedRoleUser->Arn, + ]); + $this->packedPolicySize = ($v = $data->PackedPolicySize) ? (int) (string) $v : null; + $this->provider = ($v = $data->Provider) ? (string) $v : null; + $this->audience = ($v = $data->Audience) ? (string) $v : null; + $this->sourceIdentity = ($v = $data->SourceIdentity) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php b/vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php new file mode 100644 index 000000000..1be671113 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php @@ -0,0 +1,69 @@ +initialize(); + + return $this->account; + } + + public function getArn(): ?string + { + $this->initialize(); + + return $this->arn; + } + + public function getUserId(): ?string + { + $this->initialize(); + + return $this->userId; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $data = $data->GetCallerIdentityResult; + + $this->userId = ($v = $data->UserId) ? (string) $v : null; + $this->account = ($v = $data->Account) ? (string) $v : null; + $this->arn = ($v = $data->Arn) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/core/src/Sts/StsClient.php b/vendor/async-aws/core/src/Sts/StsClient.php new file mode 100644 index 000000000..42304e21c --- /dev/null +++ b/vendor/async-aws/core/src/Sts/StsClient.php @@ -0,0 +1,445 @@ +, + * Policy?: string, + * DurationSeconds?: int, + * Tags?: array, + * TransitiveTagKeys?: string[], + * ExternalId?: string, + * SerialNumber?: string, + * TokenCode?: string, + * SourceIdentity?: string, + * ProvidedContexts?: array, + * '@region'?: string|null, + * }|AssumeRoleRequest $input + * + * @throws MalformedPolicyDocumentException + * @throws PackedPolicyTooLargeException + * @throws RegionDisabledException + * @throws ExpiredTokenException + */ + public function assumeRole($input): AssumeRoleResponse + { + $input = AssumeRoleRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'AssumeRole', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'MalformedPolicyDocument' => MalformedPolicyDocumentException::class, + 'PackedPolicyTooLarge' => PackedPolicyTooLargeException::class, + 'RegionDisabledException' => RegionDisabledException::class, + 'ExpiredTokenException' => ExpiredTokenException::class, + ]])); + + return new AssumeRoleResponse($response); + } + + /** + * Returns a set of temporary security credentials for users who have been authenticated in a mobile or web application + * with a web identity provider. Example providers include the OAuth 2.0 providers Login with Amazon and Facebook, or + * any OpenID Connect-compatible identity provider such as Google or Amazon Cognito federated identities [^1]. + * + * > For mobile applications, we recommend that you use Amazon Cognito. You can use Amazon Cognito with the Amazon Web + * > Services SDK for iOS Developer Guide [^2] and the Amazon Web Services SDK for Android Developer Guide [^3] to + * > uniquely identify a user. You can also supply the user with a consistent identity throughout the lifetime of an + * > application. + * > + * > To learn more about Amazon Cognito, see Amazon Cognito identity pools [^4] in *Amazon Cognito Developer Guide*. + * + * Calling `AssumeRoleWithWebIdentity` does not require the use of Amazon Web Services security credentials. Therefore, + * you can distribute an application (for example, on mobile devices) that requests temporary security credentials + * without including long-term Amazon Web Services credentials in the application. You also don't need to deploy + * server-based proxy services that use long-term Amazon Web Services credentials. Instead, the identity of the caller + * is validated by using a token from the web identity provider. For a comparison of `AssumeRoleWithWebIdentity` with + * the other API operations that produce temporary credentials, see Requesting Temporary Security Credentials [^5] and + * Comparing the Amazon Web Services STS API operations [^6] in the *IAM User Guide*. + * + * The temporary security credentials returned by this API consist of an access key ID, a secret access key, and a + * security token. Applications can use these temporary security credentials to sign calls to Amazon Web Services + * service API operations. + * + * **Session Duration** + * + * By default, the temporary security credentials created by `AssumeRoleWithWebIdentity` last for one hour. However, you + * can use the optional `DurationSeconds` parameter to specify the duration of your session. You can provide a value + * from 900 seconds (15 minutes) up to the maximum session duration setting for the role. This setting can have a value + * from 1 hour to 12 hours. To learn how to view the maximum value for your role, see View the Maximum Session Duration + * Setting for a Role [^7] in the *IAM User Guide*. The maximum session duration limit applies when you use the + * `AssumeRole*` API operations or the `assume-role*` CLI commands. However the limit does not apply when you use those + * operations to create a console URL. For more information, see Using IAM Roles [^8] in the *IAM User Guide*. + * + * **Permissions** + * + * The temporary security credentials created by `AssumeRoleWithWebIdentity` can be used to make API calls to any Amazon + * Web Services service with the following exception: you cannot call the STS `GetFederationToken` or `GetSessionToken` + * API operations. + * + * (Optional) You can pass inline or managed session policies [^9] to this operation. You can pass a single JSON policy + * document to use as an inline session policy. You can also specify up to 10 managed policy Amazon Resource Names + * (ARNs) to use as managed session policies. The plaintext that you use for both inline and managed session policies + * can't exceed 2,048 characters. Passing policies to this operation returns new temporary credentials. The resulting + * session's permissions are the intersection of the role's identity-based policy and the session policies. You can use + * the role's temporary credentials in subsequent Amazon Web Services API calls to access resources in the account that + * owns the role. You cannot use session policies to grant more permissions than those allowed by the identity-based + * policy of the role that is being assumed. For more information, see Session Policies [^10] in the *IAM User Guide*. + * + * **Tags** + * + * (Optional) You can configure your IdP to pass attributes into your web identity token as session tags. Each session + * tag consists of a key name and an associated value. For more information about session tags, see Passing Session Tags + * in STS [^11] in the *IAM User Guide*. + * + * You can pass up to 50 session tags. The plaintext session tag keys can’t exceed 128 characters and the values + * can’t exceed 256 characters. For these and additional limits, see IAM and STS Character Limits [^12] in the *IAM + * User Guide*. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * You can pass a session tag with the same key as a tag that is attached to the role. When you do, the session tag + * overrides the role tag with the same key. + * + * An administrator must grant you the permissions necessary to pass session tags. The administrator can also create + * granular permissions to allow you to pass only specific session tags. For more information, see Tutorial: Using Tags + * for Attribute-Based Access Control [^13] in the *IAM User Guide*. + * + * You can set the session tags as transitive. Transitive tags persist during role chaining. For more information, see + * Chaining Roles with Session Tags [^14] in the *IAM User Guide*. + * + * **Identities** + * + * Before your application can call `AssumeRoleWithWebIdentity`, you must have an identity token from a supported + * identity provider and create a role that the application can assume. The role that your application assumes must + * trust the identity provider that is associated with the identity token. In other words, the identity provider must be + * specified in the role's trust policy. + * + * ! Calling `AssumeRoleWithWebIdentity` can result in an entry in your CloudTrail logs. The entry includes the Subject + * ! [^15] of the provided web identity token. We recommend that you avoid using any personally identifiable information + * ! (PII) in this field. For example, you could instead use a GUID or a pairwise identifier, as suggested in the OIDC + * ! specification [^16]. + * + * For more information about how to use web identity federation and the `AssumeRoleWithWebIdentity` API, see the + * following resources: + * + * - Using Web Identity Federation API Operations for Mobile Apps [^17] and Federation Through a Web-based Identity + * Provider [^18]. + * - Web Identity Federation Playground [^19]. Walk through the process of authenticating through Login with Amazon, + * Facebook, or Google, getting temporary security credentials, and then using those credentials to make a request to + * Amazon Web Services. + * - Amazon Web Services SDK for iOS Developer Guide [^20] and Amazon Web Services SDK for Android Developer Guide + * [^21]. These toolkits contain sample apps that show how to invoke the identity providers. The toolkits then show + * how to use the information from these providers to get and use temporary security credentials. + * - Web Identity Federation with Mobile Applications [^22]. This article discusses web identity federation and shows an + * example of how to use web identity federation to get access to content in Amazon S3. + * + * [^1]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html + * [^2]: http://aws.amazon.com/sdkforios/ + * [^3]: http://aws.amazon.com/sdkforandroid/ + * [^4]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html + * [^5]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html + * [^6]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison + * [^7]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session + * [^8]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html + * [^9]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * [^10]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * [^11]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html + * [^12]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length + * [^13]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html + * [^14]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining + * [^15]: http://openid.net/specs/openid-connect-core-1_0.html#Claims + * [^16]: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes + * [^17]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html + * [^18]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity + * [^19]: https://aws.amazon.com/blogs/aws/the-aws-web-identity-federation-playground/ + * [^20]: http://aws.amazon.com/sdkforios/ + * [^21]: http://aws.amazon.com/sdkforandroid/ + * [^22]: http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications + * + * @see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sts-2011-06-15.html#assumerolewithwebidentity + * + * @param array{ + * RoleArn: string, + * RoleSessionName: string, + * WebIdentityToken: string, + * ProviderId?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * '@region'?: string|null, + * }|AssumeRoleWithWebIdentityRequest $input + * + * @throws MalformedPolicyDocumentException + * @throws PackedPolicyTooLargeException + * @throws IDPRejectedClaimException + * @throws IDPCommunicationErrorException + * @throws InvalidIdentityTokenException + * @throws ExpiredTokenException + * @throws RegionDisabledException + */ + public function assumeRoleWithWebIdentity($input): AssumeRoleWithWebIdentityResponse + { + $input = AssumeRoleWithWebIdentityRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'AssumeRoleWithWebIdentity', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'MalformedPolicyDocument' => MalformedPolicyDocumentException::class, + 'PackedPolicyTooLarge' => PackedPolicyTooLargeException::class, + 'IDPRejectedClaim' => IDPRejectedClaimException::class, + 'IDPCommunicationError' => IDPCommunicationErrorException::class, + 'InvalidIdentityToken' => InvalidIdentityTokenException::class, + 'ExpiredTokenException' => ExpiredTokenException::class, + 'RegionDisabledException' => RegionDisabledException::class, + ]])); + + return new AssumeRoleWithWebIdentityResponse($response); + } + + /** + * Returns details about the IAM user or role whose credentials are used to call the operation. + * + * > No permissions are required to perform this operation. If an administrator attaches a policy to your identity that + * > explicitly denies access to the `sts:GetCallerIdentity` action, you can still perform this operation. Permissions + * > are not required because the same information is returned when access is denied. To view an example response, see I + * > Am Not Authorized to Perform: iam:DeleteVirtualMFADevice [^1] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_access-denied-delete-mfa + * + * @see https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sts-2011-06-15.html#getcalleridentity + * + * @param array{ + * '@region'?: string|null, + * }|GetCallerIdentityRequest $input + */ + public function getCallerIdentity($input = []): GetCallerIdentityResponse + { + $input = GetCallerIdentityRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetCallerIdentity', 'region' => $input->getRegion()])); + + return new GetCallerIdentityResponse($response); + } + + protected function getAwsErrorFactory(): AwsErrorFactoryInterface + { + return new XmlAwsErrorFactory(); + } + + protected function getEndpointMetadata(?string $region): array + { + if (null === $region) { + return [ + 'endpoint' => 'https://sts.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + } + + switch ($region) { + case 'cn-north-1': + case 'cn-northwest-1': + return [ + 'endpoint' => "https://sts.$region.amazonaws.com.cn", + 'signRegion' => $region, + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-east-1-fips': + return [ + 'endpoint' => 'https://sts-fips.us-east-1.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-east-2-fips': + return [ + 'endpoint' => 'https://sts-fips.us-east-2.amazonaws.com', + 'signRegion' => 'us-east-2', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-west-1-fips': + return [ + 'endpoint' => 'https://sts-fips.us-west-1.amazonaws.com', + 'signRegion' => 'us-west-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-west-2-fips': + return [ + 'endpoint' => 'https://sts-fips.us-west-2.amazonaws.com', + 'signRegion' => 'us-west-2', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-gov-east-1-fips': + return [ + 'endpoint' => 'https://sts.us-gov-east-1.amazonaws.com', + 'signRegion' => 'us-gov-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-gov-west-1-fips': + return [ + 'endpoint' => 'https://sts.us-gov-west-1.amazonaws.com', + 'signRegion' => 'us-gov-west-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-iso-east-1': + case 'us-iso-west-1': + return [ + 'endpoint' => "https://sts.$region.c2s.ic.gov", + 'signRegion' => $region, + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-isob-east-1': + return [ + 'endpoint' => 'https://sts.us-isob-east-1.sc2s.sgov.gov', + 'signRegion' => 'us-isob-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + } + + return [ + 'endpoint' => "https://sts.$region.amazonaws.com", + 'signRegion' => $region, + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + } + + protected function getServiceCode(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 'sts'; + } + + protected function getSignatureScopeName(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 'sts'; + } + + protected function getSignatureVersion(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 'v4'; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php b/vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php new file mode 100644 index 000000000..e543d9990 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php @@ -0,0 +1,70 @@ +assumedRoleId = $input['AssumedRoleId'] ?? $this->throwException(new InvalidArgument('Missing required field "AssumedRoleId".')); + $this->arn = $input['Arn'] ?? $this->throwException(new InvalidArgument('Missing required field "Arn".')); + } + + /** + * @param array{ + * AssumedRoleId: string, + * Arn: string, + * }|AssumedRoleUser $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getArn(): string + { + return $this->arn; + } + + public function getAssumedRoleId(): string + { + return $this->assumedRoleId; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/Credentials.php b/vendor/async-aws/core/src/Sts/ValueObject/Credentials.php new file mode 100644 index 000000000..93cabc9fe --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/Credentials.php @@ -0,0 +1,96 @@ +accessKeyId = $input['AccessKeyId'] ?? $this->throwException(new InvalidArgument('Missing required field "AccessKeyId".')); + $this->secretAccessKey = $input['SecretAccessKey'] ?? $this->throwException(new InvalidArgument('Missing required field "SecretAccessKey".')); + $this->sessionToken = $input['SessionToken'] ?? $this->throwException(new InvalidArgument('Missing required field "SessionToken".')); + $this->expiration = $input['Expiration'] ?? $this->throwException(new InvalidArgument('Missing required field "Expiration".')); + } + + /** + * @param array{ + * AccessKeyId: string, + * SecretAccessKey: string, + * SessionToken: string, + * Expiration: \DateTimeImmutable, + * }|Credentials $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getAccessKeyId(): string + { + return $this->accessKeyId; + } + + public function getExpiration(): \DateTimeImmutable + { + return $this->expiration; + } + + public function getSecretAccessKey(): string + { + return $this->secretAccessKey; + } + + public function getSessionToken(): string + { + return $this->sessionToken; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php b/vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php new file mode 100644 index 000000000..434ea3462 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php @@ -0,0 +1,59 @@ +arn = $input['arn'] ?? null; + } + + /** + * @param array{ + * arn?: null|string, + * }|PolicyDescriptorType $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getArn(): ?string + { + return $this->arn; + } + + /** + * @internal + */ + public function requestBody(): array + { + $payload = []; + if (null !== $v = $this->arn) { + $payload['arn'] = $v; + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php b/vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php new file mode 100644 index 000000000..950e3eb49 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php @@ -0,0 +1,72 @@ +providerArn = $input['ProviderArn'] ?? null; + $this->contextAssertion = $input['ContextAssertion'] ?? null; + } + + /** + * @param array{ + * ProviderArn?: null|string, + * ContextAssertion?: null|string, + * }|ProvidedContext $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getContextAssertion(): ?string + { + return $this->contextAssertion; + } + + public function getProviderArn(): ?string + { + return $this->providerArn; + } + + /** + * @internal + */ + public function requestBody(): array + { + $payload = []; + if (null !== $v = $this->providerArn) { + $payload['ProviderArn'] = $v; + } + if (null !== $v = $this->contextAssertion) { + $payload['ContextAssertion'] = $v; + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/Tag.php b/vendor/async-aws/core/src/Sts/ValueObject/Tag.php new file mode 100644 index 000000000..3ac064b40 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/Tag.php @@ -0,0 +1,94 @@ +key = $input['Key'] ?? $this->throwException(new InvalidArgument('Missing required field "Key".')); + $this->value = $input['Value'] ?? $this->throwException(new InvalidArgument('Missing required field "Value".')); + } + + /** + * @param array{ + * Key: string, + * Value: string, + * }|Tag $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): string + { + return $this->key; + } + + public function getValue(): string + { + return $this->value; + } + + /** + * @internal + */ + public function requestBody(): array + { + $payload = []; + $v = $this->key; + $payload['Key'] = $v; + $v = $this->value; + $payload['Value'] = $v; + + return $payload; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php b/vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php new file mode 100644 index 000000000..161122ede --- /dev/null +++ b/vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php @@ -0,0 +1,91 @@ +> + */ + private $headers = []; + + /** + * @var string + */ + private $content = ''; + + /** + * @var int + */ + private $statusCode; + + /** + * @param array> $headers ['name'=>'value'] OR ['name'=>['value']] + */ + public function __construct(string $content = '', array $headers = [], int $statusCode = 200) + { + $this->content = $content; + $this->statusCode = $statusCode; + $this->headers = []; + foreach ($headers as $name => $value) { + if (!\is_array($value)) { + $value = [$value]; + } + $this->headers[$name] = $value; + } + + parent::__construct($content, [ + 'response_headers' => $this->getFlatHeaders(), + 'http_code' => $statusCode, + ]); + } + + public function getStatusCode(): int + { + return $this->statusCode; + } + + public function getHeaders(bool $throw = true): array + { + return $this->headers; + } + + public function getContent(bool $throw = true): string + { + return $this->content; + } + + /** + * @return array + */ + public function toArray(bool $throw = true): array + { + return json_decode($this->getContent($throw), true); + } + + public function cancel(): void + { + throw new LogicException('Not implemented'); + } + + /** + * @return list + */ + private function getFlatHeaders() + { + $flat = []; + foreach ($this->headers as $name => $value) { + $flat[] = sprintf('%s: %s', $name, implode(';', $value)); + } + + return $flat; + } +} diff --git a/vendor/async-aws/core/src/Test/ResultMockFactory.php b/vendor/async-aws/core/src/Test/ResultMockFactory.php new file mode 100644 index 000000000..564f83906 --- /dev/null +++ b/vendor/async-aws/core/src/Test/ResultMockFactory.php @@ -0,0 +1,290 @@ + + */ +class ResultMockFactory +{ + /** + * Instantiate a Result class that throws exception. + * + * + * ResultMockFactory::createFailing(SendEmailResponse::class, 400, 'invalid value'); + * + * + * @template T of Result + * + * @param class-string $class + * @param array $additionalContent + * + * @return T + */ + public static function createFailing( + string $class, + int $code, + ?string $message = null, + array $additionalContent = [] + ) { + if (Result::class !== $class) { + $parent = get_parent_class($class); + if (false === $parent || Result::class !== $parent) { + throw new LogicException(sprintf('The "%s::%s" can only be used for classes that extend "%s"', __CLASS__, __METHOD__, Result::class)); + } + } + + $httpResponse = new SimpleMockedResponse(json_encode(array_merge(['message' => $message], $additionalContent)), ['content-type' => 'application/json'], $code); + $client = new MockHttpClient($httpResponse); + $response = new Response($client->request('POST', 'http://localhost'), $client, new NullLogger()); + + /** @psalm-var \ReflectionClass $reflectionClass */ + $reflectionClass = new \ReflectionClass($class); + + return $reflectionClass->newInstance($response); + } + + /** + * Instantiate a Result class with some data. + * + * + * ResultMockFactory::create(SendEmailResponse::class, ['MessageId'=>'foo123']); + * + * + * @template T of Result + * + * @param class-string $class + * @param array $data + * + * @return T + */ + public static function create(string $class, array $data = []) + { + if (Result::class !== $class) { + $parent = get_parent_class($class); + if (false === $parent || Result::class !== $parent) { + throw new LogicException(sprintf('The "%s::%s" can only be used for classes that extend "%s"', __CLASS__, __METHOD__, Result::class)); + } + } + + $response = self::getResponseObject(); + + // Make sure the Result is initialized + $reflectionClass = new \ReflectionClass(Result::class); + $initializedProperty = $reflectionClass->getProperty('initialized'); + $initializedProperty->setAccessible(true); + + /** @psalm-var \ReflectionClass $reflectionClass */ + $reflectionClass = new \ReflectionClass($class); + $object = $reflectionClass->newInstance($response); + if (Result::class !== $class) { + self::addPropertiesOnResult($reflectionClass, $object, $class); + } + + $initializedProperty->setValue($object, true); + foreach ($data as $propertyName => $propertyValue) { + if ($reflectionClass->hasProperty($propertyName)) { + $property = $reflectionClass->getProperty($propertyName); + } elseif ($reflectionClass->hasProperty(lcfirst($propertyName))) { + // backward compatibility with `UpperCamelCase` naming (fast) + $property = $reflectionClass->getProperty(lcfirst($propertyName)); + } else { + // compatibility with new `wordWithABREV` naming (slow) + $lowerPropertyName = strtolower($propertyName); + $property = null; + foreach ($reflectionClass->getProperties() as $prop) { + if (strtolower($prop->getName()) === $lowerPropertyName) { + $property = $prop; + + break; + } + } + if (null === $property) { + // let bubble the original exception + $property = $reflectionClass->getProperty($propertyName); + } + } + $property->setAccessible(true); + $property->setValue($object, $propertyValue); + } + + self::addUndefinedProperties($reflectionClass, $object, $data); + + return $object; + } + + /** + * Instantiate a Waiter class with a final state. + * + * @template T of Waiter + * + * @psalm-param class-string $class + * + * @return T + */ + public static function waiter(string $class, string $finalState) + { + if (Waiter::class !== $class) { + $parent = get_parent_class($class); + if (false === $parent || Waiter::class !== $parent) { + throw new LogicException(sprintf('The "%s::%s" can only be used for classes that extend "%s"', __CLASS__, __METHOD__, Waiter::class)); + } + } + + if (Waiter::STATE_SUCCESS !== $finalState && Waiter::STATE_FAILURE !== $finalState) { + throw new LogicException(sprintf('The state passed to "%s::%s" must be "%s" or "%s".', __CLASS__, __METHOD__, Waiter::STATE_SUCCESS, Waiter::STATE_FAILURE)); + } + + $response = self::getResponseObject(); + + $reflectionClass = new \ReflectionClass(Waiter::class); + $propertyResponse = $reflectionClass->getProperty('response'); + $propertyResponse->setAccessible(true); + + $propertyState = $reflectionClass->getProperty('finalState'); + $propertyState->setAccessible(true); + + /** @psalm-var \ReflectionClass $reflectionClass */ + $reflectionClass = new \ReflectionClass($class); + $result = $reflectionClass->newInstanceWithoutConstructor(); + $propertyResponse->setValue($result, $response); + $propertyState->setValue($result, $finalState); + + return $result; + } + + /** + * Try to add some values to the properties not defined in $data. + * + * @param \ReflectionClass $reflectionClass + * @param array $data + * + * @throws \ReflectionException + */ + private static function addUndefinedProperties(\ReflectionClass $reflectionClass, object $object, array $data): void + { + foreach ($reflectionClass->getProperties(\ReflectionProperty::IS_PRIVATE) as $property) { + if (\array_key_exists($property->getName(), $data) || \array_key_exists(ucfirst($property->getName()), $data)) { + continue; + } + + if (!$reflectionClass->hasMethod('get' . $property->getName())) { + continue; + } + + $getter = $reflectionClass->getMethod('get' . $property->getName()); + if (!$getter->hasReturnType() || (!($type = $getter->getReturnType()) instanceof \ReflectionNamedType) || $type->allowsNull()) { + continue; + } + + switch ($type->getName()) { + case 'int': + $propertyValue = 0; + + break; + case 'string': + $propertyValue = ''; + + break; + case 'bool': + $propertyValue = false; + + break; + case 'float': + $propertyValue = 0.0; + + break; + case 'array': + $propertyValue = []; + + break; + default: + $propertyValue = null; + + break; + } + + if (null !== $propertyValue) { + $property->setAccessible(true); + $property->setValue($object, $propertyValue); + } + } + } + + /** + * Set input and aws client to handle pagination. + * + * @param \ReflectionClass $reflectionClass + */ + private static function addPropertiesOnResult(\ReflectionClass $reflectionClass, object $object, string $class): void + { + if (false === $pos = strrpos($class, '\\')) { + throw new LogicException(sprintf('Expected class "%s" to have a backslash. ', $class)); + } + + $className = substr($class, $pos + 1); + if ('Output' === substr($className, -6)) { + $classNameWithoutSuffix = substr($className, 0, -6); + } elseif ('Response' === substr($className, -8)) { + $classNameWithoutSuffix = substr($className, 0, -8); + } elseif ('Result' === substr($className, -6)) { + $classNameWithoutSuffix = substr($className, 0, -6); + } else { + throw new LogicException(sprintf('Unknown class suffix: "%s"', $className)); + } + + if (false === $pos = strrpos($class, '\\', -2 - \strlen($className))) { + throw new LogicException(sprintf('Expected class "%s" to have more than one backslash. ', $class)); + } + + $baseNamespace = substr($class, 0, $pos); + if (false === $pos = strrpos($baseNamespace, '\\')) { + throw new LogicException(sprintf('Expected base namespace "%s" to have a backslash. ', $baseNamespace)); + } + + $awsClientClass = $baseNamespace . substr($baseNamespace, $pos) . 'Client'; + $inputClass = $baseNamespace . '\\Input\\' . $classNameWithoutSuffix . 'Request'; + + if (class_exists($awsClientClass)) { + $awsClientMock = (new \ReflectionClass($awsClientClass))->newInstanceWithoutConstructor(); + $property = $reflectionClass->getProperty('awsClient'); + $property->setAccessible(true); + $property->setValue($object, $awsClientMock); + } + + if (class_exists($inputClass)) { + $inputMock = (new \ReflectionClass($inputClass))->newInstanceWithoutConstructor(); + $property = $reflectionClass->getProperty('input'); + $property->setAccessible(true); + $property->setValue($object, $inputMock); + } + } + + private static function getResponseObject(): Response + { + $reflectionClass = new \ReflectionClass(Response::class); + $response = $reflectionClass->newInstanceWithoutConstructor(); + + $property = $reflectionClass->getProperty('resolveResult'); + $property->setAccessible(true); + $property->setValue($response, true); + + $property = $reflectionClass->getProperty('bodyDownloaded'); + $property->setAccessible(true); + $property->setValue($response, true); + + return $response; + } +} diff --git a/vendor/async-aws/core/src/Test/SimpleResultStream.php b/vendor/async-aws/core/src/Test/SimpleResultStream.php new file mode 100644 index 000000000..402b96737 --- /dev/null +++ b/vendor/async-aws/core/src/Test/SimpleResultStream.php @@ -0,0 +1,53 @@ + + */ +class SimpleResultStream implements ResultStream +{ + /** + * @var string + */ + private $data; + + public function __construct(string $data) + { + $this->data = $data; + } + + public function getChunks(): iterable + { + yield $this->data; + } + + public function getContentAsString(): string + { + return $this->data; + } + + public function getContentAsResource() + { + $resource = fopen('php://temp', 'rw+'); + + try { + fwrite($resource, $this->data); + + // Rewind + fseek($resource, 0, \SEEK_SET); + + return $resource; + } catch (\Throwable $e) { + fclose($resource); + + throw $e; + } + } +} diff --git a/vendor/async-aws/core/src/Test/TestCase.php b/vendor/async-aws/core/src/Test/TestCase.php new file mode 100644 index 000000000..645c20bfe --- /dev/null +++ b/vendor/async-aws/core/src/Test/TestCase.php @@ -0,0 +1,103 @@ +getMethod()); + + $actualUrl = $actual->getUri(); + if ($actual->getQuery()) { + $actualUrl .= false !== strpos($actual->getUri(), '?') ? '&' : '?'; + $actualUrl .= http_build_query($actual->getQuery(), '', '&', \PHP_QUERY_RFC3986); + } + self::assertUrlEqualsUrl($url, $actualUrl); + + $expectedHeaders = []; + foreach ($headers as $header) { + $parts = explode(':', trim($header), 2); + $key = $parts[0]; + $value = $parts[1] ?? ''; + $expectedHeaders[strtolower($key)] = trim($value); + } + self::assertEqualsIgnoringCase($expectedHeaders, $actual->getHeaders(), $message); + + switch ($expectedHeaders['content-type'] ?? null) { + case 'application/x-www-form-urlencoded': + self::assertHttpFormEqualsHttpForm(trim($body), $actual->getBody()->stringify(), $message); + + break; + case 'application/json': + case 'application/x-amz-json-1.0': + case 'application/x-amz-json-1.1': + if ('' === trim($body)) { + self::assertSame($body, $actual->getBody()->stringify()); + } else { + self::assertJsonStringEqualsJsonString(trim($body), $actual->getBody()->stringify(), $message); + } + + break; + case 'application/xml': + if ('' === trim($body)) { + self::assertSame($body, $actual->getBody()->stringify()); + } else { + self::assertXmlStringEqualsXmlString(trim($body), $actual->getBody()->stringify(), $message); + } + + break; + default: + self::assertSame(trim($body), $actual->getBody()->stringify()); + + break; + } + } +} diff --git a/vendor/async-aws/core/src/Waiter.php b/vendor/async-aws/core/src/Waiter.php new file mode 100644 index 000000000..387abf7e6 --- /dev/null +++ b/vendor/async-aws/core/src/Waiter.php @@ -0,0 +1,228 @@ +response = $response; + $this->awsClient = $awsClient; + $this->input = $request; + } + + public function __destruct() + { + if (!$this->resolved) { + $this->resolve(); + } + } + + final public function isSuccess(): bool + { + return self::STATE_SUCCESS === $this->getState(); + } + + final public function isFailure(): bool + { + return self::STATE_FAILURE === $this->getState(); + } + + final public function isPending(): bool + { + return self::STATE_PENDING === $this->getState(); + } + + final public function getState(): string + { + if (null !== $this->finalState) { + return $this->finalState; + } + + if ($this->needRefresh) { + $this->stealResponse($this->refreshState()); + } + + try { + $this->response->resolve(); + $exception = null; + } catch (HttpException $exception) { + // use $exception later + } finally { + $this->resolved = true; + $this->needRefresh = true; + } + + $state = $this->extractState($this->response, $exception); + + switch ($state) { + case self::STATE_SUCCESS: + case self::STATE_FAILURE: + $this->finalState = $state; + + break; + case self::STATE_PENDING: + break; + default: + throw new LogicException(sprintf('Unexpected state "%s" from Waiter "%s".', $state, __CLASS__)); + } + + return $state; + } + + /** + * Make sure the actual request is executed. + * + * @param float|null $timeout Duration in seconds before aborting. When null wait until the end of execution. + * + * @return bool false on timeout. True if the response has returned with as status code. + * + * @throws NetworkException + */ + final public function resolve(?float $timeout = null): bool + { + try { + return $this->response->resolve($timeout); + } catch (HttpException $exception) { + return true; + } finally { + $this->resolved = true; + } + } + + /** + * Returns info on the current request. + * + * @return array{ + * resolved: bool, + * body_downloaded: bool, + * response: \Symfony\Contracts\HttpClient\ResponseInterface, + * status: int, + * } + */ + final public function info(): array + { + return $this->response->info(); + } + + final public function cancel(): void + { + $this->response->cancel(); + $this->needRefresh = true; + $this->resolved = true; + } + + /** + * Wait until the state is success. + * Stopped when the state become Failure or the defined timeout is reached. + * + * @param float $timeout Duration in seconds before aborting + * @param float $delay Duration in seconds between each check + * + * @return bool true if a final state was reached + */ + final public function wait(?float $timeout = null, ?float $delay = null): bool + { + if (null !== $this->finalState) { + return true; + } + + $timeout = $timeout ?? static::WAIT_TIMEOUT; + $delay = $delay ?? static::WAIT_DELAY; + + $start = microtime(true); + while (true) { + if ($this->needRefresh) { + $this->stealResponse($this->refreshState()); + } + + // If request times out + if (!$this->resolve($timeout - (microtime(true) - $start))) { + break; + } + + $this->getState(); + // If we reached a final state + if ($this->finalState) { + return true; + } + + // If the timeout will expire during our sleep, then exit early. + if ($delay > $timeout - (microtime(true) - $start)) { + break; + } + + usleep((int) ceil($delay * 1000000)); + } + + return false; + } + + protected function extractState(Response $response, ?HttpException $exception): string + { + return self::STATE_PENDING; + } + + protected function refreshState(): Waiter + { + return $this; + } + + private function stealResponse(self $waiter): void + { + $this->response = $waiter->response; + $this->resolved = $waiter->resolved; + $waiter->resolved = true; + $this->needRefresh = false; + } +} diff --git a/vendor/async-aws/s3/CHANGELOG.md b/vendor/async-aws/s3/CHANGELOG.md new file mode 100644 index 000000000..1ba736a56 --- /dev/null +++ b/vendor/async-aws/s3/CHANGELOG.md @@ -0,0 +1,247 @@ +# Change Log + +## 2.0.0 + +### BC-BREAK + +- The type for `\AsyncAws\S3\Input\PutObjectRequest::getContentLength` and `\AsyncAws\S3\Input\PutObjectRequest::setContentLength` uses `int` instead of `string` to reflect the AWS type. +- The type for `\AsyncAws\S3\Input\UploadPartRequest::getContentLength` and `\AsyncAws\S3\Input\UploadPartRequest::setContentLength` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\Result\GetObjectOutput::getContentLength` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\Result\HeadObjectOutput::getContentLength` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\ValueObject\AwsObject::getSize` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\ValueObject\Part::getSize` uses `int` instead of `string` to reflect the AWS type. + +### Added + +- AWS api-change: The S3 LISTObjects, ListObjectsV2 and ListObjectVersions API now supports a new optional header x-amz-optional-object-attributes. If header contains RestoreStatus as the value, then S3 will include Glacier restore status i.e. isRestoreInProgress and RestoreExpiryDate in List response. +- AWS api-change: Added `ap-south-2` and `eu-south-2` bucket location constraints. +- AWS api-change: Add support for the `il-central-1` region +- Use int as the PHP representation of long fields in generated code + +### Changed + +- Improve parameter type and return type in phpdoc + +## 1.14.0 + +### Added + +- AWS api-change: Added `ap-southeast-4` region. +- AWS enhancement: Documentation updates. +- AWS api-change: Provides support for "Snow" Storage class. +- AWS api-change: Integrate double encryption feature to SDKs. +- AWS api-change: This release adds SDK support for request-payer request header and request-charged response header in the "GetBucketAccelerateConfiguration", "ListMultipartUploads", "ListObjects", "ListObjectsV2" and "ListObjectVersions" S3 APIs. + +## 1.13.0 + +### Added + +- Added `me-central-1`, `ap-southeast-3`, `eu-central-2`, `eu-south-2` and `ap-south-2` regions + +## 1.12.0 + +### Fixed + +- Format datetime with `RFC7231` to provide a workaround for unsupported `RFC822` format. +- Broken path to host when operation's URL contains a query string. + +### Changed + +- Set default value to `false` for the `sendChunkedBody` option. + +## 1.11.0 + +### Added + +- AWS api-change: Added `ap-southeast-3` region. +- AWS enhancement: Documentation updates. +- AWS feature: Adds support for flexible checksums +- AWS api-change: This release adds support for new integrity checking capabilities in Amazon S3. You can choose from four supported checksum algorithms for data integrity checking on your upload and download requests. In addition, AWS SDK can automatically calculate a checksum as it streams data into S3 + +## 1.10.0 + +### Added + +- AWS api-change: used unique endpoint for `accesspoint-*` regions +- AWS api-change: Rework regions configuration. +- AWS api-change: Introduce Amazon S3 Glacier Instant Retrieval storage class and a new setting in S3 Object Ownership to disable ACLs for bucket and the objects in it. +- AWS api-change: Amazon S3 Event Notifications adds Amazon EventBridge as a destination and supports additional event types. The PutBucketNotificationConfiguration API can now skip validation of Amazon SQS, Amazon SNS and AWS Lambda destinations. +- AWS api-change: Introduce two new Filters to S3 Lifecycle configurations - ObjectSizeGreaterThan and ObjectSizeLessThan. Introduce a new way to trigger actions on noncurrent versions by providing the number of newer noncurrent versions along with noncurrent days. + +## 1.9.2 + +### Added + +- AWS enhancement: Documentation updates for Amazon S3 +- Fixed camelCased of Dom classes + +## 1.9.1 + +### Fixed + +- Fix issue when a request to upload a file is retried +- camelCased methods with paginator and waiter +- AWS enhancement: Documentation updates for Amazon S3 + +## 1.9.0 + +### Added + +- AWS api-change: Adding ID element to the CORSRule schema +- AWS api-change: Adding many more regions + +### Changed + +- AWS api-change: Reword docblocks +- AWS enhancement: Amazon S3 Documentation updates +- AWS api-change: Improve documentation +- AWS enhancement: Documentation updates for Amazon S3 + +### Fixed + +- Wrong custom encoding on chunked stream + +## 1.8.0 + +### Added + +- Changed case of object's properties to camelCase. +- Added documentation in class headers. +- Added `PutBucketCors`, `DeleteBucketCors` and `GetBucketCors` methods. +- Added domain exceptions + +## 1.7.0 + +### Added + +- AWS api-change: S3 adds support for multiple-destination replication, option to sync replica modifications; S3 Bucket Keys to reduce cost of S3 SSE with AWS KMS +- AWS api-change: Format GetObject's Expires header to be an http-date instead of iso8601 +- Added support for `sendChunkedBody` option to enable/disabled chunked body. + +## 1.6.0 + +### Added + +- Added `S3Client::putBucketNotificationConfiguration()` +- AWS api-change: S3 Intelligent-Tiering adds support for Archive and Deep Archive Access tiers + +### Changed + +- Removed deprecation warning on Content-MD5 headers. + +### Fixed + +- Make sure we throw exception from async-aws/core + +## 1.5.1 + +### Fixed + +- Fixed endpoint issue when a bucket name started with a number. +- Improve StorageClass documentation. + +## 1.5.0 + +### Added + +- AWS api-change: Amazon S3 on Outposts expands object storage to on-premises AWS Outposts environments, enabling you to store and retrieve objects using S3 APIs and features. + +## 1.4.0 + +### Added + +- AWS api-change: Bucket owner verification feature added. This feature introduces the x-amz-expected-bucket-owner and x-amz-source-expected-bucket-owner headers. + +## 1.3.0 + +### Added + +- Support for PHP 8 +- Added `S3Client::deleteBucket()` + +### Fixed + +- Fixed an issue in Metadata not beeing sent to AWS in `PutObject`, `CopyObject` and `CreateMultipartUpload` +- Internal AWS prefix were added to Metadata's name in `GetObject` and `HeadObject`. + +### Deprecated by AWS + +- `PutObjectAclRequest::getContentMD5()` +- `PutObjectAclRequest::setContentMD5()` + +## 1.2.0 + +### Added + +- Changed from "path style" endpoints (https://amazon.com/bucket) to "host style" endpoints (https://bucket.amazon.com). To keep the old behavior, use `s3PathStyleEndpoint: true` configuration option. + +### Fixed + +- Fixed issue when Bucket or Object's Key contained a special char like `#` + +### Deprecation + +- Protected methods `getServiceCode`, `getSignatureVersion` and `getSignatureScopeName` of `S3Client` are deprecated and will be removed in 2.0 + +## 1.1.0 + +### Added + +- Backported split request behavior in `SignerV4ForS3` + +### Fixed + +- Add return typehint for `listMultipartUploads`, `listObjectsV2` and `listParts` + +## 1.0.0 + +### Added + +- Support for async-aws/core 1.0. + +## 0.4.0 + +### Added + +- Support for presign +- Multipart upload +- Waiters: `S3Client::bucketExists()` and `S3Client::objectExists()` +- The `AsyncAws\S3\Enum\*`, `AsyncAws\S3\Input\*` and `AsyncAws\S3\ValueObject*` classes are marked final. + +### Changed + +- Moved value objects to a dedicated namespace. +- Results' `populateResult()` has only one argument. It takes a `AsyncAws\Core\Response`. +- Using `DateTimeImmutable` instead of `DateTimeInterface` + +### Removed + +- Dependency on `symfony/http-client-contracts` +- All `validate()` methods on the inputs. They are merged with `request()`. + +## 0.3.0 + +### Added + +- Enums; `BucketCannedACL`, `BucketLocationConstraint`, `EncodingType`, `MetadataDirective`, `ObjectCannedACL`, `ObjectLockLegalHoldStatus` + `ObjectLockMode`, `ObjectStorageClass`, `Permission`, `ReplicationStatus`, `RequestCharged`, `RequestPayer`, `ServerSideEncryption` + `StorageClass`, `TaggingDirective`, `Type` + +### Changed + +- Removed `requestBody()`, `requestHeaders()`, `requestQuery()` and `requestUri()` input classes. They are replaced with `request()`. +- Using async-aws/core: 0.4.0 + +### Fixed + +- Dont generate a request body when no body is needed. + +## 0.2.0 + +### Changed + +- Using async-aws/core: 0.3.0 + +## 0.1.0 + +First version diff --git a/vendor/async-aws/s3/LICENSE b/vendor/async-aws/s3/LICENSE new file mode 100644 index 000000000..191fcfb40 --- /dev/null +++ b/vendor/async-aws/s3/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Jérémy Derussé, Tobias Nyholm + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/async-aws/s3/README.md b/vendor/async-aws/s3/README.md new file mode 100644 index 000000000..b7071b41b --- /dev/null +++ b/vendor/async-aws/s3/README.md @@ -0,0 +1,20 @@ +# AsyncAws S3 Client + +![](https://github.com/async-aws/s3/workflows/Tests/badge.svg?branch=master) +![](https://github.com/async-aws/s3/workflows/BC%20Check/badge.svg?branch=master) + +An API client for S3. + +## Install + +```cli +composer require async-aws/s3 +``` + +## Documentation + +See https://async-aws.com/clients/s3.html for documentation. + +## Contribute + +Contributions are welcome and appreciated. Please read https://async-aws.com/contribute/ diff --git a/vendor/async-aws/s3/composer.json b/vendor/async-aws/s3/composer.json new file mode 100644 index 000000000..b12a7e1fb --- /dev/null +++ b/vendor/async-aws/s3/composer.json @@ -0,0 +1,36 @@ +{ + "name": "async-aws/s3", + "description": "S3 client, part of the AWS SDK provided by AsyncAws.", + "license": "MIT", + "type": "library", + "keywords": [ + "aws", + "amazon", + "sdk", + "async-aws", + "s3" + ], + "require": { + "php": "^7.2.5 || ^8.0", + "ext-SimpleXML": "*", + "ext-dom": "*", + "ext-filter": "*", + "ext-hash": "*", + "async-aws/core": "^1.9" + }, + "autoload": { + "psr-4": { + "AsyncAws\\S3\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "AsyncAws\\S3\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + } +} diff --git a/vendor/async-aws/s3/src/Enum/ArchiveStatus.php b/vendor/async-aws/s3/src/Enum/ArchiveStatus.php new file mode 100644 index 000000000..2b57ceaf6 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ArchiveStatus.php @@ -0,0 +1,17 @@ + true, + self::DEEP_ARCHIVE_ACCESS => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/BucketCannedACL.php b/vendor/async-aws/s3/src/Enum/BucketCannedACL.php new file mode 100644 index 000000000..e923df03f --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/BucketCannedACL.php @@ -0,0 +1,21 @@ + true, + self::PRIVATE => true, + self::PUBLIC_READ => true, + self::PUBLIC_READ_WRITE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php b/vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php new file mode 100644 index 000000000..cdd40e4a5 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php @@ -0,0 +1,69 @@ + true, + self::AP_EAST_1 => true, + self::AP_NORTHEAST_1 => true, + self::AP_NORTHEAST_2 => true, + self::AP_NORTHEAST_3 => true, + self::AP_SOUTHEAST_1 => true, + self::AP_SOUTHEAST_2 => true, + self::AP_SOUTHEAST_3 => true, + self::AP_SOUTH_1 => true, + self::AP_SOUTH_2 => true, + self::CA_CENTRAL_1 => true, + self::CN_NORTHWEST_1 => true, + self::CN_NORTH_1 => true, + self::EU => true, + self::EU_CENTRAL_1 => true, + self::EU_NORTH_1 => true, + self::EU_SOUTH_1 => true, + self::EU_SOUTH_2 => true, + self::EU_WEST_1 => true, + self::EU_WEST_2 => true, + self::EU_WEST_3 => true, + self::ME_SOUTH_1 => true, + self::SA_EAST_1 => true, + self::US_EAST_2 => true, + self::US_GOV_EAST_1 => true, + self::US_GOV_WEST_1 => true, + self::US_WEST_1 => true, + self::US_WEST_2 => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php b/vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php new file mode 100644 index 000000000..a2eb4adb6 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php @@ -0,0 +1,21 @@ + true, + self::CRC32C => true, + self::SHA1 => true, + self::SHA256 => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ChecksumMode.php b/vendor/async-aws/s3/src/Enum/ChecksumMode.php new file mode 100644 index 000000000..307467f1c --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ChecksumMode.php @@ -0,0 +1,15 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/EncodingType.php b/vendor/async-aws/s3/src/Enum/EncodingType.php new file mode 100644 index 000000000..f6816062b --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/EncodingType.php @@ -0,0 +1,21 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/Event.php b/vendor/async-aws/s3/src/Enum/Event.php new file mode 100644 index 000000000..b52aaba14 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/Event.php @@ -0,0 +1,70 @@ + true, + self::S3_LIFECYCLE_EXPIRATION_ALL => true, + self::S3_LIFECYCLE_EXPIRATION_DELETE => true, + self::S3_LIFECYCLE_EXPIRATION_DELETE_MARKER_CREATED => true, + self::S3_LIFECYCLE_TRANSITION => true, + self::S3_OBJECT_ACL_PUT => true, + self::S3_OBJECT_CREATED_ALL => true, + self::S3_OBJECT_CREATED_COMPLETE_MULTIPART_UPLOAD => true, + self::S3_OBJECT_CREATED_COPY => true, + self::S3_OBJECT_CREATED_POST => true, + self::S3_OBJECT_CREATED_PUT => true, + self::S3_OBJECT_REMOVED_ALL => true, + self::S3_OBJECT_REMOVED_DELETE => true, + self::S3_OBJECT_REMOVED_DELETE_MARKER_CREATED => true, + self::S3_OBJECT_RESTORE_ALL => true, + self::S3_OBJECT_RESTORE_COMPLETED => true, + self::S3_OBJECT_RESTORE_DELETE => true, + self::S3_OBJECT_RESTORE_POST => true, + self::S3_OBJECT_TAGGING_ALL => true, + self::S3_OBJECT_TAGGING_DELETE => true, + self::S3_OBJECT_TAGGING_PUT => true, + self::S3_REDUCED_REDUNDANCY_LOST_OBJECT => true, + self::S3_REPLICATION_ALL => true, + self::S3_REPLICATION_OPERATION_FAILED_REPLICATION => true, + self::S3_REPLICATION_OPERATION_MISSED_THRESHOLD => true, + self::S3_REPLICATION_OPERATION_NOT_TRACKED => true, + self::S3_REPLICATION_OPERATION_REPLICATED_AFTER_THRESHOLD => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/FilterRuleName.php b/vendor/async-aws/s3/src/Enum/FilterRuleName.php new file mode 100644 index 000000000..1628c7f69 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/FilterRuleName.php @@ -0,0 +1,17 @@ + true, + self::SUFFIX => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php b/vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php new file mode 100644 index 000000000..1b62f24ed --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php @@ -0,0 +1,17 @@ + true, + self::DEEP_ARCHIVE_ACCESS => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/MetadataDirective.php b/vendor/async-aws/s3/src/Enum/MetadataDirective.php new file mode 100644 index 000000000..173e492b7 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/MetadataDirective.php @@ -0,0 +1,17 @@ + true, + self::REPLACE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectCannedACL.php b/vendor/async-aws/s3/src/Enum/ObjectCannedACL.php new file mode 100644 index 000000000..6f5ab1608 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectCannedACL.php @@ -0,0 +1,27 @@ + true, + self::AWS_EXEC_READ => true, + self::BUCKET_OWNER_FULL_CONTROL => true, + self::BUCKET_OWNER_READ => true, + self::PRIVATE => true, + self::PUBLIC_READ => true, + self::PUBLIC_READ_WRITE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php b/vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php new file mode 100644 index 000000000..959b1949e --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php @@ -0,0 +1,17 @@ + true, + self::ON => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectLockMode.php b/vendor/async-aws/s3/src/Enum/ObjectLockMode.php new file mode 100644 index 000000000..568d9e1af --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectLockMode.php @@ -0,0 +1,17 @@ + true, + self::GOVERNANCE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectOwnership.php b/vendor/async-aws/s3/src/Enum/ObjectOwnership.php new file mode 100644 index 000000000..9158c4d1b --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectOwnership.php @@ -0,0 +1,33 @@ + true, + self::BUCKET_OWNER_PREFERRED => true, + self::OBJECT_WRITER => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectStorageClass.php b/vendor/async-aws/s3/src/Enum/ObjectStorageClass.php new file mode 100644 index 000000000..e41e12d2a --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectStorageClass.php @@ -0,0 +1,33 @@ + true, + self::GLACIER => true, + self::GLACIER_IR => true, + self::INTELLIGENT_TIERING => true, + self::ONEZONE_IA => true, + self::OUTPOSTS => true, + self::REDUCED_REDUNDANCY => true, + self::SNOW => true, + self::STANDARD => true, + self::STANDARD_IA => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php b/vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php new file mode 100644 index 000000000..3477c8bf3 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php @@ -0,0 +1,15 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/Permission.php b/vendor/async-aws/s3/src/Enum/Permission.php new file mode 100644 index 000000000..1a2f918c6 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/Permission.php @@ -0,0 +1,23 @@ + true, + self::READ => true, + self::READ_ACP => true, + self::WRITE => true, + self::WRITE_ACP => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ReplicationStatus.php b/vendor/async-aws/s3/src/Enum/ReplicationStatus.php new file mode 100644 index 000000000..753c8268d --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ReplicationStatus.php @@ -0,0 +1,21 @@ + true, + self::FAILED => true, + self::PENDING => true, + self::REPLICA => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/RequestCharged.php b/vendor/async-aws/s3/src/Enum/RequestCharged.php new file mode 100644 index 000000000..e0e4afb90 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/RequestCharged.php @@ -0,0 +1,18 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/RequestPayer.php b/vendor/async-aws/s3/src/Enum/RequestPayer.php new file mode 100644 index 000000000..ff8ce7675 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/RequestPayer.php @@ -0,0 +1,22 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ServerSideEncryption.php b/vendor/async-aws/s3/src/Enum/ServerSideEncryption.php new file mode 100644 index 000000000..12dd2429b --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ServerSideEncryption.php @@ -0,0 +1,19 @@ + true, + self::AWS_KMS => true, + self::AWS_KMS_DSSE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/StorageClass.php b/vendor/async-aws/s3/src/Enum/StorageClass.php new file mode 100644 index 000000000..5df870dda --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/StorageClass.php @@ -0,0 +1,33 @@ + true, + self::GLACIER => true, + self::GLACIER_IR => true, + self::INTELLIGENT_TIERING => true, + self::ONEZONE_IA => true, + self::OUTPOSTS => true, + self::REDUCED_REDUNDANCY => true, + self::SNOW => true, + self::STANDARD => true, + self::STANDARD_IA => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/TaggingDirective.php b/vendor/async-aws/s3/src/Enum/TaggingDirective.php new file mode 100644 index 000000000..c908c78ed --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/TaggingDirective.php @@ -0,0 +1,17 @@ + true, + self::REPLACE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/Type.php b/vendor/async-aws/s3/src/Enum/Type.php new file mode 100644 index 000000000..b07830451 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/Type.php @@ -0,0 +1,19 @@ + true, + self::CANONICAL_USER => true, + self::GROUP => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php b/vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php new file mode 100644 index 000000000..a72e63145 --- /dev/null +++ b/vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php @@ -0,0 +1,13 @@ +accessTier; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + protected function populateResult(ResponseInterface $response): void + { + $data = new \SimpleXMLElement($response->getContent(false)); + if (0 < $data->Error->count()) { + $data = $data->Error; + } + $this->storageClass = ($v = $data->StorageClass) ? (string) $v : null; + $this->accessTier = ($v = $data->AccessTier) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/s3/src/Exception/NoSuchBucketException.php b/vendor/async-aws/s3/src/Exception/NoSuchBucketException.php new file mode 100644 index 000000000..5dc50a07b --- /dev/null +++ b/vendor/async-aws/s3/src/Exception/NoSuchBucketException.php @@ -0,0 +1,12 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->uploadId = $input['UploadId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * UploadId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|AbortMultipartUploadRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php b/vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php new file mode 100644 index 000000000..670281245 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php @@ -0,0 +1,449 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->multipartUpload = isset($input['MultipartUpload']) ? CompletedMultipartUpload::create($input['MultipartUpload']) : null; + $this->uploadId = $input['UploadId'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * MultipartUpload?: CompletedMultipartUpload|array, + * UploadId?: string, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|CompleteMultipartUploadRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMultipartUpload(): ?CompletedMultipartUpload + { + return $this->multipartUpload; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->checksumCrc32) { + $headers['x-amz-checksum-crc32'] = $this->checksumCrc32; + } + if (null !== $this->checksumCrc32C) { + $headers['x-amz-checksum-crc32c'] = $this->checksumCrc32C; + } + if (null !== $this->checksumSha1) { + $headers['x-amz-checksum-sha1'] = $this->checksumSha1; + } + if (null !== $this->checksumSha256) { + $headers['x-amz-checksum-sha256'] = $this->checksumSha256; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + + // Prepare query + $query = []; + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setChecksumCrc32(?string $value): self + { + $this->checksumCrc32 = $value; + + return $this; + } + + public function setChecksumCrc32C(?string $value): self + { + $this->checksumCrc32C = $value; + + return $this; + } + + public function setChecksumSha1(?string $value): self + { + $this->checksumSha1 = $value; + + return $this; + } + + public function setChecksumSha256(?string $value): self + { + $this->checksumSha256 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setMultipartUpload(?CompletedMultipartUpload $value): self + { + $this->multipartUpload = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null !== $v = $this->multipartUpload) { + $node->appendChild($child = $document->createElement('CompleteMultipartUpload')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/Input/CopyObjectRequest.php b/vendor/async-aws/s3/src/Input/CopyObjectRequest.php new file mode 100644 index 000000000..579d2325b --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CopyObjectRequest.php @@ -0,0 +1,1267 @@ +::accesspoint//object/`. For + * example, to copy the object `reports/january.pdf` through access point `my-access-point` owned by account + * `123456789012` in Region `us-west-2`, use the URL encoding of + * `arn:aws:s3:us-west-2:123456789012:accesspoint/my-access-point/object/reports/january.pdf`. The value must be URL + * encoded. + * + * > Amazon S3 supports copy operations using access points only when the source and destination buckets are in the + * > same Amazon Web Services Region. + * + * Alternatively, for objects accessed through Amazon S3 on Outposts, specify the ARN of the object as accessed in the + * format `arn:aws:s3-outposts:::outpost//object/`. For + * example, to copy the object `reports/january.pdf` through outpost `my-outpost` owned by account `123456789012` in + * Region `us-west-2`, use the URL encoding of + * `arn:aws:s3-outposts:us-west-2:123456789012:outpost/my-outpost/object/reports/january.pdf`. The value must be + * URL-encoded. + * + * To copy a specific version of an object, append `?versionId=` to the value (for example, + * `awsexamplebucket/reports/january.pdf?versionId=QUpfdndhfd8438MNFDN93jdnJFkdmqnh893`). If you don't specify a version + * ID, Amazon S3 copies the latest version of the source object. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points.html + * + * @required + * + * @var string|null + */ + private $copySource; + + /** + * Copies the object if its entity tag (ETag) matches the specified tag. + * + * @var string|null + */ + private $copySourceIfMatch; + + /** + * Copies the object if it has been modified since the specified time. + * + * @var \DateTimeImmutable|null + */ + private $copySourceIfModifiedSince; + + /** + * Copies the object if its entity tag (ETag) is different than the specified ETag. + * + * @var string|null + */ + private $copySourceIfNoneMatch; + + /** + * Copies the object if it hasn't been modified since the specified time. + * + * @var \DateTimeImmutable|null + */ + private $copySourceIfUnmodifiedSince; + + /** + * The date and time at which the object is no longer cacheable. + * + * @var \DateTimeImmutable|null + */ + private $expires; + + /** + * Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantFullControl; + + /** + * Allows grantee to read the object data and its metadata. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantRead; + + /** + * Allows grantee to read the object ACL. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantReadAcp; + + /** + * Allows grantee to write the ACL for the applicable object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantWriteAcp; + + /** + * The key of the destination object. + * + * @required + * + * @var string|null + */ + private $key; + + /** + * A map of metadata to store with the object in S3. + * + * @var array|null + */ + private $metadata; + + /** + * Specifies whether the metadata is copied from the source object or replaced with metadata provided in the request. + * + * @var MetadataDirective::*|null + */ + private $metadataDirective; + + /** + * Specifies whether the object tag-set are copied from the source object or replaced with tag-set provided in the + * request. + * + * @var TaggingDirective::*|null + */ + private $taggingDirective; + + /** + * The server-side encryption algorithm used when storing this object in Amazon S3 (for example, `AES256`, `aws:kms`, + * `aws:kms:dsse`). + * + * @var ServerSideEncryption::*|null + */ + private $serverSideEncryption; + + /** + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^1] in + * the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * If the bucket is configured as a website, redirects requests for this object to another object in the same bucket or + * to an external URL. Amazon S3 stores the value of this header in the object metadata. This value is unique to each + * object and is not copied when using the `x-amz-metadata-directive` header. Instead, you may opt to provide this + * header in combination with the directive. + * + * @var string|null + */ + private $websiteRedirectLocation; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * Specifies the KMS key ID to use for object encryption. All GET and PUT requests for an object protected by KMS will + * fail if they're not made via SSL or using SigV4. For information about configuring any of the officially supported + * Amazon Web Services SDKs and Amazon Web Services CLI, see Specifying the Signature Version in Request Authentication + * [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Specifies the Amazon Web Services KMS Encryption Context to use for object encryption. The value of this header is a + * base64-encoded UTF-8 string holding JSON with the encryption context key-value pairs. + * + * @var string|null + */ + private $sseKmsEncryptionContext; + + /** + * Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption with server-side encryption using Key + * Management Service (KMS) keys (SSE-KMS). Setting this header to `true` causes Amazon S3 to use an S3 Bucket Key for + * object encryption with SSE-KMS. + * + * Specifying this header with a COPY action doesn’t affect bucket-level settings for S3 Bucket Key. + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * Specifies the algorithm to use when decrypting the source object (for example, AES256). + * + * @var string|null + */ + private $copySourceSseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use to decrypt the source object. The encryption key + * provided in this header must be one that was used when the source object was created. + * + * @var string|null + */ + private $copySourceSseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $copySourceSseCustomerKeyMd5; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The tag-set for the object destination object this value must be used in conjunction with the `TaggingDirective`. The + * tag-set must be encoded as URL Query parameters. + * + * @var string|null + */ + private $tagging; + + /** + * The Object Lock mode that you want to apply to the copied object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when you want the copied object's Object Lock to expire. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether you want to apply a legal hold to the copied object. + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + /** + * The account ID of the expected destination bucket owner. If the destination bucket is owned by a different account, + * the request fails with the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * The account ID of the expected source bucket owner. If the source bucket is owned by a different account, the request + * fails with the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedSourceBucketOwner; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * CopySource?: string, + * CopySourceIfMatch?: string, + * CopySourceIfModifiedSince?: \DateTimeImmutable|string, + * CopySourceIfNoneMatch?: string, + * CopySourceIfUnmodifiedSince?: \DateTimeImmutable|string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * MetadataDirective?: MetadataDirective::*, + * TaggingDirective?: TaggingDirective::*, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * CopySourceSSECustomerAlgorithm?: string, + * CopySourceSSECustomerKey?: string, + * CopySourceSSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ExpectedSourceBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->cacheControl = $input['CacheControl'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->contentDisposition = $input['ContentDisposition'] ?? null; + $this->contentEncoding = $input['ContentEncoding'] ?? null; + $this->contentLanguage = $input['ContentLanguage'] ?? null; + $this->contentType = $input['ContentType'] ?? null; + $this->copySource = $input['CopySource'] ?? null; + $this->copySourceIfMatch = $input['CopySourceIfMatch'] ?? null; + $this->copySourceIfModifiedSince = !isset($input['CopySourceIfModifiedSince']) ? null : ($input['CopySourceIfModifiedSince'] instanceof \DateTimeImmutable ? $input['CopySourceIfModifiedSince'] : new \DateTimeImmutable($input['CopySourceIfModifiedSince'])); + $this->copySourceIfNoneMatch = $input['CopySourceIfNoneMatch'] ?? null; + $this->copySourceIfUnmodifiedSince = !isset($input['CopySourceIfUnmodifiedSince']) ? null : ($input['CopySourceIfUnmodifiedSince'] instanceof \DateTimeImmutable ? $input['CopySourceIfUnmodifiedSince'] : new \DateTimeImmutable($input['CopySourceIfUnmodifiedSince'])); + $this->expires = !isset($input['Expires']) ? null : ($input['Expires'] instanceof \DateTimeImmutable ? $input['Expires'] : new \DateTimeImmutable($input['Expires'])); + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->metadata = $input['Metadata'] ?? null; + $this->metadataDirective = $input['MetadataDirective'] ?? null; + $this->taggingDirective = $input['TaggingDirective'] ?? null; + $this->serverSideEncryption = $input['ServerSideEncryption'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->websiteRedirectLocation = $input['WebsiteRedirectLocation'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->sseKmsKeyId = $input['SSEKMSKeyId'] ?? null; + $this->sseKmsEncryptionContext = $input['SSEKMSEncryptionContext'] ?? null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + $this->copySourceSseCustomerAlgorithm = $input['CopySourceSSECustomerAlgorithm'] ?? null; + $this->copySourceSseCustomerKey = $input['CopySourceSSECustomerKey'] ?? null; + $this->copySourceSseCustomerKeyMd5 = $input['CopySourceSSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->tagging = $input['Tagging'] ?? null; + $this->objectLockMode = $input['ObjectLockMode'] ?? null; + $this->objectLockRetainUntilDate = !isset($input['ObjectLockRetainUntilDate']) ? null : ($input['ObjectLockRetainUntilDate'] instanceof \DateTimeImmutable ? $input['ObjectLockRetainUntilDate'] : new \DateTimeImmutable($input['ObjectLockRetainUntilDate'])); + $this->objectLockLegalHoldStatus = $input['ObjectLockLegalHoldStatus'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->expectedSourceBucketOwner = $input['ExpectedSourceBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * CopySource?: string, + * CopySourceIfMatch?: string, + * CopySourceIfModifiedSince?: \DateTimeImmutable|string, + * CopySourceIfNoneMatch?: string, + * CopySourceIfUnmodifiedSince?: \DateTimeImmutable|string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * MetadataDirective?: MetadataDirective::*, + * TaggingDirective?: TaggingDirective::*, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * CopySourceSSECustomerAlgorithm?: string, + * CopySourceSSECustomerKey?: string, + * CopySourceSSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ExpectedSourceBucketOwner?: string, + * '@region'?: string|null, + * }|CopyObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + return $this->cacheControl; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentDisposition(): ?string + { + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + return $this->contentLanguage; + } + + public function getContentType(): ?string + { + return $this->contentType; + } + + public function getCopySource(): ?string + { + return $this->copySource; + } + + public function getCopySourceIfMatch(): ?string + { + return $this->copySourceIfMatch; + } + + public function getCopySourceIfModifiedSince(): ?\DateTimeImmutable + { + return $this->copySourceIfModifiedSince; + } + + public function getCopySourceIfNoneMatch(): ?string + { + return $this->copySourceIfNoneMatch; + } + + public function getCopySourceIfUnmodifiedSince(): ?\DateTimeImmutable + { + return $this->copySourceIfUnmodifiedSince; + } + + public function getCopySourceSseCustomerAlgorithm(): ?string + { + return $this->copySourceSseCustomerAlgorithm; + } + + public function getCopySourceSseCustomerKey(): ?string + { + return $this->copySourceSseCustomerKey; + } + + public function getCopySourceSseCustomerKeyMd5(): ?string + { + return $this->copySourceSseCustomerKeyMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getExpectedSourceBucketOwner(): ?string + { + return $this->expectedSourceBucketOwner; + } + + public function getExpires(): ?\DateTimeImmutable + { + return $this->expires; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata ?? []; + } + + /** + * @return MetadataDirective::*|null + */ + public function getMetadataDirective(): ?string + { + return $this->metadataDirective; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + return $this->objectLockRetainUntilDate; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getTagging(): ?string + { + return $this->tagging; + } + + /** + * @return TaggingDirective::*|null + */ + public function getTaggingDirective(): ?string + { + return $this->taggingDirective; + } + + public function getWebsiteRedirectLocation(): ?string + { + return $this->websiteRedirectLocation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->cacheControl) { + $headers['Cache-Control'] = $this->cacheControl; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->contentDisposition) { + $headers['Content-Disposition'] = $this->contentDisposition; + } + if (null !== $this->contentEncoding) { + $headers['Content-Encoding'] = $this->contentEncoding; + } + if (null !== $this->contentLanguage) { + $headers['Content-Language'] = $this->contentLanguage; + } + if (null !== $this->contentType) { + $headers['Content-Type'] = $this->contentType; + } + if (null === $v = $this->copySource) { + throw new InvalidArgument(sprintf('Missing parameter "CopySource" for "%s". The value cannot be null.', __CLASS__)); + } + $headers['x-amz-copy-source'] = $v; + if (null !== $this->copySourceIfMatch) { + $headers['x-amz-copy-source-if-match'] = $this->copySourceIfMatch; + } + if (null !== $this->copySourceIfModifiedSince) { + $headers['x-amz-copy-source-if-modified-since'] = $this->copySourceIfModifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->copySourceIfNoneMatch) { + $headers['x-amz-copy-source-if-none-match'] = $this->copySourceIfNoneMatch; + } + if (null !== $this->copySourceIfUnmodifiedSince) { + $headers['x-amz-copy-source-if-unmodified-since'] = $this->copySourceIfUnmodifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->expires) { + $headers['Expires'] = $this->expires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->metadataDirective) { + if (!MetadataDirective::exists($this->metadataDirective)) { + throw new InvalidArgument(sprintf('Invalid parameter "MetadataDirective" for "%s". The value "%s" is not a valid "MetadataDirective".', __CLASS__, $this->metadataDirective)); + } + $headers['x-amz-metadata-directive'] = $this->metadataDirective; + } + if (null !== $this->taggingDirective) { + if (!TaggingDirective::exists($this->taggingDirective)) { + throw new InvalidArgument(sprintf('Invalid parameter "TaggingDirective" for "%s". The value "%s" is not a valid "TaggingDirective".', __CLASS__, $this->taggingDirective)); + } + $headers['x-amz-tagging-directive'] = $this->taggingDirective; + } + if (null !== $this->serverSideEncryption) { + if (!ServerSideEncryption::exists($this->serverSideEncryption)) { + throw new InvalidArgument(sprintf('Invalid parameter "ServerSideEncryption" for "%s". The value "%s" is not a valid "ServerSideEncryption".', __CLASS__, $this->serverSideEncryption)); + } + $headers['x-amz-server-side-encryption'] = $this->serverSideEncryption; + } + if (null !== $this->storageClass) { + if (!StorageClass::exists($this->storageClass)) { + throw new InvalidArgument(sprintf('Invalid parameter "StorageClass" for "%s". The value "%s" is not a valid "StorageClass".', __CLASS__, $this->storageClass)); + } + $headers['x-amz-storage-class'] = $this->storageClass; + } + if (null !== $this->websiteRedirectLocation) { + $headers['x-amz-website-redirect-location'] = $this->websiteRedirectLocation; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->sseKmsKeyId) { + $headers['x-amz-server-side-encryption-aws-kms-key-id'] = $this->sseKmsKeyId; + } + if (null !== $this->sseKmsEncryptionContext) { + $headers['x-amz-server-side-encryption-context'] = $this->sseKmsEncryptionContext; + } + if (null !== $this->bucketKeyEnabled) { + $headers['x-amz-server-side-encryption-bucket-key-enabled'] = $this->bucketKeyEnabled ? 'true' : 'false'; + } + if (null !== $this->copySourceSseCustomerAlgorithm) { + $headers['x-amz-copy-source-server-side-encryption-customer-algorithm'] = $this->copySourceSseCustomerAlgorithm; + } + if (null !== $this->copySourceSseCustomerKey) { + $headers['x-amz-copy-source-server-side-encryption-customer-key'] = $this->copySourceSseCustomerKey; + } + if (null !== $this->copySourceSseCustomerKeyMd5) { + $headers['x-amz-copy-source-server-side-encryption-customer-key-MD5'] = $this->copySourceSseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->tagging) { + $headers['x-amz-tagging'] = $this->tagging; + } + if (null !== $this->objectLockMode) { + if (!ObjectLockMode::exists($this->objectLockMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockMode" for "%s". The value "%s" is not a valid "ObjectLockMode".', __CLASS__, $this->objectLockMode)); + } + $headers['x-amz-object-lock-mode'] = $this->objectLockMode; + } + if (null !== $this->objectLockRetainUntilDate) { + $headers['x-amz-object-lock-retain-until-date'] = $this->objectLockRetainUntilDate->format(\DateTimeInterface::ISO8601); + } + if (null !== $this->objectLockLegalHoldStatus) { + if (!ObjectLockLegalHoldStatus::exists($this->objectLockLegalHoldStatus)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockLegalHoldStatus" for "%s". The value "%s" is not a valid "ObjectLockLegalHoldStatus".', __CLASS__, $this->objectLockLegalHoldStatus)); + } + $headers['x-amz-object-lock-legal-hold'] = $this->objectLockLegalHoldStatus; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->expectedSourceBucketOwner) { + $headers['x-amz-source-expected-bucket-owner'] = $this->expectedSourceBucketOwner; + } + if (null !== $this->metadata) { + foreach ($this->metadata as $key => $value) { + $headers["x-amz-meta-$key"] = $value; + } + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBucketKeyEnabled(?bool $value): self + { + $this->bucketKeyEnabled = $value; + + return $this; + } + + public function setCacheControl(?string $value): self + { + $this->cacheControl = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentDisposition(?string $value): self + { + $this->contentDisposition = $value; + + return $this; + } + + public function setContentEncoding(?string $value): self + { + $this->contentEncoding = $value; + + return $this; + } + + public function setContentLanguage(?string $value): self + { + $this->contentLanguage = $value; + + return $this; + } + + public function setContentType(?string $value): self + { + $this->contentType = $value; + + return $this; + } + + public function setCopySource(?string $value): self + { + $this->copySource = $value; + + return $this; + } + + public function setCopySourceIfMatch(?string $value): self + { + $this->copySourceIfMatch = $value; + + return $this; + } + + public function setCopySourceIfModifiedSince(?\DateTimeImmutable $value): self + { + $this->copySourceIfModifiedSince = $value; + + return $this; + } + + public function setCopySourceIfNoneMatch(?string $value): self + { + $this->copySourceIfNoneMatch = $value; + + return $this; + } + + public function setCopySourceIfUnmodifiedSince(?\DateTimeImmutable $value): self + { + $this->copySourceIfUnmodifiedSince = $value; + + return $this; + } + + public function setCopySourceSseCustomerAlgorithm(?string $value): self + { + $this->copySourceSseCustomerAlgorithm = $value; + + return $this; + } + + public function setCopySourceSseCustomerKey(?string $value): self + { + $this->copySourceSseCustomerKey = $value; + + return $this; + } + + public function setCopySourceSseCustomerKeyMd5(?string $value): self + { + $this->copySourceSseCustomerKeyMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setExpectedSourceBucketOwner(?string $value): self + { + $this->expectedSourceBucketOwner = $value; + + return $this; + } + + public function setExpires(?\DateTimeImmutable $value): self + { + $this->expires = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param array $value + */ + public function setMetadata(array $value): self + { + $this->metadata = $value; + + return $this; + } + + /** + * @param MetadataDirective::*|null $value + */ + public function setMetadataDirective(?string $value): self + { + $this->metadataDirective = $value; + + return $this; + } + + /** + * @param ObjectLockLegalHoldStatus::*|null $value + */ + public function setObjectLockLegalHoldStatus(?string $value): self + { + $this->objectLockLegalHoldStatus = $value; + + return $this; + } + + /** + * @param ObjectLockMode::*|null $value + */ + public function setObjectLockMode(?string $value): self + { + $this->objectLockMode = $value; + + return $this; + } + + public function setObjectLockRetainUntilDate(?\DateTimeImmutable $value): self + { + $this->objectLockRetainUntilDate = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + /** + * @param ServerSideEncryption::*|null $value + */ + public function setServerSideEncryption(?string $value): self + { + $this->serverSideEncryption = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setSseKmsEncryptionContext(?string $value): self + { + $this->sseKmsEncryptionContext = $value; + + return $this; + } + + public function setSseKmsKeyId(?string $value): self + { + $this->sseKmsKeyId = $value; + + return $this; + } + + /** + * @param StorageClass::*|null $value + */ + public function setStorageClass(?string $value): self + { + $this->storageClass = $value; + + return $this; + } + + public function setTagging(?string $value): self + { + $this->tagging = $value; + + return $this; + } + + /** + * @param TaggingDirective::*|null $value + */ + public function setTaggingDirective(?string $value): self + { + $this->taggingDirective = $value; + + return $this; + } + + public function setWebsiteRedirectLocation(?string $value): self + { + $this->websiteRedirectLocation = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/CreateBucketRequest.php b/vendor/async-aws/s3/src/Input/CreateBucketRequest.php new file mode 100644 index 000000000..74862f720 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CreateBucketRequest.php @@ -0,0 +1,337 @@ +acl = $input['ACL'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->createBucketConfiguration = isset($input['CreateBucketConfiguration']) ? CreateBucketConfiguration::create($input['CreateBucketConfiguration']) : null; + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWrite = $input['GrantWrite'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->objectLockEnabledForBucket = $input['ObjectLockEnabledForBucket'] ?? null; + $this->objectOwnership = $input['ObjectOwnership'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: BucketCannedACL::*, + * Bucket?: string, + * CreateBucketConfiguration?: CreateBucketConfiguration|array, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * ObjectLockEnabledForBucket?: bool, + * ObjectOwnership?: ObjectOwnership::*, + * '@region'?: string|null, + * }|CreateBucketRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return BucketCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getCreateBucketConfiguration(): ?CreateBucketConfiguration + { + return $this->createBucketConfiguration; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWrite(): ?string + { + return $this->grantWrite; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getObjectLockEnabledForBucket(): ?bool + { + return $this->objectLockEnabledForBucket; + } + + /** + * @return ObjectOwnership::*|null + */ + public function getObjectOwnership(): ?string + { + return $this->objectOwnership; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!BucketCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "BucketCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWrite) { + $headers['x-amz-grant-write'] = $this->grantWrite; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->objectLockEnabledForBucket) { + $headers['x-amz-bucket-object-lock-enabled'] = $this->objectLockEnabledForBucket ? 'true' : 'false'; + } + if (null !== $this->objectOwnership) { + if (!ObjectOwnership::exists($this->objectOwnership)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectOwnership" for "%s". The value "%s" is not a valid "ObjectOwnership".', __CLASS__, $this->objectOwnership)); + } + $headers['x-amz-object-ownership'] = $this->objectOwnership; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']); + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param BucketCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setCreateBucketConfiguration(?CreateBucketConfiguration $value): self + { + $this->createBucketConfiguration = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWrite(?string $value): self + { + $this->grantWrite = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setObjectLockEnabledForBucket(?bool $value): self + { + $this->objectLockEnabledForBucket = $value; + + return $this; + } + + /** + * @param ObjectOwnership::*|null $value + */ + public function setObjectOwnership(?string $value): self + { + $this->objectOwnership = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null !== $v = $this->createBucketConfiguration) { + $node->appendChild($child = $document->createElement('CreateBucketConfiguration')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php b/vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php new file mode 100644 index 000000000..7c4d369e4 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php @@ -0,0 +1,933 @@ +|null + */ + private $metadata; + + /** + * The server-side encryption algorithm used when storing this object in Amazon S3 (for example, `AES256`, `aws:kms`). + * + * @var ServerSideEncryption::*|null + */ + private $serverSideEncryption; + + /** + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^1] in + * the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * If the bucket is configured as a website, redirects requests for this object to another object in the same bucket or + * to an external URL. Amazon S3 stores the value of this header in the object metadata. + * + * @var string|null + */ + private $websiteRedirectLocation; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * Specifies the ID of the symmetric encryption customer managed key to use for object encryption. All GET and PUT + * requests for an object protected by KMS will fail if they're not made via SSL or using SigV4. For information about + * configuring any of the officially supported Amazon Web Services SDKs and Amazon Web Services CLI, see Specifying the + * Signature Version in Request Authentication [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Specifies the Amazon Web Services KMS Encryption Context to use for object encryption. The value of this header is a + * base64-encoded UTF-8 string holding JSON with the encryption context key-value pairs. + * + * @var string|null + */ + private $sseKmsEncryptionContext; + + /** + * Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption with server-side encryption using Key + * Management Service (KMS) keys (SSE-KMS). Setting this header to `true` causes Amazon S3 to use an S3 Bucket Key for + * object encryption with SSE-KMS. + * + * Specifying this header with an object action doesn’t affect bucket-level settings for S3 Bucket Key. + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The tag-set for the object. The tag-set must be encoded as URL Query parameters. + * + * @var string|null + */ + private $tagging; + + /** + * Specifies the Object Lock mode that you want to apply to the uploaded object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * Specifies the date and time when you want the Object Lock to expire. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether you want to apply a legal hold to the uploaded object. + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * Indicates the algorithm you want Amazon S3 to use to create the checksum for the object. For more information, see + * Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->cacheControl = $input['CacheControl'] ?? null; + $this->contentDisposition = $input['ContentDisposition'] ?? null; + $this->contentEncoding = $input['ContentEncoding'] ?? null; + $this->contentLanguage = $input['ContentLanguage'] ?? null; + $this->contentType = $input['ContentType'] ?? null; + $this->expires = !isset($input['Expires']) ? null : ($input['Expires'] instanceof \DateTimeImmutable ? $input['Expires'] : new \DateTimeImmutable($input['Expires'])); + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->metadata = $input['Metadata'] ?? null; + $this->serverSideEncryption = $input['ServerSideEncryption'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->websiteRedirectLocation = $input['WebsiteRedirectLocation'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->sseKmsKeyId = $input['SSEKMSKeyId'] ?? null; + $this->sseKmsEncryptionContext = $input['SSEKMSEncryptionContext'] ?? null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->tagging = $input['Tagging'] ?? null; + $this->objectLockMode = $input['ObjectLockMode'] ?? null; + $this->objectLockRetainUntilDate = !isset($input['ObjectLockRetainUntilDate']) ? null : ($input['ObjectLockRetainUntilDate'] instanceof \DateTimeImmutable ? $input['ObjectLockRetainUntilDate'] : new \DateTimeImmutable($input['ObjectLockRetainUntilDate'])); + $this->objectLockLegalHoldStatus = $input['ObjectLockLegalHoldStatus'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|CreateMultipartUploadRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + return $this->cacheControl; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentDisposition(): ?string + { + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + return $this->contentLanguage; + } + + public function getContentType(): ?string + { + return $this->contentType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getExpires(): ?\DateTimeImmutable + { + return $this->expires; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata ?? []; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + return $this->objectLockRetainUntilDate; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getTagging(): ?string + { + return $this->tagging; + } + + public function getWebsiteRedirectLocation(): ?string + { + return $this->websiteRedirectLocation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->cacheControl) { + $headers['Cache-Control'] = $this->cacheControl; + } + if (null !== $this->contentDisposition) { + $headers['Content-Disposition'] = $this->contentDisposition; + } + if (null !== $this->contentEncoding) { + $headers['Content-Encoding'] = $this->contentEncoding; + } + if (null !== $this->contentLanguage) { + $headers['Content-Language'] = $this->contentLanguage; + } + if (null !== $this->contentType) { + $headers['Content-Type'] = $this->contentType; + } + if (null !== $this->expires) { + $headers['Expires'] = $this->expires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->serverSideEncryption) { + if (!ServerSideEncryption::exists($this->serverSideEncryption)) { + throw new InvalidArgument(sprintf('Invalid parameter "ServerSideEncryption" for "%s". The value "%s" is not a valid "ServerSideEncryption".', __CLASS__, $this->serverSideEncryption)); + } + $headers['x-amz-server-side-encryption'] = $this->serverSideEncryption; + } + if (null !== $this->storageClass) { + if (!StorageClass::exists($this->storageClass)) { + throw new InvalidArgument(sprintf('Invalid parameter "StorageClass" for "%s". The value "%s" is not a valid "StorageClass".', __CLASS__, $this->storageClass)); + } + $headers['x-amz-storage-class'] = $this->storageClass; + } + if (null !== $this->websiteRedirectLocation) { + $headers['x-amz-website-redirect-location'] = $this->websiteRedirectLocation; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->sseKmsKeyId) { + $headers['x-amz-server-side-encryption-aws-kms-key-id'] = $this->sseKmsKeyId; + } + if (null !== $this->sseKmsEncryptionContext) { + $headers['x-amz-server-side-encryption-context'] = $this->sseKmsEncryptionContext; + } + if (null !== $this->bucketKeyEnabled) { + $headers['x-amz-server-side-encryption-bucket-key-enabled'] = $this->bucketKeyEnabled ? 'true' : 'false'; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->tagging) { + $headers['x-amz-tagging'] = $this->tagging; + } + if (null !== $this->objectLockMode) { + if (!ObjectLockMode::exists($this->objectLockMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockMode" for "%s". The value "%s" is not a valid "ObjectLockMode".', __CLASS__, $this->objectLockMode)); + } + $headers['x-amz-object-lock-mode'] = $this->objectLockMode; + } + if (null !== $this->objectLockRetainUntilDate) { + $headers['x-amz-object-lock-retain-until-date'] = $this->objectLockRetainUntilDate->format(\DateTimeInterface::ISO8601); + } + if (null !== $this->objectLockLegalHoldStatus) { + if (!ObjectLockLegalHoldStatus::exists($this->objectLockLegalHoldStatus)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockLegalHoldStatus" for "%s". The value "%s" is not a valid "ObjectLockLegalHoldStatus".', __CLASS__, $this->objectLockLegalHoldStatus)); + } + $headers['x-amz-object-lock-legal-hold'] = $this->objectLockLegalHoldStatus; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->metadata) { + foreach ($this->metadata as $key => $value) { + $headers["x-amz-meta-$key"] = $value; + } + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?uploads'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBucketKeyEnabled(?bool $value): self + { + $this->bucketKeyEnabled = $value; + + return $this; + } + + public function setCacheControl(?string $value): self + { + $this->cacheControl = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentDisposition(?string $value): self + { + $this->contentDisposition = $value; + + return $this; + } + + public function setContentEncoding(?string $value): self + { + $this->contentEncoding = $value; + + return $this; + } + + public function setContentLanguage(?string $value): self + { + $this->contentLanguage = $value; + + return $this; + } + + public function setContentType(?string $value): self + { + $this->contentType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setExpires(?\DateTimeImmutable $value): self + { + $this->expires = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param array $value + */ + public function setMetadata(array $value): self + { + $this->metadata = $value; + + return $this; + } + + /** + * @param ObjectLockLegalHoldStatus::*|null $value + */ + public function setObjectLockLegalHoldStatus(?string $value): self + { + $this->objectLockLegalHoldStatus = $value; + + return $this; + } + + /** + * @param ObjectLockMode::*|null $value + */ + public function setObjectLockMode(?string $value): self + { + $this->objectLockMode = $value; + + return $this; + } + + public function setObjectLockRetainUntilDate(?\DateTimeImmutable $value): self + { + $this->objectLockRetainUntilDate = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + /** + * @param ServerSideEncryption::*|null $value + */ + public function setServerSideEncryption(?string $value): self + { + $this->serverSideEncryption = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setSseKmsEncryptionContext(?string $value): self + { + $this->sseKmsEncryptionContext = $value; + + return $this; + } + + public function setSseKmsKeyId(?string $value): self + { + $this->sseKmsKeyId = $value; + + return $this; + } + + /** + * @param StorageClass::*|null $value + */ + public function setStorageClass(?string $value): self + { + $this->storageClass = $value; + + return $this; + } + + public function setTagging(?string $value): self + { + $this->tagging = $value; + + return $this; + } + + public function setWebsiteRedirectLocation(?string $value): self + { + $this->websiteRedirectLocation = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php b/vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php new file mode 100644 index 000000000..a039a743b --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php @@ -0,0 +1,107 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketCorsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?cors'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteBucketRequest.php b/vendor/async-aws/s3/src/Input/DeleteBucketRequest.php new file mode 100644 index 000000000..ee2371db7 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteBucketRequest.php @@ -0,0 +1,107 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteObjectRequest.php b/vendor/async-aws/s3/src/Input/DeleteObjectRequest.php new file mode 100644 index 000000000..3ded441ff --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteObjectRequest.php @@ -0,0 +1,260 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->mfa = $input['MFA'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->bypassGovernanceRetention = $input['BypassGovernanceRetention'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * MFA?: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBypassGovernanceRetention(): ?bool + { + return $this->bypassGovernanceRetention; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMfa(): ?string + { + return $this->mfa; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->mfa) { + $headers['x-amz-mfa'] = $this->mfa; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->bypassGovernanceRetention) { + $headers['x-amz-bypass-governance-retention'] = $this->bypassGovernanceRetention ? 'true' : 'false'; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBypassGovernanceRetention(?bool $value): self + { + $this->bypassGovernanceRetention = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setMfa(?string $value): self + { + $this->mfa = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php b/vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php new file mode 100644 index 000000000..06c73ab7d --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php @@ -0,0 +1,174 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?tagging'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php b/vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php new file mode 100644 index 000000000..2f7a115e6 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php @@ -0,0 +1,292 @@ +bucket = $input['Bucket'] ?? null; + $this->delete = isset($input['Delete']) ? Delete::create($input['Delete']) : null; + $this->mfa = $input['MFA'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->bypassGovernanceRetention = $input['BypassGovernanceRetention'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Delete?: Delete|array, + * MFA?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|DeleteObjectsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBypassGovernanceRetention(): ?bool + { + return $this->bypassGovernanceRetention; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getDelete(): ?Delete + { + return $this->delete; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getMfa(): ?string + { + return $this->mfa; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->mfa) { + $headers['x-amz-mfa'] = $this->mfa; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->bypassGovernanceRetention) { + $headers['x-amz-bypass-governance-retention'] = $this->bypassGovernanceRetention ? 'true' : 'false'; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?delete'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBypassGovernanceRetention(?bool $value): self + { + $this->bypassGovernanceRetention = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setDelete(?Delete $value): self + { + $this->delete = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setMfa(?string $value): self + { + $this->mfa = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->delete) { + throw new InvalidArgument(sprintf('Missing parameter "Delete" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('Delete')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php b/vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php new file mode 100644 index 000000000..67a6e4c2e --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php @@ -0,0 +1,116 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketCorsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?cors'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php b/vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php new file mode 100644 index 000000000..82254c4ec --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php @@ -0,0 +1,107 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketEncryptionRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?encryption'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetObjectAclRequest.php b/vendor/async-aws/s3/src/Input/GetObjectAclRequest.php new file mode 100644 index 000000000..97e06432e --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetObjectAclRequest.php @@ -0,0 +1,200 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetObjectAclRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?acl'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetObjectRequest.php b/vendor/async-aws/s3/src/Input/GetObjectRequest.php new file mode 100644 index 000000000..f4f5185c6 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetObjectRequest.php @@ -0,0 +1,633 @@ + Amazon S3 doesn't support retrieving multiple ranges of data per `GET` request. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#name-range + * + * @var string|null + */ + private $range; + + /** + * Sets the `Cache-Control` header of the response. + * + * @var string|null + */ + private $responseCacheControl; + + /** + * Sets the `Content-Disposition` header of the response. + * + * @var string|null + */ + private $responseContentDisposition; + + /** + * Sets the `Content-Encoding` header of the response. + * + * @var string|null + */ + private $responseContentEncoding; + + /** + * Sets the `Content-Language` header of the response. + * + * @var string|null + */ + private $responseContentLanguage; + + /** + * Sets the `Content-Type` header of the response. + * + * @var string|null + */ + private $responseContentType; + + /** + * Sets the `Expires` header of the response. + * + * @var \DateTimeImmutable|null + */ + private $responseExpires; + + /** + * VersionId used to reference a specific version of the object. + * + * @var string|null + */ + private $versionId; + + /** + * Specifies the algorithm to use to when decrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 used to encrypt the data. This value is used to decrypt + * the object when recovering it and must match the one used when storing the data. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * Part number of the object being read. This is a positive integer between 1 and 10,000. Effectively performs a + * 'ranged' GET request for the part specified. Useful for downloading just a part of an object. + * + * @var int|null + */ + private $partNumber; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * To retrieve the checksum, this mode must be enabled. + * + * @var ChecksumMode::*|null + */ + private $checksumMode; + + /** + * @param array{ + * Bucket?: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key?: string, + * Range?: string, + * ResponseCacheControl?: string, + * ResponseContentDisposition?: string, + * ResponseContentEncoding?: string, + * ResponseContentLanguage?: string, + * ResponseContentType?: string, + * ResponseExpires?: \DateTimeImmutable|string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->bucket = $input['Bucket'] ?? null; + $this->ifMatch = $input['IfMatch'] ?? null; + $this->ifModifiedSince = !isset($input['IfModifiedSince']) ? null : ($input['IfModifiedSince'] instanceof \DateTimeImmutable ? $input['IfModifiedSince'] : new \DateTimeImmutable($input['IfModifiedSince'])); + $this->ifNoneMatch = $input['IfNoneMatch'] ?? null; + $this->ifUnmodifiedSince = !isset($input['IfUnmodifiedSince']) ? null : ($input['IfUnmodifiedSince'] instanceof \DateTimeImmutable ? $input['IfUnmodifiedSince'] : new \DateTimeImmutable($input['IfUnmodifiedSince'])); + $this->key = $input['Key'] ?? null; + $this->range = $input['Range'] ?? null; + $this->responseCacheControl = $input['ResponseCacheControl'] ?? null; + $this->responseContentDisposition = $input['ResponseContentDisposition'] ?? null; + $this->responseContentEncoding = $input['ResponseContentEncoding'] ?? null; + $this->responseContentLanguage = $input['ResponseContentLanguage'] ?? null; + $this->responseContentType = $input['ResponseContentType'] ?? null; + $this->responseExpires = !isset($input['ResponseExpires']) ? null : ($input['ResponseExpires'] instanceof \DateTimeImmutable ? $input['ResponseExpires'] : new \DateTimeImmutable($input['ResponseExpires'])); + $this->versionId = $input['VersionId'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumMode = $input['ChecksumMode'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key?: string, + * Range?: string, + * ResponseCacheControl?: string, + * ResponseContentDisposition?: string, + * ResponseContentEncoding?: string, + * ResponseContentLanguage?: string, + * ResponseContentType?: string, + * ResponseExpires?: \DateTimeImmutable|string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|GetObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumMode::*|null + */ + public function getChecksumMode(): ?string + { + return $this->checksumMode; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getIfMatch(): ?string + { + return $this->ifMatch; + } + + public function getIfModifiedSince(): ?\DateTimeImmutable + { + return $this->ifModifiedSince; + } + + public function getIfNoneMatch(): ?string + { + return $this->ifNoneMatch; + } + + public function getIfUnmodifiedSince(): ?\DateTimeImmutable + { + return $this->ifUnmodifiedSince; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + public function getRange(): ?string + { + return $this->range; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getResponseCacheControl(): ?string + { + return $this->responseCacheControl; + } + + public function getResponseContentDisposition(): ?string + { + return $this->responseContentDisposition; + } + + public function getResponseContentEncoding(): ?string + { + return $this->responseContentEncoding; + } + + public function getResponseContentLanguage(): ?string + { + return $this->responseContentLanguage; + } + + public function getResponseContentType(): ?string + { + return $this->responseContentType; + } + + public function getResponseExpires(): ?\DateTimeImmutable + { + return $this->responseExpires; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->ifMatch) { + $headers['If-Match'] = $this->ifMatch; + } + if (null !== $this->ifModifiedSince) { + $headers['If-Modified-Since'] = $this->ifModifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->ifNoneMatch) { + $headers['If-None-Match'] = $this->ifNoneMatch; + } + if (null !== $this->ifUnmodifiedSince) { + $headers['If-Unmodified-Since'] = $this->ifUnmodifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->range) { + $headers['Range'] = $this->range; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumMode) { + if (!ChecksumMode::exists($this->checksumMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumMode" for "%s". The value "%s" is not a valid "ChecksumMode".', __CLASS__, $this->checksumMode)); + } + $headers['x-amz-checksum-mode'] = $this->checksumMode; + } + + // Prepare query + $query = []; + if (null !== $this->responseCacheControl) { + $query['response-cache-control'] = $this->responseCacheControl; + } + if (null !== $this->responseContentDisposition) { + $query['response-content-disposition'] = $this->responseContentDisposition; + } + if (null !== $this->responseContentEncoding) { + $query['response-content-encoding'] = $this->responseContentEncoding; + } + if (null !== $this->responseContentLanguage) { + $query['response-content-language'] = $this->responseContentLanguage; + } + if (null !== $this->responseContentType) { + $query['response-content-type'] = $this->responseContentType; + } + if (null !== $this->responseExpires) { + $query['response-expires'] = $this->responseExpires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + if (null !== $this->partNumber) { + $query['partNumber'] = (string) $this->partNumber; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumMode::*|null $value + */ + public function setChecksumMode(?string $value): self + { + $this->checksumMode = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setIfMatch(?string $value): self + { + $this->ifMatch = $value; + + return $this; + } + + public function setIfModifiedSince(?\DateTimeImmutable $value): self + { + $this->ifModifiedSince = $value; + + return $this; + } + + public function setIfNoneMatch(?string $value): self + { + $this->ifNoneMatch = $value; + + return $this; + } + + public function setIfUnmodifiedSince(?\DateTimeImmutable $value): self + { + $this->ifUnmodifiedSince = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setPartNumber(?int $value): self + { + $this->partNumber = $value; + + return $this; + } + + public function setRange(?string $value): self + { + $this->range = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setResponseCacheControl(?string $value): self + { + $this->responseCacheControl = $value; + + return $this; + } + + public function setResponseContentDisposition(?string $value): self + { + $this->responseContentDisposition = $value; + + return $this; + } + + public function setResponseContentEncoding(?string $value): self + { + $this->responseContentEncoding = $value; + + return $this; + } + + public function setResponseContentLanguage(?string $value): self + { + $this->responseContentLanguage = $value; + + return $this; + } + + public function setResponseContentType(?string $value): self + { + $this->responseContentType = $value; + + return $this; + } + + public function setResponseExpires(?\DateTimeImmutable $value): self + { + $this->responseExpires = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php b/vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php new file mode 100644 index 000000000..8d049b9d3 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php @@ -0,0 +1,207 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|GetObjectTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?tagging'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/HeadBucketRequest.php b/vendor/async-aws/s3/src/Input/HeadBucketRequest.php new file mode 100644 index 000000000..9e0482853 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/HeadBucketRequest.php @@ -0,0 +1,127 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|HeadBucketRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('HEAD', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/HeadObjectRequest.php b/vendor/async-aws/s3/src/Input/HeadObjectRequest.php new file mode 100644 index 000000000..ee4055e67 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/HeadObjectRequest.php @@ -0,0 +1,480 @@ +bucket = $input['Bucket'] ?? null; + $this->ifMatch = $input['IfMatch'] ?? null; + $this->ifModifiedSince = !isset($input['IfModifiedSince']) ? null : ($input['IfModifiedSince'] instanceof \DateTimeImmutable ? $input['IfModifiedSince'] : new \DateTimeImmutable($input['IfModifiedSince'])); + $this->ifNoneMatch = $input['IfNoneMatch'] ?? null; + $this->ifUnmodifiedSince = !isset($input['IfUnmodifiedSince']) ? null : ($input['IfUnmodifiedSince'] instanceof \DateTimeImmutable ? $input['IfUnmodifiedSince'] : new \DateTimeImmutable($input['IfUnmodifiedSince'])); + $this->key = $input['Key'] ?? null; + $this->range = $input['Range'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumMode = $input['ChecksumMode'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key?: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumMode::*|null + */ + public function getChecksumMode(): ?string + { + return $this->checksumMode; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getIfMatch(): ?string + { + return $this->ifMatch; + } + + public function getIfModifiedSince(): ?\DateTimeImmutable + { + return $this->ifModifiedSince; + } + + public function getIfNoneMatch(): ?string + { + return $this->ifNoneMatch; + } + + public function getIfUnmodifiedSince(): ?\DateTimeImmutable + { + return $this->ifUnmodifiedSince; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + public function getRange(): ?string + { + return $this->range; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->ifMatch) { + $headers['If-Match'] = $this->ifMatch; + } + if (null !== $this->ifModifiedSince) { + $headers['If-Modified-Since'] = $this->ifModifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->ifNoneMatch) { + $headers['If-None-Match'] = $this->ifNoneMatch; + } + if (null !== $this->ifUnmodifiedSince) { + $headers['If-Unmodified-Since'] = $this->ifUnmodifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->range) { + $headers['Range'] = $this->range; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumMode) { + if (!ChecksumMode::exists($this->checksumMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumMode" for "%s". The value "%s" is not a valid "ChecksumMode".', __CLASS__, $this->checksumMode)); + } + $headers['x-amz-checksum-mode'] = $this->checksumMode; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + if (null !== $this->partNumber) { + $query['partNumber'] = (string) $this->partNumber; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('HEAD', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumMode::*|null $value + */ + public function setChecksumMode(?string $value): self + { + $this->checksumMode = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setIfMatch(?string $value): self + { + $this->ifMatch = $value; + + return $this; + } + + public function setIfModifiedSince(?\DateTimeImmutable $value): self + { + $this->ifModifiedSince = $value; + + return $this; + } + + public function setIfNoneMatch(?string $value): self + { + $this->ifNoneMatch = $value; + + return $this; + } + + public function setIfUnmodifiedSince(?\DateTimeImmutable $value): self + { + $this->ifUnmodifiedSince = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setPartNumber(?int $value): self + { + $this->partNumber = $value; + + return $this; + } + + public function setRange(?string $value): self + { + $this->range = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/ListBucketsRequest.php b/vendor/async-aws/s3/src/Input/ListBucketsRequest.php new file mode 100644 index 000000000..43ae23b87 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListBucketsRequest.php @@ -0,0 +1,51 @@ + 'application/xml']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } +} diff --git a/vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php b/vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php new file mode 100644 index 000000000..a1e0c7c48 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php @@ -0,0 +1,329 @@ +bucket = $input['Bucket'] ?? null; + $this->delimiter = $input['Delimiter'] ?? null; + $this->encodingType = $input['EncodingType'] ?? null; + $this->keyMarker = $input['KeyMarker'] ?? null; + $this->maxUploads = $input['MaxUploads'] ?? null; + $this->prefix = $input['Prefix'] ?? null; + $this->uploadIdMarker = $input['UploadIdMarker'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * KeyMarker?: string, + * MaxUploads?: int, + * Prefix?: string, + * UploadIdMarker?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|ListMultipartUploadsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getDelimiter(): ?string + { + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + return $this->encodingType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKeyMarker(): ?string + { + return $this->keyMarker; + } + + public function getMaxUploads(): ?int + { + return $this->maxUploads; + } + + public function getPrefix(): ?string + { + return $this->prefix; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getUploadIdMarker(): ?string + { + return $this->uploadIdMarker; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + + // Prepare query + $query = []; + if (null !== $this->delimiter) { + $query['delimiter'] = $this->delimiter; + } + if (null !== $this->encodingType) { + if (!EncodingType::exists($this->encodingType)) { + throw new InvalidArgument(sprintf('Invalid parameter "EncodingType" for "%s". The value "%s" is not a valid "EncodingType".', __CLASS__, $this->encodingType)); + } + $query['encoding-type'] = $this->encodingType; + } + if (null !== $this->keyMarker) { + $query['key-marker'] = $this->keyMarker; + } + if (null !== $this->maxUploads) { + $query['max-uploads'] = (string) $this->maxUploads; + } + if (null !== $this->prefix) { + $query['prefix'] = $this->prefix; + } + if (null !== $this->uploadIdMarker) { + $query['upload-id-marker'] = $this->uploadIdMarker; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?uploads'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setDelimiter(?string $value): self + { + $this->delimiter = $value; + + return $this; + } + + /** + * @param EncodingType::*|null $value + */ + public function setEncodingType(?string $value): self + { + $this->encodingType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKeyMarker(?string $value): self + { + $this->keyMarker = $value; + + return $this; + } + + public function setMaxUploads(?int $value): self + { + $this->maxUploads = $value; + + return $this; + } + + public function setPrefix(?string $value): self + { + $this->prefix = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setUploadIdMarker(?string $value): self + { + $this->uploadIdMarker = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/ListObjectsV2Request.php b/vendor/async-aws/s3/src/Input/ListObjectsV2Request.php new file mode 100644 index 000000000..6c84410bb --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListObjectsV2Request.php @@ -0,0 +1,386 @@ +|null + */ + private $optionalObjectAttributes; + + /** + * @param array{ + * Bucket?: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * MaxKeys?: int, + * Prefix?: string, + * ContinuationToken?: string, + * FetchOwner?: bool, + * StartAfter?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * OptionalObjectAttributes?: array, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->bucket = $input['Bucket'] ?? null; + $this->delimiter = $input['Delimiter'] ?? null; + $this->encodingType = $input['EncodingType'] ?? null; + $this->maxKeys = $input['MaxKeys'] ?? null; + $this->prefix = $input['Prefix'] ?? null; + $this->continuationToken = $input['ContinuationToken'] ?? null; + $this->fetchOwner = $input['FetchOwner'] ?? null; + $this->startAfter = $input['StartAfter'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->optionalObjectAttributes = $input['OptionalObjectAttributes'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * MaxKeys?: int, + * Prefix?: string, + * ContinuationToken?: string, + * FetchOwner?: bool, + * StartAfter?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * OptionalObjectAttributes?: array, + * '@region'?: string|null, + * }|ListObjectsV2Request $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getContinuationToken(): ?string + { + return $this->continuationToken; + } + + public function getDelimiter(): ?string + { + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + return $this->encodingType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getFetchOwner(): ?bool + { + return $this->fetchOwner; + } + + public function getMaxKeys(): ?int + { + return $this->maxKeys; + } + + /** + * @return list + */ + public function getOptionalObjectAttributes(): array + { + return $this->optionalObjectAttributes ?? []; + } + + public function getPrefix(): ?string + { + return $this->prefix; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getStartAfter(): ?string + { + return $this->startAfter; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->optionalObjectAttributes) { + $items = []; + foreach ($this->optionalObjectAttributes as $value) { + if (!OptionalObjectAttributes::exists($value)) { + throw new InvalidArgument(sprintf('Invalid parameter "OptionalObjectAttributes" for "%s". The value "%s" is not a valid "OptionalObjectAttributes".', __CLASS__, $value)); + } + $items[] = $value; + } + $headers['x-amz-optional-object-attributes'] = implode(',', $items); + } + + // Prepare query + $query = []; + if (null !== $this->delimiter) { + $query['delimiter'] = $this->delimiter; + } + if (null !== $this->encodingType) { + if (!EncodingType::exists($this->encodingType)) { + throw new InvalidArgument(sprintf('Invalid parameter "EncodingType" for "%s". The value "%s" is not a valid "EncodingType".', __CLASS__, $this->encodingType)); + } + $query['encoding-type'] = $this->encodingType; + } + if (null !== $this->maxKeys) { + $query['max-keys'] = (string) $this->maxKeys; + } + if (null !== $this->prefix) { + $query['prefix'] = $this->prefix; + } + if (null !== $this->continuationToken) { + $query['continuation-token'] = $this->continuationToken; + } + if (null !== $this->fetchOwner) { + $query['fetch-owner'] = $this->fetchOwner ? 'true' : 'false'; + } + if (null !== $this->startAfter) { + $query['start-after'] = $this->startAfter; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?list-type=2'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setContinuationToken(?string $value): self + { + $this->continuationToken = $value; + + return $this; + } + + public function setDelimiter(?string $value): self + { + $this->delimiter = $value; + + return $this; + } + + /** + * @param EncodingType::*|null $value + */ + public function setEncodingType(?string $value): self + { + $this->encodingType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setFetchOwner(?bool $value): self + { + $this->fetchOwner = $value; + + return $this; + } + + public function setMaxKeys(?int $value): self + { + $this->maxKeys = $value; + + return $this; + } + + /** + * @param list $value + */ + public function setOptionalObjectAttributes(array $value): self + { + $this->optionalObjectAttributes = $value; + + return $this; + } + + public function setPrefix(?string $value): self + { + $this->prefix = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setStartAfter(?string $value): self + { + $this->startAfter = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/ListPartsRequest.php b/vendor/async-aws/s3/src/Input/ListPartsRequest.php new file mode 100644 index 000000000..a1ed7e19f --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListPartsRequest.php @@ -0,0 +1,347 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->maxParts = $input['MaxParts'] ?? null; + $this->partNumberMarker = $input['PartNumberMarker'] ?? null; + $this->uploadId = $input['UploadId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * MaxParts?: int, + * PartNumberMarker?: int, + * UploadId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|ListPartsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMaxParts(): ?int + { + return $this->maxParts; + } + + public function getPartNumberMarker(): ?int + { + return $this->partNumberMarker; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + + // Prepare query + $query = []; + if (null !== $this->maxParts) { + $query['max-parts'] = (string) $this->maxParts; + } + if (null !== $this->partNumberMarker) { + $query['part-number-marker'] = (string) $this->partNumberMarker; + } + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setMaxParts(?int $value): self + { + $this->maxParts = $value; + + return $this; + } + + public function setPartNumberMarker(?int $value): self + { + $this->partNumberMarker = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php b/vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php new file mode 100644 index 000000000..38f97b891 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php @@ -0,0 +1,223 @@ +bucket = $input['Bucket'] ?? null; + $this->corsConfiguration = isset($input['CORSConfiguration']) ? CORSConfiguration::create($input['CORSConfiguration']) : null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * CORSConfiguration?: CORSConfiguration|array, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketCorsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getCorsConfiguration(): ?CORSConfiguration + { + return $this->corsConfiguration; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?cors'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setCorsConfiguration(?CORSConfiguration $value): self + { + $this->corsConfiguration = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->corsConfiguration) { + throw new InvalidArgument(sprintf('Missing parameter "CORSConfiguration" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('CORSConfiguration')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php b/vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php new file mode 100644 index 000000000..0e56aba11 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php @@ -0,0 +1,170 @@ +bucket = $input['Bucket'] ?? null; + $this->notificationConfiguration = isset($input['NotificationConfiguration']) ? NotificationConfiguration::create($input['NotificationConfiguration']) : null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->skipDestinationValidation = $input['SkipDestinationValidation'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * NotificationConfiguration?: NotificationConfiguration|array, + * ExpectedBucketOwner?: string, + * SkipDestinationValidation?: bool, + * '@region'?: string|null, + * }|PutBucketNotificationConfigurationRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getNotificationConfiguration(): ?NotificationConfiguration + { + return $this->notificationConfiguration; + } + + public function getSkipDestinationValidation(): ?bool + { + return $this->skipDestinationValidation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->skipDestinationValidation) { + $headers['x-amz-skip-destination-validation'] = $this->skipDestinationValidation ? 'true' : 'false'; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?notification'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setNotificationConfiguration(?NotificationConfiguration $value): self + { + $this->notificationConfiguration = $value; + + return $this; + } + + public function setSkipDestinationValidation(?bool $value): self + { + $this->skipDestinationValidation = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->notificationConfiguration) { + throw new InvalidArgument(sprintf('Missing parameter "NotificationConfiguration" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('NotificationConfiguration')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php b/vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php new file mode 100644 index 000000000..23ce581ef --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php @@ -0,0 +1,221 @@ +bucket = $input['Bucket'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->tagging = isset($input['Tagging']) ? Tagging::create($input['Tagging']) : null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging?: Tagging|array, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getTagging(): ?Tagging + { + return $this->tagging; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?tagging'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setTagging(?Tagging $value): self + { + $this->tagging = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->tagging) { + throw new InvalidArgument(sprintf('Missing parameter "Tagging" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('Tagging')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/PutObjectAclRequest.php b/vendor/async-aws/s3/src/Input/PutObjectAclRequest.php new file mode 100644 index 000000000..d9022f361 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutObjectAclRequest.php @@ -0,0 +1,497 @@ + [^1]. + * + * For requests made using the Amazon Web Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field + * is calculated automatically. + * + * [^1]: http://www.ietf.org/rfc/rfc1864.txt + * + * @var string|null + */ + private $contentMd5; + + /** + * Indicates the algorithm used to create the checksum for the object when using the SDK. This header will not provide + * any additional functionality if not using the SDK. When sending this header, there must be a corresponding + * `x-amz-checksum` or `x-amz-trailer` header sent. Otherwise, Amazon S3 fails the request with the HTTP status code + * `400 Bad Request`. For more information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * If you provide an individual checksum, Amazon S3 ignores any provided `ChecksumAlgorithm` parameter. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * Allows grantee the read, write, read ACP, and write ACP permissions on the bucket. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantFullControl; + + /** + * Allows grantee to list the objects in the bucket. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantRead; + + /** + * Allows grantee to read the bucket ACL. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantReadAcp; + + /** + * Allows grantee to create new objects in the bucket. + * + * For the bucket and object owners of existing objects, also allows deletions and overwrites of those objects. + * + * @var string|null + */ + private $grantWrite; + + /** + * Allows grantee to write the ACL for the applicable bucket. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantWriteAcp; + + /** + * Key for which the PUT action was initiated. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @required + * + * @var string|null + */ + private $key; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * VersionId used to reference a specific version of the object. + * + * @var string|null + */ + private $versionId; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * AccessControlPolicy?: AccessControlPolicy|array, + * Bucket?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * Key?: string, + * RequestPayer?: RequestPayer::*, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->accessControlPolicy = isset($input['AccessControlPolicy']) ? AccessControlPolicy::create($input['AccessControlPolicy']) : null; + $this->bucket = $input['Bucket'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWrite = $input['GrantWrite'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * AccessControlPolicy?: AccessControlPolicy|array, + * Bucket?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * Key?: string, + * RequestPayer?: RequestPayer::*, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectAclRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getAccessControlPolicy(): ?AccessControlPolicy + { + return $this->accessControlPolicy; + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWrite(): ?string + { + return $this->grantWrite; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWrite) { + $headers['x-amz-grant-write'] = $this->grantWrite; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?acl'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setAccessControlPolicy(?AccessControlPolicy $value): self + { + $this->accessControlPolicy = $value; + + return $this; + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWrite(?string $value): self + { + $this->grantWrite = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null !== $v = $this->accessControlPolicy) { + $node->appendChild($child = $document->createElement('AccessControlPolicy')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/Input/PutObjectRequest.php b/vendor/async-aws/s3/src/Input/PutObjectRequest.php new file mode 100644 index 000000000..b500f7755 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutObjectRequest.php @@ -0,0 +1,1178 @@ +|null + */ + private $body; + + /** + * The bucket name to which the PUT action was initiated. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @required + * + * @var string|null + */ + private $bucket; + + /** + * Can be used to specify caching behavior along the request/reply chain. For more information, see + * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 [^1]. + * + * [^1]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 + * + * @var string|null + */ + private $cacheControl; + + /** + * Specifies presentational information for the object. For more information, see + * https://www.rfc-editor.org/rfc/rfc6266#section-4 [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc6266#section-4 + * + * @var string|null + */ + private $contentDisposition; + + /** + * Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied to + * obtain the media-type referenced by the Content-Type header field. For more information, see + * https://www.rfc-editor.org/rfc/rfc9110.html#field.content-encoding [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-encoding + * + * @var string|null + */ + private $contentEncoding; + + /** + * The language the content is in. + * + * @var string|null + */ + private $contentLanguage; + + /** + * Size of the body in bytes. This parameter is useful when the size of the body cannot be determined automatically. For + * more information, see https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length + * + * @var int|null + */ + private $contentLength; + + /** + * The base64-encoded 128-bit MD5 digest of the message (without the headers) according to RFC 1864. This header can be + * used as a message integrity check to verify that the data is the same data that was originally sent. Although it is + * optional, we recommend using the Content-MD5 mechanism as an end-to-end integrity check. For more information about + * REST request authentication, see REST Authentication [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html + * + * @var string|null + */ + private $contentMd5; + + /** + * A standard MIME type describing the format of the contents. For more information, see + * https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type + * + * @var string|null + */ + private $contentType; + + /** + * Indicates the algorithm used to create the checksum for the object when using the SDK. This header will not provide + * any additional functionality if not using the SDK. When sending this header, there must be a corresponding + * `x-amz-checksum` or `x-amz-trailer` header sent. Otherwise, Amazon S3 fails the request with the HTTP status code + * `400 Bad Request`. For more information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * If you provide an individual checksum, Amazon S3 ignores any provided `ChecksumAlgorithm` parameter. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32 checksum of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32C checksum of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32C; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 160-bit SHA-1 digest of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha1; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 256-bit SHA-256 digest of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha256; + + /** + * The date and time at which the object is no longer cacheable. For more information, see + * https://www.rfc-editor.org/rfc/rfc7234#section-5.3 [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc7234#section-5.3 + * + * @var \DateTimeImmutable|null + */ + private $expires; + + /** + * Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantFullControl; + + /** + * Allows grantee to read the object data and its metadata. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantRead; + + /** + * Allows grantee to read the object ACL. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantReadAcp; + + /** + * Allows grantee to write the ACL for the applicable object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantWriteAcp; + + /** + * Object key for which the PUT action was initiated. + * + * @required + * + * @var string|null + */ + private $key; + + /** + * A map of metadata to store with the object in S3. + * + * @var array|null + */ + private $metadata; + + /** + * The server-side encryption algorithm used when storing this object in Amazon S3 (for example, `AES256`, `aws:kms`, + * `aws:kms:dsse`). + * + * @var ServerSideEncryption::*|null + */ + private $serverSideEncryption; + + /** + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^1] in + * the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * If the bucket is configured as a website, redirects requests for this object to another object in the same bucket or + * to an external URL. Amazon S3 stores the value of this header in the object metadata. For information about object + * metadata, see Object Key and Metadata [^1]. + * + * In the following example, the request header sets the redirect to an object (anotherPage.html) in the same bucket: + * + * `x-amz-website-redirect-location: /anotherPage.html` + * + * In the following example, the request header sets the object redirect to another website: + * + * `x-amz-website-redirect-location: http://www.example.com/` + * + * For more information about website hosting in Amazon S3, see Hosting Websites on Amazon S3 [^2] and How to Configure + * Website Page Redirects [^3]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html + * + * @var string|null + */ + private $websiteRedirectLocation; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * If `x-amz-server-side-encryption` has a valid value of `aws:kms` or `aws:kms:dsse`, this header specifies the ID of + * the Key Management Service (KMS) symmetric encryption customer managed key that was used for the object. If you + * specify `x-amz-server-side-encryption:aws:kms` or `x-amz-server-side-encryption:aws:kms:dsse`, but do not provide` + * x-amz-server-side-encryption-aws-kms-key-id`, Amazon S3 uses the Amazon Web Services managed key (`aws/s3`) to + * protect the data. If the KMS key does not exist in the same account that's issuing the command, you must use the full + * ARN and not just the ID. + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Specifies the Amazon Web Services KMS Encryption Context to use for object encryption. The value of this header is a + * base64-encoded UTF-8 string holding JSON with the encryption context key-value pairs. This value is stored as object + * metadata and automatically gets passed on to Amazon Web Services KMS for future `GetObject` or `CopyObject` + * operations on this object. + * + * @var string|null + */ + private $sseKmsEncryptionContext; + + /** + * Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption with server-side encryption using Key + * Management Service (KMS) keys (SSE-KMS). Setting this header to `true` causes Amazon S3 to use an S3 Bucket Key for + * object encryption with SSE-KMS. + * + * Specifying this header with a PUT action doesn’t affect bucket-level settings for S3 Bucket Key. + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The tag-set for the object. The tag-set must be encoded as URL Query parameters. (For example, "Key1=Value1"). + * + * @var string|null + */ + private $tagging; + + /** + * The Object Lock mode that you want to apply to this object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when you want this object's Object Lock to expire. Must be formatted as a timestamp parameter. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether a legal hold will be applied to this object. For more information about S3 Object Lock, see Object + * Lock [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ContentType?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->body = $input['Body'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->cacheControl = $input['CacheControl'] ?? null; + $this->contentDisposition = $input['ContentDisposition'] ?? null; + $this->contentEncoding = $input['ContentEncoding'] ?? null; + $this->contentLanguage = $input['ContentLanguage'] ?? null; + $this->contentLength = $input['ContentLength'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->contentType = $input['ContentType'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->expires = !isset($input['Expires']) ? null : ($input['Expires'] instanceof \DateTimeImmutable ? $input['Expires'] : new \DateTimeImmutable($input['Expires'])); + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->metadata = $input['Metadata'] ?? null; + $this->serverSideEncryption = $input['ServerSideEncryption'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->websiteRedirectLocation = $input['WebsiteRedirectLocation'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->sseKmsKeyId = $input['SSEKMSKeyId'] ?? null; + $this->sseKmsEncryptionContext = $input['SSEKMSEncryptionContext'] ?? null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->tagging = $input['Tagging'] ?? null; + $this->objectLockMode = $input['ObjectLockMode'] ?? null; + $this->objectLockRetainUntilDate = !isset($input['ObjectLockRetainUntilDate']) ? null : ($input['ObjectLockRetainUntilDate'] instanceof \DateTimeImmutable ? $input['ObjectLockRetainUntilDate'] : new \DateTimeImmutable($input['ObjectLockRetainUntilDate'])); + $this->objectLockLegalHoldStatus = $input['ObjectLockLegalHoldStatus'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ContentType?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + /** + * @return string|resource|(callable(int): string)|iterable|null + */ + public function getBody() + { + return $this->body; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + return $this->cacheControl; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getContentDisposition(): ?string + { + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + return $this->contentLanguage; + } + + public function getContentLength(): ?int + { + return $this->contentLength; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getContentType(): ?string + { + return $this->contentType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getExpires(): ?\DateTimeImmutable + { + return $this->expires; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata ?? []; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + return $this->objectLockRetainUntilDate; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getTagging(): ?string + { + return $this->tagging; + } + + public function getWebsiteRedirectLocation(): ?string + { + return $this->websiteRedirectLocation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = []; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->cacheControl) { + $headers['Cache-Control'] = $this->cacheControl; + } + if (null !== $this->contentDisposition) { + $headers['Content-Disposition'] = $this->contentDisposition; + } + if (null !== $this->contentEncoding) { + $headers['Content-Encoding'] = $this->contentEncoding; + } + if (null !== $this->contentLanguage) { + $headers['Content-Language'] = $this->contentLanguage; + } + if (null !== $this->contentLength) { + $headers['Content-Length'] = (string) $this->contentLength; + } + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->contentType) { + $headers['Content-Type'] = $this->contentType; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->checksumCrc32) { + $headers['x-amz-checksum-crc32'] = $this->checksumCrc32; + } + if (null !== $this->checksumCrc32C) { + $headers['x-amz-checksum-crc32c'] = $this->checksumCrc32C; + } + if (null !== $this->checksumSha1) { + $headers['x-amz-checksum-sha1'] = $this->checksumSha1; + } + if (null !== $this->checksumSha256) { + $headers['x-amz-checksum-sha256'] = $this->checksumSha256; + } + if (null !== $this->expires) { + $headers['Expires'] = $this->expires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->serverSideEncryption) { + if (!ServerSideEncryption::exists($this->serverSideEncryption)) { + throw new InvalidArgument(sprintf('Invalid parameter "ServerSideEncryption" for "%s". The value "%s" is not a valid "ServerSideEncryption".', __CLASS__, $this->serverSideEncryption)); + } + $headers['x-amz-server-side-encryption'] = $this->serverSideEncryption; + } + if (null !== $this->storageClass) { + if (!StorageClass::exists($this->storageClass)) { + throw new InvalidArgument(sprintf('Invalid parameter "StorageClass" for "%s". The value "%s" is not a valid "StorageClass".', __CLASS__, $this->storageClass)); + } + $headers['x-amz-storage-class'] = $this->storageClass; + } + if (null !== $this->websiteRedirectLocation) { + $headers['x-amz-website-redirect-location'] = $this->websiteRedirectLocation; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->sseKmsKeyId) { + $headers['x-amz-server-side-encryption-aws-kms-key-id'] = $this->sseKmsKeyId; + } + if (null !== $this->sseKmsEncryptionContext) { + $headers['x-amz-server-side-encryption-context'] = $this->sseKmsEncryptionContext; + } + if (null !== $this->bucketKeyEnabled) { + $headers['x-amz-server-side-encryption-bucket-key-enabled'] = $this->bucketKeyEnabled ? 'true' : 'false'; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->tagging) { + $headers['x-amz-tagging'] = $this->tagging; + } + if (null !== $this->objectLockMode) { + if (!ObjectLockMode::exists($this->objectLockMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockMode" for "%s". The value "%s" is not a valid "ObjectLockMode".', __CLASS__, $this->objectLockMode)); + } + $headers['x-amz-object-lock-mode'] = $this->objectLockMode; + } + if (null !== $this->objectLockRetainUntilDate) { + $headers['x-amz-object-lock-retain-until-date'] = $this->objectLockRetainUntilDate->format(\DateTimeInterface::ISO8601); + } + if (null !== $this->objectLockLegalHoldStatus) { + if (!ObjectLockLegalHoldStatus::exists($this->objectLockLegalHoldStatus)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockLegalHoldStatus" for "%s". The value "%s" is not a valid "ObjectLockLegalHoldStatus".', __CLASS__, $this->objectLockLegalHoldStatus)); + } + $headers['x-amz-object-lock-legal-hold'] = $this->objectLockLegalHoldStatus; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->metadata) { + foreach ($this->metadata as $key => $value) { + $headers["x-amz-meta-$key"] = $value; + } + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = $this->body ?? ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + /** + * @param string|resource|(callable(int): string)|iterable|null $value + */ + public function setBody($value): self + { + $this->body = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBucketKeyEnabled(?bool $value): self + { + $this->bucketKeyEnabled = $value; + + return $this; + } + + public function setCacheControl(?string $value): self + { + $this->cacheControl = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setChecksumCrc32(?string $value): self + { + $this->checksumCrc32 = $value; + + return $this; + } + + public function setChecksumCrc32C(?string $value): self + { + $this->checksumCrc32C = $value; + + return $this; + } + + public function setChecksumSha1(?string $value): self + { + $this->checksumSha1 = $value; + + return $this; + } + + public function setChecksumSha256(?string $value): self + { + $this->checksumSha256 = $value; + + return $this; + } + + public function setContentDisposition(?string $value): self + { + $this->contentDisposition = $value; + + return $this; + } + + public function setContentEncoding(?string $value): self + { + $this->contentEncoding = $value; + + return $this; + } + + public function setContentLanguage(?string $value): self + { + $this->contentLanguage = $value; + + return $this; + } + + public function setContentLength(?int $value): self + { + $this->contentLength = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setContentType(?string $value): self + { + $this->contentType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setExpires(?\DateTimeImmutable $value): self + { + $this->expires = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param array $value + */ + public function setMetadata(array $value): self + { + $this->metadata = $value; + + return $this; + } + + /** + * @param ObjectLockLegalHoldStatus::*|null $value + */ + public function setObjectLockLegalHoldStatus(?string $value): self + { + $this->objectLockLegalHoldStatus = $value; + + return $this; + } + + /** + * @param ObjectLockMode::*|null $value + */ + public function setObjectLockMode(?string $value): self + { + $this->objectLockMode = $value; + + return $this; + } + + public function setObjectLockRetainUntilDate(?\DateTimeImmutable $value): self + { + $this->objectLockRetainUntilDate = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + /** + * @param ServerSideEncryption::*|null $value + */ + public function setServerSideEncryption(?string $value): self + { + $this->serverSideEncryption = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setSseKmsEncryptionContext(?string $value): self + { + $this->sseKmsEncryptionContext = $value; + + return $this; + } + + public function setSseKmsKeyId(?string $value): self + { + $this->sseKmsKeyId = $value; + + return $this; + } + + /** + * @param StorageClass::*|null $value + */ + public function setStorageClass(?string $value): self + { + $this->storageClass = $value; + + return $this; + } + + public function setTagging(?string $value): self + { + $this->tagging = $value; + + return $this; + } + + public function setWebsiteRedirectLocation(?string $value): self + { + $this->websiteRedirectLocation = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php b/vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php new file mode 100644 index 000000000..ee14771a4 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php @@ -0,0 +1,318 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->tagging = isset($input['Tagging']) ? Tagging::create($input['Tagging']) : null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging?: Tagging|array, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|PutObjectTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getTagging(): ?Tagging + { + return $this->tagging; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?tagging'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setTagging(?Tagging $value): self + { + $this->tagging = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->tagging) { + throw new InvalidArgument(sprintf('Missing parameter "Tagging" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('Tagging')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/UploadPartRequest.php b/vendor/async-aws/s3/src/Input/UploadPartRequest.php new file mode 100644 index 000000000..7527d2181 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/UploadPartRequest.php @@ -0,0 +1,557 @@ +|null + */ + private $body; + + /** + * The name of the bucket to which the multipart upload was initiated. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @required + * + * @var string|null + */ + private $bucket; + + /** + * Size of the body in bytes. This parameter is useful when the size of the body cannot be determined automatically. + * + * @var int|null + */ + private $contentLength; + + /** + * The base64-encoded 128-bit MD5 digest of the part data. This parameter is auto-populated when using the command from + * the CLI. This parameter is required if object lock parameters are specified. + * + * @var string|null + */ + private $contentMd5; + + /** + * Indicates the algorithm used to create the checksum for the object when using the SDK. This header will not provide + * any additional functionality if not using the SDK. When sending this header, there must be a corresponding + * `x-amz-checksum` or `x-amz-trailer` header sent. Otherwise, Amazon S3 fails the request with the HTTP status code + * `400 Bad Request`. For more information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * If you provide an individual checksum, Amazon S3 ignores any provided `ChecksumAlgorithm` parameter. + * + * This checksum algorithm must be the same for all parts and it match the checksum value supplied in the + * `CreateMultipartUpload` request. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32 checksum of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32C checksum of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32C; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 160-bit SHA-1 digest of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha1; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 256-bit SHA-256 digest of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha256; + + /** + * Object key for which the multipart upload was initiated. + * + * @required + * + * @var string|null + */ + private $key; + + /** + * Part number of part being uploaded. This is a positive integer between 1 and 10,000. + * + * @required + * + * @var int|null + */ + private $partNumber; + + /** + * Upload ID identifying the multipart upload whose part is being uploaded. + * + * @required + * + * @var string|null + */ + private $uploadId; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm header`. This must be the same + * encryption key specified in the initiate multipart upload request. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * @param array{ + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Key?: string, + * PartNumber?: int, + * UploadId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->body = $input['Body'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->contentLength = $input['ContentLength'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->key = $input['Key'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + $this->uploadId = $input['UploadId'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Key?: string, + * PartNumber?: int, + * UploadId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|UploadPartRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return string|resource|(callable(int): string)|iterable|null + */ + public function getBody() + { + return $this->body; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getContentLength(): ?int + { + return $this->contentLength; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = []; + if (null !== $this->contentLength) { + $headers['Content-Length'] = (string) $this->contentLength; + } + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->checksumCrc32) { + $headers['x-amz-checksum-crc32'] = $this->checksumCrc32; + } + if (null !== $this->checksumCrc32C) { + $headers['x-amz-checksum-crc32c'] = $this->checksumCrc32C; + } + if (null !== $this->checksumSha1) { + $headers['x-amz-checksum-sha1'] = $this->checksumSha1; + } + if (null !== $this->checksumSha256) { + $headers['x-amz-checksum-sha256'] = $this->checksumSha256; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null === $v = $this->partNumber) { + throw new InvalidArgument(sprintf('Missing parameter "PartNumber" for "%s". The value cannot be null.', __CLASS__)); + } + $query['partNumber'] = (string) $v; + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = $this->body ?? ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param string|resource|(callable(int): string)|iterable|null $value + */ + public function setBody($value): self + { + $this->body = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setChecksumCrc32(?string $value): self + { + $this->checksumCrc32 = $value; + + return $this; + } + + public function setChecksumCrc32C(?string $value): self + { + $this->checksumCrc32C = $value; + + return $this; + } + + public function setChecksumSha1(?string $value): self + { + $this->checksumSha1 = $value; + + return $this; + } + + public function setChecksumSha256(?string $value): self + { + $this->checksumSha256 = $value; + + return $this; + } + + public function setContentLength(?int $value): self + { + $this->contentLength = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setPartNumber(?int $value): self + { + $this->partNumber = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php b/vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php new file mode 100644 index 000000000..efe26b296 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php @@ -0,0 +1,32 @@ +initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/BucketExistsWaiter.php b/vendor/async-aws/s3/src/Result/BucketExistsWaiter.php new file mode 100644 index 000000000..7da4bc784 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/BucketExistsWaiter.php @@ -0,0 +1,49 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (301 === $response->getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (403 === $response->getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (404 === $response->getStatusCode()) { + return self::STATE_PENDING; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadBucketRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->bucketExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php b/vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php new file mode 100644 index 000000000..a0d16cb56 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php @@ -0,0 +1,37 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadBucketRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->bucketNotExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php b/vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php new file mode 100644 index 000000000..9299b067a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php @@ -0,0 +1,273 @@ +initialize(); + + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + public function getKey(): ?string + { + $this->initialize(); + + return $this->key; + } + + public function getLocation(): ?string + { + $this->initialize(); + + return $this->location; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->location = ($v = $data->Location) ? (string) $v : null; + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->key = ($v = $data->Key) ? (string) $v : null; + $this->etag = ($v = $data->ETag) ? (string) $v : null; + $this->checksumCrc32 = ($v = $data->ChecksumCRC32) ? (string) $v : null; + $this->checksumCrc32C = ($v = $data->ChecksumCRC32C) ? (string) $v : null; + $this->checksumSha1 = ($v = $data->ChecksumSHA1) ? (string) $v : null; + $this->checksumSha256 = ($v = $data->ChecksumSHA256) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/s3/src/Result/CopyObjectOutput.php b/vendor/async-aws/s3/src/Result/CopyObjectOutput.php new file mode 100644 index 000000000..e518f272b --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CopyObjectOutput.php @@ -0,0 +1,202 @@ +initialize(); + + return $this->bucketKeyEnabled; + } + + public function getCopyObjectResult(): ?CopyObjectResult + { + $this->initialize(); + + return $this->copyObjectResult; + } + + public function getCopySourceVersionId(): ?string + { + $this->initialize(); + + return $this->copySourceVersionId; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + $this->initialize(); + + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->copySourceVersionId = $headers['x-amz-copy-source-version-id'][0] ?? null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->sseKmsEncryptionContext = $headers['x-amz-server-side-encryption-context'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->copyObjectResult = new CopyObjectResult([ + 'ETag' => ($v = $data->ETag) ? (string) $v : null, + 'LastModified' => ($v = $data->LastModified) ? new \DateTimeImmutable((string) $v) : null, + 'ChecksumCRC32' => ($v = $data->ChecksumCRC32) ? (string) $v : null, + 'ChecksumCRC32C' => ($v = $data->ChecksumCRC32C) ? (string) $v : null, + 'ChecksumSHA1' => ($v = $data->ChecksumSHA1) ? (string) $v : null, + 'ChecksumSHA256' => ($v = $data->ChecksumSHA256) ? (string) $v : null, + ]); + } +} diff --git a/vendor/async-aws/s3/src/Result/CreateBucketOutput.php b/vendor/async-aws/s3/src/Result/CreateBucketOutput.php new file mode 100644 index 000000000..441d7a2bf --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CreateBucketOutput.php @@ -0,0 +1,30 @@ +initialize(); + + return $this->location; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->location = $headers['location'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php b/vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php new file mode 100644 index 000000000..dbac5891a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php @@ -0,0 +1,251 @@ +initialize(); + + return $this->abortDate; + } + + public function getAbortRuleId(): ?string + { + $this->initialize(); + + return $this->abortRuleId; + } + + public function getBucket(): ?string + { + $this->initialize(); + + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + $this->initialize(); + + return $this->checksumAlgorithm; + } + + public function getKey(): ?string + { + $this->initialize(); + + return $this->key; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + $this->initialize(); + + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getUploadId(): ?string + { + $this->initialize(); + + return $this->uploadId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->abortDate = isset($headers['x-amz-abort-date'][0]) ? new \DateTimeImmutable($headers['x-amz-abort-date'][0]) : null; + $this->abortRuleId = $headers['x-amz-abort-rule-id'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->sseKmsEncryptionContext = $headers['x-amz-server-side-encryption-context'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + $this->checksumAlgorithm = $headers['x-amz-checksum-algorithm'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->key = ($v = $data->Key) ? (string) $v : null; + $this->uploadId = ($v = $data->UploadId) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/s3/src/Result/DeleteObjectOutput.php b/vendor/async-aws/s3/src/Result/DeleteObjectOutput.php new file mode 100644 index 000000000..f689fc1bf --- /dev/null +++ b/vendor/async-aws/s3/src/Result/DeleteObjectOutput.php @@ -0,0 +1,62 @@ +initialize(); + + return $this->deleteMarker; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->deleteMarker = isset($headers['x-amz-delete-marker'][0]) ? filter_var($headers['x-amz-delete-marker'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php b/vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php new file mode 100644 index 000000000..9b115a2a5 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php @@ -0,0 +1,30 @@ +initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php b/vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php new file mode 100644 index 000000000..a5988d4da --- /dev/null +++ b/vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php @@ -0,0 +1,109 @@ +initialize(); + + return $this->deleted; + } + + /** + * @return Error[] + */ + public function getErrors(): array + { + $this->initialize(); + + return $this->errors; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->deleted = !$data->Deleted ? [] : $this->populateResultDeletedObjects($data->Deleted); + $this->errors = !$data->Error ? [] : $this->populateResultErrors($data->Error); + } + + /** + * @return DeletedObject[] + */ + private function populateResultDeletedObjects(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new DeletedObject([ + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'VersionId' => ($v = $item->VersionId) ? (string) $v : null, + 'DeleteMarker' => ($v = $item->DeleteMarker) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, + 'DeleteMarkerVersionId' => ($v = $item->DeleteMarkerVersionId) ? (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return Error[] + */ + private function populateResultErrors(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new Error([ + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'VersionId' => ($v = $item->VersionId) ? (string) $v : null, + 'Code' => ($v = $item->Code) ? (string) $v : null, + 'Message' => ($v = $item->Message) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php b/vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php new file mode 100644 index 000000000..0c0f02ab6 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php @@ -0,0 +1,118 @@ +initialize(); + + return $this->corsRules; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $this->corsRules = !$data->CORSRule ? [] : $this->populateResultCORSRules($data->CORSRule); + } + + /** + * @return string[] + */ + private function populateResultAllowedHeaders(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return string[] + */ + private function populateResultAllowedMethods(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return string[] + */ + private function populateResultAllowedOrigins(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return CORSRule[] + */ + private function populateResultCORSRules(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new CORSRule([ + 'ID' => ($v = $item->ID) ? (string) $v : null, + 'AllowedHeaders' => !$item->AllowedHeader ? null : $this->populateResultAllowedHeaders($item->AllowedHeader), + 'AllowedMethods' => $this->populateResultAllowedMethods($item->AllowedMethod), + 'AllowedOrigins' => $this->populateResultAllowedOrigins($item->AllowedOrigin), + 'ExposeHeaders' => !$item->ExposeHeader ? null : $this->populateResultExposeHeaders($item->ExposeHeader), + 'MaxAgeSeconds' => ($v = $item->MaxAgeSeconds) ? (int) (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return string[] + */ + private function populateResultExposeHeaders(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php b/vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php new file mode 100644 index 000000000..ab48d8a70 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php @@ -0,0 +1,51 @@ +initialize(); + + return $this->serverSideEncryptionConfiguration; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $this->serverSideEncryptionConfiguration = new ServerSideEncryptionConfiguration([ + 'Rules' => $this->populateResultServerSideEncryptionRules($data->Rule), + ]); + } + + /** + * @return ServerSideEncryptionRule[] + */ + private function populateResultServerSideEncryptionRules(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new ServerSideEncryptionRule([ + 'ApplyServerSideEncryptionByDefault' => !$item->ApplyServerSideEncryptionByDefault ? null : new ServerSideEncryptionByDefault([ + 'SSEAlgorithm' => (string) $item->ApplyServerSideEncryptionByDefault->SSEAlgorithm, + 'KMSMasterKeyID' => ($v = $item->ApplyServerSideEncryptionByDefault->KMSMasterKeyID) ? (string) $v : null, + ]), + 'BucketKeyEnabled' => ($v = $item->BucketKeyEnabled) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetObjectAclOutput.php b/vendor/async-aws/s3/src/Result/GetObjectAclOutput.php new file mode 100644 index 000000000..2d58c6e4a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetObjectAclOutput.php @@ -0,0 +1,95 @@ +initialize(); + + return $this->grants; + } + + public function getOwner(): ?Owner + { + $this->initialize(); + + return $this->owner; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->owner = !$data->Owner ? null : new Owner([ + 'DisplayName' => ($v = $data->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $data->Owner->ID) ? (string) $v : null, + ]); + $this->grants = !$data->AccessControlList ? [] : $this->populateResultGrants($data->AccessControlList); + } + + /** + * @return Grant[] + */ + private function populateResultGrants(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml->Grant as $item) { + $items[] = new Grant([ + 'Grantee' => !$item->Grantee ? null : new Grantee([ + 'DisplayName' => ($v = $item->Grantee->DisplayName) ? (string) $v : null, + 'EmailAddress' => ($v = $item->Grantee->EmailAddress) ? (string) $v : null, + 'ID' => ($v = $item->Grantee->ID) ? (string) $v : null, + 'Type' => (string) ($item->Grantee->attributes('xsi', true)['type'][0] ?? null), + 'URI' => ($v = $item->Grantee->URI) ? (string) $v : null, + ]), + 'Permission' => ($v = $item->Permission) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetObjectOutput.php b/vendor/async-aws/s3/src/Result/GetObjectOutput.php new file mode 100644 index 000000000..f4251efc3 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetObjectOutput.php @@ -0,0 +1,621 @@ + + */ + private $metadata; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header confirming the encryption algorithm used. + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header to provide round-trip message integrity verification of the customer-provided encryption key. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * If present, specifies the ID of the Key Management Service (KMS) symmetric encryption customer managed key that was + * used for the object. + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Indicates whether the object uses an S3 Bucket Key for server-side encryption with Key Management Service (KMS) keys + * (SSE-KMS). + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * Provides storage class information of the object. Amazon S3 returns this header for all objects except for S3 + * Standard storage class objects. + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * Amazon S3 can return this if your request involves a bucket that is either a source or destination in a replication + * rule. + * + * @var ReplicationStatus::*|null + */ + private $replicationStatus; + + /** + * The count of parts this object has. This value is only returned if you specify `partNumber` in your request and the + * object was uploaded as a multipart upload. + * + * @var int|null + */ + private $partsCount; + + /** + * The number of tags, if any, on the object. + * + * @var int|null + */ + private $tagCount; + + /** + * The Object Lock mode currently in place for this object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when this object's Object Lock will expire. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Indicates whether this object has an active legal hold. This field is only returned if you have permission to view an + * object's legal hold status. + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + public function getAcceptRanges(): ?string + { + $this->initialize(); + + return $this->acceptRanges; + } + + public function getBody(): ResultStream + { + $this->initialize(); + + return $this->body; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + $this->initialize(); + + return $this->cacheControl; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getContentDisposition(): ?string + { + $this->initialize(); + + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + $this->initialize(); + + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + $this->initialize(); + + return $this->contentLanguage; + } + + public function getContentLength(): ?int + { + $this->initialize(); + + return $this->contentLength; + } + + public function getContentRange(): ?string + { + $this->initialize(); + + return $this->contentRange; + } + + public function getContentType(): ?string + { + $this->initialize(); + + return $this->contentType; + } + + public function getDeleteMarker(): ?bool + { + $this->initialize(); + + return $this->deleteMarker; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + public function getExpires(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->expires; + } + + public function getLastModified(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->lastModified; + } + + /** + * @return array + */ + public function getMetadata(): array + { + $this->initialize(); + + return $this->metadata; + } + + public function getMissingMeta(): ?int + { + $this->initialize(); + + return $this->missingMeta; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + $this->initialize(); + + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + $this->initialize(); + + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->objectLockRetainUntilDate; + } + + public function getPartsCount(): ?int + { + $this->initialize(); + + return $this->partsCount; + } + + /** + * @return ReplicationStatus::*|null + */ + public function getReplicationStatus(): ?string + { + $this->initialize(); + + return $this->replicationStatus; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getRestore(): ?string + { + $this->initialize(); + + return $this->restore; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + $this->initialize(); + + return $this->storageClass; + } + + public function getTagCount(): ?int + { + $this->initialize(); + + return $this->tagCount; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + public function getWebsiteRedirectLocation(): ?string + { + $this->initialize(); + + return $this->websiteRedirectLocation; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->deleteMarker = isset($headers['x-amz-delete-marker'][0]) ? filter_var($headers['x-amz-delete-marker'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->acceptRanges = $headers['accept-ranges'][0] ?? null; + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->restore = $headers['x-amz-restore'][0] ?? null; + $this->lastModified = isset($headers['last-modified'][0]) ? new \DateTimeImmutable($headers['last-modified'][0]) : null; + $this->contentLength = isset($headers['content-length'][0]) ? (int) $headers['content-length'][0] : null; + $this->etag = $headers['etag'][0] ?? null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->missingMeta = isset($headers['x-amz-missing-meta'][0]) ? (int) $headers['x-amz-missing-meta'][0] : null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->cacheControl = $headers['cache-control'][0] ?? null; + $this->contentDisposition = $headers['content-disposition'][0] ?? null; + $this->contentEncoding = $headers['content-encoding'][0] ?? null; + $this->contentLanguage = $headers['content-language'][0] ?? null; + $this->contentRange = $headers['content-range'][0] ?? null; + $this->contentType = $headers['content-type'][0] ?? null; + $this->expires = isset($headers['expires'][0]) ? new \DateTimeImmutable($headers['expires'][0]) : null; + $this->websiteRedirectLocation = $headers['x-amz-website-redirect-location'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->storageClass = $headers['x-amz-storage-class'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + $this->replicationStatus = $headers['x-amz-replication-status'][0] ?? null; + $this->partsCount = isset($headers['x-amz-mp-parts-count'][0]) ? (int) $headers['x-amz-mp-parts-count'][0] : null; + $this->tagCount = isset($headers['x-amz-tagging-count'][0]) ? (int) $headers['x-amz-tagging-count'][0] : null; + $this->objectLockMode = $headers['x-amz-object-lock-mode'][0] ?? null; + $this->objectLockRetainUntilDate = isset($headers['x-amz-object-lock-retain-until-date'][0]) ? new \DateTimeImmutable($headers['x-amz-object-lock-retain-until-date'][0]) : null; + $this->objectLockLegalHoldStatus = $headers['x-amz-object-lock-legal-hold'][0] ?? null; + + $this->metadata = []; + foreach ($headers as $name => $value) { + if ('x-amz-meta-' === substr($name, 0, 11)) { + $this->metadata[substr($name, 11)] = $value[0]; + } + } + + $this->body = $response->toStream(); + } +} diff --git a/vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php b/vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php new file mode 100644 index 000000000..d868b8aaf --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php @@ -0,0 +1,67 @@ +initialize(); + + return $this->tagSet; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->tagSet = $this->populateResultTagSet($data->TagSet); + } + + /** + * @return Tag[] + */ + private function populateResultTagSet(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml->Tag as $item) { + $items[] = new Tag([ + 'Key' => (string) $item->Key, + 'Value' => (string) $item->Value, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/HeadObjectOutput.php b/vendor/async-aws/s3/src/Result/HeadObjectOutput.php new file mode 100644 index 000000000..7e2f78f56 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/HeadObjectOutput.php @@ -0,0 +1,641 @@ + + */ + private $metadata; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header confirming the encryption algorithm used. + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header to provide round-trip message integrity verification of the customer-provided encryption key. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * If present, specifies the ID of the Key Management Service (KMS) symmetric encryption customer managed key that was + * used for the object. + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Indicates whether the object uses an S3 Bucket Key for server-side encryption with Key Management Service (KMS) keys + * (SSE-KMS). + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * Provides storage class information of the object. Amazon S3 returns this header for all objects except for S3 + * Standard storage class objects. + * + * For more information, see Storage Classes [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * Amazon S3 can return this header if your request involves a bucket that is either a source or a destination in a + * replication rule. + * + * In replication, you have a source bucket on which you configure replication and destination bucket or buckets where + * Amazon S3 stores object replicas. When you request an object (`GetObject`) or object metadata (`HeadObject`) from + * these buckets, Amazon S3 will return the `x-amz-replication-status` header in the response as follows: + * + * - **If requesting an object from the source bucket**, Amazon S3 will return the `x-amz-replication-status` header if + * the object in your request is eligible for replication. + * + * For example, suppose that in your replication configuration, you specify object prefix `TaxDocs` requesting Amazon + * S3 to replicate objects with key prefix `TaxDocs`. Any objects you upload with this key name prefix, for example + * `TaxDocs/document1.pdf`, are eligible for replication. For any object request with this key name prefix, Amazon S3 + * will return the `x-amz-replication-status` header with value PENDING, COMPLETED or FAILED indicating object + * replication status. + * - **If requesting an object from a destination bucket**, Amazon S3 will return the `x-amz-replication-status` header + * with value REPLICA if the object in your request is a replica that Amazon S3 created and there is no replica + * modification replication in progress. + * - **When replicating objects to multiple destination buckets**, the `x-amz-replication-status` header acts + * differently. The header of the source object will only return a value of COMPLETED when replication is successful + * to all destinations. The header will remain at value PENDING until replication has completed for all destinations. + * If one or more destinations fails replication the header will return FAILED. + * + * For more information, see Replication [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html + * + * @var ReplicationStatus::*|null + */ + private $replicationStatus; + + /** + * The count of parts this object has. This value is only returned if you specify `partNumber` in your request and the + * object was uploaded as a multipart upload. + * + * @var int|null + */ + private $partsCount; + + /** + * The Object Lock mode, if any, that's in effect for this object. This header is only returned if the requester has the + * `s3:GetObjectRetention` permission. For more information about S3 Object Lock, see Object Lock [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when the Object Lock retention period expires. This header is only returned if the requester has + * the `s3:GetObjectRetention` permission. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether a legal hold is in effect for this object. This header is only returned if the requester has the + * `s3:GetObjectLegalHold` permission. This header is not returned if the specified version of this object has never had + * a legal hold applied. For more information about S3 Object Lock, see Object Lock [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + public function getAcceptRanges(): ?string + { + $this->initialize(); + + return $this->acceptRanges; + } + + /** + * @return ArchiveStatus::*|null + */ + public function getArchiveStatus(): ?string + { + $this->initialize(); + + return $this->archiveStatus; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + $this->initialize(); + + return $this->cacheControl; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getContentDisposition(): ?string + { + $this->initialize(); + + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + $this->initialize(); + + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + $this->initialize(); + + return $this->contentLanguage; + } + + public function getContentLength(): ?int + { + $this->initialize(); + + return $this->contentLength; + } + + public function getContentType(): ?string + { + $this->initialize(); + + return $this->contentType; + } + + public function getDeleteMarker(): ?bool + { + $this->initialize(); + + return $this->deleteMarker; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + public function getExpires(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->expires; + } + + public function getLastModified(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->lastModified; + } + + /** + * @return array + */ + public function getMetadata(): array + { + $this->initialize(); + + return $this->metadata; + } + + public function getMissingMeta(): ?int + { + $this->initialize(); + + return $this->missingMeta; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + $this->initialize(); + + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + $this->initialize(); + + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->objectLockRetainUntilDate; + } + + public function getPartsCount(): ?int + { + $this->initialize(); + + return $this->partsCount; + } + + /** + * @return ReplicationStatus::*|null + */ + public function getReplicationStatus(): ?string + { + $this->initialize(); + + return $this->replicationStatus; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getRestore(): ?string + { + $this->initialize(); + + return $this->restore; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + $this->initialize(); + + return $this->storageClass; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + public function getWebsiteRedirectLocation(): ?string + { + $this->initialize(); + + return $this->websiteRedirectLocation; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->deleteMarker = isset($headers['x-amz-delete-marker'][0]) ? filter_var($headers['x-amz-delete-marker'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->acceptRanges = $headers['accept-ranges'][0] ?? null; + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->restore = $headers['x-amz-restore'][0] ?? null; + $this->archiveStatus = $headers['x-amz-archive-status'][0] ?? null; + $this->lastModified = isset($headers['last-modified'][0]) ? new \DateTimeImmutable($headers['last-modified'][0]) : null; + $this->contentLength = isset($headers['content-length'][0]) ? (int) $headers['content-length'][0] : null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->etag = $headers['etag'][0] ?? null; + $this->missingMeta = isset($headers['x-amz-missing-meta'][0]) ? (int) $headers['x-amz-missing-meta'][0] : null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->cacheControl = $headers['cache-control'][0] ?? null; + $this->contentDisposition = $headers['content-disposition'][0] ?? null; + $this->contentEncoding = $headers['content-encoding'][0] ?? null; + $this->contentLanguage = $headers['content-language'][0] ?? null; + $this->contentType = $headers['content-type'][0] ?? null; + $this->expires = isset($headers['expires'][0]) ? new \DateTimeImmutable($headers['expires'][0]) : null; + $this->websiteRedirectLocation = $headers['x-amz-website-redirect-location'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->storageClass = $headers['x-amz-storage-class'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + $this->replicationStatus = $headers['x-amz-replication-status'][0] ?? null; + $this->partsCount = isset($headers['x-amz-mp-parts-count'][0]) ? (int) $headers['x-amz-mp-parts-count'][0] : null; + $this->objectLockMode = $headers['x-amz-object-lock-mode'][0] ?? null; + $this->objectLockRetainUntilDate = isset($headers['x-amz-object-lock-retain-until-date'][0]) ? new \DateTimeImmutable($headers['x-amz-object-lock-retain-until-date'][0]) : null; + $this->objectLockLegalHoldStatus = $headers['x-amz-object-lock-legal-hold'][0] ?? null; + + $this->metadata = []; + foreach ($headers as $name => $value) { + if ('x-amz-meta-' === substr($name, 0, 11)) { + $this->metadata[substr($name, 11)] = $value[0]; + } + } + } +} diff --git a/vendor/async-aws/s3/src/Result/ListBucketsOutput.php b/vendor/async-aws/s3/src/Result/ListBucketsOutput.php new file mode 100644 index 000000000..a9126636d --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListBucketsOutput.php @@ -0,0 +1,81 @@ + + */ +class ListBucketsOutput extends Result implements \IteratorAggregate +{ + /** + * The list of buckets owned by the requester. + * + * @var Bucket[] + */ + private $buckets; + + /** + * The owner of the buckets listed. + * + * @var Owner|null + */ + private $owner; + + /** + * @return iterable + */ + public function getBuckets(): iterable + { + $this->initialize(); + + return $this->buckets; + } + + /** + * Iterates over Buckets. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + yield from $this->getBuckets(); + } + + public function getOwner(): ?Owner + { + $this->initialize(); + + return $this->owner; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $this->buckets = !$data->Buckets ? [] : $this->populateResultBuckets($data->Buckets); + $this->owner = !$data->Owner ? null : new Owner([ + 'DisplayName' => ($v = $data->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $data->Owner->ID) ? (string) $v : null, + ]); + } + + /** + * @return Bucket[] + */ + private function populateResultBuckets(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml->Bucket as $item) { + $items[] = new Bucket([ + 'Name' => ($v = $item->Name) ? (string) $v : null, + 'CreationDate' => ($v = $item->CreationDate) ? new \DateTimeImmutable((string) $v) : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php b/vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php new file mode 100644 index 000000000..13c7aea51 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php @@ -0,0 +1,402 @@ + + */ +class ListMultipartUploadsOutput extends Result implements \IteratorAggregate +{ + /** + * The name of the bucket to which the multipart upload was initiated. Does not return the access point ARN or access + * point alias if used. + * + * @var string|null + */ + private $bucket; + + /** + * The key at or after which the listing began. + * + * @var string|null + */ + private $keyMarker; + + /** + * Upload ID after which listing began. + * + * @var string|null + */ + private $uploadIdMarker; + + /** + * When a list is truncated, this element specifies the value that should be used for the key-marker request parameter + * in a subsequent request. + * + * @var string|null + */ + private $nextKeyMarker; + + /** + * When a prefix is provided in the request, this field contains the specified prefix. The result contains only keys + * starting with the specified prefix. + * + * @var string|null + */ + private $prefix; + + /** + * Contains the delimiter you specified in the request. If you don't specify a delimiter in your request, this element + * is absent from the response. + * + * @var string|null + */ + private $delimiter; + + /** + * When a list is truncated, this element specifies the value that should be used for the `upload-id-marker` request + * parameter in a subsequent request. + * + * @var string|null + */ + private $nextUploadIdMarker; + + /** + * Maximum number of multipart uploads that could have been included in the response. + * + * @var int|null + */ + private $maxUploads; + + /** + * Indicates whether the returned list of multipart uploads is truncated. A value of true indicates that the list was + * truncated. The list can be truncated if the number of multipart uploads exceeds the limit allowed or specified by max + * uploads. + * + * @var bool|null + */ + private $isTruncated; + + /** + * Container for elements related to a particular multipart upload. A response can contain zero or more `Upload` + * elements. + * + * @var MultipartUpload[] + */ + private $uploads; + + /** + * If you specify a delimiter in the request, then the result returns each distinct key prefix containing the delimiter + * in a `CommonPrefixes` element. The distinct key prefixes are returned in the `Prefix` child element. + * + * @var CommonPrefix[] + */ + private $commonPrefixes; + + /** + * Encoding type used by Amazon S3 to encode object keys in the response. + * + * If you specify the `encoding-type` request parameter, Amazon S3 includes this element in the response, and returns + * encoded key name values in the following response elements: + * + * `Delimiter`, `KeyMarker`, `Prefix`, `NextKeyMarker`, `Key`. + * + * @var EncodingType::*|null + */ + private $encodingType; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + public function getBucket(): ?string + { + $this->initialize(); + + return $this->bucket; + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getCommonPrefixes(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->commonPrefixes; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListMultipartUploadsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setKeyMarker($page->nextKeyMarker); + + $input->setUploadIdMarker($page->nextUploadIdMarker); + + $this->registerPrefetch($nextPage = $client->listMultipartUploads($input)); + } else { + $nextPage = null; + } + + yield from $page->commonPrefixes; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getDelimiter(): ?string + { + $this->initialize(); + + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + $this->initialize(); + + return $this->encodingType; + } + + public function getIsTruncated(): ?bool + { + $this->initialize(); + + return $this->isTruncated; + } + + /** + * Iterates over Uploads and CommonPrefixes. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListMultipartUploadsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setKeyMarker($page->nextKeyMarker); + + $input->setUploadIdMarker($page->nextUploadIdMarker); + + $this->registerPrefetch($nextPage = $client->listMultipartUploads($input)); + } else { + $nextPage = null; + } + + yield from $page->getUploads(true); + yield from $page->getCommonPrefixes(true); + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getKeyMarker(): ?string + { + $this->initialize(); + + return $this->keyMarker; + } + + public function getMaxUploads(): ?int + { + $this->initialize(); + + return $this->maxUploads; + } + + public function getNextKeyMarker(): ?string + { + $this->initialize(); + + return $this->nextKeyMarker; + } + + public function getNextUploadIdMarker(): ?string + { + $this->initialize(); + + return $this->nextUploadIdMarker; + } + + public function getPrefix(): ?string + { + $this->initialize(); + + return $this->prefix; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getUploadIdMarker(): ?string + { + $this->initialize(); + + return $this->uploadIdMarker; + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getUploads(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->uploads; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListMultipartUploadsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setKeyMarker($page->nextKeyMarker); + + $input->setUploadIdMarker($page->nextUploadIdMarker); + + $this->registerPrefetch($nextPage = $client->listMultipartUploads($input)); + } else { + $nextPage = null; + } + + yield from $page->uploads; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->keyMarker = ($v = $data->KeyMarker) ? (string) $v : null; + $this->uploadIdMarker = ($v = $data->UploadIdMarker) ? (string) $v : null; + $this->nextKeyMarker = ($v = $data->NextKeyMarker) ? (string) $v : null; + $this->prefix = ($v = $data->Prefix) ? (string) $v : null; + $this->delimiter = ($v = $data->Delimiter) ? (string) $v : null; + $this->nextUploadIdMarker = ($v = $data->NextUploadIdMarker) ? (string) $v : null; + $this->maxUploads = ($v = $data->MaxUploads) ? (int) (string) $v : null; + $this->isTruncated = ($v = $data->IsTruncated) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null; + $this->uploads = !$data->Upload ? [] : $this->populateResultMultipartUploadList($data->Upload); + $this->commonPrefixes = !$data->CommonPrefixes ? [] : $this->populateResultCommonPrefixList($data->CommonPrefixes); + $this->encodingType = ($v = $data->EncodingType) ? (string) $v : null; + } + + /** + * @return CommonPrefix[] + */ + private function populateResultCommonPrefixList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new CommonPrefix([ + 'Prefix' => ($v = $item->Prefix) ? (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return MultipartUpload[] + */ + private function populateResultMultipartUploadList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new MultipartUpload([ + 'UploadId' => ($v = $item->UploadId) ? (string) $v : null, + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'Initiated' => ($v = $item->Initiated) ? new \DateTimeImmutable((string) $v) : null, + 'StorageClass' => ($v = $item->StorageClass) ? (string) $v : null, + 'Owner' => !$item->Owner ? null : new Owner([ + 'DisplayName' => ($v = $item->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $item->Owner->ID) ? (string) $v : null, + ]), + 'Initiator' => !$item->Initiator ? null : new Initiator([ + 'ID' => ($v = $item->Initiator->ID) ? (string) $v : null, + 'DisplayName' => ($v = $item->Initiator->DisplayName) ? (string) $v : null, + ]), + 'ChecksumAlgorithm' => ($v = $item->ChecksumAlgorithm) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ListObjectsV2Output.php b/vendor/async-aws/s3/src/Result/ListObjectsV2Output.php new file mode 100644 index 000000000..49f4114c1 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListObjectsV2Output.php @@ -0,0 +1,438 @@ + + */ +class ListObjectsV2Output extends Result implements \IteratorAggregate +{ + /** + * Set to `false` if all of the results were returned. Set to `true` if more keys are available to return. If the number + * of results exceeds that specified by `MaxKeys`, all of the results might not be returned. + * + * @var bool|null + */ + private $isTruncated; + + /** + * Metadata about each object returned. + * + * @var AwsObject[] + */ + private $contents; + + /** + * The bucket name. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @var string|null + */ + private $name; + + /** + * Keys that begin with the indicated prefix. + * + * @var string|null + */ + private $prefix; + + /** + * Causes keys that contain the same string between the `prefix` and the first occurrence of the delimiter to be rolled + * up into a single result element in the `CommonPrefixes` collection. These rolled-up keys are not returned elsewhere + * in the response. Each rolled-up result counts as only one return against the `MaxKeys` value. + * + * @var string|null + */ + private $delimiter; + + /** + * Sets the maximum number of keys returned in the response. By default, the action returns up to 1,000 key names. The + * response might contain fewer keys but will never contain more. + * + * @var int|null + */ + private $maxKeys; + + /** + * All of the keys (up to 1,000) rolled up into a common prefix count as a single return when calculating the number of + * returns. + * + * A response can contain `CommonPrefixes` only if you specify a delimiter. + * + * `CommonPrefixes` contains all (if there are any) keys between `Prefix` and the next occurrence of the string + * specified by a delimiter. + * + * `CommonPrefixes` lists keys that act like subdirectories in the directory specified by `Prefix`. + * + * For example, if the prefix is `notes/` and the delimiter is a slash (`/`) as in `notes/summer/july`, the common + * prefix is `notes/summer/`. All of the keys that roll up into a common prefix count as a single return when + * calculating the number of returns. + * + * @var CommonPrefix[] + */ + private $commonPrefixes; + + /** + * Encoding type used by Amazon S3 to encode object key names in the XML response. + * + * If you specify the `encoding-type` request parameter, Amazon S3 includes this element in the response, and returns + * encoded key name values in the following response elements: + * + * `Delimiter, Prefix, Key,` and `StartAfter`. + * + * @var EncodingType::*|null + */ + private $encodingType; + + /** + * `KeyCount` is the number of keys returned with this request. `KeyCount` will always be less than or equal to the + * `MaxKeys` field. For example, if you ask for 50 keys, your result will include 50 keys or fewer. + * + * @var int|null + */ + private $keyCount; + + /** + * If `ContinuationToken` was sent with the request, it is included in the response. + * + * @var string|null + */ + private $continuationToken; + + /** + * `NextContinuationToken` is sent when `isTruncated` is true, which means there are more keys in the bucket that can be + * listed. The next list requests to Amazon S3 can be continued with this `NextContinuationToken`. + * `NextContinuationToken` is obfuscated and is not a real key. + * + * @var string|null + */ + private $nextContinuationToken; + + /** + * If StartAfter was sent with the request, it is included in the response. + * + * @var string|null + */ + private $startAfter; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getCommonPrefixes(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->commonPrefixes; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListObjectsV2Request) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->nextContinuationToken) { + $input->setContinuationToken($page->nextContinuationToken); + + $this->registerPrefetch($nextPage = $client->listObjectsV2($input)); + } else { + $nextPage = null; + } + + yield from $page->commonPrefixes; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getContents(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->contents; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListObjectsV2Request) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->nextContinuationToken) { + $input->setContinuationToken($page->nextContinuationToken); + + $this->registerPrefetch($nextPage = $client->listObjectsV2($input)); + } else { + $nextPage = null; + } + + yield from $page->contents; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getContinuationToken(): ?string + { + $this->initialize(); + + return $this->continuationToken; + } + + public function getDelimiter(): ?string + { + $this->initialize(); + + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + $this->initialize(); + + return $this->encodingType; + } + + public function getIsTruncated(): ?bool + { + $this->initialize(); + + return $this->isTruncated; + } + + /** + * Iterates over Contents and CommonPrefixes. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListObjectsV2Request) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->nextContinuationToken) { + $input->setContinuationToken($page->nextContinuationToken); + + $this->registerPrefetch($nextPage = $client->listObjectsV2($input)); + } else { + $nextPage = null; + } + + yield from $page->getContents(true); + yield from $page->getCommonPrefixes(true); + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getKeyCount(): ?int + { + $this->initialize(); + + return $this->keyCount; + } + + public function getMaxKeys(): ?int + { + $this->initialize(); + + return $this->maxKeys; + } + + public function getName(): ?string + { + $this->initialize(); + + return $this->name; + } + + public function getNextContinuationToken(): ?string + { + $this->initialize(); + + return $this->nextContinuationToken; + } + + public function getPrefix(): ?string + { + $this->initialize(); + + return $this->prefix; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getStartAfter(): ?string + { + $this->initialize(); + + return $this->startAfter; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->isTruncated = ($v = $data->IsTruncated) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null; + $this->contents = !$data->Contents ? [] : $this->populateResultObjectList($data->Contents); + $this->name = ($v = $data->Name) ? (string) $v : null; + $this->prefix = ($v = $data->Prefix) ? (string) $v : null; + $this->delimiter = ($v = $data->Delimiter) ? (string) $v : null; + $this->maxKeys = ($v = $data->MaxKeys) ? (int) (string) $v : null; + $this->commonPrefixes = !$data->CommonPrefixes ? [] : $this->populateResultCommonPrefixList($data->CommonPrefixes); + $this->encodingType = ($v = $data->EncodingType) ? (string) $v : null; + $this->keyCount = ($v = $data->KeyCount) ? (int) (string) $v : null; + $this->continuationToken = ($v = $data->ContinuationToken) ? (string) $v : null; + $this->nextContinuationToken = ($v = $data->NextContinuationToken) ? (string) $v : null; + $this->startAfter = ($v = $data->StartAfter) ? (string) $v : null; + } + + /** + * @return list + */ + private function populateResultChecksumAlgorithmList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return CommonPrefix[] + */ + private function populateResultCommonPrefixList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new CommonPrefix([ + 'Prefix' => ($v = $item->Prefix) ? (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return AwsObject[] + */ + private function populateResultObjectList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new AwsObject([ + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'LastModified' => ($v = $item->LastModified) ? new \DateTimeImmutable((string) $v) : null, + 'ETag' => ($v = $item->ETag) ? (string) $v : null, + 'ChecksumAlgorithm' => !$item->ChecksumAlgorithm ? null : $this->populateResultChecksumAlgorithmList($item->ChecksumAlgorithm), + 'Size' => ($v = $item->Size) ? (int) (string) $v : null, + 'StorageClass' => ($v = $item->StorageClass) ? (string) $v : null, + 'Owner' => !$item->Owner ? null : new Owner([ + 'DisplayName' => ($v = $item->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $item->Owner->ID) ? (string) $v : null, + ]), + 'RestoreStatus' => !$item->RestoreStatus ? null : new RestoreStatus([ + 'IsRestoreInProgress' => ($v = $item->RestoreStatus->IsRestoreInProgress) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, + 'RestoreExpiryDate' => ($v = $item->RestoreStatus->RestoreExpiryDate) ? new \DateTimeImmutable((string) $v) : null, + ]), + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ListPartsOutput.php b/vendor/async-aws/s3/src/Result/ListPartsOutput.php new file mode 100644 index 000000000..80aff981e --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListPartsOutput.php @@ -0,0 +1,352 @@ + + */ +class ListPartsOutput extends Result implements \IteratorAggregate +{ + /** + * If the bucket has a lifecycle rule configured with an action to abort incomplete multipart uploads and the prefix in + * the lifecycle rule matches the object name in the request, then the response includes this header indicating when the + * initiated multipart upload will become eligible for abort operation. For more information, see Aborting Incomplete + * Multipart Uploads Using a Bucket Lifecycle Configuration [^1]. + * + * The response will also include the `x-amz-abort-rule-id` header that will provide the ID of the lifecycle + * configuration rule that defines this action. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config + * + * @var \DateTimeImmutable|null + */ + private $abortDate; + + /** + * This header is returned along with the `x-amz-abort-date` header. It identifies applicable lifecycle configuration + * rule that defines the action to abort incomplete multipart uploads. + * + * @var string|null + */ + private $abortRuleId; + + /** + * The name of the bucket to which the multipart upload was initiated. Does not return the access point ARN or access + * point alias if used. + * + * @var string|null + */ + private $bucket; + + /** + * Object key for which the multipart upload was initiated. + * + * @var string|null + */ + private $key; + + /** + * Upload ID identifying the multipart upload whose parts are being listed. + * + * @var string|null + */ + private $uploadId; + + /** + * When a list is truncated, this element specifies the last part in the list, as well as the value to use for the + * part-number-marker request parameter in a subsequent request. + * + * @var int|null + */ + private $partNumberMarker; + + /** + * When a list is truncated, this element specifies the last part in the list, as well as the value to use for the + * `part-number-marker` request parameter in a subsequent request. + * + * @var int|null + */ + private $nextPartNumberMarker; + + /** + * Maximum number of parts that were allowed in the response. + * + * @var int|null + */ + private $maxParts; + + /** + * Indicates whether the returned list of parts is truncated. A true value indicates that the list was truncated. A list + * can be truncated if the number of parts exceeds the limit returned in the MaxParts element. + * + * @var bool|null + */ + private $isTruncated; + + /** + * Container for elements related to a particular part. A response can contain zero or more `Part` elements. + * + * @var Part[] + */ + private $parts; + + /** + * Container element that identifies who initiated the multipart upload. If the initiator is an Amazon Web Services + * account, this element provides the same information as the `Owner` element. If the initiator is an IAM User, this + * element provides the user ARN and display name. + * + * @var Initiator|null + */ + private $initiator; + + /** + * Container element that identifies the object owner, after the object is created. If multipart upload is initiated by + * an IAM user, this element provides the parent account ID and display name. + * + * @var Owner|null + */ + private $owner; + + /** + * Class of storage (STANDARD or REDUCED_REDUNDANCY) used to store the uploaded object. + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * The algorithm that was used to create a checksum of the object. + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + public function getAbortDate(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->abortDate; + } + + public function getAbortRuleId(): ?string + { + $this->initialize(); + + return $this->abortRuleId; + } + + public function getBucket(): ?string + { + $this->initialize(); + + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + $this->initialize(); + + return $this->checksumAlgorithm; + } + + public function getInitiator(): ?Initiator + { + $this->initialize(); + + return $this->initiator; + } + + public function getIsTruncated(): ?bool + { + $this->initialize(); + + return $this->isTruncated; + } + + /** + * Iterates over Parts. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + yield from $this->getParts(); + } + + public function getKey(): ?string + { + $this->initialize(); + + return $this->key; + } + + public function getMaxParts(): ?int + { + $this->initialize(); + + return $this->maxParts; + } + + public function getNextPartNumberMarker(): ?int + { + $this->initialize(); + + return $this->nextPartNumberMarker; + } + + public function getOwner(): ?Owner + { + $this->initialize(); + + return $this->owner; + } + + public function getPartNumberMarker(): ?int + { + $this->initialize(); + + return $this->partNumberMarker; + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getParts(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->parts; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListPartsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setPartNumberMarker($page->nextPartNumberMarker); + + $this->registerPrefetch($nextPage = $client->listParts($input)); + } else { + $nextPage = null; + } + + yield from $page->parts; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + $this->initialize(); + + return $this->storageClass; + } + + public function getUploadId(): ?string + { + $this->initialize(); + + return $this->uploadId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->abortDate = isset($headers['x-amz-abort-date'][0]) ? new \DateTimeImmutable($headers['x-amz-abort-date'][0]) : null; + $this->abortRuleId = $headers['x-amz-abort-rule-id'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->key = ($v = $data->Key) ? (string) $v : null; + $this->uploadId = ($v = $data->UploadId) ? (string) $v : null; + $this->partNumberMarker = ($v = $data->PartNumberMarker) ? (int) (string) $v : null; + $this->nextPartNumberMarker = ($v = $data->NextPartNumberMarker) ? (int) (string) $v : null; + $this->maxParts = ($v = $data->MaxParts) ? (int) (string) $v : null; + $this->isTruncated = ($v = $data->IsTruncated) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null; + $this->parts = !$data->Part ? [] : $this->populateResultParts($data->Part); + $this->initiator = !$data->Initiator ? null : new Initiator([ + 'ID' => ($v = $data->Initiator->ID) ? (string) $v : null, + 'DisplayName' => ($v = $data->Initiator->DisplayName) ? (string) $v : null, + ]); + $this->owner = !$data->Owner ? null : new Owner([ + 'DisplayName' => ($v = $data->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $data->Owner->ID) ? (string) $v : null, + ]); + $this->storageClass = ($v = $data->StorageClass) ? (string) $v : null; + $this->checksumAlgorithm = ($v = $data->ChecksumAlgorithm) ? (string) $v : null; + } + + /** + * @return Part[] + */ + private function populateResultParts(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new Part([ + 'PartNumber' => ($v = $item->PartNumber) ? (int) (string) $v : null, + 'LastModified' => ($v = $item->LastModified) ? new \DateTimeImmutable((string) $v) : null, + 'ETag' => ($v = $item->ETag) ? (string) $v : null, + 'Size' => ($v = $item->Size) ? (int) (string) $v : null, + 'ChecksumCRC32' => ($v = $item->ChecksumCRC32) ? (string) $v : null, + 'ChecksumCRC32C' => ($v = $item->ChecksumCRC32C) ? (string) $v : null, + 'ChecksumSHA1' => ($v = $item->ChecksumSHA1) ? (string) $v : null, + 'ChecksumSHA256' => ($v = $item->ChecksumSHA256) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php b/vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php new file mode 100644 index 000000000..cf689dfd6 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php @@ -0,0 +1,41 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (404 === $response->getStatusCode()) { + return self::STATE_PENDING; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadObjectRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->objectExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php b/vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php new file mode 100644 index 000000000..17c02ad4a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php @@ -0,0 +1,37 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadObjectRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->objectNotExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/PutObjectAclOutput.php b/vendor/async-aws/s3/src/Result/PutObjectAclOutput.php new file mode 100644 index 000000000..99718958b --- /dev/null +++ b/vendor/async-aws/s3/src/Result/PutObjectAclOutput.php @@ -0,0 +1,32 @@ +initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/PutObjectOutput.php b/vendor/async-aws/s3/src/Result/PutObjectOutput.php new file mode 100644 index 000000000..8ec2e7af9 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/PutObjectOutput.php @@ -0,0 +1,259 @@ +initialize(); + + return $this->bucketKeyEnabled; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + $this->initialize(); + + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->etag = $headers['etag'][0] ?? null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->sseKmsEncryptionContext = $headers['x-amz-server-side-encryption-context'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php b/vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php new file mode 100644 index 000000000..a0cedbab9 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php @@ -0,0 +1,30 @@ +initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/UploadPartOutput.php b/vendor/async-aws/s3/src/Result/UploadPartOutput.php new file mode 100644 index 000000000..96a404150 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/UploadPartOutput.php @@ -0,0 +1,206 @@ +initialize(); + + return $this->bucketKeyEnabled; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->etag = $headers['etag'][0] ?? null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/S3Client.php b/vendor/async-aws/s3/src/S3Client.php new file mode 100644 index 000000000..4fdba87f8 --- /dev/null +++ b/vendor/async-aws/s3/src/S3Client.php @@ -0,0 +1,2651 @@ +getResponse($input->request(), new RequestContext(['operation' => 'AbortMultipartUpload', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchUpload' => NoSuchUploadException::class, + ]])); + + return new AbortMultipartUploadOutput($response); + } + + /** + * @see headBucket + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|HeadBucketRequest $input + */ + public function bucketExists($input): BucketExistsWaiter + { + $input = HeadBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadBucket', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchBucket' => NoSuchBucketException::class, + ]])); + + return new BucketExistsWaiter($response, $this, $input); + } + + /** + * @see headBucket + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|HeadBucketRequest $input + */ + public function bucketNotExists($input): BucketNotExistsWaiter + { + $input = HeadBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadBucket', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchBucket' => NoSuchBucketException::class, + ]])); + + return new BucketNotExistsWaiter($response, $this, $input); + } + + /** + * Completes a multipart upload by assembling previously uploaded parts. + * + * You first initiate the multipart upload and then upload all parts using the UploadPart [^1] operation. After + * successfully uploading all relevant parts of an upload, you call this action to complete the upload. Upon receiving + * this request, Amazon S3 concatenates all the parts in ascending order by part number to create a new object. In the + * Complete Multipart Upload request, you must provide the parts list. You must ensure that the parts list is complete. + * This action concatenates the parts that you provide in the list. For each part in the list, you must provide the part + * number and the `ETag` value, returned after that part was uploaded. + * + * Processing of a Complete Multipart Upload request could take several minutes to complete. After Amazon S3 begins + * processing the request, it sends an HTTP response header that specifies a 200 OK response. While processing is in + * progress, Amazon S3 periodically sends white space characters to keep the connection from timing out. A request could + * fail after the initial 200 OK response has been sent. This means that a `200 OK` response can contain either a + * success or an error. If you call the S3 API directly, make sure to design your application to parse the contents of + * the response and handle it appropriately. If you use Amazon Web Services SDKs, SDKs handle this condition. The SDKs + * detect the embedded error and apply error handling per your configuration settings (including automatically retrying + * the request as appropriate). If the condition persists, the SDKs throws an exception (or, for the SDKs that don't use + * exceptions, they return the error). + * + * Note that if `CompleteMultipartUpload` fails, applications should be prepared to retry the failed requests. For more + * information, see Amazon S3 Error Best Practices [^2]. + * + * ! You cannot use `Content-Type: application/x-www-form-urlencoded` with Complete Multipart Upload requests. Also, if + * ! you do not provide a `Content-Type` header, `CompleteMultipartUpload` returns a 200 OK response. + * + * For more information about multipart uploads, see Uploading Objects Using Multipart Upload [^3]. + * + * For information about permissions required to use the multipart upload API, see Multipart Upload and Permissions + * [^4]. + * + * `CompleteMultipartUpload` has the following special errors: + * + * - Error code: `EntityTooSmall` + * + * - Description: Your proposed upload is smaller than the minimum allowed object size. Each part must be at least 5 + * MB in size, except the last part. + * - 400 Bad Request + * + * - Error code: `InvalidPart` + * + * - Description: One or more of the specified parts could not be found. The part might not have been uploaded, or the + * specified entity tag might not have matched the part's entity tag. + * - 400 Bad Request + * + * - Error code: `InvalidPartOrder` + * + * - Description: The list of parts was not in ascending order. The parts list must be specified in order by part + * number. + * - 400 Bad Request + * + * - Error code: `NoSuchUpload` + * + * - Description: The specified multipart upload does not exist. The upload ID might be invalid, or the multipart + * upload might have been aborted or completed. + * - 404 Not Found + * + * + * The following operations are related to `CompleteMultipartUpload`: + * + * - CreateMultipartUpload [^5] + * - UploadPart [^6] + * - AbortMultipartUpload [^7] + * - ListParts [^8] + * - ListMultipartUploads [^9] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ErrorBestPractices.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadComplete.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#completemultipartupload + * + * @param array{ + * Bucket: string, + * Key: string, + * MultipartUpload?: CompletedMultipartUpload|array, + * UploadId: string, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|CompleteMultipartUploadRequest $input + */ + public function completeMultipartUpload($input): CompleteMultipartUploadOutput + { + $input = CompleteMultipartUploadRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CompleteMultipartUpload', 'region' => $input->getRegion()])); + + return new CompleteMultipartUploadOutput($response); + } + + /** + * Creates a copy of an object that is already stored in Amazon S3. + * + * > You can store individual objects of up to 5 TB in Amazon S3. You create a copy of your object up to 5 GB in size in + * > a single atomic action using this API. However, to copy an object greater than 5 GB, you must use the multipart + * > upload Upload Part - Copy (UploadPartCopy) API. For more information, see Copy Object Using the REST Multipart + * > Upload API [^1]. + * + * All copy requests must be authenticated. Additionally, you must have *read* access to the source object and *write* + * access to the destination bucket. For more information, see REST Authentication [^2]. Both the Region that you want + * to copy the object from and the Region that you want to copy the object to must be enabled for your account. + * + * A copy request might return an error when Amazon S3 receives the copy request or while Amazon S3 is copying the + * files. If the error occurs before the copy action starts, you receive a standard Amazon S3 error. If the error occurs + * during the copy operation, the error response is embedded in the `200 OK` response. This means that a `200 OK` + * response can contain either a success or an error. If you call the S3 API directly, make sure to design your + * application to parse the contents of the response and handle it appropriately. If you use Amazon Web Services SDKs, + * SDKs handle this condition. The SDKs detect the embedded error and apply error handling per your configuration + * settings (including automatically retrying the request as appropriate). If the condition persists, the SDKs throws an + * exception (or, for the SDKs that don't use exceptions, they return the error). + * + * If the copy is successful, you receive a response with information about the copied object. + * + * > If the request is an HTTP 1.1 request, the response is chunk encoded. If it were not, it would not contain the + * > content-length, and you would need to read the entire body. + * + * The copy request charge is based on the storage class and Region that you specify for the destination object. The + * request can also result in a data retrieval charge for the source if the source storage class bills for data + * retrieval. For pricing information, see Amazon S3 pricing [^3]. + * + * ! Amazon S3 transfer acceleration does not support cross-Region copies. If you request a cross-Region copy using a + * ! transfer acceleration endpoint, you get a 400 `Bad Request` error. For more information, see Transfer Acceleration + * ! [^4]. + * + * - `Metadata`: + * + * When copying an object, you can preserve all metadata (the default) or specify new metadata. However, the access + * control list (ACL) is not preserved and is set to private for the user making the request. To override the default + * ACL setting, specify a new ACL when generating a copy request. For more information, see Using ACLs [^5]. + * + * To specify whether you want the object metadata copied from the source object or replaced with metadata provided in + * the request, you can optionally add the `x-amz-metadata-directive` header. When you grant permissions, you can use + * the `s3:x-amz-metadata-directive` condition key to enforce certain metadata behavior when objects are uploaded. For + * more information, see Specifying Conditions in a Policy [^6] in the *Amazon S3 User Guide*. For a complete list of + * Amazon S3-specific condition keys, see Actions, Resources, and Condition Keys for Amazon S3 [^7]. + * + * > `x-amz-website-redirect-location` is unique to each object and must be specified in the request headers to copy + * > the value. + * + * - `x-amz-copy-source-if Headers`: + * + * To only copy an object under certain conditions, such as whether the `Etag` matches or whether the object was + * modified before or after a specified date, use the following request parameters: + * + * - `x-amz-copy-source-if-match` + * - `x-amz-copy-source-if-none-match` + * - `x-amz-copy-source-if-unmodified-since` + * - `x-amz-copy-source-if-modified-since` + * + * If both the `x-amz-copy-source-if-match` and `x-amz-copy-source-if-unmodified-since` headers are present in the + * request and evaluate as follows, Amazon S3 returns `200 OK` and copies the data: + * + * - `x-amz-copy-source-if-match` condition evaluates to true + * - `x-amz-copy-source-if-unmodified-since` condition evaluates to false + * + * If both the `x-amz-copy-source-if-none-match` and `x-amz-copy-source-if-modified-since` headers are present in the + * request and evaluate as follows, Amazon S3 returns the `412 Precondition Failed` response code: + * + * - `x-amz-copy-source-if-none-match` condition evaluates to false + * - `x-amz-copy-source-if-modified-since` condition evaluates to true + * + * > All headers with the `x-amz-` prefix, including `x-amz-copy-source`, must be signed. + * + * - `Server-side encryption`: + * + * Amazon S3 automatically encrypts all new objects that are copied to an S3 bucket. When copying an object, if you + * don't specify encryption information in your copy request, the encryption setting of the target object is set to + * the default encryption configuration of the destination bucket. By default, all buckets have a base level of + * encryption configuration that uses server-side encryption with Amazon S3 managed keys (SSE-S3). If the destination + * bucket has a default encryption configuration that uses server-side encryption with Key Management Service (KMS) + * keys (SSE-KMS), dual-layer server-side encryption with Amazon Web Services KMS keys (DSSE-KMS), or server-side + * encryption with customer-provided encryption keys (SSE-C), Amazon S3 uses the corresponding KMS key, or a + * customer-provided key to encrypt the target object copy. + * + * When you perform a `CopyObject` operation, if you want to use a different type of encryption setting for the target + * object, you can use other appropriate encryption-related headers to encrypt the target object with a KMS key, an + * Amazon S3 managed key, or a customer-provided key. With server-side encryption, Amazon S3 encrypts your data as it + * writes your data to disks in its data centers and decrypts the data when you access it. If the encryption setting + * in your request is different from the default encryption configuration of the destination bucket, the encryption + * setting in your request takes precedence. If the source object for the copy is stored in Amazon S3 using SSE-C, you + * must provide the necessary encryption information in your request so that Amazon S3 can decrypt the object for + * copying. For more information about server-side encryption, see Using Server-Side Encryption [^8]. + * + * If a target object uses SSE-KMS, you can enable an S3 Bucket Key for the object. For more information, see Amazon + * S3 Bucket Keys [^9] in the *Amazon S3 User Guide*. + * - `Access Control List (ACL)-Specific Request Headers`: + * + * When copying an object, you can optionally use headers to grant ACL-based permissions. By default, all objects are + * private. Only the owner has full access control. When adding a new object, you can grant permissions to individual + * Amazon Web Services accounts or to predefined groups that are defined by Amazon S3. These permissions are then + * added to the ACL on the object. For more information, see Access Control List (ACL) Overview [^10] and Managing + * ACLs Using the REST API [^11]. + * + * If the bucket that you're copying objects to uses the bucket owner enforced setting for S3 Object Ownership, ACLs + * are disabled and no longer affect permissions. Buckets that use this setting only accept `PUT` requests that don't + * specify an ACL or `PUT` requests that specify bucket owner full control ACLs, such as the + * `bucket-owner-full-control` canned ACL or an equivalent form of this ACL expressed in the XML format. + * + * For more information, see Controlling ownership of objects and disabling ACLs [^12] in the *Amazon S3 User Guide*. + * + * > If your bucket uses the bucket owner enforced setting for Object Ownership, all objects written to the bucket by + * > any account will be owned by the bucket owner. + * + * - `Checksums`: + * + * When copying an object, if it has a checksum, that checksum will be copied to the new object by default. When you + * copy the object over, you can optionally specify a different checksum algorithm to use with the + * `x-amz-checksum-algorithm` header. + * - `Storage Class Options`: + * + * You can use the `CopyObject` action to change the storage class of an object that is already stored in Amazon S3 by + * using the `StorageClass` parameter. For more information, see Storage Classes [^13] in the *Amazon S3 User Guide*. + * + * If the source object's storage class is GLACIER, you must restore a copy of this object before you can use it as a + * source object for the copy operation. For more information, see RestoreObject [^14]. For more information, see + * Copying Objects [^15]. + * - `Versioning`: + * + * By default, `x-amz-copy-source` header identifies the current version of an object to copy. If the current version + * is a delete marker, Amazon S3 behaves as if the object was deleted. To copy a different version, use the + * `versionId` subresource. + * + * If you enable versioning on the target bucket, Amazon S3 generates a unique version ID for the object being copied. + * This version ID is different from the version ID of the source object. Amazon S3 returns the version ID of the + * copied object in the `x-amz-version-id` response header in the response. + * + * If you do not enable versioning or suspend it on the target bucket, the version ID that Amazon S3 generates is + * always null. + * + * The following operations are related to `CopyObject`: + * + * - PutObject [^16] + * - GetObject [^17] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjctsUsingRESTMPUapi.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html + * [^3]: http://aws.amazon.com/s3/pricing/ + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/dev/list_amazons3.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html + * [^12]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^13]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * [^14]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html + * [^15]: https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjectsExamples.html + * [^16]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * [^17]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectCOPY.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#copyobject + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket: string, + * CacheControl?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * CopySource: string, + * CopySourceIfMatch?: string, + * CopySourceIfModifiedSince?: \DateTimeImmutable|string, + * CopySourceIfNoneMatch?: string, + * CopySourceIfUnmodifiedSince?: \DateTimeImmutable|string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key: string, + * Metadata?: array, + * MetadataDirective?: MetadataDirective::*, + * TaggingDirective?: TaggingDirective::*, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * CopySourceSSECustomerAlgorithm?: string, + * CopySourceSSECustomerKey?: string, + * CopySourceSSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ExpectedSourceBucketOwner?: string, + * '@region'?: string|null, + * }|CopyObjectRequest $input + * + * @throws ObjectNotInActiveTierErrorException + */ + public function copyObject($input): CopyObjectOutput + { + $input = CopyObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CopyObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'ObjectNotInActiveTierError' => ObjectNotInActiveTierErrorException::class, + ]])); + + return new CopyObjectOutput($response); + } + + /** + * Creates a new S3 bucket. To create a bucket, you must register with Amazon S3 and have a valid Amazon Web Services + * Access Key ID to authenticate requests. Anonymous requests are never allowed to create buckets. By creating the + * bucket, you become the bucket owner. + * + * Not every string is an acceptable bucket name. For information about bucket naming restrictions, see Bucket naming + * rules [^1]. + * + * If you want to create an Amazon S3 on Outposts bucket, see Create Bucket [^2]. + * + * By default, the bucket is created in the US East (N. Virginia) Region. You can optionally specify a Region in the + * request body. You might choose a Region to optimize latency, minimize costs, or address regulatory requirements. For + * example, if you reside in Europe, you will probably find it advantageous to create buckets in the Europe (Ireland) + * Region. For more information, see Accessing a bucket [^3]. + * + * > If you send your create bucket request to the `s3.amazonaws.com` endpoint, the request goes to the `us-east-1` + * > Region. Accordingly, the signature calculations in Signature Version 4 must use `us-east-1` as the Region, even if + * > the location constraint in the request specifies another Region where the bucket is to be created. If you create a + * > bucket in a Region other than US East (N. Virginia), your application must be able to handle 307 redirect. For more + * > information, see Virtual hosting of buckets [^4]. + * + * - `Permissions`: + * + * In addition to `s3:CreateBucket`, the following permissions are required when your `CreateBucket` request includes + * specific headers: + * + * - **Access control lists (ACLs)** - If your `CreateBucket` request specifies access control list (ACL) permissions + * and the ACL is public-read, public-read-write, authenticated-read, or if you specify access permissions + * explicitly through any other ACL, both `s3:CreateBucket` and `s3:PutBucketAcl` permissions are needed. If the ACL + * for the `CreateBucket` request is private or if the request doesn't specify any ACLs, only `s3:CreateBucket` + * permission is needed. + * - **Object Lock** - If `ObjectLockEnabledForBucket` is set to true in your `CreateBucket` request, + * `s3:PutBucketObjectLockConfiguration` and `s3:PutBucketVersioning` permissions are required. + * - **S3 Object Ownership** - If your `CreateBucket` request includes the `x-amz-object-ownership` header, then the + * `s3:PutBucketOwnershipControls` permission is required. By default, `ObjectOwnership` is set to + * `BucketOWnerEnforced` and ACLs are disabled. We recommend keeping ACLs disabled, except in uncommon use cases + * where you must control access for each object individually. If you want to change the `ObjectOwnership` setting, + * you can use the `x-amz-object-ownership` header in your `CreateBucket` request to set the `ObjectOwnership` + * setting of your choice. For more information about S3 Object Ownership, see Controlling object ownership [^5] in + * the *Amazon S3 User Guide*. + * - **S3 Block Public Access** - If your specific use case requires granting public access to your S3 resources, you + * can disable Block Public Access. You can create a new bucket with Block Public Access enabled, then separately + * call the `DeletePublicAccessBlock` [^6] API. To use this operation, you must have the + * `s3:PutBucketPublicAccessBlock` permission. By default, all Block Public Access settings are enabled for new + * buckets. To avoid inadvertent exposure of your resources, we recommend keeping the S3 Block Public Access + * settings enabled. For more information about S3 Block Public Access, see Blocking public access to your Amazon S3 + * storage [^7] in the *Amazon S3 User Guide*. + * + * + * ! If your `CreateBucket` request sets `BucketOwnerEnforced` for Amazon S3 Object Ownership and specifies a bucket ACL + * ! that provides access to an external Amazon Web Services account, your request fails with a `400` error and returns + * ! the `InvalidBucketAcLWithObjectOwnership` error code. For more information, see Setting Object Ownership on an + * ! existing bucket [^8] in the *Amazon S3 User Guide*. + * + * The following operations are related to `CreateBucket`: + * + * - PutObject [^9] + * - DeleteBucket [^10] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_CreateBucket.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-ownership-existing-bucket.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createbucket + * + * @param array{ + * ACL?: BucketCannedACL::*, + * Bucket: string, + * CreateBucketConfiguration?: CreateBucketConfiguration|array, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * ObjectLockEnabledForBucket?: bool, + * ObjectOwnership?: ObjectOwnership::*, + * '@region'?: string|null, + * }|CreateBucketRequest $input + * + * @throws BucketAlreadyExistsException + * @throws BucketAlreadyOwnedByYouException + */ + public function createBucket($input): CreateBucketOutput + { + $input = CreateBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CreateBucket', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'BucketAlreadyExists' => BucketAlreadyExistsException::class, + 'BucketAlreadyOwnedByYou' => BucketAlreadyOwnedByYouException::class, + ]])); + + return new CreateBucketOutput($response); + } + + /** + * This action initiates a multipart upload and returns an upload ID. This upload ID is used to associate all of the + * parts in the specific multipart upload. You specify this upload ID in each of your subsequent upload part requests + * (see UploadPart [^1]). You also include this upload ID in the final request to either complete or abort the multipart + * upload request. + * + * For more information about multipart uploads, see Multipart Upload Overview [^2]. + * + * If you have configured a lifecycle rule to abort incomplete multipart uploads, the upload must complete within the + * number of days specified in the bucket lifecycle configuration. Otherwise, the incomplete multipart upload becomes + * eligible for an abort action and Amazon S3 aborts the multipart upload. For more information, see Aborting Incomplete + * Multipart Uploads Using a Bucket Lifecycle Configuration [^3]. + * + * For information about the permissions required to use the multipart upload API, see Multipart Upload and Permissions + * [^4]. + * + * For request signing, multipart upload is just a series of regular requests. You initiate a multipart upload, send one + * or more requests to upload parts, and then complete the multipart upload process. You sign each request individually. + * There is nothing special about signing multipart upload requests. For more information about signing, see + * Authenticating Requests (Amazon Web Services Signature Version 4) [^5]. + * + * > After you initiate a multipart upload and upload one or more parts, to stop being charged for storing the uploaded + * > parts, you must either complete or abort the multipart upload. Amazon S3 frees up the space used to store the parts + * > and stop charging you for storing them only after you either complete or abort a multipart upload. + * + * Server-side encryption is for data encryption at rest. Amazon S3 encrypts your data as it writes it to disks in its + * data centers and decrypts it when you access it. Amazon S3 automatically encrypts all new objects that are uploaded + * to an S3 bucket. When doing a multipart upload, if you don't specify encryption information in your request, the + * encryption setting of the uploaded parts is set to the default encryption configuration of the destination bucket. By + * default, all buckets have a base level of encryption configuration that uses server-side encryption with Amazon S3 + * managed keys (SSE-S3). If the destination bucket has a default encryption configuration that uses server-side + * encryption with an Key Management Service (KMS) key (SSE-KMS), or a customer-provided encryption key (SSE-C), Amazon + * S3 uses the corresponding KMS key, or a customer-provided key to encrypt the uploaded parts. When you perform a + * CreateMultipartUpload operation, if you want to use a different type of encryption setting for the uploaded parts, + * you can request that Amazon S3 encrypts the object with a KMS key, an Amazon S3 managed key, or a customer-provided + * key. If the encryption setting in your request is different from the default encryption configuration of the + * destination bucket, the encryption setting in your request takes precedence. If you choose to provide your own + * encryption key, the request headers you provide in UploadPart [^6] and UploadPartCopy [^7] requests must match the + * headers you used in the request to initiate the upload by using `CreateMultipartUpload`. You can request that Amazon + * S3 save the uploaded parts encrypted with server-side encryption with an Amazon S3 managed key (SSE-S3), an Key + * Management Service (KMS) key (SSE-KMS), or a customer-provided encryption key (SSE-C). + * + * To perform a multipart upload with encryption by using an Amazon Web Services KMS key, the requester must have + * permission to the `kms:Decrypt` and `kms:GenerateDataKey*` actions on the key. These permissions are required because + * Amazon S3 must decrypt and read data from the encrypted file parts before it completes the multipart upload. For more + * information, see Multipart upload API and permissions [^8] and Protecting data using server-side encryption with + * Amazon Web Services KMS [^9] in the *Amazon S3 User Guide*. + * + * If your Identity and Access Management (IAM) user or role is in the same Amazon Web Services account as the KMS key, + * then you must have these permissions on the key policy. If your IAM user or role belongs to a different account than + * the key, then you must have the permissions on both the key policy and your IAM user or role. + * + * For more information, see Protecting Data Using Server-Side Encryption [^10]. + * + * - `Access Permissions`: + * + * When copying an object, you can optionally specify the accounts or groups that should be granted specific + * permissions on the new object. There are two ways to grant the permissions using the request headers: + * + * - Specify a canned ACL with the `x-amz-acl` request header. For more information, see Canned ACL [^11]. + * - Specify access permissions explicitly with the `x-amz-grant-read`, `x-amz-grant-read-acp`, + * `x-amz-grant-write-acp`, and `x-amz-grant-full-control` headers. These parameters map to the set of permissions + * that Amazon S3 supports in an ACL. For more information, see Access Control List (ACL) Overview [^12]. + * + * You can use either a canned ACL or specify access permissions explicitly. You cannot do both. + * - `Server-Side- Encryption-Specific Request Headers`: + * + * Amazon S3 encrypts data by using server-side encryption with an Amazon S3 managed key (SSE-S3) by default. + * Server-side encryption is for data encryption at rest. Amazon S3 encrypts your data as it writes it to disks in its + * data centers and decrypts it when you access it. You can request that Amazon S3 encrypts data at rest by using + * server-side encryption with other key options. The option you use depends on whether you want to use KMS keys + * (SSE-KMS) or provide your own encryption keys (SSE-C). + * + * - Use KMS keys (SSE-KMS) that include the Amazon Web Services managed key (`aws/s3`) and KMS customer managed keys + * stored in Key Management Service (KMS) – If you want Amazon Web Services to manage the keys used to encrypt + * data, specify the following headers in the request. + * + * - `x-amz-server-side-encryption` + * - `x-amz-server-side-encryption-aws-kms-key-id` + * - `x-amz-server-side-encryption-context` + * + * > If you specify `x-amz-server-side-encryption:aws:kms`, but don't provide + * > `x-amz-server-side-encryption-aws-kms-key-id`, Amazon S3 uses the Amazon Web Services managed key (`aws/s3` + * > key) in KMS to protect the data. + * + * ! All `GET` and `PUT` requests for an object protected by KMS fail if you don't make them by using Secure Sockets + * ! Layer (SSL), Transport Layer Security (TLS), or Signature Version 4. + * + * For more information about server-side encryption with KMS keys (SSE-KMS), see Protecting Data Using Server-Side + * Encryption with KMS keys [^13]. + * - Use customer-provided encryption keys (SSE-C) – If you want to manage your own encryption keys, provide all the + * following headers in the request. + * + * - `x-amz-server-side-encryption-customer-algorithm` + * - `x-amz-server-side-encryption-customer-key` + * - `x-amz-server-side-encryption-customer-key-MD5` + * + * For more information about server-side encryption with customer-provided encryption keys (SSE-C), see Protecting + * data using server-side encryption with customer-provided encryption keys (SSE-C) [^14]. + * + * - `Access-Control-List (ACL)-Specific Request Headers`: + * + * You also can use the following access control–related headers with this operation. By default, all objects are + * private. Only the owner has full access control. When adding a new object, you can grant permissions to individual + * Amazon Web Services accounts or to predefined groups defined by Amazon S3. These permissions are then added to the + * access control list (ACL) on the object. For more information, see Using ACLs [^15]. With this operation, you can + * grant access permissions using one of the following two methods: + * + * - Specify a canned ACL (`x-amz-acl`) — Amazon S3 supports a set of predefined ACLs, known as *canned ACLs*. Each + * canned ACL has a predefined set of grantees and permissions. For more information, see Canned ACL [^16]. + * - Specify access permissions explicitly — To explicitly grant access permissions to specific Amazon Web Services + * accounts or groups, use the following headers. Each header maps to specific permissions that Amazon S3 supports + * in an ACL. For more information, see Access Control List (ACL) Overview [^17]. In the header, you specify a list + * of grantees who get the specific permission. To grant permissions explicitly, use: + * + * - `x-amz-grant-read` + * - `x-amz-grant-write` + * - `x-amz-grant-read-acp` + * - `x-amz-grant-write-acp` + * - `x-amz-grant-full-control` + * + * You specify each grantee as a type=value pair, where the type is one of the following: + * + * - `id` – if the value specified is the canonical user ID of an Amazon Web Services account + * - `uri` – if you are granting permissions to a predefined group + * - `emailAddress` – if the value specified is the email address of an Amazon Web Services account + * + * > Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^18] in the + * > Amazon Web Services General Reference. + * + * + * For example, the following `x-amz-grant-read` header grants the Amazon Web Services accounts identified by + * account IDs permissions to read object data and its metadata: + * + * `x-amz-grant-read: id="11112222333", id="444455556666" ` + * + * + * The following operations are related to `CreateMultipartUpload`: + * + * - UploadPart [^19] + * - CompleteMultipartUpload [^20] + * - AbortMultipartUpload [^21] + * - ListParts [^22] + * - ListMultipartUploads [^23] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html#mpuAndPermissions + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL + * [^12]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^13]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html + * [^14]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html + * [^15]: https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html + * [^16]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL + * [^17]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^18]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * [^19]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^20]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^21]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^22]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^23]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|CreateMultipartUploadRequest $input + */ + public function createMultipartUpload($input): CreateMultipartUploadOutput + { + $input = CreateMultipartUploadRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CreateMultipartUpload', 'region' => $input->getRegion()])); + + return new CreateMultipartUploadOutput($response); + } + + /** + * Deletes the S3 bucket. All objects (including all object versions and delete markers) in the bucket must be deleted + * before the bucket itself can be deleted. + * + * The following operations are related to `DeleteBucket`: + * + * - CreateBucket [^1] + * - DeleteObject [^2] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETE.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deletebucket + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketRequest $input + */ + public function deleteBucket($input): Result + { + $input = DeleteBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteBucket', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Deletes the `cors` configuration information set for the bucket. + * + * To use this operation, you must have permission to perform the `s3:PutBucketCORS` action. The bucket owner has this + * permission by default and can grant this permission to others. + * + * For information about `cors`, see Enabling Cross-Origin Resource Sharing [^1] in the *Amazon S3 User Guide*. + * + * **Related Resources** + * + * - PutBucketCors [^2] + * - RESTOPTIONSobject [^3] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEcors.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deletebucketcors + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketCorsRequest $input + */ + public function deleteBucketCors($input): Result + { + $input = DeleteBucketCorsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteBucketCors', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Removes the null version (if there is one) of an object and inserts a delete marker, which becomes the latest version + * of the object. If there isn't a null version, Amazon S3 does not remove any objects but will still respond that the + * command was successful. + * + * To remove a specific version, you must use the version Id subresource. Using this subresource permanently deletes the + * version. If the object deleted is a delete marker, Amazon S3 sets the response header, `x-amz-delete-marker`, to + * true. + * + * If the object you want to delete is in a bucket where the bucket versioning configuration is MFA Delete enabled, you + * must include the `x-amz-mfa` request header in the DELETE `versionId` request. Requests that include `x-amz-mfa` must + * use HTTPS. + * + * For more information about MFA Delete, see Using MFA Delete [^1]. To see sample requests that use versioning, see + * Sample Request [^2]. + * + * You can delete objects by explicitly calling DELETE Object or configure its lifecycle (PutBucketLifecycle [^3]) to + * enable Amazon S3 to remove them for you. If you want to block users or accounts from removing or deleting objects + * from your bucket, you must deny them the `s3:DeleteObject`, `s3:DeleteObjectVersion`, and + * `s3:PutLifeCycleConfiguration` actions. + * + * The following action is related to `DeleteObject`: + * + * - PutObject [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html#ExampleVersionObjectDelete + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectDELETE.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deleteobject + * + * @param array{ + * Bucket: string, + * Key: string, + * MFA?: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectRequest $input + */ + public function deleteObject($input): DeleteObjectOutput + { + $input = DeleteObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteObject', 'region' => $input->getRegion()])); + + return new DeleteObjectOutput($response); + } + + /** + * Removes the entire tag set from the specified object. For more information about managing object tags, see Object + * Tagging [^1]. + * + * To use this operation, you must have permission to perform the `s3:DeleteObjectTagging` action. + * + * To delete tags of a specific object version, add the `versionId` query parameter in the request. You will need + * permission for the `s3:DeleteObjectVersionTagging` action. + * + * The following operations are related to `DeleteObjectTagging`: + * + * - PutObjectTagging [^2] + * - GetObjectTagging [^3] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deleteobjecttagging + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectTaggingRequest $input + */ + public function deleteObjectTagging($input): DeleteObjectTaggingOutput + { + $input = DeleteObjectTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteObjectTagging', 'region' => $input->getRegion()])); + + return new DeleteObjectTaggingOutput($response); + } + + /** + * This action enables you to delete multiple objects from a bucket using a single HTTP request. If you know the object + * keys that you want to delete, then this action provides a suitable alternative to sending individual delete requests, + * reducing per-request overhead. + * + * The request contains a list of up to 1000 keys that you want to delete. In the XML, you provide the object key names, + * and optionally, version IDs if you want to delete a specific version of the object from a versioning-enabled bucket. + * For each key, Amazon S3 performs a delete action and returns the result of that delete, success, or failure, in the + * response. Note that if the object specified in the request is not found, Amazon S3 returns the result as deleted. + * + * The action supports two modes for the response: verbose and quiet. By default, the action uses verbose mode in which + * the response includes the result of deletion of each key in your request. In quiet mode the response includes only + * keys where the delete action encountered an error. For a successful deletion, the action does not return any + * information about the delete in the response body. + * + * When performing this action on an MFA Delete enabled bucket, that attempts to delete any versioned objects, you must + * include an MFA token. If you do not provide one, the entire request will fail, even if there are non-versioned + * objects you are trying to delete. If you provide an invalid token, whether there are versioned keys in the request or + * not, the entire Multi-Object Delete request will fail. For information about MFA Delete, see MFA Delete [^1]. + * + * Finally, the Content-MD5 header is required for all Multi-Object Delete requests. Amazon S3 uses the header value to + * ensure that your request body has not been altered in transit. + * + * The following operations are related to `DeleteObjects`: + * + * - CreateMultipartUpload [^2] + * - UploadPart [^3] + * - CompleteMultipartUpload [^4] + * - ListParts [^5] + * - AbortMultipartUpload [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/multiobjectdeleteapi.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deleteobjects + * + * @param array{ + * Bucket: string, + * Delete: Delete|array, + * MFA?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|DeleteObjectsRequest $input + */ + public function deleteObjects($input): DeleteObjectsOutput + { + $input = DeleteObjectsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteObjects', 'region' => $input->getRegion()])); + + return new DeleteObjectsOutput($response); + } + + /** + * Returns the Cross-Origin Resource Sharing (CORS) configuration information set for the bucket. + * + * To use this operation, you must have permission to perform the `s3:GetBucketCORS` action. By default, the bucket + * owner has this permission and can grant it to others. + * + * To use this API operation against an access point, provide the alias of the access point in place of the bucket name. + * + * To use this API operation against an Object Lambda access point, provide the alias of the Object Lambda access point + * in place of the bucket name. If the Object Lambda access point alias in a request is not valid, the error code + * `InvalidAccessPointAliasError` is returned. For more information about `InvalidAccessPointAliasError`, see List of + * Error Codes [^1]. + * + * For more information about CORS, see Enabling Cross-Origin Resource Sharing [^2]. + * + * The following operations are related to `GetBucketCors`: + * + * - PutBucketCors [^3] + * - DeleteBucketCors [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETcors.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getbucketcors + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketCorsRequest $input + */ + public function getBucketCors($input): GetBucketCorsOutput + { + $input = GetBucketCorsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetBucketCors', 'region' => $input->getRegion()])); + + return new GetBucketCorsOutput($response); + } + + /** + * Returns the default encryption configuration for an Amazon S3 bucket. By default, all buckets have a default + * encryption configuration that uses server-side encryption with Amazon S3 managed keys (SSE-S3). For information about + * the bucket default encryption feature, see Amazon S3 Bucket Default Encryption [^1] in the *Amazon S3 User Guide*. + * + * To use this operation, you must have permission to perform the `s3:GetEncryptionConfiguration` action. The bucket + * owner has this permission by default. The bucket owner can grant this permission to others. For more information + * about permissions, see Permissions Related to Bucket Subresource Operations [^2] and Managing Access Permissions to + * Your Amazon S3 Resources [^3]. + * + * The following operations are related to `GetBucketEncryption`: + * + * - PutBucketEncryption [^4] + * - DeleteBucketEncryption [^5] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getbucketencryption + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketEncryptionRequest $input + */ + public function getBucketEncryption($input): GetBucketEncryptionOutput + { + $input = GetBucketEncryptionRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetBucketEncryption', 'region' => $input->getRegion()])); + + return new GetBucketEncryptionOutput($response); + } + + /** + * Retrieves objects from Amazon S3. To use `GET`, you must have `READ` access to the object. If you grant `READ` access + * to the anonymous user, you can return the object without using an authorization header. + * + * An Amazon S3 bucket has no directory hierarchy such as you would find in a typical computer file system. You can, + * however, create a logical hierarchy by using object key names that imply a folder structure. For example, instead of + * naming an object `sample.jpg`, you can name it `photos/2006/February/sample.jpg`. + * + * To get an object from such a logical hierarchy, specify the full key name for the object in the `GET` operation. For + * a virtual hosted-style request example, if you have the object `photos/2006/February/sample.jpg`, specify the + * resource as `/photos/2006/February/sample.jpg`. For a path-style request example, if you have the object + * `photos/2006/February/sample.jpg` in the bucket named `examplebucket`, specify the resource as + * `/examplebucket/photos/2006/February/sample.jpg`. For more information about request types, see HTTP Host Header + * Bucket Specification [^1]. + * + * For more information about returning the ACL of an object, see GetObjectAcl [^2]. + * + * If the object you are retrieving is stored in the S3 Glacier Flexible Retrieval or S3 Glacier Deep Archive storage + * class, or S3 Intelligent-Tiering Archive or S3 Intelligent-Tiering Deep Archive tiers, before you can retrieve the + * object you must first restore a copy using RestoreObject [^3]. Otherwise, this action returns an `InvalidObjectState` + * error. For information about restoring archived objects, see Restoring Archived Objects [^4]. + * + * Encryption request headers, like `x-amz-server-side-encryption`, should not be sent for GET requests if your object + * uses server-side encryption with Key Management Service (KMS) keys (SSE-KMS), dual-layer server-side encryption with + * Amazon Web Services KMS keys (DSSE-KMS), or server-side encryption with Amazon S3 managed encryption keys (SSE-S3). + * If your object does use these types of keys, you’ll get an HTTP 400 Bad Request error. + * + * If you encrypt an object by using server-side encryption with customer-provided encryption keys (SSE-C) when you + * store the object in Amazon S3, then when you GET the object, you must use the following headers: + * + * - `x-amz-server-side-encryption-customer-algorithm` + * - `x-amz-server-side-encryption-customer-key` + * - `x-amz-server-side-encryption-customer-key-MD5` + * + * For more information about SSE-C, see Server-Side Encryption (Using Customer-Provided Encryption Keys) [^5]. + * + * Assuming you have the relevant permission to read object tags, the response also returns the `x-amz-tagging-count` + * header that provides the count of number of tags associated with the object. You can use GetObjectTagging [^6] to + * retrieve the tag set associated with an object. + * + * - `Permissions`: + * + * You need the relevant read object (or version) permission for this operation. For more information, see Specifying + * Permissions in a Policy [^7]. If the object that you request doesn’t exist, the error that Amazon S3 returns + * depends on whether you also have the `s3:ListBucket` permission. + * + * If you have the `s3:ListBucket` permission on the bucket, Amazon S3 returns an HTTP status code 404 (Not Found) + * error. + * + * If you don’t have the `s3:ListBucket` permission, Amazon S3 returns an HTTP status code 403 ("access denied") + * error. + * - `Versioning`: + * + * By default, the `GET` action returns the current version of an object. To return a different version, use the + * `versionId` subresource. + * + * > - If you supply a `versionId`, you need the `s3:GetObjectVersion` permission to access a specific version of an + * > object. If you request a specific version, you do not need to have the `s3:GetObject` permission. If you + * > request the current version without a specific version ID, only `s3:GetObject` permission is required. + * > `s3:GetObjectVersion` permission won't be required. + * > - If the current version of the object is a delete marker, Amazon S3 behaves as if the object was deleted and + * > includes `x-amz-delete-marker: true` in the response. + * > + * + * For more information about versioning, see PutBucketVersioning [^8]. + * - `Overriding Response Header Values`: + * + * There are times when you want to override certain response header values in a `GET` response. For example, you + * might override the `Content-Disposition` response header value in your `GET` request. + * + * You can override values for a set of response headers using the following query parameters. These response header + * values are sent only on a successful request, that is, when status code 200 OK is returned. The set of headers you + * can override using these parameters is a subset of the headers that Amazon S3 accepts when you create an object. + * The response headers that you can override for the `GET` response are `Content-Type`, `Content-Language`, + * `Expires`, `Cache-Control`, `Content-Disposition`, and `Content-Encoding`. To override these header values in the + * `GET` response, you use the following request parameters. + * + * > You must sign the request, either using an Authorization header or a presigned URL, when using these parameters. + * > They cannot be used with an unsigned (anonymous) request. + * + * - `response-content-type` + * - `response-content-language` + * - `response-expires` + * - `response-cache-control` + * - `response-content-disposition` + * - `response-content-encoding` + * + * - `Overriding Response Header Values`: + * + * If both of the `If-Match` and `If-Unmodified-Since` headers are present in the request as follows: `If-Match` + * condition evaluates to `true`, and; `If-Unmodified-Since` condition evaluates to `false`; then, S3 returns 200 OK + * and the data requested. + * + * If both of the `If-None-Match` and `If-Modified-Since` headers are present in the request as follows:` + * If-None-Match` condition evaluates to `false`, and; `If-Modified-Since` condition evaluates to `true`; then, S3 + * returns 304 Not Modified response code. + * + * For more information about conditional requests, see RFC 7232 [^9]. + * + * The following operations are related to `GetObject`: + * + * - ListBuckets [^10] + * - GetObjectAcl [^11] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#VirtualHostingSpecifyBucket + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html + * [^9]: https://tools.ietf.org/html/rfc7232 + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getobject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * ResponseCacheControl?: string, + * ResponseContentDisposition?: string, + * ResponseContentEncoding?: string, + * ResponseContentLanguage?: string, + * ResponseContentType?: string, + * ResponseExpires?: \DateTimeImmutable|string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|GetObjectRequest $input + * + * @throws NoSuchKeyException + * @throws InvalidObjectStateException + */ + public function getObject($input): GetObjectOutput + { + $input = GetObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + 'InvalidObjectState' => InvalidObjectStateException::class, + ]])); + + return new GetObjectOutput($response); + } + + /** + * Returns the access control list (ACL) of an object. To use this operation, you must have `s3:GetObjectAcl` + * permissions or `READ_ACP` access to the object. For more information, see Mapping of ACL permissions and access + * policy permissions [^1] in the *Amazon S3 User Guide*. + * + * This action is not supported by Amazon S3 on Outposts. + * + * By default, GET returns ACL information about the current version of an object. To return ACL information about a + * different version, use the versionId subresource. + * + * > If your bucket uses the bucket owner enforced setting for S3 Object Ownership, requests to read ACLs are still + * > supported and return the `bucket-owner-full-control` ACL with the owner being the account that created the bucket. + * > For more information, see Controlling object ownership and disabling ACLs [^2] in the *Amazon S3 User Guide*. + * + * The following operations are related to `GetObjectAcl`: + * + * - GetObject [^3] + * - GetObjectAttributes [^4] + * - DeleteObject [^5] + * - PutObject [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#acl-access-policy-permission-mapping + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGETacl.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getobjectacl + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetObjectAclRequest $input + * + * @throws NoSuchKeyException + */ + public function getObjectAcl($input): GetObjectAclOutput + { + $input = GetObjectAclRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetObjectAcl', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new GetObjectAclOutput($response); + } + + /** + * Returns the tag-set of an object. You send the GET request against the tagging subresource associated with the + * object. + * + * To use this operation, you must have permission to perform the `s3:GetObjectTagging` action. By default, the GET + * action returns information about current version of an object. For a versioned bucket, you can have multiple versions + * of an object in your bucket. To retrieve tags of any other version, use the versionId query parameter. You also need + * permission for the `s3:GetObjectVersionTagging` action. + * + * By default, the bucket owner has this permission and can grant this permission to others. + * + * For information about the Amazon S3 object tagging feature, see Object Tagging [^1]. + * + * The following actions are related to `GetObjectTagging`: + * + * - DeleteObjectTagging [^2] + * - GetObjectAttributes [^3] + * - PutObjectTagging [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getobjecttagging + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|GetObjectTaggingRequest $input + */ + public function getObjectTagging($input): GetObjectTaggingOutput + { + $input = GetObjectTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetObjectTagging', 'region' => $input->getRegion()])); + + return new GetObjectTaggingOutput($response); + } + + /** + * The `HEAD` action retrieves metadata from an object without returning the object itself. This action is useful if + * you're only interested in an object's metadata. To use `HEAD`, you must have READ access to the object. + * + * A `HEAD` request has the same options as a `GET` action on an object. The response is identical to the `GET` response + * except that there is no response body. Because of this, if the `HEAD` request generates an error, it returns a + * generic `400 Bad Request`, `403 Forbidden` or `404 Not Found` code. It is not possible to retrieve the exact + * exception beyond these error codes. + * + * If you encrypt an object by using server-side encryption with customer-provided encryption keys (SSE-C) when you + * store the object in Amazon S3, then when you retrieve the metadata from the object, you must use the following + * headers: + * + * - `x-amz-server-side-encryption-customer-algorithm` + * - `x-amz-server-side-encryption-customer-key` + * - `x-amz-server-side-encryption-customer-key-MD5` + * + * For more information about SSE-C, see Server-Side Encryption (Using Customer-Provided Encryption Keys) [^1]. + * + * > - Encryption request headers, like `x-amz-server-side-encryption`, should not be sent for `GET` requests if your + * > object uses server-side encryption with Key Management Service (KMS) keys (SSE-KMS), dual-layer server-side + * > encryption with Amazon Web Services KMS keys (DSSE-KMS), or server-side encryption with Amazon S3 managed + * > encryption keys (SSE-S3). If your object does use these types of keys, you’ll get an HTTP 400 Bad Request + * > error. + * > - The last modified property in this case is the creation date of the object. + * > + * + * Request headers are limited to 8 KB in size. For more information, see Common Request Headers [^2]. + * + * Consider the following when using request headers: + * + * - Consideration 1 – If both of the `If-Match` and `If-Unmodified-Since` headers are present in the request as + * follows: + * + * - `If-Match` condition evaluates to `true`, and; + * - `If-Unmodified-Since` condition evaluates to `false`; + * + * Then Amazon S3 returns `200 OK` and the data requested. + * - Consideration 2 – If both of the `If-None-Match` and `If-Modified-Since` headers are present in the request as + * follows: + * + * - `If-None-Match` condition evaluates to `false`, and; + * - `If-Modified-Since` condition evaluates to `true`; + * + * Then Amazon S3 returns the `304 Not Modified` response code. + * + * For more information about conditional requests, see RFC 7232 [^3]. + * + * - `Permissions`: + * + * You need the relevant read object (or version) permission for this operation. For more information, see Actions, + * resources, and condition keys for Amazon S3 [^4]. If the object you request doesn't exist, the error that Amazon S3 + * returns depends on whether you also have the s3:ListBucket permission. + * + * - If you have the `s3:ListBucket` permission on the bucket, Amazon S3 returns an HTTP status code 404 error. + * - If you don’t have the `s3:ListBucket` permission, Amazon S3 returns an HTTP status code 403 error. + * + * + * The following actions are related to `HeadObject`: + * + * - GetObject [^5] + * - GetObjectAttributes [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html + * [^3]: https://tools.ietf.org/html/rfc7232 + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/list_amazons3.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectHEAD.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#headobject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + * + * @throws NoSuchKeyException + */ + public function headObject($input): HeadObjectOutput + { + $input = HeadObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new HeadObjectOutput($response); + } + + /** + * Returns a list of all buckets owned by the authenticated sender of the request. To use this operation, you must have + * the `s3:ListAllMyBuckets` permission. + * + * For information about Amazon S3 buckets, see Creating, configuring, and working with Amazon S3 buckets [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-buckets-s3.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTServiceGET.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listbuckets + * + * @param array{ + * '@region'?: string|null, + * }|ListBucketsRequest $input + */ + public function listBuckets($input = []): ListBucketsOutput + { + $input = ListBucketsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListBuckets', 'region' => $input->getRegion()])); + + return new ListBucketsOutput($response); + } + + /** + * This action lists in-progress multipart uploads. An in-progress multipart upload is a multipart upload that has been + * initiated using the Initiate Multipart Upload request, but has not yet been completed or aborted. + * + * This action returns at most 1,000 multipart uploads in the response. 1,000 multipart uploads is the maximum number of + * uploads a response can include, which is also the default value. You can further limit the number of uploads in a + * response by specifying the `max-uploads` parameter in the response. If additional multipart uploads satisfy the list + * criteria, the response will contain an `IsTruncated` element with the value true. To list the additional multipart + * uploads, use the `key-marker` and `upload-id-marker` request parameters. + * + * In the response, the uploads are sorted by key. If your application has initiated more than one multipart upload + * using the same object key, then uploads in the response are first sorted by key. Additionally, uploads are sorted in + * ascending order within each key by the upload initiation time. + * + * For more information on multipart uploads, see Uploading Objects Using Multipart Upload [^1]. + * + * For information on permissions required to use the multipart upload API, see Multipart Upload and Permissions [^2]. + * + * The following operations are related to `ListMultipartUploads`: + * + * - CreateMultipartUpload [^3] + * - UploadPart [^4] + * - CompleteMultipartUpload [^5] + * - ListParts [^6] + * - AbortMultipartUpload [^7] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListMPUpload.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listmultipartuploads + * + * @param array{ + * Bucket: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * KeyMarker?: string, + * MaxUploads?: int, + * Prefix?: string, + * UploadIdMarker?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|ListMultipartUploadsRequest $input + */ + public function listMultipartUploads($input): ListMultipartUploadsOutput + { + $input = ListMultipartUploadsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListMultipartUploads', 'region' => $input->getRegion()])); + + return new ListMultipartUploadsOutput($response, $this, $input); + } + + /** + * Returns some or all (up to 1,000) of the objects in a bucket with each request. You can use the request parameters as + * selection criteria to return a subset of the objects in a bucket. A `200 OK` response can contain valid or invalid + * XML. Make sure to design your application to parse the contents of the response and handle it appropriately. Objects + * are returned sorted in an ascending order of the respective key names in the list. For more information about listing + * objects, see Listing object keys programmatically [^1] in the *Amazon S3 User Guide*. + * + * To use this operation, you must have READ access to the bucket. + * + * To use this action in an Identity and Access Management (IAM) policy, you must have permission to perform the + * `s3:ListBucket` action. The bucket owner has this permission by default and can grant this permission to others. For + * more information about permissions, see Permissions Related to Bucket Subresource Operations [^2] and Managing Access + * Permissions to Your Amazon S3 Resources [^3] in the *Amazon S3 User Guide*. + * + * ! This section describes the latest revision of this action. We recommend that you use this revised API operation for + * ! application development. For backward compatibility, Amazon S3 continues to support the prior version of this API + * ! operation, ListObjects [^4]. + * + * To get a list of your buckets, see ListBuckets [^5]. + * + * The following operations are related to `ListObjectsV2`: + * + * - GetObject [^6] + * - PutObject [^7] + * - CreateBucket [^8] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ListingKeysUsingAPIs.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listobjectsv2 + * + * @param array{ + * Bucket: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * MaxKeys?: int, + * Prefix?: string, + * ContinuationToken?: string, + * FetchOwner?: bool, + * StartAfter?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * OptionalObjectAttributes?: array, + * '@region'?: string|null, + * }|ListObjectsV2Request $input + * + * @throws NoSuchBucketException + */ + public function listObjectsV2($input): ListObjectsV2Output + { + $input = ListObjectsV2Request::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListObjectsV2', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchBucket' => NoSuchBucketException::class, + ]])); + + return new ListObjectsV2Output($response, $this, $input); + } + + /** + * Lists the parts that have been uploaded for a specific multipart upload. This operation must include the upload ID, + * which you obtain by sending the initiate multipart upload request (see CreateMultipartUpload [^1]). This request + * returns a maximum of 1,000 uploaded parts. The default number of parts returned is 1,000 parts. You can restrict the + * number of parts returned by specifying the `max-parts` request parameter. If your multipart upload consists of more + * than 1,000 parts, the response returns an `IsTruncated` field with the value of true, and a `NextPartNumberMarker` + * element. In subsequent `ListParts` requests you can include the part-number-marker query string parameter and set its + * value to the `NextPartNumberMarker` field value from the previous response. + * + * If the upload was created using a checksum algorithm, you will need to have permission to the `kms:Decrypt` action + * for the request to succeed. + * + * For more information on multipart uploads, see Uploading Objects Using Multipart Upload [^2]. + * + * For information on permissions required to use the multipart upload API, see Multipart Upload and Permissions [^3]. + * + * The following operations are related to `ListParts`: + * + * - CreateMultipartUpload [^4] + * - UploadPart [^5] + * - CompleteMultipartUpload [^6] + * - AbortMultipartUpload [^7] + * - GetObjectAttributes [^8] + * - ListMultipartUploads [^9] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListParts.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listparts + * + * @param array{ + * Bucket: string, + * Key: string, + * MaxParts?: int, + * PartNumberMarker?: int, + * UploadId: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|ListPartsRequest $input + */ + public function listParts($input): ListPartsOutput + { + $input = ListPartsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListParts', 'region' => $input->getRegion()])); + + return new ListPartsOutput($response, $this, $input); + } + + /** + * @see headObject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + */ + public function objectExists($input): ObjectExistsWaiter + { + $input = HeadObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new ObjectExistsWaiter($response, $this, $input); + } + + /** + * @see headObject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + */ + public function objectNotExists($input): ObjectNotExistsWaiter + { + $input = HeadObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new ObjectNotExistsWaiter($response, $this, $input); + } + + /** + * Sets the `cors` configuration for your bucket. If the configuration exists, Amazon S3 replaces it. + * + * To use this operation, you must be allowed to perform the `s3:PutBucketCORS` action. By default, the bucket owner has + * this permission and can grant it to others. + * + * You set this configuration on a bucket so that the bucket can service cross-origin requests. For example, you might + * want to enable a request whose origin is `http://www.example.com` to access your Amazon S3 bucket at + * `my.example.bucket.com` by using the browser's `XMLHttpRequest` capability. + * + * To enable cross-origin resource sharing (CORS) on a bucket, you add the `cors` subresource to the bucket. The `cors` + * subresource is an XML document in which you configure rules that identify origins and the HTTP methods that can be + * executed on your bucket. The document is limited to 64 KB in size. + * + * When Amazon S3 receives a cross-origin request (or a pre-flight OPTIONS request) against a bucket, it evaluates the + * `cors` configuration on the bucket and uses the first `CORSRule` rule that matches the incoming browser request to + * enable a cross-origin request. For a rule to match, the following conditions must be met: + * + * - The request's `Origin` header must match `AllowedOrigin` elements. + * - The request method (for example, GET, PUT, HEAD, and so on) or the `Access-Control-Request-Method` header in case + * of a pre-flight `OPTIONS` request must be one of the `AllowedMethod` elements. + * - Every header specified in the `Access-Control-Request-Headers` request header of a pre-flight request must match an + * `AllowedHeader` element. + * + * For more information about CORS, go to Enabling Cross-Origin Resource Sharing [^1] in the *Amazon S3 User Guide*. + * + * The following operations are related to `PutBucketCors`: + * + * - GetBucketCors [^2] + * - DeleteBucketCors [^3] + * - RESTOPTIONSobject [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTcors.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putbucketcors + * + * @param array{ + * Bucket: string, + * CORSConfiguration: CORSConfiguration|array, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketCorsRequest $input + */ + public function putBucketCors($input): Result + { + $input = PutBucketCorsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutBucketCors', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Enables notifications of specified events for a bucket. For more information about event notifications, see + * Configuring Event Notifications [^1]. + * + * Using this API, you can replace an existing notification configuration. The configuration is an XML file that defines + * the event types that you want Amazon S3 to publish and the destination where you want Amazon S3 to publish an event + * notification when it detects an event of the specified type. + * + * By default, your bucket has no event notifications configured. That is, the notification configuration will be an + * empty `NotificationConfiguration`. + * + * `` + * + * `` + * + * This action replaces the existing notification configuration with the configuration you include in the request body. + * + * After Amazon S3 receives this request, it first verifies that any Amazon Simple Notification Service (Amazon SNS) or + * Amazon Simple Queue Service (Amazon SQS) destination exists, and that the bucket owner has permission to publish to + * it by sending a test notification. In the case of Lambda destinations, Amazon S3 verifies that the Lambda function + * permissions grant Amazon S3 permission to invoke the function from the Amazon S3 bucket. For more information, see + * Configuring Notifications for Amazon S3 Events [^2]. + * + * You can disable notifications by adding the empty NotificationConfiguration element. + * + * For more information about the number of event notification configurations that you can create per bucket, see Amazon + * S3 service quotas [^3] in *Amazon Web Services General Reference*. + * + * By default, only the bucket owner can configure notifications on a bucket. However, bucket owners can use a bucket + * policy to grant permission to other users to set this configuration with the required `s3:PutBucketNotification` + * permission. + * + * > The PUT notification is an atomic operation. For example, suppose your notification configuration includes SNS + * > topic, SQS queue, and Lambda function configurations. When you send a PUT request with this configuration, Amazon + * > S3 sends test messages to your SNS topic. If the message fails, the entire PUT action will fail, and Amazon S3 will + * > not add the configuration to your bucket. + * + * If the configuration in the request body includes only one `TopicConfiguration` specifying only the + * `s3:ReducedRedundancyLostObject` event type, the response will also include the `x-amz-sns-test-message-id` header + * containing the message ID of the test notification sent to the topic. + * + * The following action is related to `PutBucketNotificationConfiguration`: + * + * - GetBucketNotificationConfiguration [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html + * [^3]: https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3 + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotificationConfiguration.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putbucketnotificationconfiguration + * + * @param array{ + * Bucket: string, + * NotificationConfiguration: NotificationConfiguration|array, + * ExpectedBucketOwner?: string, + * SkipDestinationValidation?: bool, + * '@region'?: string|null, + * }|PutBucketNotificationConfigurationRequest $input + */ + public function putBucketNotificationConfiguration($input): Result + { + $input = PutBucketNotificationConfigurationRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutBucketNotificationConfiguration', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Sets the tags for a bucket. + * + * Use tags to organize your Amazon Web Services bill to reflect your own cost structure. To do this, sign up to get + * your Amazon Web Services account bill with tag key values included. Then, to see the cost of combined resources, + * organize your billing information according to resources with the same tag key values. For example, you can tag + * several resources with a specific application name, and then organize your billing information to see the total cost + * of that application across several services. For more information, see Cost Allocation and Tagging [^1] and Using + * Cost Allocation in Amazon S3 Bucket Tags [^2]. + * + * > When this operation sets the tags for a bucket, it will overwrite any current tags the bucket already has. You + * > cannot use this operation to add tags to an existing list of tags. + * + * To use this operation, you must have permissions to perform the `s3:PutBucketTagging` action. The bucket owner has + * this permission by default and can grant this permission to others. For more information about permissions, see + * Permissions Related to Bucket Subresource Operations [^3] and Managing Access Permissions to Your Amazon S3 Resources + * [^4]. + * + * `PutBucketTagging` has the following special errors: + * + * - Error code: `InvalidTagError` + * + * - Description: The tag provided was not a valid tag. This error can occur if the tag did not pass input validation. + * For information about tag restrictions, see User-Defined Tag Restrictions [^5] and Amazon Web Services-Generated + * Cost Allocation Tag Restrictions [^6]. + * + * - Error code: `MalformedXMLError` + * + * - Description: The XML provided does not match the schema. + * + * - Error code: `OperationAbortedError ` + * + * - Description: A conflicting conditional action is currently in progress against this resource. Please try again. + * + * - Error code: `InternalError` + * + * - Description: The service was unable to apply the provided tag to the bucket. + * + * + * The following operations are related to `PutBucketTagging`: + * + * - GetBucketTagging [^7] + * - DeleteBucketTagging [^8] + * + * [^1]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/CostAllocTagging.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html + * [^5]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html + * [^6]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/aws-tag-restrictions.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTtagging.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putbuckettagging + * + * @param array{ + * Bucket: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging: Tagging|array, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketTaggingRequest $input + */ + public function putBucketTagging($input): Result + { + $input = PutBucketTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutBucketTagging', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Adds an object to a bucket. You must have WRITE permissions on a bucket to add an object to it. + * + * > Amazon S3 never adds partial objects; if you receive a success response, Amazon S3 added the entire object to the + * > bucket. You cannot use `PutObject` to only update a single piece of metadata for an existing object. You must put + * > the entire object with updated metadata if you want to update some values. + * + * Amazon S3 is a distributed system. If it receives multiple write requests for the same object simultaneously, it + * overwrites all but the last object written. To prevent objects from being deleted or overwritten, you can use Amazon + * S3 Object Lock [^1]. + * + * To ensure that data is not corrupted traversing the network, use the `Content-MD5` header. When you use this header, + * Amazon S3 checks the object against the provided MD5 value and, if they do not match, returns an error. Additionally, + * you can calculate the MD5 while putting an object to Amazon S3 and compare the returned ETag to the calculated MD5 + * value. + * + * > - To successfully complete the `PutObject` request, you must have the `s3:PutObject` in your IAM permissions. + * > - To successfully change the objects acl of your `PutObject` request, you must have the `s3:PutObjectAcl` in your + * > IAM permissions. + * > - To successfully set the tag-set with your `PutObject` request, you must have the `s3:PutObjectTagging` in your + * > IAM permissions. + * > - The `Content-MD5` header is required for any request to upload an object with a retention period configured using + * > Amazon S3 Object Lock. For more information about Amazon S3 Object Lock, see Amazon S3 Object Lock Overview [^2] + * > in the *Amazon S3 User Guide*. + * > + * + * You have four mutually exclusive options to protect data using server-side encryption in Amazon S3, depending on how + * you choose to manage the encryption keys. Specifically, the encryption key options are Amazon S3 managed keys + * (SSE-S3), Amazon Web Services KMS keys (SSE-KMS or DSSE-KMS), and customer-provided keys (SSE-C). Amazon S3 encrypts + * data with server-side encryption by using Amazon S3 managed keys (SSE-S3) by default. You can optionally tell Amazon + * S3 to encrypt data at rest by using server-side encryption with other key options. For more information, see Using + * Server-Side Encryption [^3]. + * + * When adding a new object, you can use headers to grant ACL-based permissions to individual Amazon Web Services + * accounts or to predefined groups defined by Amazon S3. These permissions are then added to the ACL on the object. By + * default, all objects are private. Only the owner has full access control. For more information, see Access Control + * List (ACL) Overview [^4] and Managing ACLs Using the REST API [^5]. + * + * If the bucket that you're uploading objects to uses the bucket owner enforced setting for S3 Object Ownership, ACLs + * are disabled and no longer affect permissions. Buckets that use this setting only accept PUT requests that don't + * specify an ACL or PUT requests that specify bucket owner full control ACLs, such as the `bucket-owner-full-control` + * canned ACL or an equivalent form of this ACL expressed in the XML format. PUT requests that contain other ACLs (for + * example, custom grants to certain Amazon Web Services accounts) fail and return a `400` error with the error code + * `AccessControlListNotSupported`. For more information, see Controlling ownership of objects and disabling ACLs [^6] + * in the *Amazon S3 User Guide*. + * + * > If your bucket uses the bucket owner enforced setting for Object Ownership, all objects written to the bucket by + * > any account will be owned by the bucket owner. + * + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^7] in + * the *Amazon S3 User Guide*. + * + * If you enable versioning for a bucket, Amazon S3 automatically generates a unique version ID for the object being + * stored. Amazon S3 returns this ID in the response. When you enable versioning for a bucket, if Amazon S3 receives + * multiple write requests for the same object simultaneously, it stores all of the objects. For more information about + * versioning, see Adding Objects to Versioning-Enabled Buckets [^8]. For information about returning the versioning + * state of a bucket, see GetBucketVersioning [^9]. + * + * For more information about related Amazon S3 APIs, see the following: + * + * - CopyObject [^10] + * - DeleteObject [^11] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/dev/AddingObjectstoVersioningEnabledBuckets.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUT.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ContentType?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectRequest $input + */ + public function putObject($input): PutObjectOutput + { + $input = PutObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObject', 'region' => $input->getRegion()])); + + return new PutObjectOutput($response); + } + + /** + * Uses the `acl` subresource to set the access control list (ACL) permissions for a new or existing object in an S3 + * bucket. You must have `WRITE_ACP` permission to set the ACL of an object. For more information, see What permissions + * can I grant? [^1] in the *Amazon S3 User Guide*. + * + * This action is not supported by Amazon S3 on Outposts. + * + * Depending on your application needs, you can choose to set the ACL on an object using either the request body or the + * headers. For example, if you have an existing application that updates a bucket ACL using the request body, you can + * continue to use that approach. For more information, see Access Control List (ACL) Overview [^2] in the *Amazon S3 + * User Guide*. + * + * ! If your bucket uses the bucket owner enforced setting for S3 Object Ownership, ACLs are disabled and no longer + * ! affect permissions. You must use policies to grant access to your bucket and the objects in it. Requests to set + * ! ACLs or update ACLs fail and return the `AccessControlListNotSupported` error code. Requests to read ACLs are still + * ! supported. For more information, see Controlling object ownership [^3] in the *Amazon S3 User Guide*. + * + * - `Permissions`: + * + * You can set access permissions using one of the following methods: + * + * - Specify a canned ACL with the `x-amz-acl` request header. Amazon S3 supports a set of predefined ACLs, known as + * canned ACLs. Each canned ACL has a predefined set of grantees and permissions. Specify the canned ACL name as the + * value of `x-amz-ac`l. If you use this header, you cannot use other access control-specific headers in your + * request. For more information, see Canned ACL [^4]. + * - Specify access permissions explicitly with the `x-amz-grant-read`, `x-amz-grant-read-acp`, + * `x-amz-grant-write-acp`, and `x-amz-grant-full-control` headers. When using these headers, you specify explicit + * access permissions and grantees (Amazon Web Services accounts or Amazon S3 groups) who will receive the + * permission. If you use these ACL-specific headers, you cannot use `x-amz-acl` header to set a canned ACL. These + * parameters map to the set of permissions that Amazon S3 supports in an ACL. For more information, see Access + * Control List (ACL) Overview [^5]. + * + * You specify each grantee as a type=value pair, where the type is one of the following: + * + * - `id` – if the value specified is the canonical user ID of an Amazon Web Services account + * - `uri` – if you are granting permissions to a predefined group + * - `emailAddress` – if the value specified is the email address of an Amazon Web Services account + * + * > Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^6] in the Amazon + * > Web Services General Reference. + * + * + * For example, the following `x-amz-grant-read` header grants list objects permission to the two Amazon Web + * Services accounts identified by their email addresses. + * + * `x-amz-grant-read: emailAddress="xyz@amazon.com", emailAddress="abc@amazon.com" ` + * + * You can use either a canned ACL or specify access permissions explicitly. You cannot do both. + * - `Grantee Values`: + * + * You can specify the person (grantee) to whom you're assigning access rights (using request elements) in the + * following ways: + * + * - By the person's ID: + * + * `<>ID<><>GranteesEmail<> + * ` + * + * DisplayName is optional and ignored in the request. + * - By URI: + * + * `<>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<>` + * - By Email address: + * + * `<>Grantees@email.com<>lt;/Grantee>` + * + * The grantee is resolved to the CanonicalUser and, in a response to a GET Object acl request, appears as the + * CanonicalUser. + * + * > Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^7] in the Amazon + * > Web Services General Reference. + * + * + * - `Versioning`: + * + * The ACL of an object is set at the object version level. By default, PUT sets the ACL of the current version of an + * object. To set the ACL of a different version, use the `versionId` subresource. + * + * The following operations are related to `PutObjectAcl`: + * + * - CopyObject [^8] + * - GetObject [^9] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#permissions + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^6]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * [^7]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUTacl.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectAcl.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobjectacl + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * AccessControlPolicy?: AccessControlPolicy|array, + * Bucket: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * Key: string, + * RequestPayer?: RequestPayer::*, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectAclRequest $input + * + * @throws NoSuchKeyException + */ + public function putObjectAcl($input): PutObjectAclOutput + { + $input = PutObjectAclRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObjectAcl', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new PutObjectAclOutput($response); + } + + /** + * Sets the supplied tag-set to an object that already exists in a bucket. + * + * A tag is a key-value pair. You can associate tags with an object by sending a PUT request against the tagging + * subresource that is associated with the object. You can retrieve tags by sending a GET request. For more information, + * see GetObjectTagging [^1]. + * + * For tagging-related restrictions related to characters and encodings, see Tag Restrictions [^2]. Note that Amazon S3 + * limits the maximum number of tags to 10 tags per object. + * + * To use this operation, you must have permission to perform the `s3:PutObjectTagging` action. By default, the bucket + * owner has this permission and can grant this permission to others. + * + * To put tags of any other version, use the `versionId` query parameter. You also need permission for the + * `s3:PutObjectVersionTagging` action. + * + * For information about the Amazon S3 object tagging feature, see Object Tagging [^3]. + * + * `PutObjectTagging` has the following special errors: + * + * - - *Code: InvalidTagError * + * - - *Cause: The tag provided was not a valid tag. This error can occur if the tag did not pass input validation. For + * - more information, see Object Tagging [^4].* + * - + * - - *Code: MalformedXMLError * + * - - *Cause: The XML provided does not match the schema.* + * - + * - - *Code: OperationAbortedError * + * - - *Cause: A conflicting conditional action is currently in progress against this resource. Please try again.* + * - + * - - *Code: InternalError* + * - - *Cause: The service was unable to apply the provided tag to the object.* + * - + * + * The following operations are related to `PutObjectTagging`: + * + * - GetObjectTagging [^5] + * - DeleteObjectTagging [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * [^2]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobjecttagging + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging: Tagging|array, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|PutObjectTaggingRequest $input + */ + public function putObjectTagging($input): PutObjectTaggingOutput + { + $input = PutObjectTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObjectTagging', 'region' => $input->getRegion()])); + + return new PutObjectTaggingOutput($response); + } + + /** + * Uploads a part in a multipart upload. + * + * > In this operation, you provide part data in your request. However, you have an option to specify your existing + * > Amazon S3 object as a data source for the part you are uploading. To upload a part from an existing object, you use + * > the UploadPartCopy [^1] operation. + * + * You must initiate a multipart upload (see CreateMultipartUpload [^2]) before you can upload any part. In response to + * your initiate request, Amazon S3 returns an upload ID, a unique identifier, that you must include in your upload part + * request. + * + * Part numbers can be any number from 1 to 10,000, inclusive. A part number uniquely identifies a part and also defines + * its position within the object being created. If you upload a new part using the same part number that was used with + * a previous part, the previously uploaded part is overwritten. + * + * For information about maximum and minimum part sizes and other multipart upload specifications, see Multipart upload + * limits [^3] in the *Amazon S3 User Guide*. + * + * To ensure that data is not corrupted when traversing the network, specify the `Content-MD5` header in the upload part + * request. Amazon S3 checks the part data against the provided MD5 value. If they do not match, Amazon S3 returns an + * error. + * + * If the upload request is signed with Signature Version 4, then Amazon Web Services S3 uses the `x-amz-content-sha256` + * header as a checksum instead of `Content-MD5`. For more information see Authenticating Requests: Using the + * Authorization Header (Amazon Web Services Signature Version 4) [^4]. + * + * **Note:** After you initiate multipart upload and upload one or more parts, you must either complete or abort + * multipart upload in order to stop getting charged for storage of the uploaded parts. Only after you either complete + * or abort multipart upload, Amazon S3 frees up the parts storage and stops charging you for the parts storage. + * + * For more information on multipart uploads, go to Multipart Upload Overview [^5] in the *Amazon S3 User Guide *. + * + * For information on the permissions required to use the multipart upload API, go to Multipart Upload and Permissions + * [^6] in the *Amazon S3 User Guide*. + * + * Server-side encryption is for data encryption at rest. Amazon S3 encrypts your data as it writes it to disks in its + * data centers and decrypts it when you access it. You have three mutually exclusive options to protect data using + * server-side encryption in Amazon S3, depending on how you choose to manage the encryption keys. Specifically, the + * encryption key options are Amazon S3 managed keys (SSE-S3), Amazon Web Services KMS keys (SSE-KMS), and + * Customer-Provided Keys (SSE-C). Amazon S3 encrypts data with server-side encryption using Amazon S3 managed keys + * (SSE-S3) by default. You can optionally tell Amazon S3 to encrypt data at rest using server-side encryption with + * other key options. The option you use depends on whether you want to use KMS keys (SSE-KMS) or provide your own + * encryption key (SSE-C). If you choose to provide your own encryption key, the request headers you provide in the + * request must match the headers you used in the request to initiate the upload by using CreateMultipartUpload [^7]. + * For more information, go to Using Server-Side Encryption [^8] in the *Amazon S3 User Guide*. + * + * Server-side encryption is supported by the S3 Multipart Upload actions. Unless you are using a customer-provided + * encryption key (SSE-C), you don't need to specify the encryption parameters in each UploadPart request. Instead, you + * only need to specify the server-side encryption parameters in the initial Initiate Multipart request. For more + * information, see CreateMultipartUpload [^9]. + * + * If you requested server-side encryption using a customer-provided encryption key (SSE-C) in your initiate multipart + * upload request, you must provide identical encryption information in each part upload using the following headers. + * + * - x-amz-server-side-encryption-customer-algorithm + * - x-amz-server-side-encryption-customer-key + * - x-amz-server-side-encryption-customer-key-MD5 + * + * `UploadPart` has the following special errors: + * + * - - *Code: NoSuchUpload* + * - - *Cause: The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload + * - might have been aborted or completed.* + * - - * HTTP Status Code: 404 Not Found * + * - - *SOAP Fault Code Prefix: Client* + * - + * + * The following operations are related to `UploadPart`: + * + * - CreateMultipartUpload [^10] + * - CompleteMultipartUpload [^11] + * - AbortMultipartUpload [^12] + * - ListParts [^13] + * - ListMultipartUploads [^14] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^12]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^13]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^14]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPart.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#uploadpart + * + * @param array{ + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket: string, + * ContentLength?: int, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Key: string, + * PartNumber: int, + * UploadId: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|UploadPartRequest $input + */ + public function uploadPart($input): UploadPartOutput + { + $input = UploadPartRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'UploadPart', 'region' => $input->getRegion()])); + + return new UploadPartOutput($response); + } + + protected function getAwsErrorFactory(): AwsErrorFactoryInterface + { + return new XmlAwsErrorFactory(); + } + + protected function getEndpoint(string $uri, array $query, ?string $region): string + { + $uriParts = explode('/', $uri, 3); + $bucket = explode('?', $uriParts[1] ?? '', 2)[0]; + $uriWithOutBucket = substr($uriParts[1] ?? '', \strlen($bucket)) . ($uriParts[2] ?? ''); + $bucketLen = \strlen($bucket); + $configuration = $this->getConfiguration(); + + if ( + $bucketLen < 3 || $bucketLen > 63 + || filter_var($bucket, \FILTER_VALIDATE_IP) // Cannot look like an IP address + || !preg_match('/^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$/', $bucket) // Bucket cannot have dot (because of TLS) + || filter_var(parse_url($configuration->get('endpoint'), \PHP_URL_HOST), \FILTER_VALIDATE_IP) // Custom endpoint cannot look like an IP address + || filter_var($configuration->get('pathStyleEndpoint'), \FILTER_VALIDATE_BOOLEAN) + ) { + return parent::getEndpoint($uri, $query, $region); + } + + return preg_replace('|https?://|', '${0}' . $bucket . '.', parent::getEndpoint('/' . $uriWithOutBucket, $query, $region)); + } + + protected function getEndpointMetadata(?string $region): array + { + if (null === $region) { + return [ + 'endpoint' => 'https://s3.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + } + + switch ($region) { + case 'af-south-1': + case 'ap-east-1': + case 'ap-northeast-1': + case 'ap-northeast-2': + case 'ap-northeast-3': + case 'ap-south-1': + case 'ap-south-2': + case 'ap-southeast-1': + case 'ap-southeast-2': + case 'ap-southeast-3': + case 'ap-southeast-4': + case 'ca-central-1': + case 'eu-central-1': + case 'eu-central-2': + case 'eu-north-1': + case 'eu-south-1': + case 'eu-south-2': + case 'eu-west-1': + case 'eu-west-2': + case 'eu-west-3': + case 'il-central-1': + case 'me-central-1': + case 'me-south-1': + case 'sa-east-1': + case 'us-east-1': + case 'us-east-2': + case 'us-gov-east-1': + case 'us-gov-west-1': + case 'us-west-1': + case 'us-west-2': + return [ + 'endpoint' => "https://s3.$region.amazonaws.com", + 'signRegion' => $region, + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'cn-north-1': + case 'cn-northwest-1': + return [ + 'endpoint' => "https://s3.$region.amazonaws.com.cn", + 'signRegion' => $region, + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 's3-external-1': + return [ + 'endpoint' => 'https://s3-external-1.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-ca-central-1': + return [ + 'endpoint' => 'https://s3-fips.ca-central-1.amazonaws.com', + 'signRegion' => 'ca-central-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-east-1': + return [ + 'endpoint' => 'https://s3-fips.us-east-1.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-east-2': + return [ + 'endpoint' => 'https://s3-fips.us-east-2.amazonaws.com', + 'signRegion' => 'us-east-2', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-west-1': + return [ + 'endpoint' => 'https://s3-fips.us-west-1.amazonaws.com', + 'signRegion' => 'us-west-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-west-2': + return [ + 'endpoint' => 'https://s3-fips.us-west-2.amazonaws.com', + 'signRegion' => 'us-west-2', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-gov-east-1': + return [ + 'endpoint' => 'https://s3-fips.us-gov-east-1.amazonaws.com', + 'signRegion' => 'us-gov-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-gov-west-1': + return [ + 'endpoint' => 'https://s3-fips.us-gov-west-1.amazonaws.com', + 'signRegion' => 'us-gov-west-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'us-iso-east-1': + case 'us-iso-west-1': + return [ + 'endpoint' => "https://s3.$region.c2s.ic.gov", + 'signRegion' => $region, + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'us-isob-east-1': + return [ + 'endpoint' => 'https://s3.us-isob-east-1.sc2s.sgov.gov', + 'signRegion' => 'us-isob-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + } + + return [ + 'endpoint' => 'https://s3.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + } + + protected function getServiceCode(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 's3'; + } + + protected function getSignatureScopeName(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 's3'; + } + + protected function getSignatureVersion(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 's3v4'; + } + + protected function getSignerFactories(): array + { + return [ + 's3v4' => function (string $service, string $region) { + $configuration = $this->getConfiguration(); + $options = []; + + // We need async-aws/core: 1.8 or above to use sendChunkedBody. + if (Configuration::optionExists('sendChunkedBody')) { + $options['sendChunkedBody'] = filter_var($configuration->get('sendChunkedBody'), \FILTER_VALIDATE_BOOLEAN); + } + + return new SignerV4ForS3($service, $region, $options); + }, + ] + parent::getSignerFactories(); + } +} diff --git a/vendor/async-aws/s3/src/Signer/SignerV4ForS3.php b/vendor/async-aws/s3/src/Signer/SignerV4ForS3.php new file mode 100644 index 000000000..dad5c97db --- /dev/null +++ b/vendor/async-aws/s3/src/Signer/SignerV4ForS3.php @@ -0,0 +1,173 @@ + + */ +class SignerV4ForS3 extends SignerV4 +{ + private const ALGORITHM_CHUNK = 'AWS4-HMAC-SHA256-PAYLOAD'; + private const CHUNK_SIZE = 64 * 1024; + + private const MD5_OPERATIONS = [ + 'DeleteObjects' => true, + 'PutBucketCors' => true, + 'PutBucketLifecycle' => true, + 'PutBucketLifecycleConfiguration' => true, + 'PutBucketPolicy' => true, + 'PutBucketTagging' => true, + 'PutBucketReplication' => true, + 'PutObjectLegalHold' => true, + 'PutObjectRetention' => true, + 'PutObjectLockConfiguration' => true, + ]; + + /** + * @var bool + */ + private $sendChunkedBody; + + /** + * @param array{ + * sendChunkedBody?: bool, + * } $s3SignerOptions + */ + public function __construct(string $scopeName, string $region, array $s3SignerOptions = []) + { + parent::__construct($scopeName, $region); + + $this->sendChunkedBody = $s3SignerOptions[Configuration::OPTION_SEND_CHUNKED_BODY] ?? false; + unset($s3SignerOptions[Configuration::OPTION_SEND_CHUNKED_BODY]); + + if (!empty($s3SignerOptions)) { + throw new InvalidArgument(sprintf('Invalid option(s) "%s" passed to "%s::%s". ', implode('", "', array_keys($s3SignerOptions)), __CLASS__, __METHOD__)); + } + } + + public function sign(Request $request, Credentials $credentials, RequestContext $context): void + { + if ((null === ($operation = $context->getOperation()) || isset(self::MD5_OPERATIONS[$operation])) && !$request->hasHeader('content-md5')) { + $request->setHeader('content-md5', base64_encode($request->getBody()->hash('md5', true))); + } + + if (!$request->hasHeader('x-amz-content-sha256')) { + $request->setHeader('x-amz-content-sha256', $request->getBody()->hash()); + } + + parent::sign($request, $credentials, $context); + } + + protected function buildBodyDigest(Request $request, bool $isPresign): string + { + if ($isPresign) { + $request->setHeader('x-amz-content-sha256', 'UNSIGNED-PAYLOAD'); + + return 'UNSIGNED-PAYLOAD'; + } + + return parent::buildBodyDigest($request, $isPresign); + } + + /** + * Amazon S3 does not double-encode the path component in the canonical request. + */ + protected function buildCanonicalPath(Request $request): string + { + return '/' . ltrim($request->getUri(), '/'); + } + + protected function convertBodyToStream(SigningContext $context): void + { + $request = $context->getRequest(); + $body = $request->getBody(); + if ($request->hasHeader('content-length')) { + $contentLength = (int) $request->getHeader('content-length'); + } else { + $contentLength = $body->length(); + } + + // If content length is unknown, use the rewindable stream to read it once locally in order to get the length + if (null === $contentLength) { + $request->setBody($body = RewindableStream::create($body)); + $body->read(); + $contentLength = $body->length(); + } + + // no need to stream small body. It's simple to convert it to string directly + if ($contentLength < self::CHUNK_SIZE || !$this->sendChunkedBody) { + if ($body instanceof ReadOnceResultStream) { + $request->setBody(RewindableStream::create($body)); + } + + return; + } + + // Add content-encoding for chunked stream if available + $customEncoding = $request->getHeader('content-encoding'); + + // Convert the body into a chunked stream + $request->setHeader('content-encoding', $customEncoding ? "aws-chunked, $customEncoding" : 'aws-chunked'); + $request->setHeader('x-amz-decoded-content-length', (string) $contentLength); + $request->setHeader('x-amz-content-sha256', 'STREAMING-' . self::ALGORITHM_CHUNK); + + // Compute size of content + metadata used sign each Chunk + $chunkCount = (int) ceil($contentLength / self::CHUNK_SIZE); + $fullChunkCount = $chunkCount * self::CHUNK_SIZE === $contentLength ? $chunkCount : ($chunkCount - 1); + $metaLength = \strlen(";chunk-signature=\r\n\r\n") + 64; + $request->setHeader('content-length', (string) ($contentLength + $fullChunkCount * ($metaLength + \strlen(dechex(self::CHUNK_SIZE))) + ($chunkCount - $fullChunkCount) * ($metaLength + \strlen(dechex($contentLength % self::CHUNK_SIZE))) + $metaLength + 1)); + $body = RewindableStream::create(IterableStream::create((function (RequestStream $body) use ($context): iterable { + $now = $context->getNow(); + $credentialString = $context->getCredentialString(); + $signingKey = $context->getSigningKey(); + $signature = $context->getSignature(); + foreach (FixedSizeStream::create($body, self::CHUNK_SIZE) as $chunk) { + $stringToSign = $this->buildChunkStringToSign($now, $credentialString, $signature, $chunk); + $context->setSignature($signature = $this->buildSignature($stringToSign, $signingKey)); + yield sprintf("%s;chunk-signature=%s\r\n", dechex(\strlen($chunk)), $signature) . "$chunk\r\n"; + } + + $stringToSign = $this->buildChunkStringToSign($now, $credentialString, $signature, ''); + $context->setSignature($signature = $this->buildSignature($stringToSign, $signingKey)); + + yield sprintf("%s;chunk-signature=%s\r\n\r\n", dechex(0), $signature); + })($body))); + + $request->setBody($body); + } + + private function buildChunkStringToSign(\DateTimeImmutable $now, string $credentialString, string $signature, string $chunk): string + { + static $emptyHash; + $emptyHash = $emptyHash ?? hash('sha256', ''); + + return implode("\n", [ + self::ALGORITHM_CHUNK, + $now->format('Ymd\THis\Z'), + $credentialString, + $signature, + $emptyHash, + hash('sha256', $chunk), + ]); + } + + private function buildSignature(string $stringToSign, string $signingKey): string + { + return hash_hmac('sha256', $stringToSign, $signingKey); + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php b/vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php new file mode 100644 index 000000000..117ad9f21 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php @@ -0,0 +1,79 @@ +, + * Owner?: null|Owner|array, + * } $input + */ + public function __construct(array $input) + { + $this->grants = isset($input['Grants']) ? array_map([Grant::class, 'create'], $input['Grants']) : null; + $this->owner = isset($input['Owner']) ? Owner::create($input['Owner']) : null; + } + + /** + * @param array{ + * Grants?: null|array, + * Owner?: null|Owner|array, + * }|AccessControlPolicy $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return Grant[] + */ + public function getGrants(): array + { + return $this->grants ?? []; + } + + public function getOwner(): ?Owner + { + return $this->owner; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->grants) { + $node->appendChild($nodeList = $document->createElement('AccessControlList')); + foreach ($v as $item) { + $nodeList->appendChild($child = $document->createElement('Grant')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->owner) { + $node->appendChild($child = $document->createElement('Owner')); + + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/AwsObject.php b/vendor/async-aws/s3/src/ValueObject/AwsObject.php new file mode 100644 index 000000000..30f8e57bf --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/AwsObject.php @@ -0,0 +1,169 @@ +|null + */ + private $checksumAlgorithm; + + /** + * Size in bytes of the object. + * + * @var int|null + */ + private $size; + + /** + * The class of storage used to store the object. + * + * @var ObjectStorageClass::*|null + */ + private $storageClass; + + /** + * The owner of the object. + * + * @var Owner|null + */ + private $owner; + + /** + * Specifies the restoration status of an object. Objects in certain storage classes must be restored before they can be + * retrieved. For more information about these storage classes and how to work with archived objects, see Working with + * archived objects [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/archived-objects.html + * + * @var RestoreStatus|null + */ + private $restoreStatus; + + /** + * @param array{ + * Key?: null|string, + * LastModified?: null|\DateTimeImmutable, + * ETag?: null|string, + * ChecksumAlgorithm?: null|array, + * Size?: null|int, + * StorageClass?: null|ObjectStorageClass::*, + * Owner?: null|Owner|array, + * RestoreStatus?: null|RestoreStatus|array, + * } $input + */ + public function __construct(array $input) + { + $this->key = $input['Key'] ?? null; + $this->lastModified = $input['LastModified'] ?? null; + $this->etag = $input['ETag'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->size = $input['Size'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->owner = isset($input['Owner']) ? Owner::create($input['Owner']) : null; + $this->restoreStatus = isset($input['RestoreStatus']) ? RestoreStatus::create($input['RestoreStatus']) : null; + } + + /** + * @param array{ + * Key?: null|string, + * LastModified?: null|\DateTimeImmutable, + * ETag?: null|string, + * ChecksumAlgorithm?: null|array, + * Size?: null|int, + * StorageClass?: null|ObjectStorageClass::*, + * Owner?: null|Owner|array, + * RestoreStatus?: null|RestoreStatus|array, + * }|AwsObject $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getChecksumAlgorithm(): array + { + return $this->checksumAlgorithm ?? []; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getLastModified(): ?\DateTimeImmutable + { + return $this->lastModified; + } + + public function getOwner(): ?Owner + { + return $this->owner; + } + + public function getRestoreStatus(): ?RestoreStatus + { + return $this->restoreStatus; + } + + public function getSize(): ?int + { + return $this->size; + } + + /** + * @return ObjectStorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Bucket.php b/vendor/async-aws/s3/src/ValueObject/Bucket.php new file mode 100644 index 000000000..1e3800e66 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Bucket.php @@ -0,0 +1,58 @@ +name = $input['Name'] ?? null; + $this->creationDate = $input['CreationDate'] ?? null; + } + + /** + * @param array{ + * Name?: null|string, + * CreationDate?: null|\DateTimeImmutable, + * }|Bucket $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getCreationDate(): ?\DateTimeImmutable + { + return $this->creationDate; + } + + public function getName(): ?string + { + return $this->name; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php b/vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php new file mode 100644 index 000000000..7d7e30014 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php @@ -0,0 +1,71 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->corsRules = isset($input['CORSRules']) ? array_map([CORSRule::class, 'create'], $input['CORSRules']) : $this->throwException(new InvalidArgument('Missing required field "CORSRules".')); + } + + /** + * @param array{ + * CORSRules: array, + * }|CORSConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return CORSRule[] + */ + public function getCorsRules(): array + { + return $this->corsRules; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->corsRules; + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('CORSRule')); + + $item->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CORSRule.php b/vendor/async-aws/s3/src/ValueObject/CORSRule.php new file mode 100644 index 000000000..161030cbc --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CORSRule.php @@ -0,0 +1,174 @@ +id = $input['ID'] ?? null; + $this->allowedHeaders = $input['AllowedHeaders'] ?? null; + $this->allowedMethods = $input['AllowedMethods'] ?? $this->throwException(new InvalidArgument('Missing required field "AllowedMethods".')); + $this->allowedOrigins = $input['AllowedOrigins'] ?? $this->throwException(new InvalidArgument('Missing required field "AllowedOrigins".')); + $this->exposeHeaders = $input['ExposeHeaders'] ?? null; + $this->maxAgeSeconds = $input['MaxAgeSeconds'] ?? null; + } + + /** + * @param array{ + * ID?: null|string, + * AllowedHeaders?: null|string[], + * AllowedMethods: string[], + * AllowedOrigins: string[], + * ExposeHeaders?: null|string[], + * MaxAgeSeconds?: null|int, + * }|CORSRule $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return string[] + */ + public function getAllowedHeaders(): array + { + return $this->allowedHeaders ?? []; + } + + /** + * @return string[] + */ + public function getAllowedMethods(): array + { + return $this->allowedMethods; + } + + /** + * @return string[] + */ + public function getAllowedOrigins(): array + { + return $this->allowedOrigins; + } + + /** + * @return string[] + */ + public function getExposeHeaders(): array + { + return $this->exposeHeaders ?? []; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getMaxAgeSeconds(): ?int + { + return $this->maxAgeSeconds; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('ID', $v)); + } + if (null !== $v = $this->allowedHeaders) { + foreach ($v as $item) { + $node->appendChild($document->createElement('AllowedHeader', $item)); + } + } + $v = $this->allowedMethods; + foreach ($v as $item) { + $node->appendChild($document->createElement('AllowedMethod', $item)); + } + + $v = $this->allowedOrigins; + foreach ($v as $item) { + $node->appendChild($document->createElement('AllowedOrigin', $item)); + } + + if (null !== $v = $this->exposeHeaders) { + foreach ($v as $item) { + $node->appendChild($document->createElement('ExposeHeader', $item)); + } + } + if (null !== $v = $this->maxAgeSeconds) { + $node->appendChild($document->createElement('MaxAgeSeconds', (string) $v)); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CommonPrefix.php b/vendor/async-aws/s3/src/ValueObject/CommonPrefix.php new file mode 100644 index 000000000..ca0256337 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CommonPrefix.php @@ -0,0 +1,43 @@ +prefix = $input['Prefix'] ?? null; + } + + /** + * @param array{ + * Prefix?: null|string, + * }|CommonPrefix $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getPrefix(): ?string + { + return $this->prefix; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php b/vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php new file mode 100644 index 000000000..44e088101 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php @@ -0,0 +1,60 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->parts = isset($input['Parts']) ? array_map([CompletedPart::class, 'create'], $input['Parts']) : null; + } + + /** + * @param array{ + * Parts?: null|array, + * }|CompletedMultipartUpload $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return CompletedPart[] + */ + public function getParts(): array + { + return $this->parts ?? []; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->parts) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('Part')); + + $item->requestBody($child, $document); + } + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CompletedPart.php b/vendor/async-aws/s3/src/ValueObject/CompletedPart.php new file mode 100644 index 000000000..ff679d1d4 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CompletedPart.php @@ -0,0 +1,157 @@ +etag = $input['ETag'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + } + + /** + * @param array{ + * ETag?: null|string, + * ChecksumCRC32?: null|string, + * ChecksumCRC32C?: null|string, + * ChecksumSHA1?: null|string, + * ChecksumSHA256?: null|string, + * PartNumber?: null|int, + * }|CompletedPart $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->etag) { + $node->appendChild($document->createElement('ETag', $v)); + } + if (null !== $v = $this->checksumCrc32) { + $node->appendChild($document->createElement('ChecksumCRC32', $v)); + } + if (null !== $v = $this->checksumCrc32C) { + $node->appendChild($document->createElement('ChecksumCRC32C', $v)); + } + if (null !== $v = $this->checksumSha1) { + $node->appendChild($document->createElement('ChecksumSHA1', $v)); + } + if (null !== $v = $this->checksumSha256) { + $node->appendChild($document->createElement('ChecksumSHA256', $v)); + } + if (null !== $v = $this->partNumber) { + $node->appendChild($document->createElement('PartNumber', (string) $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php b/vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php new file mode 100644 index 000000000..bca5cbc46 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php @@ -0,0 +1,132 @@ +etag = $input['ETag'] ?? null; + $this->lastModified = $input['LastModified'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + } + + /** + * @param array{ + * ETag?: null|string, + * LastModified?: null|\DateTimeImmutable, + * ChecksumCRC32?: null|string, + * ChecksumCRC32C?: null|string, + * ChecksumSHA1?: null|string, + * ChecksumSHA256?: null|string, + * }|CopyObjectResult $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getLastModified(): ?\DateTimeImmutable + { + return $this->lastModified; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php b/vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php new file mode 100644 index 000000000..c87fc55a7 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php @@ -0,0 +1,61 @@ +locationConstraint = $input['LocationConstraint'] ?? null; + } + + /** + * @param array{ + * LocationConstraint?: null|BucketLocationConstraint::*, + * }|CreateBucketConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return BucketLocationConstraint::*|null + */ + public function getLocationConstraint(): ?string + { + return $this->locationConstraint; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->locationConstraint) { + if (!BucketLocationConstraint::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "LocationConstraint" for "%s". The value "%s" is not a valid "BucketLocationConstraint".', __CLASS__, $v)); + } + $node->appendChild($document->createElement('LocationConstraint', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Delete.php b/vendor/async-aws/s3/src/ValueObject/Delete.php new file mode 100644 index 000000000..461c4233d --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Delete.php @@ -0,0 +1,86 @@ +, + * Quiet?: null|bool, + * } $input + */ + public function __construct(array $input) + { + $this->objects = isset($input['Objects']) ? array_map([ObjectIdentifier::class, 'create'], $input['Objects']) : $this->throwException(new InvalidArgument('Missing required field "Objects".')); + $this->quiet = $input['Quiet'] ?? null; + } + + /** + * @param array{ + * Objects: array, + * Quiet?: null|bool, + * }|Delete $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectIdentifier[] + */ + public function getObjects(): array + { + return $this->objects; + } + + public function getQuiet(): ?bool + { + return $this->quiet; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->objects; + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('Object')); + + $item->requestBody($child, $document); + } + + if (null !== $v = $this->quiet) { + $node->appendChild($document->createElement('Quiet', $v ? 'true' : 'false')); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/DeletedObject.php b/vendor/async-aws/s3/src/ValueObject/DeletedObject.php new file mode 100644 index 000000000..63b892c73 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/DeletedObject.php @@ -0,0 +1,88 @@ +key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->deleteMarker = $input['DeleteMarker'] ?? null; + $this->deleteMarkerVersionId = $input['DeleteMarkerVersionId'] ?? null; + } + + /** + * @param array{ + * Key?: null|string, + * VersionId?: null|string, + * DeleteMarker?: null|bool, + * DeleteMarkerVersionId?: null|string, + * }|DeletedObject $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDeleteMarker(): ?bool + { + return $this->deleteMarker; + } + + public function getDeleteMarkerVersionId(): ?string + { + return $this->deleteMarkerVersionId; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Error.php b/vendor/async-aws/s3/src/ValueObject/Error.php new file mode 100644 index 000000000..76757f941 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Error.php @@ -0,0 +1,563 @@ +key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->code = $input['Code'] ?? null; + $this->message = $input['Message'] ?? null; + } + + /** + * @param array{ + * Key?: null|string, + * VersionId?: null|string, + * Code?: null|string, + * Message?: null|string, + * }|Error $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getCode(): ?string + { + return $this->code; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMessage(): ?string + { + return $this->message; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php b/vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php new file mode 100644 index 000000000..af46db007 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php @@ -0,0 +1,24 @@ +name = $input['Name'] ?? null; + $this->value = $input['Value'] ?? null; + } + + /** + * @param array{ + * Name?: null|FilterRuleName::*, + * Value?: null|string, + * }|FilterRule $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return FilterRuleName::*|null + */ + public function getName(): ?string + { + return $this->name; + } + + public function getValue(): ?string + { + return $this->value; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->name) { + if (!FilterRuleName::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "Name" for "%s". The value "%s" is not a valid "FilterRuleName".', __CLASS__, $v)); + } + $node->appendChild($document->createElement('Name', $v)); + } + if (null !== $v = $this->value) { + $node->appendChild($document->createElement('Value', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Grant.php b/vendor/async-aws/s3/src/ValueObject/Grant.php new file mode 100644 index 000000000..7e2796aab --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Grant.php @@ -0,0 +1,80 @@ +grantee = isset($input['Grantee']) ? Grantee::create($input['Grantee']) : null; + $this->permission = $input['Permission'] ?? null; + } + + /** + * @param array{ + * Grantee?: null|Grantee|array, + * Permission?: null|Permission::*, + * }|Grant $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getGrantee(): ?Grantee + { + return $this->grantee; + } + + /** + * @return Permission::*|null + */ + public function getPermission(): ?string + { + return $this->permission; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->grantee) { + $node->appendChild($child = $document->createElement('Grantee')); + $child->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $v->requestBody($child, $document); + } + if (null !== $v = $this->permission) { + if (!Permission::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "Permission" for "%s". The value "%s" is not a valid "Permission".', __CLASS__, $v)); + } + $node->appendChild($document->createElement('Permission', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Grantee.php b/vendor/async-aws/s3/src/ValueObject/Grantee.php new file mode 100644 index 000000000..02ec9e48c --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Grantee.php @@ -0,0 +1,155 @@ + Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^1] in the Amazon Web + * > Services General Reference. + * + * [^1]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * + * @var string|null + */ + private $emailAddress; + + /** + * The canonical user ID of the grantee. + * + * @var string|null + */ + private $id; + + /** + * Type of grantee. + * + * @var Type::* + */ + private $type; + + /** + * URI of the grantee group. + * + * @var string|null + */ + private $uri; + + /** + * @param array{ + * DisplayName?: null|string, + * EmailAddress?: null|string, + * ID?: null|string, + * Type: Type::*, + * URI?: null|string, + * } $input + */ + public function __construct(array $input) + { + $this->displayName = $input['DisplayName'] ?? null; + $this->emailAddress = $input['EmailAddress'] ?? null; + $this->id = $input['ID'] ?? null; + $this->type = $input['Type'] ?? $this->throwException(new InvalidArgument('Missing required field "Type".')); + $this->uri = $input['URI'] ?? null; + } + + /** + * @param array{ + * DisplayName?: null|string, + * EmailAddress?: null|string, + * ID?: null|string, + * Type: Type::*, + * URI?: null|string, + * }|Grantee $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDisplayName(): ?string + { + return $this->displayName; + } + + public function getEmailAddress(): ?string + { + return $this->emailAddress; + } + + public function getId(): ?string + { + return $this->id; + } + + /** + * @return Type::* + */ + public function getType(): string + { + return $this->type; + } + + public function getUri(): ?string + { + return $this->uri; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->displayName) { + $node->appendChild($document->createElement('DisplayName', $v)); + } + if (null !== $v = $this->emailAddress) { + $node->appendChild($document->createElement('EmailAddress', $v)); + } + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('ID', $v)); + } + $v = $this->type; + if (!Type::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "xsi:type" for "%s". The value "%s" is not a valid "Type".', __CLASS__, $v)); + } + $node->setAttribute('xsi:type', $v); + if (null !== $v = $this->uri) { + $node->appendChild($document->createElement('URI', $v)); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Initiator.php b/vendor/async-aws/s3/src/ValueObject/Initiator.php new file mode 100644 index 000000000..92ac8cc85 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Initiator.php @@ -0,0 +1,57 @@ +id = $input['ID'] ?? null; + $this->displayName = $input['DisplayName'] ?? null; + } + + /** + * @param array{ + * ID?: null|string, + * DisplayName?: null|string, + * }|Initiator $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDisplayName(): ?string + { + return $this->displayName; + } + + public function getId(): ?string + { + return $this->id; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php b/vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php new file mode 100644 index 000000000..93560e896 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php @@ -0,0 +1,124 @@ + + */ + private $events; + + /** + * @var NotificationConfigurationFilter|null + */ + private $filter; + + /** + * @param array{ + * Id?: null|string, + * LambdaFunctionArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * } $input + */ + public function __construct(array $input) + { + $this->id = $input['Id'] ?? null; + $this->lambdaFunctionArn = $input['LambdaFunctionArn'] ?? $this->throwException(new InvalidArgument('Missing required field "LambdaFunctionArn".')); + $this->events = $input['Events'] ?? $this->throwException(new InvalidArgument('Missing required field "Events".')); + $this->filter = isset($input['Filter']) ? NotificationConfigurationFilter::create($input['Filter']) : null; + } + + /** + * @param array{ + * Id?: null|string, + * LambdaFunctionArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * }|LambdaFunctionConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getEvents(): array + { + return $this->events; + } + + public function getFilter(): ?NotificationConfigurationFilter + { + return $this->filter; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getLambdaFunctionArn(): string + { + return $this->lambdaFunctionArn; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('Id', $v)); + } + $v = $this->lambdaFunctionArn; + $node->appendChild($document->createElement('CloudFunction', $v)); + $v = $this->events; + foreach ($v as $item) { + if (!Event::exists($item)) { + throw new InvalidArgument(sprintf('Invalid parameter "Event" for "%s". The value "%s" is not a valid "Event".', __CLASS__, $item)); + } + $node->appendChild($document->createElement('Event', $item)); + } + + if (null !== $v = $this->filter) { + $node->appendChild($child = $document->createElement('Filter')); + + $v->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/MultipartUpload.php b/vendor/async-aws/s3/src/ValueObject/MultipartUpload.php new file mode 100644 index 000000000..2123ffc64 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/MultipartUpload.php @@ -0,0 +1,140 @@ +uploadId = $input['UploadId'] ?? null; + $this->key = $input['Key'] ?? null; + $this->initiated = $input['Initiated'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->owner = isset($input['Owner']) ? Owner::create($input['Owner']) : null; + $this->initiator = isset($input['Initiator']) ? Initiator::create($input['Initiator']) : null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + } + + /** + * @param array{ + * UploadId?: null|string, + * Key?: null|string, + * Initiated?: null|\DateTimeImmutable, + * StorageClass?: null|StorageClass::*, + * Owner?: null|Owner|array, + * Initiator?: null|Initiator|array, + * ChecksumAlgorithm?: null|ChecksumAlgorithm::*, + * }|MultipartUpload $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getInitiated(): ?\DateTimeImmutable + { + return $this->initiated; + } + + public function getInitiator(): ?Initiator + { + return $this->initiator; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getOwner(): ?Owner + { + return $this->owner; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php b/vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php new file mode 100644 index 000000000..1ed51523e --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php @@ -0,0 +1,129 @@ +, + * QueueConfigurations?: null|array, + * LambdaFunctionConfigurations?: null|array, + * EventBridgeConfiguration?: null|EventBridgeConfiguration|array, + * } $input + */ + public function __construct(array $input) + { + $this->topicConfigurations = isset($input['TopicConfigurations']) ? array_map([TopicConfiguration::class, 'create'], $input['TopicConfigurations']) : null; + $this->queueConfigurations = isset($input['QueueConfigurations']) ? array_map([QueueConfiguration::class, 'create'], $input['QueueConfigurations']) : null; + $this->lambdaFunctionConfigurations = isset($input['LambdaFunctionConfigurations']) ? array_map([LambdaFunctionConfiguration::class, 'create'], $input['LambdaFunctionConfigurations']) : null; + $this->eventBridgeConfiguration = isset($input['EventBridgeConfiguration']) ? EventBridgeConfiguration::create($input['EventBridgeConfiguration']) : null; + } + + /** + * @param array{ + * TopicConfigurations?: null|array, + * QueueConfigurations?: null|array, + * LambdaFunctionConfigurations?: null|array, + * EventBridgeConfiguration?: null|EventBridgeConfiguration|array, + * }|NotificationConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getEventBridgeConfiguration(): ?EventBridgeConfiguration + { + return $this->eventBridgeConfiguration; + } + + /** + * @return LambdaFunctionConfiguration[] + */ + public function getLambdaFunctionConfigurations(): array + { + return $this->lambdaFunctionConfigurations ?? []; + } + + /** + * @return QueueConfiguration[] + */ + public function getQueueConfigurations(): array + { + return $this->queueConfigurations ?? []; + } + + /** + * @return TopicConfiguration[] + */ + public function getTopicConfigurations(): array + { + return $this->topicConfigurations ?? []; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->topicConfigurations) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('TopicConfiguration')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->queueConfigurations) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('QueueConfiguration')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->lambdaFunctionConfigurations) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('CloudFunctionConfiguration')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->eventBridgeConfiguration) { + $node->appendChild($child = $document->createElement('EventBridgeConfiguration')); + + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php b/vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php new file mode 100644 index 000000000..d50acbabe --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php @@ -0,0 +1,54 @@ +key = isset($input['Key']) ? S3KeyFilter::create($input['Key']) : null; + } + + /** + * @param array{ + * Key?: null|S3KeyFilter|array, + * }|NotificationConfigurationFilter $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): ?S3KeyFilter + { + return $this->key; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->key) { + $node->appendChild($child = $document->createElement('S3Key')); + + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php b/vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php new file mode 100644 index 000000000..39308f337 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php @@ -0,0 +1,83 @@ +key = $input['Key'] ?? $this->throwException(new InvalidArgument('Missing required field "Key".')); + $this->versionId = $input['VersionId'] ?? null; + } + + /** + * @param array{ + * Key: string, + * VersionId?: null|string, + * }|ObjectIdentifier $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): string + { + return $this->key; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->key; + $node->appendChild($document->createElement('Key', $v)); + if (null !== $v = $this->versionId) { + $node->appendChild($document->createElement('VersionId', $v)); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Owner.php b/vendor/async-aws/s3/src/ValueObject/Owner.php new file mode 100644 index 000000000..43f1910a0 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Owner.php @@ -0,0 +1,79 @@ +displayName = $input['DisplayName'] ?? null; + $this->id = $input['ID'] ?? null; + } + + /** + * @param array{ + * DisplayName?: null|string, + * ID?: null|string, + * }|Owner $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDisplayName(): ?string + { + return $this->displayName; + } + + public function getId(): ?string + { + return $this->id; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->displayName) { + $node->appendChild($document->createElement('DisplayName', $v)); + } + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('ID', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Part.php b/vendor/async-aws/s3/src/ValueObject/Part.php new file mode 100644 index 000000000..3c873eac2 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Part.php @@ -0,0 +1,162 @@ +partNumber = $input['PartNumber'] ?? null; + $this->lastModified = $input['LastModified'] ?? null; + $this->etag = $input['ETag'] ?? null; + $this->size = $input['Size'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + } + + /** + * @param array{ + * PartNumber?: null|int, + * LastModified?: null|\DateTimeImmutable, + * ETag?: null|string, + * Size?: null|int, + * ChecksumCRC32?: null|string, + * ChecksumCRC32C?: null|string, + * ChecksumSHA1?: null|string, + * ChecksumSHA256?: null|string, + * }|Part $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getLastModified(): ?\DateTimeImmutable + { + return $this->lastModified; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + public function getSize(): ?int + { + return $this->size; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php b/vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php new file mode 100644 index 000000000..29a6c78d1 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php @@ -0,0 +1,123 @@ + + */ + private $events; + + /** + * @var NotificationConfigurationFilter|null + */ + private $filter; + + /** + * @param array{ + * Id?: null|string, + * QueueArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * } $input + */ + public function __construct(array $input) + { + $this->id = $input['Id'] ?? null; + $this->queueArn = $input['QueueArn'] ?? $this->throwException(new InvalidArgument('Missing required field "QueueArn".')); + $this->events = $input['Events'] ?? $this->throwException(new InvalidArgument('Missing required field "Events".')); + $this->filter = isset($input['Filter']) ? NotificationConfigurationFilter::create($input['Filter']) : null; + } + + /** + * @param array{ + * Id?: null|string, + * QueueArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * }|QueueConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getEvents(): array + { + return $this->events; + } + + public function getFilter(): ?NotificationConfigurationFilter + { + return $this->filter; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getQueueArn(): string + { + return $this->queueArn; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('Id', $v)); + } + $v = $this->queueArn; + $node->appendChild($document->createElement('Queue', $v)); + $v = $this->events; + foreach ($v as $item) { + if (!Event::exists($item)) { + throw new InvalidArgument(sprintf('Invalid parameter "Event" for "%s". The value "%s" is not a valid "Event".', __CLASS__, $item)); + } + $node->appendChild($document->createElement('Event', $item)); + } + + if (null !== $v = $this->filter) { + $node->appendChild($child = $document->createElement('Filter')); + + $v->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/RestoreStatus.php b/vendor/async-aws/s3/src/ValueObject/RestoreStatus.php new file mode 100644 index 000000000..9bb53275b --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/RestoreStatus.php @@ -0,0 +1,72 @@ +isRestoreInProgress = $input['IsRestoreInProgress'] ?? null; + $this->restoreExpiryDate = $input['RestoreExpiryDate'] ?? null; + } + + /** + * @param array{ + * IsRestoreInProgress?: null|bool, + * RestoreExpiryDate?: null|\DateTimeImmutable, + * }|RestoreStatus $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getIsRestoreInProgress(): ?bool + { + return $this->isRestoreInProgress; + } + + public function getRestoreExpiryDate(): ?\DateTimeImmutable + { + return $this->restoreExpiryDate; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php b/vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php new file mode 100644 index 000000000..4cd6925ed --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php @@ -0,0 +1,56 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->filterRules = isset($input['FilterRules']) ? array_map([FilterRule::class, 'create'], $input['FilterRules']) : null; + } + + /** + * @param array{ + * FilterRules?: null|array, + * }|S3KeyFilter $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return FilterRule[] + */ + public function getFilterRules(): array + { + return $this->filterRules ?? []; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->filterRules) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('FilterRule')); + + $item->requestBody($child, $document); + } + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php new file mode 100644 index 000000000..36f4a6384 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php @@ -0,0 +1,92 @@ +sseAlgorithm = $input['SSEAlgorithm'] ?? $this->throwException(new InvalidArgument('Missing required field "SSEAlgorithm".')); + $this->kmsMasterKeyId = $input['KMSMasterKeyID'] ?? null; + } + + /** + * @param array{ + * SSEAlgorithm: ServerSideEncryption::*, + * KMSMasterKeyID?: null|string, + * }|ServerSideEncryptionByDefault $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKmsMasterKeyId(): ?string + { + return $this->kmsMasterKeyId; + } + + /** + * @return ServerSideEncryption::* + */ + public function getSseAlgorithm(): string + { + return $this->sseAlgorithm; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php new file mode 100644 index 000000000..5b598b2b6 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php @@ -0,0 +1,54 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->rules = isset($input['Rules']) ? array_map([ServerSideEncryptionRule::class, 'create'], $input['Rules']) : $this->throwException(new InvalidArgument('Missing required field "Rules".')); + } + + /** + * @param array{ + * Rules: array, + * }|ServerSideEncryptionConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ServerSideEncryptionRule[] + */ + public function getRules(): array + { + return $this->rules; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php new file mode 100644 index 000000000..ded004a3f --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php @@ -0,0 +1,63 @@ +applyServerSideEncryptionByDefault = isset($input['ApplyServerSideEncryptionByDefault']) ? ServerSideEncryptionByDefault::create($input['ApplyServerSideEncryptionByDefault']) : null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + } + + /** + * @param array{ + * ApplyServerSideEncryptionByDefault?: null|ServerSideEncryptionByDefault|array, + * BucketKeyEnabled?: null|bool, + * }|ServerSideEncryptionRule $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getApplyServerSideEncryptionByDefault(): ?ServerSideEncryptionByDefault + { + return $this->applyServerSideEncryptionByDefault; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Tag.php b/vendor/async-aws/s3/src/ValueObject/Tag.php new file mode 100644 index 000000000..13affe7d1 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Tag.php @@ -0,0 +1,77 @@ +key = $input['Key'] ?? $this->throwException(new InvalidArgument('Missing required field "Key".')); + $this->value = $input['Value'] ?? $this->throwException(new InvalidArgument('Missing required field "Value".')); + } + + /** + * @param array{ + * Key: string, + * Value: string, + * }|Tag $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): string + { + return $this->key; + } + + public function getValue(): string + { + return $this->value; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->key; + $node->appendChild($document->createElement('Key', $v)); + $v = $this->value; + $node->appendChild($document->createElement('Value', $v)); + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Tagging.php b/vendor/async-aws/s3/src/ValueObject/Tagging.php new file mode 100644 index 000000000..fb586ddfd --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Tagging.php @@ -0,0 +1,69 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->tagSet = isset($input['TagSet']) ? array_map([Tag::class, 'create'], $input['TagSet']) : $this->throwException(new InvalidArgument('Missing required field "TagSet".')); + } + + /** + * @param array{ + * TagSet: array, + * }|Tagging $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return Tag[] + */ + public function getTagSet(): array + { + return $this->tagSet; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->tagSet; + + $node->appendChild($nodeList = $document->createElement('TagSet')); + foreach ($v as $item) { + $nodeList->appendChild($child = $document->createElement('Tag')); + + $item->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php b/vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php new file mode 100644 index 000000000..6f1eb0050 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php @@ -0,0 +1,126 @@ + + */ + private $events; + + /** + * @var NotificationConfigurationFilter|null + */ + private $filter; + + /** + * @param array{ + * Id?: null|string, + * TopicArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * } $input + */ + public function __construct(array $input) + { + $this->id = $input['Id'] ?? null; + $this->topicArn = $input['TopicArn'] ?? $this->throwException(new InvalidArgument('Missing required field "TopicArn".')); + $this->events = $input['Events'] ?? $this->throwException(new InvalidArgument('Missing required field "Events".')); + $this->filter = isset($input['Filter']) ? NotificationConfigurationFilter::create($input['Filter']) : null; + } + + /** + * @param array{ + * Id?: null|string, + * TopicArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * }|TopicConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getEvents(): array + { + return $this->events; + } + + public function getFilter(): ?NotificationConfigurationFilter + { + return $this->filter; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getTopicArn(): string + { + return $this->topicArn; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('Id', $v)); + } + $v = $this->topicArn; + $node->appendChild($document->createElement('Topic', $v)); + $v = $this->events; + foreach ($v as $item) { + if (!Event::exists($item)) { + throw new InvalidArgument(sprintf('Invalid parameter "Event" for "%s". The value "%s" is not a valid "Event".', __CLASS__, $item)); + } + $node->appendChild($document->createElement('Event', $item)); + } + + if (null !== $v = $this->filter) { + $node->appendChild($child = $document->createElement('Filter')); + + $v->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/autoload.php b/vendor/autoload.php index 717a7011d..a0b938724 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,24 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + trigger_error( + $err, + E_USER_ERROR + ); +} + require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9::getLoader(); +return ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea::getLoader(); diff --git a/vendor/bin/jp.php b/vendor/bin/jp.php index e4ea10a0f..fc4e0a769 120000 --- a/vendor/bin/jp.php +++ b/vendor/bin/jp.php @@ -1 +1,119 @@ -../mtdowling/jmespath.php/bin/jp.php \ No newline at end of file +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php'); + } +} + +return include __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php'; diff --git a/vendor/bin/jp.php.bat b/vendor/bin/jp.php.bat new file mode 100644 index 000000000..9af045e20 --- /dev/null +++ b/vendor/bin/jp.php.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/jp.php +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index dc02dfb11..7824d8f7e 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -37,57 +37,126 @@ * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + // PSR-4 + /** + * @var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var list + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ private $prefixesPsr0 = array(); + /** + * @var list + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var array + */ private $missingClasses = array(); + + /** @var string|null */ private $apcuPrefix; + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); } + /** + * @return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return list + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return list + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return array Array of classname => path + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param array $classMap Class to filename map + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,22 +171,25 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -126,19 +198,19 @@ public function add($prefix, $paths, $prepend = false) $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -147,25 +219,28 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -175,18 +250,18 @@ public function addPsr4($prefix, $paths, $prepend = false) throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -195,8 +270,10 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +288,12 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +313,8 @@ public function setPsr4($prefix, $paths) * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -256,6 +337,8 @@ public function getUseIncludePath() * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -276,10 +359,12 @@ public function isClassMapAuthoritative() * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -296,33 +381,55 @@ public function getApcuPrefix() * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -367,6 +474,21 @@ public function findFile($class) return $file; } + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -377,7 +499,7 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { @@ -432,14 +554,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 000000000..51e734a77 --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 8a6aeb3bb..dd28fe712 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2,7 +2,7 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( @@ -29,4 +29,11 @@ 'AWS\\CRT\\NativeResource' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/NativeResource.php', 'AWS\\CRT\\OptionValue' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Options.php', 'AWS\\CRT\\Options' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Options.php', + 'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', + 'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', + 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', + 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', + 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', + 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index c1bf4f1fb..82860d3f7 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -2,13 +2,15 @@ // autoload_files.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', - '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', + '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', 'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc0125d..15a2ff3ad 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index a9ebd9f44..f1f91bc2a 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -2,16 +2,26 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), + 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), + 'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), + 'Symfony\\Contracts\\HttpClient\\' => array($vendorDir . '/symfony/http-client-contracts'), + 'Symfony\\Component\\HttpClient\\' => array($vendorDir . '/symfony/http-client'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'), 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), + 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), + 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'), + 'AsyncAws\\S3\\' => array($vendorDir . '/async-aws/s3/src'), + 'AsyncAws\\Core\\' => array($vendorDir . '/async-aws/core/src'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index d13c299d8..d14ad96f4 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9 +class ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea { private static $loader; @@ -13,58 +13,38 @@ public static function loadClassLoader($class) } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9', 'loadClassLoader')); + require __DIR__ . '/platform_check.php'; - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + spl_autoload_register(array('ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); + spl_autoload_unregister(array('ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea', 'loadClassLoader')); - call_user_func(\Composer\Autoload\ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInit1be153197e5434e9f4e42506e8945cea::getInitializer($loader)); $loader->register(true); - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire40514c60e4fd367b9870ef577edbc7b9($fileIdentifier, $file); + $filesToLoad = \Composer\Autoload\ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); } return $loader; } } - -function composerRequire40514c60e4fd367b9870ef577edbc7b9($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index c6135b405..bbbad9f74 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,12 +4,14 @@ namespace Composer\Autoload; -class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 +class ComposerStaticInit1be153197e5434e9f4e42506e8945cea { public static $files = array ( + '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', - '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', + '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', 'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php', @@ -19,12 +21,20 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 public static $prefixLengthsPsr4 = array ( 'S' => array ( + 'Symfony\\Polyfill\\Php80\\' => 23, + 'Symfony\\Polyfill\\Php73\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Contracts\\Service\\' => 26, + 'Symfony\\Contracts\\HttpClient\\' => 29, + 'Symfony\\Component\\HttpClient\\' => 29, ), 'P' => array ( + 'Psr\\Log\\' => 8, 'Psr\\Http\\Message\\' => 17, 'Psr\\Http\\Client\\' => 16, + 'Psr\\Container\\' => 14, + 'Psr\\Cache\\' => 10, ), 'J' => array ( @@ -39,23 +49,57 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 'A' => array ( 'Aws\\' => 4, + 'AsyncAws\\S3\\' => 12, + 'AsyncAws\\Core\\' => 14, ), ); public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Php80\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', + ), + 'Symfony\\Polyfill\\Php73\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php73', + ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), + 'Symfony\\Contracts\\Service\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/service-contracts', + ), + 'Symfony\\Contracts\\HttpClient\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/http-client-contracts', + ), + 'Symfony\\Component\\HttpClient\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/http-client', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), 'Psr\\Http\\Message\\' => array ( - 0 => __DIR__ . '/..' . '/psr/http-factory/src', - 1 => __DIR__ . '/..' . '/psr/http-message/src', + 0 => __DIR__ . '/..' . '/psr/http-message/src', + 1 => __DIR__ . '/..' . '/psr/http-factory/src', ), 'Psr\\Http\\Client\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-client/src', ), + 'Psr\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/container/src', + ), + 'Psr\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/cache/src', + ), 'JmesPath\\' => array ( 0 => __DIR__ . '/..' . '/mtdowling/jmespath.php/src', @@ -76,6 +120,14 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 array ( 0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src', ), + 'AsyncAws\\S3\\' => + array ( + 0 => __DIR__ . '/..' . '/async-aws/s3/src', + ), + 'AsyncAws\\Core\\' => + array ( + 0 => __DIR__ . '/..' . '/async-aws/core/src', + ), ); public static $classMap = array ( @@ -102,14 +154,21 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 'AWS\\CRT\\NativeResource' => __DIR__ . '/..' . '/aws/aws-crt-php/src/AWS/CRT/NativeResource.php', 'AWS\\CRT\\OptionValue' => __DIR__ . '/..' . '/aws/aws-crt-php/src/AWS/CRT/Options.php', 'AWS\\CRT\\Options' => __DIR__ . '/..' . '/aws/aws-crt-php/src/AWS/CRT/Options.php', + 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', + 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', + 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', + 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', + 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index b9c7349c9..88e788383 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,804 +1,1539 @@ -[ - { - "name": "aws/aws-crt-php", - "version": "v1.2.1", - "version_normalized": "1.2.1.0", - "source": { - "type": "git", - "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", - "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", - "yoast/phpunit-polyfills": "^1.0" - }, - "suggest": { - "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." - }, - "time": "2023-03-24T20:22:19+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "AWS SDK Common Runtime Team", - "email": "aws-sdk-common-runtime@amazon.com" - } - ], - "description": "AWS Common Runtime for PHP", - "homepage": "https://github.com/awslabs/aws-crt-php", - "keywords": [ - "amazon", - "aws", - "crt", - "sdk" - ] - }, - { - "name": "aws/aws-sdk-php", - "version": "3.269.1", - "version_normalized": "3.269.1.0", - "source": { - "type": "git", - "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", - "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", - "shasum": "" - }, - "require": { - "aws/aws-crt-php": "^1.0.4", - "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" - }, - "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", - "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" - }, - "suggest": { - "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", - "doctrine/cache": "To use the DoctrineCacheAdapter", - "ext-curl": "To send requests using cURL", - "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", - "ext-sockets": "To use client-side monitoring" - }, - "time": "2023-04-27T18:22:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Aws\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Amazon Web Services", - "homepage": "http://aws.amazon.com" - } - ], - "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", - "homepage": "http://aws.amazon.com/sdkforphp", - "keywords": [ - "amazon", - "aws", - "cloud", - "dynamodb", - "ec2", - "glacier", - "s3", - "sdk" - ] - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.5.1", - "version_normalized": "7.5.1.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b964ca597e86b752cd994f27293e9fa6b6a95ed9", - "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "psr/log": "^1.1 || ^2.0 || ^3.0" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "time": "2023-04-17T16:30:08+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Jeremy Lindblom", - "email": "jeremeamia@gmail.com", - "homepage": "https://github.com/jeremeamia" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "psr-18", - "psr-7", - "rest", - "web service" - ] - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.2", - "version_normalized": "1.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "time": "2022-08-28T14:55:35+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ] - }, - { - "name": "guzzlehttp/psr7", - "version": "2.5.0", - "version_normalized": "2.5.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "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" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "time": "2023-04-17T16:11:26+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ] - }, - { - "name": "mtdowling/jmespath.php", - "version": "2.6.1", - "version_normalized": "2.6.1.0", - "source": { - "type": "git", - "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0", - "symfony/polyfill-mbstring": "^1.17" - }, - "require-dev": { - "composer/xdebug-handler": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^7.5.15" - }, - "time": "2021-06-14T00:11:39+00:00", - "bin": [ - "bin/jp.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/JmesPath.php" - ], - "psr-4": { - "JmesPath\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Declaratively specify how to extract elements from a JSON document", - "keywords": [ - "json", - "jsonpath" - ] - }, - { - "name": "psr/http-client", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:12:12+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ] - }, - { - "name": "psr/http-factory", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:10:41+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/http-message", - "version": "1.1", - "version_normalized": "1.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "time": "2023-04-04T09:50:52+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ] - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "version_normalized": "3.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "time": "2019-03-08T08:55:37+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders." - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2022-01-02T09:53:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "function.php" - ] - }, - "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": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "time": "2022-11-03T14:55:06+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "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 for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ] - } -] +{ + "packages": [ + { + "name": "async-aws/core", + "version": "1.20.0", + "version_normalized": "1.20.0.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/core.git", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/core/zipball/e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/http-client": "^4.4.16 || ^5.1.7 || ^6.0 || ^7.0", + "symfony/http-client-contracts": "^1.1.8 || ^2.0 || ^3.0", + "symfony/service-contracts": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "async-aws/s3": "<1.1", + "symfony/http-client": "5.2.0" + }, + "time": "2023-08-07T20:00:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.20-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "AsyncAws\\Core\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Core package to integrate with AWS. This is a lightweight AWS SDK provider by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "sdk", + "sts" + ], + "support": { + "source": "https://github.com/async-aws/core/tree/1.20.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "install-path": "../async-aws/core" + }, + { + "name": "async-aws/s3", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/s3.git", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/s3/zipball/1486ae6592a8f870da60dfc29bfc98390c7b9092", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092", + "shasum": "" + }, + "require": { + "async-aws/core": "^1.9", + "ext-dom": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0" + }, + "time": "2023-08-07T20:00:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "AsyncAws\\S3\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "S3 client, part of the AWS SDK provided by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "s3", + "sdk" + ], + "support": { + "source": "https://github.com/async-aws/s3/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "install-path": "../async-aws/s3" + }, + { + "name": "aws/aws-crt-php", + "version": "v1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "time": "2023-03-24T20:22:19+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "install-path": "../aws/aws-crt-php" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.269.1", + "version_normalized": "3.269.1.0", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", + "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.0.4", + "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" + }, + "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", + "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" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "time": "2023-04-27T18:22:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "install-path": "../aws/aws-sdk-php" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.1", + "version_normalized": "7.5.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b964ca597e86b752cd994f27293e9fa6b6a95ed9", + "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "time": "2023-04-17T16:30:08+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "install-path": "../guzzlehttp/guzzle" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "version_normalized": "1.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "time": "2022-08-28T14:55:35+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "install-path": "../guzzlehttp/promises" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.5.0", + "version_normalized": "2.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "b635f279edd83fc275f822a1188157ffea568ff6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", + "reference": "b635f279edd83fc275f822a1188157ffea568ff6", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "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" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "time": "2023-04-17T16:11:26+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "install-path": "../guzzlehttp/psr7" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.6.1", + "version_normalized": "2.6.1.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^7.5.15" + }, + "time": "2021-06-14T00:11:39+00:00", + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "install-path": "../mtdowling/jmespath.php" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-08-06T20:24:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "install-path": "../psr/cache" + }, + { + "name": "psr/container", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "time": "2021-03-05T17:36:06+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "install-path": "../psr/container" + }, + { + "name": "psr/http-client", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-04-10T20:12:12+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "install-path": "../psr/http-client" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-04-10T20:10:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-factory" + }, + { + "name": "psr/http-message", + "version": "1.1", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2023-04-04T09:50:52+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-message" + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2021-05-03T11:20:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "install-path": "../psr/log" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "time": "2019-03-08T08:55:37+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "install-path": "../ralouphie/getallheaders" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2022-01-02T09:53:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.php" + ] + }, + "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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "install-path": "../symfony/deprecation-contracts" + }, + { + "name": "symfony/http-client", + "version": "v5.4.26", + "version_normalized": "5.4.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/19d48ef7f38e5057ed1789a503cd3eccef039bce", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.4", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "2.4" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "time": "2023-07-03T12:14:50+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "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": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v5.4.26" + }, + "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" + } + ], + "install-path": "../symfony/http-client" + }, + { + "name": "symfony/http-client-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "time": "2022-04-12T15:48:08+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "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": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.2" + }, + "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" + } + ], + "install-path": "../symfony/http-client-contracts" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "version_normalized": "1.27.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2022-11-03T14:55:06+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "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 for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "install-path": "../symfony/polyfill-mbstring" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.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" + } + ], + "install-path": "../symfony/polyfill-php73" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.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" + } + ], + "install-path": "../symfony/polyfill-php80" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "time": "2022-05-30T19:17:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, + "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" + } + ], + "install-path": "../symfony/service-contracts" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 000000000..c49f47d19 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,257 @@ + array( + 'name' => '__root__', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '18a48a414f663c2bb6718ddbd4000a40164ae8f8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '18a48a414f663c2bb6718ddbd4000a40164ae8f8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'async-aws/core' => array( + 'pretty_version' => '1.20.0', + 'version' => '1.20.0.0', + 'reference' => 'e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68', + 'type' => 'library', + 'install_path' => __DIR__ . '/../async-aws/core', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'async-aws/s3' => array( + 'pretty_version' => '2.0.0', + 'version' => '2.0.0.0', + 'reference' => '1486ae6592a8f870da60dfc29bfc98390c7b9092', + 'type' => 'library', + 'install_path' => __DIR__ . '/../async-aws/s3', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'aws/aws-crt-php' => array( + 'pretty_version' => 'v1.2.1', + 'version' => '1.2.1.0', + 'reference' => '1926277fc71d253dfa820271ac5987bdb193ccf5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../aws/aws-crt-php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'aws/aws-sdk-php' => array( + 'pretty_version' => '3.269.1', + 'version' => '3.269.1.0', + 'reference' => '03b0b8984c46c469c70bfb05fea7b1ac9b859a8e', + 'type' => 'library', + 'install_path' => __DIR__ . '/../aws/aws-sdk-php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/guzzle' => array( + 'pretty_version' => '7.5.1', + 'version' => '7.5.1.0', + 'reference' => 'b964ca597e86b752cd994f27293e9fa6b6a95ed9', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/promises' => array( + 'pretty_version' => '1.5.2', + 'version' => '1.5.2.0', + 'reference' => 'b94b2807d85443f9719887892882d0329d1e2598', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/promises', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/psr7' => array( + 'pretty_version' => '2.5.0', + 'version' => '2.5.0.0', + 'reference' => 'b635f279edd83fc275f822a1188157ffea568ff6', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/psr7', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'mtdowling/jmespath.php' => array( + 'pretty_version' => '2.6.1', + 'version' => '2.6.1.0', + 'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb', + 'type' => 'library', + 'install_path' => __DIR__ . '/../mtdowling/jmespath.php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'php-http/async-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '*', + ), + ), + 'php-http/client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '*', + ), + ), + 'psr/cache' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/container' => array( + 'pretty_version' => '1.1.1', + 'version' => '1.1.1.0', + 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/container', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => '0955afe48220520692d2d09f7ab7e0f93ffd6a31', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/http-factory' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-factory', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-factory-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/http-message' => array( + 'pretty_version' => '1.1', + 'version' => '1.1.0.0', + 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-message-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'ralouphie/getallheaders' => array( + 'pretty_version' => '3.0.3', + 'version' => '3.0.3.0', + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ralouphie/getallheaders', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client' => array( + 'pretty_version' => 'v5.4.26', + 'version' => '5.4.26.0', + 'reference' => '19d48ef7f38e5057ed1789a503cd3eccef039bce', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => 'ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/http-client-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '2.4', + ), + ), + 'symfony/polyfill-mbstring' => array( + 'pretty_version' => 'v1.27.0', + 'version' => '1.27.0.0', + 'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php73' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => 'fe2f306d1d9d346a7fee353d0d5012e401e984b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php73', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php80' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php80', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/service-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/service-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 000000000..a8b98d5ce --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70205)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/vendor/psr/cache/CHANGELOG.md b/vendor/psr/cache/CHANGELOG.md new file mode 100644 index 000000000..58ddab05a --- /dev/null +++ b/vendor/psr/cache/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 1.0.1 - 2016-08-06 + +### Fixed + +- Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr +- Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr +- Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell +- For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell + +## 1.0.0 - 2015-12-11 + +Initial stable release; reflects accepted PSR-6 specification diff --git a/vendor/psr/cache/LICENSE.txt b/vendor/psr/cache/LICENSE.txt new file mode 100644 index 000000000..b1c2c97b9 --- /dev/null +++ b/vendor/psr/cache/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2015 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/psr/cache/README.md b/vendor/psr/cache/README.md new file mode 100644 index 000000000..c8706ceea --- /dev/null +++ b/vendor/psr/cache/README.md @@ -0,0 +1,9 @@ +PSR Cache +========= + +This repository holds all interfaces defined by +[PSR-6](http://www.php-fig.org/psr/psr-6/). + +Note that this is not a Cache implementation of its own. It is merely an +interface that describes a Cache implementation. See the specification for more +details. diff --git a/vendor/psr/cache/composer.json b/vendor/psr/cache/composer.json new file mode 100644 index 000000000..e828fec94 --- /dev/null +++ b/vendor/psr/cache/composer.json @@ -0,0 +1,25 @@ +{ + "name": "psr/cache", + "description": "Common interface for caching libraries", + "keywords": ["psr", "psr-6", "cache"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/psr/cache/src/CacheException.php b/vendor/psr/cache/src/CacheException.php new file mode 100644 index 000000000..e27f22f8d --- /dev/null +++ b/vendor/psr/cache/src/CacheException.php @@ -0,0 +1,10 @@ +=7.2.0" + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + } +} diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php new file mode 100644 index 000000000..cf10b8b4f --- /dev/null +++ b/vendor/psr/container/src/ContainerExceptionInterface.php @@ -0,0 +1,10 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 000000000..67f852d1d --- /dev/null +++ b/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 000000000..2206cfde4 --- /dev/null +++ b/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,125 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 000000000..c8f7293b1 --- /dev/null +++ b/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,30 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/vendor/psr/log/Psr/Log/Test/DummyTest.php b/vendor/psr/log/Psr/Log/Test/DummyTest.php new file mode 100644 index 000000000..9638c1101 --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/DummyTest.php @@ -0,0 +1,18 @@ + ". + * + * Example ->error('Foo') would yield "error Foo". + * + * @return string[] + */ + abstract public function getLogs(); + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException \Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + } + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextCanContainAnything() + { + $closed = fopen('php://memory', 'r'); + fclose($closed); + + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest), + 'object' => new \DateTime, + 'resource' => fopen('php://memory', 'r'), + 'closed' => $closed, + ); + + $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!' + ); + $this->assertEquals($expected, $this->getLogs()); + } +} diff --git a/vendor/psr/log/Psr/Log/Test/TestLogger.php b/vendor/psr/log/Psr/Log/Test/TestLogger.php new file mode 100644 index 000000000..1be323049 --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/TestLogger.php @@ -0,0 +1,147 @@ + $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + $this->recordsByLevel = []; + } +} diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md new file mode 100644 index 000000000..a9f20c437 --- /dev/null +++ b/vendor/psr/log/README.md @@ -0,0 +1,58 @@ +PSR Log +======= + +This repository holds all interfaces/classes/traits related to +[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Note that this is not a logger of its own. It is merely an interface that +describes a logger. See the specification for more details. + +Installation +------------ + +```bash +composer require psr/log +``` + +Usage +----- + +If you need a logger, you can use the interface like this: + +```php +logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + try { + $this->doSomethingElse(); + } catch (Exception $exception) { + $this->logger->error('Oh no!', array('exception' => $exception)); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json new file mode 100644 index 000000000..ca0569537 --- /dev/null +++ b/vendor/psr/log/composer.json @@ -0,0 +1,26 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + } +} diff --git a/vendor/symfony/http-client-contracts/.gitignore b/vendor/symfony/http-client-contracts/.gitignore new file mode 100644 index 000000000..c49a5d8df --- /dev/null +++ b/vendor/symfony/http-client-contracts/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/vendor/symfony/http-client-contracts/CHANGELOG.md b/vendor/symfony/http-client-contracts/CHANGELOG.md new file mode 100644 index 000000000..7932e2613 --- /dev/null +++ b/vendor/symfony/http-client-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/vendor/symfony/http-client-contracts/ChunkInterface.php b/vendor/symfony/http-client-contracts/ChunkInterface.php new file mode 100644 index 000000000..0800cb366 --- /dev/null +++ b/vendor/symfony/http-client-contracts/ChunkInterface.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * The interface of chunks returned by ResponseStreamInterface::current(). + * + * When the chunk is first, last or timeout, the content MUST be empty. + * When an unchecked timeout or a network error occurs, a TransportExceptionInterface + * MUST be thrown by the destructor unless one was already thrown by another method. + * + * @author Nicolas Grekas + */ +interface ChunkInterface +{ + /** + * Tells when the idle timeout has been reached. + * + * @throws TransportExceptionInterface on a network error + */ + public function isTimeout(): bool; + + /** + * Tells when headers just arrived. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function isFirst(): bool; + + /** + * Tells when the body just completed. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function isLast(): bool; + + /** + * Returns a [status code, headers] tuple when a 1xx status code was just received. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function getInformationalStatus(): ?array; + + /** + * Returns the content of the response chunk. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function getContent(): string; + + /** + * Returns the offset of the chunk in the response body. + */ + public function getOffset(): int; + + /** + * In case of error, returns the message that describes it. + */ + public function getError(): ?string; +} diff --git a/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php new file mode 100644 index 000000000..22d2b456a --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a 4xx response is returned. + * + * @author Nicolas Grekas + */ +interface ClientExceptionInterface extends HttpExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php new file mode 100644 index 000000000..971a7a29b --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a content-type cannot be decoded to the expected representation. + * + * @author Nicolas Grekas + */ +interface DecodingExceptionInterface extends ExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php new file mode 100644 index 000000000..e553b47a1 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * The base interface for all exceptions in the contract. + * + * @author Nicolas Grekas + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php new file mode 100644 index 000000000..17865ed36 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * Base interface for HTTP-related exceptions. + * + * @author Anton Chernikov + */ +interface HttpExceptionInterface extends ExceptionInterface +{ + public function getResponse(): ResponseInterface; +} diff --git a/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php new file mode 100644 index 000000000..edd9b8a9b --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a 3xx response is returned and the "max_redirects" option has been reached. + * + * @author Nicolas Grekas + */ +interface RedirectionExceptionInterface extends HttpExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php new file mode 100644 index 000000000..9bfe1354b --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a 5xx response is returned. + * + * @author Nicolas Grekas + */ +interface ServerExceptionInterface extends HttpExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php new file mode 100644 index 000000000..08acf9fb6 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When an idle timeout occurs. + * + * @author Nicolas Grekas + */ +interface TimeoutExceptionInterface extends TransportExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php new file mode 100644 index 000000000..0c8d131a0 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When any error happens at the transport level. + * + * @author Nicolas Grekas + */ +interface TransportExceptionInterface extends ExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/HttpClientInterface.php b/vendor/symfony/http-client-contracts/HttpClientInterface.php new file mode 100644 index 000000000..158c1a7d0 --- /dev/null +++ b/vendor/symfony/http-client-contracts/HttpClientInterface.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\Test\HttpClientTestCase; + +/** + * Provides flexible methods for requesting HTTP resources synchronously or asynchronously. + * + * @see HttpClientTestCase for a reference test suite + * + * @method static withOptions(array $options) Returns a new instance of the client with new default options + * + * @author Nicolas Grekas + */ +interface HttpClientInterface +{ + public const OPTIONS_DEFAULTS = [ + 'auth_basic' => null, // array|string - an array containing the username as first value, and optionally the + // password as the second one; or string like username:password - enabling HTTP Basic + // authentication (RFC 7617) + 'auth_bearer' => null, // string - a token enabling HTTP Bearer authorization (RFC 6750) + 'query' => [], // string[] - associative array of query string values to merge with the request's URL + 'headers' => [], // iterable|string[]|string[][] - headers names provided as keys or as part of values + 'body' => '', // array|string|resource|\Traversable|\Closure - the callback SHOULD yield a string + // smaller than the amount requested as argument; the empty string signals EOF; if + // an array is passed, it is meant as a form payload of field names and values + 'json' => null, // mixed - if set, implementations MUST set the "body" option to the JSON-encoded + // value and set the "content-type" header to a JSON-compatible value if it is not + // explicitly defined in the headers option - typically "application/json" + 'user_data' => null, // mixed - any extra data to attach to the request (scalar, callable, object...) that + // MUST be available via $response->getInfo('user_data') - not used internally + 'max_redirects' => 20, // int - the maximum number of redirects to follow; a value lower than or equal to 0 + // means redirects should not be followed; "Authorization" and "Cookie" headers MUST + // NOT follow except for the initial host name + 'http_version' => null, // string - defaults to the best supported version, typically 1.1 or 2.0 + 'base_uri' => null, // string - the URI to resolve relative URLs, following rules in RFC 3986, section 2 + 'buffer' => true, // bool|resource|\Closure - whether the content of the response should be buffered or not, + // or a stream resource where the response body should be written, + // or a closure telling if/where the response should be buffered based on its headers + 'on_progress' => null, // callable(int $dlNow, int $dlSize, array $info) - throwing any exceptions MUST abort + // the request; it MUST be called on DNS resolution, on arrival of headers and on + // completion; it SHOULD be called on upload/download of data and at least 1/s + 'resolve' => [], // string[] - a map of host to IP address that SHOULD replace DNS resolution + 'proxy' => null, // string - by default, the proxy-related env vars handled by curl SHOULD be honored + 'no_proxy' => null, // string - a comma separated list of hosts that do not require a proxy to be reached + 'timeout' => null, // float - the idle timeout - defaults to ini_get('default_socket_timeout') + 'max_duration' => 0, // float - the maximum execution time for the request+response as a whole; + // a value lower than or equal to 0 means it is unlimited + 'bindto' => '0', // string - the interface or the local socket to bind to + 'verify_peer' => true, // see https://php.net/context.ssl for the following options + 'verify_host' => true, + 'cafile' => null, + 'capath' => null, + 'local_cert' => null, + 'local_pk' => null, + 'passphrase' => null, + 'ciphers' => null, + 'peer_fingerprint' => null, + 'capture_peer_cert_chain' => false, + 'extra' => [], // array - additional options that can be ignored if unsupported, unlike regular options + ]; + + /** + * Requests an HTTP resource. + * + * Responses MUST be lazy, but their status code MUST be + * checked even if none of their public methods are called. + * + * Implementations are not required to support all options described above; they can also + * support more custom options; but in any case, they MUST throw a TransportExceptionInterface + * when an unsupported option is passed. + * + * @throws TransportExceptionInterface When an unsupported option is passed + */ + public function request(string $method, string $url, array $options = []): ResponseInterface; + + /** + * Yields responses chunk by chunk as they complete. + * + * @param ResponseInterface|iterable $responses One or more responses created by the current HTTP client + * @param float|null $timeout The idle timeout before yielding timeout chunks + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface; +} diff --git a/vendor/symfony/http-client-contracts/LICENSE b/vendor/symfony/http-client-contracts/LICENSE new file mode 100644 index 000000000..74cdc2dbf --- /dev/null +++ b/vendor/symfony/http-client-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/http-client-contracts/README.md b/vendor/symfony/http-client-contracts/README.md new file mode 100644 index 000000000..03b3a69b7 --- /dev/null +++ b/vendor/symfony/http-client-contracts/README.md @@ -0,0 +1,9 @@ +Symfony HttpClient Contracts +============================ + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful - and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/main/README.md for more information. diff --git a/vendor/symfony/http-client-contracts/ResponseInterface.php b/vendor/symfony/http-client-contracts/ResponseInterface.php new file mode 100644 index 000000000..df7148816 --- /dev/null +++ b/vendor/symfony/http-client-contracts/ResponseInterface.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * A (lazily retrieved) HTTP response. + * + * @author Nicolas Grekas + */ +interface ResponseInterface +{ + /** + * Gets the HTTP status code of the response. + * + * @throws TransportExceptionInterface when a network error occurs + */ + public function getStatusCode(): int; + + /** + * Gets the HTTP headers of the response. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @return string[][] The headers of the response keyed by header names in lowercase + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function getHeaders(bool $throw = true): array; + + /** + * Gets the response body as a string. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function getContent(bool $throw = true): string; + + /** + * Gets the response body decoded as array, typically from a JSON payload. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @throws DecodingExceptionInterface When the body cannot be decoded to an array + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function toArray(bool $throw = true): array; + + /** + * Closes the response stream and all related buffers. + * + * No further chunk will be yielded after this method has been called. + */ + public function cancel(): void; + + /** + * Returns info coming from the transport layer. + * + * This method SHOULD NOT throw any ExceptionInterface and SHOULD be non-blocking. + * The returned info is "live": it can be empty and can change from one call to + * another, as the request/response progresses. + * + * The following info MUST be returned: + * - canceled (bool) - true if the response was canceled using ResponseInterface::cancel(), false otherwise + * - error (string|null) - the error message when the transfer was aborted, null otherwise + * - http_code (int) - the last response code or 0 when it is not known yet + * - http_method (string) - the HTTP verb of the last request + * - redirect_count (int) - the number of redirects followed while executing the request + * - redirect_url (string|null) - the resolved location of redirect responses, null otherwise + * - response_headers (array) - an array modelled after the special $http_response_header variable + * - start_time (float) - the time when the request was sent or 0.0 when it's pending + * - url (string) - the last effective URL of the request + * - user_data (mixed) - the value of the "user_data" request option, null if not set + * + * When the "capture_peer_cert_chain" option is true, the "peer_certificate_chain" + * attribute SHOULD list the peer certificates as an array of OpenSSL X.509 resources. + * + * Other info SHOULD be named after curl_getinfo()'s associative return value. + * + * @return mixed An array of all available info, or one of them when $type is + * provided, or null when an unsupported type is requested + */ + public function getInfo(string $type = null); +} diff --git a/vendor/symfony/http-client-contracts/ResponseStreamInterface.php b/vendor/symfony/http-client-contracts/ResponseStreamInterface.php new file mode 100644 index 000000000..fa3e5db6c --- /dev/null +++ b/vendor/symfony/http-client-contracts/ResponseStreamInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +/** + * Yields response chunks, returned by HttpClientInterface::stream(). + * + * @author Nicolas Grekas + * + * @extends \Iterator + */ +interface ResponseStreamInterface extends \Iterator +{ + public function key(): ResponseInterface; + + public function current(): ChunkInterface; +} diff --git a/vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php b/vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php new file mode 100644 index 000000000..30a704975 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php @@ -0,0 +1,192 @@ + $v) { + switch ($k) { + default: + if (0 !== strpos($k, 'HTTP_')) { + continue 2; + } + // no break + case 'SERVER_NAME': + case 'SERVER_PROTOCOL': + case 'REQUEST_URI': + case 'REQUEST_METHOD': + case 'PHP_AUTH_USER': + case 'PHP_AUTH_PW': + $vars[$k] = $v; + } +} + +$json = json_encode($vars, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); + +switch ($vars['REQUEST_URI']) { + default: + exit; + + case '/head': + header('Content-Length: '.strlen($json), true); + break; + + case '/': + case '/?a=a&b=b': + case 'http://127.0.0.1:8057/': + case 'http://localhost:8057/': + ob_start('ob_gzhandler'); + break; + + case '/103': + header('HTTP/1.1 103 Early Hints'); + header('Link: ; rel=preload; as=style', false); + header('Link: ; rel=preload; as=script', false); + flush(); + usleep(1000); + echo "HTTP/1.1 200 OK\r\n"; + echo "Date: Fri, 26 May 2017 10:02:11 GMT\r\n"; + echo "Content-Length: 13\r\n"; + echo "\r\n"; + echo 'Here the body'; + exit; + + case '/404': + header('Content-Type: application/json', true, 404); + break; + + case '/404-gzipped': + header('Content-Type: text/plain', true, 404); + ob_start('ob_gzhandler'); + @ob_flush(); + flush(); + usleep(300000); + echo 'some text'; + exit; + + case '/301': + if ('Basic Zm9vOmJhcg==' === $vars['HTTP_AUTHORIZATION']) { + header('Location: http://127.0.0.1:8057/302', true, 301); + } + break; + + case '/301/bad-tld': + header('Location: http://foo.example.', true, 301); + break; + + case '/301/invalid': + header('Location: //?foo=bar', true, 301); + break; + + case '/302': + if (!isset($vars['HTTP_AUTHORIZATION'])) { + header('Location: http://localhost:8057/', true, 302); + } + break; + + case '/302/relative': + header('Location: ..', true, 302); + break; + + case '/304': + header('Content-Length: 10', true, 304); + echo '12345'; + + return; + + case '/307': + header('Location: http://localhost:8057/post', true, 307); + break; + + case '/length-broken': + header('Content-Length: 1000'); + break; + + case '/post': + $output = json_encode($_POST + ['REQUEST_METHOD' => $vars['REQUEST_METHOD']], \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); + header('Content-Type: application/json', true); + header('Content-Length: '.strlen($output)); + echo $output; + exit; + + case '/timeout-header': + usleep(300000); + break; + + case '/timeout-body': + echo '<1>'; + @ob_flush(); + flush(); + usleep(500000); + echo '<2>'; + exit; + + case '/timeout-long': + ignore_user_abort(false); + sleep(1); + while (true) { + echo '<1>'; + @ob_flush(); + flush(); + usleep(500); + } + exit; + + case '/chunked': + header('Transfer-Encoding: chunked'); + echo "8\r\nSymfony \r\n5\r\nis aw\r\n6\r\nesome!\r\n0\r\n\r\n"; + exit; + + case '/chunked-broken': + header('Transfer-Encoding: chunked'); + echo "8\r\nSymfony \r\n5\r\nis aw\r\n6\r\ne"; + exit; + + case '/gzip-broken': + header('Content-Encoding: gzip'); + echo str_repeat('-', 1000); + exit; + + case '/max-duration': + ignore_user_abort(false); + while (true) { + echo '<1>'; + @ob_flush(); + flush(); + usleep(500); + } + exit; + + case '/json': + header('Content-Type: application/json'); + echo json_encode([ + 'documents' => [ + ['id' => '/json/1'], + ['id' => '/json/2'], + ['id' => '/json/3'], + ], + ]); + exit; + + case '/json/1': + case '/json/2': + case '/json/3': + header('Content-Type: application/json'); + echo json_encode([ + 'title' => $vars['REQUEST_URI'], + ]); + + exit; +} + +header('Content-Type: application/json', true); + +echo $json; diff --git a/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php b/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php new file mode 100644 index 000000000..7acd6b79c --- /dev/null +++ b/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php @@ -0,0 +1,1137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Test; + +use PHPUnit\Framework\TestCase; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TimeoutExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A reference test suite for HttpClientInterface implementations. + */ +abstract class HttpClientTestCase extends TestCase +{ + public static function setUpBeforeClass(): void + { + TestHttpServer::start(); + } + + abstract protected function getHttpClient(string $testCase): HttpClientInterface; + + public function testGetRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'headers' => ['Foo' => 'baR'], + 'user_data' => $data = new \stdClass(), + ]); + + $this->assertSame([], $response->getInfo('response_headers')); + $this->assertSame($data, $response->getInfo()['user_data']); + $this->assertSame(200, $response->getStatusCode()); + + $info = $response->getInfo(); + $this->assertNull($info['error']); + $this->assertSame(0, $info['redirect_count']); + $this->assertSame('HTTP/1.1 200 OK', $info['response_headers'][0]); + $this->assertSame('Host: localhost:8057', $info['response_headers'][1]); + $this->assertSame('http://localhost:8057/', $info['url']); + + $headers = $response->getHeaders(); + + $this->assertSame('localhost:8057', $headers['host'][0]); + $this->assertSame(['application/json'], $headers['content-type']); + + $body = json_decode($response->getContent(), true); + $this->assertSame($body, $response->toArray()); + + $this->assertSame('HTTP/1.1', $body['SERVER_PROTOCOL']); + $this->assertSame('/', $body['REQUEST_URI']); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('localhost:8057', $body['HTTP_HOST']); + $this->assertSame('baR', $body['HTTP_FOO']); + + $response = $client->request('GET', 'http://localhost:8057/length-broken'); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testHeadRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('HEAD', 'http://localhost:8057/head', [ + 'headers' => ['Foo' => 'baR'], + 'user_data' => $data = new \stdClass(), + 'buffer' => false, + ]); + + $this->assertSame([], $response->getInfo('response_headers')); + $this->assertSame(200, $response->getStatusCode()); + + $info = $response->getInfo(); + $this->assertSame('HTTP/1.1 200 OK', $info['response_headers'][0]); + $this->assertSame('Host: localhost:8057', $info['response_headers'][1]); + + $headers = $response->getHeaders(); + + $this->assertSame('localhost:8057', $headers['host'][0]); + $this->assertSame(['application/json'], $headers['content-type']); + $this->assertTrue(0 < $headers['content-length'][0]); + + $this->assertSame('', $response->getContent()); + } + + public function testNonBufferedGetRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'buffer' => false, + 'headers' => ['Foo' => 'baR'], + ]); + + $body = $response->toArray(); + $this->assertSame('baR', $body['HTTP_FOO']); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testBufferSink() + { + $sink = fopen('php://temp', 'w+'); + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'buffer' => $sink, + 'headers' => ['Foo' => 'baR'], + ]); + + $body = $response->toArray(); + $this->assertSame('baR', $body['HTTP_FOO']); + + rewind($sink); + $sink = stream_get_contents($sink); + $this->assertSame($sink, $response->getContent()); + } + + public function testConditionalBuffering() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057'); + $firstContent = $response->getContent(); + $secondContent = $response->getContent(); + + $this->assertSame($firstContent, $secondContent); + + $response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () { return false; }]); + $response->getContent(); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testReentrantBufferCallback() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () use (&$response) { + $response->cancel(); + + return true; + }]); + + $this->assertSame(200, $response->getStatusCode()); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testThrowingBufferCallback() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () { + throw new \Exception('Boo.'); + }]); + + $this->assertSame(200, $response->getStatusCode()); + + $this->expectException(TransportExceptionInterface::class); + $this->expectExceptionMessage('Boo'); + $response->getContent(); + } + + public function testUnsupportedOption() + { + $client = $this->getHttpClient(__FUNCTION__); + + $this->expectException(\InvalidArgumentException::class); + $client->request('GET', 'http://localhost:8057', [ + 'capture_peer_cert' => 1.0, + ]); + } + + public function testHttpVersion() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'http_version' => 1.0, + ]); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('HTTP/1.0 200 OK', $response->getInfo('response_headers')[0]); + + $body = $response->toArray(); + + $this->assertSame('HTTP/1.0', $body['SERVER_PROTOCOL']); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('/', $body['REQUEST_URI']); + } + + public function testChunkedEncoding() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/chunked'); + + $this->assertSame(['chunked'], $response->getHeaders()['transfer-encoding']); + $this->assertSame('Symfony is awesome!', $response->getContent()); + + $response = $client->request('GET', 'http://localhost:8057/chunked-broken'); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testClientError() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/404'); + + $client->stream($response)->valid(); + + $this->assertSame(404, $response->getInfo('http_code')); + + try { + $response->getHeaders(); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + } + + try { + $response->getContent(); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + } + + $this->assertSame(404, $response->getStatusCode()); + $this->assertSame(['application/json'], $response->getHeaders(false)['content-type']); + $this->assertNotEmpty($response->getContent(false)); + + $response = $client->request('GET', 'http://localhost:8057/404'); + + try { + foreach ($client->stream($response) as $chunk) { + $this->assertTrue($chunk->isFirst()); + } + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + } + } + + public function testIgnoreErrors() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/404'); + + $this->assertSame(404, $response->getStatusCode()); + } + + public function testDnsError() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/301/bad-tld'); + + try { + $response->getStatusCode(); + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + try { + $response->getStatusCode(); + $this->fail(TransportExceptionInterface::class.' still expected'); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + $response = $client->request('GET', 'http://localhost:8057/301/bad-tld'); + + try { + foreach ($client->stream($response) as $r => $chunk) { + } + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + $this->assertSame($response, $r); + $this->assertNotNull($chunk->getError()); + + $this->expectException(TransportExceptionInterface::class); + foreach ($client->stream($response) as $chunk) { + } + } + + public function testInlineAuth() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://foo:bar%3Dbar@localhost:8057'); + + $body = $response->toArray(); + + $this->assertSame('foo', $body['PHP_AUTH_USER']); + $this->assertSame('bar=bar', $body['PHP_AUTH_PW']); + } + + public function testBadRequestBody() + { + $client = $this->getHttpClient(__FUNCTION__); + + $this->expectException(TransportExceptionInterface::class); + + $response = $client->request('POST', 'http://localhost:8057/', [ + 'body' => function () { yield []; }, + ]); + + $response->getStatusCode(); + } + + public function test304() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/304', [ + 'headers' => ['If-Match' => '"abc"'], + 'buffer' => false, + ]); + + $this->assertSame(304, $response->getStatusCode()); + $this->assertSame('', $response->getContent(false)); + } + + /** + * @testWith [[]] + * [["Content-Length: 7"]] + */ + public function testRedirects(array $headers = []) + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('POST', 'http://localhost:8057/301', [ + 'auth_basic' => 'foo:bar', + 'headers' => $headers, + 'body' => function () { + yield 'foo=bar'; + }, + ]); + + $body = $response->toArray(); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('Basic Zm9vOmJhcg==', $body['HTTP_AUTHORIZATION']); + $this->assertSame('http://localhost:8057/', $response->getInfo('url')); + + $this->assertSame(2, $response->getInfo('redirect_count')); + $this->assertNull($response->getInfo('redirect_url')); + + $expected = [ + 'HTTP/1.1 301 Moved Permanently', + 'Location: http://127.0.0.1:8057/302', + 'Content-Type: application/json', + 'HTTP/1.1 302 Found', + 'Location: http://localhost:8057/', + 'Content-Type: application/json', + 'HTTP/1.1 200 OK', + 'Content-Type: application/json', + ]; + + $filteredHeaders = array_values(array_filter($response->getInfo('response_headers'), function ($h) { + return \in_array(substr($h, 0, 4), ['HTTP', 'Loca', 'Cont'], true) && 'Content-Encoding: gzip' !== $h; + })); + + $this->assertSame($expected, $filteredHeaders); + } + + public function testInvalidRedirect() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/301/invalid'); + + $this->assertSame(301, $response->getStatusCode()); + $this->assertSame(['//?foo=bar'], $response->getHeaders(false)['location']); + $this->assertSame(0, $response->getInfo('redirect_count')); + $this->assertNull($response->getInfo('redirect_url')); + + $this->expectException(RedirectionExceptionInterface::class); + $response->getHeaders(); + } + + public function testRelativeRedirects() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/302/relative'); + + $body = $response->toArray(); + + $this->assertSame('/', $body['REQUEST_URI']); + $this->assertNull($response->getInfo('redirect_url')); + + $response = $client->request('GET', 'http://localhost:8057/302/relative', [ + 'max_redirects' => 0, + ]); + + $this->assertSame(302, $response->getStatusCode()); + $this->assertSame('http://localhost:8057/', $response->getInfo('redirect_url')); + } + + public function testRedirect307() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/307', [ + 'body' => function () { + yield 'foo=bar'; + }, + 'max_redirects' => 0, + ]); + + $this->assertSame(307, $response->getStatusCode()); + + $response = $client->request('POST', 'http://localhost:8057/307', [ + 'body' => 'foo=bar', + ]); + + $body = $response->toArray(); + + $this->assertSame(['foo' => 'bar', 'REQUEST_METHOD' => 'POST'], $body); + } + + public function testMaxRedirects() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/301', [ + 'max_redirects' => 1, + 'auth_basic' => 'foo:bar', + ]); + + try { + $response->getHeaders(); + $this->fail(RedirectionExceptionInterface::class.' expected'); + } catch (RedirectionExceptionInterface $e) { + } + + $this->assertSame(302, $response->getStatusCode()); + $this->assertSame(1, $response->getInfo('redirect_count')); + $this->assertSame('http://localhost:8057/', $response->getInfo('redirect_url')); + + $expected = [ + 'HTTP/1.1 301 Moved Permanently', + 'Location: http://127.0.0.1:8057/302', + 'Content-Type: application/json', + 'HTTP/1.1 302 Found', + 'Location: http://localhost:8057/', + 'Content-Type: application/json', + ]; + + $filteredHeaders = array_values(array_filter($response->getInfo('response_headers'), function ($h) { + return \in_array(substr($h, 0, 4), ['HTTP', 'Loca', 'Cont'], true); + })); + + $this->assertSame($expected, $filteredHeaders); + } + + public function testStream() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057'); + $chunks = $client->stream($response); + $result = []; + + foreach ($chunks as $r => $chunk) { + if ($chunk->isTimeout()) { + $result[] = 't'; + } elseif ($chunk->isLast()) { + $result[] = 'l'; + } elseif ($chunk->isFirst()) { + $result[] = 'f'; + } + } + + $this->assertSame($response, $r); + $this->assertSame(['f', 'l'], $result); + + $chunk = null; + $i = 0; + + foreach ($client->stream($response) as $chunk) { + ++$i; + } + + $this->assertSame(1, $i); + $this->assertTrue($chunk->isLast()); + } + + public function testAddToStream() + { + $client = $this->getHttpClient(__FUNCTION__); + + $r1 = $client->request('GET', 'http://localhost:8057'); + + $completed = []; + + $pool = [$r1]; + + while ($pool) { + $chunks = $client->stream($pool); + $pool = []; + + foreach ($chunks as $r => $chunk) { + if (!$chunk->isLast()) { + continue; + } + + if ($r1 === $r) { + $r2 = $client->request('GET', 'http://localhost:8057'); + $pool[] = $r2; + } + + $completed[] = $r; + } + } + + $this->assertSame([$r1, $r2], $completed); + } + + public function testCompleteTypeError() + { + $client = $this->getHttpClient(__FUNCTION__); + + $this->expectException(\TypeError::class); + $client->stream(123); + } + + public function testOnProgress() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'headers' => ['Content-Length' => 14], + 'body' => 'foo=0123456789', + 'on_progress' => function (...$state) use (&$steps) { $steps[] = $state; }, + ]); + + $body = $response->toArray(); + + $this->assertSame(['foo' => '0123456789', 'REQUEST_METHOD' => 'POST'], $body); + $this->assertSame([0, 0], \array_slice($steps[0], 0, 2)); + $lastStep = \array_slice($steps, -1)[0]; + $this->assertSame([57, 57], \array_slice($lastStep, 0, 2)); + $this->assertSame('http://localhost:8057/post', $steps[0][2]['url']); + } + + public function testPostJson() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'json' => ['foo' => 'bar'], + ]); + + $body = $response->toArray(); + + $this->assertStringContainsString('json', $body['content-type']); + unset($body['content-type']); + $this->assertSame(['foo' => 'bar', 'REQUEST_METHOD' => 'POST'], $body); + } + + public function testPostArray() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'body' => ['foo' => 'bar'], + ]); + + $this->assertSame(['foo' => 'bar', 'REQUEST_METHOD' => 'POST'], $response->toArray()); + } + + public function testPostResource() + { + $client = $this->getHttpClient(__FUNCTION__); + + $h = fopen('php://temp', 'w+'); + fwrite($h, 'foo=0123456789'); + rewind($h); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'body' => $h, + ]); + + $body = $response->toArray(); + + $this->assertSame(['foo' => '0123456789', 'REQUEST_METHOD' => 'POST'], $body); + } + + public function testPostCallback() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'body' => function () { + yield 'foo'; + yield ''; + yield '='; + yield '0123456789'; + }, + ]); + + $this->assertSame(['foo' => '0123456789', 'REQUEST_METHOD' => 'POST'], $response->toArray()); + } + + public function testCancel() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-header'); + + $response->cancel(); + $this->expectException(TransportExceptionInterface::class); + $response->getHeaders(); + } + + public function testInfoOnCanceledResponse() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057/timeout-header'); + + $this->assertFalse($response->getInfo('canceled')); + $response->cancel(); + $this->assertTrue($response->getInfo('canceled')); + } + + public function testCancelInStream() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/404'); + + foreach ($client->stream($response) as $chunk) { + $response->cancel(); + } + + $this->expectException(TransportExceptionInterface::class); + + foreach ($client->stream($response) as $chunk) { + } + } + + public function testOnProgressCancel() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body', [ + 'on_progress' => function ($dlNow) { + if (0 < $dlNow) { + throw new \Exception('Aborting the request.'); + } + }, + ]); + + try { + foreach ($client->stream([$response]) as $chunk) { + } + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + $this->assertSame('Aborting the request.', $e->getPrevious()->getMessage()); + } + + $this->assertNotNull($response->getInfo('error')); + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testOnProgressError() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body', [ + 'on_progress' => function ($dlNow) { + if (0 < $dlNow) { + throw new \Error('BUG.'); + } + }, + ]); + + try { + foreach ($client->stream([$response]) as $chunk) { + } + $this->fail('Error expected'); + } catch (\Error $e) { + $this->assertSame('BUG.', $e->getMessage()); + } + + $this->assertNotNull($response->getInfo('error')); + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testResolve() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://symfony.com:8057/', [ + 'resolve' => ['symfony.com' => '127.0.0.1'], + ]); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame(200, $client->request('GET', 'http://symfony.com:8057/')->getStatusCode()); + + $response = null; + $this->expectException(TransportExceptionInterface::class); + $client->request('GET', 'http://symfony.com:8057/', ['timeout' => 1]); + } + + public function testIdnResolve() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://0-------------------------------------------------------------0.com:8057/', [ + 'resolve' => ['0-------------------------------------------------------------0.com' => '127.0.0.1'], + ]); + + $this->assertSame(200, $response->getStatusCode()); + + $response = $client->request('GET', 'http://Bücher.example:8057/', [ + 'resolve' => ['xn--bcher-kva.example' => '127.0.0.1'], + ]); + + $this->assertSame(200, $response->getStatusCode()); + } + + public function testNotATimeout() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-header', [ + 'timeout' => 0.9, + ]); + sleep(1); + $this->assertSame(200, $response->getStatusCode()); + } + + public function testTimeoutOnAccess() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-header', [ + 'timeout' => 0.1, + ]); + + $this->expectException(TransportExceptionInterface::class); + $response->getHeaders(); + } + + public function testTimeoutIsNotAFatalError() + { + usleep(300000); // wait for the previous test to release the server + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body', [ + 'timeout' => 0.25, + ]); + + try { + $response->getContent(); + $this->fail(TimeoutExceptionInterface::class.' expected'); + } catch (TimeoutExceptionInterface $e) { + } + + for ($i = 0; $i < 10; ++$i) { + try { + $this->assertSame('<1><2>', $response->getContent()); + break; + } catch (TimeoutExceptionInterface $e) { + } + } + + if (10 === $i) { + throw $e; + } + } + + public function testTimeoutOnStream() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body'); + + $this->assertSame(200, $response->getStatusCode()); + $chunks = $client->stream([$response], 0.2); + + $result = []; + + foreach ($chunks as $r => $chunk) { + if ($chunk->isTimeout()) { + $result[] = 't'; + } else { + $result[] = $chunk->getContent(); + } + } + + $this->assertSame(['<1>', 't'], $result); + + $chunks = $client->stream([$response]); + + foreach ($chunks as $r => $chunk) { + $this->assertSame('<2>', $chunk->getContent()); + $this->assertSame('<1><2>', $r->getContent()); + + return; + } + + $this->fail('The response should have completed'); + } + + public function testUncheckedTimeoutThrows() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body'); + $chunks = $client->stream([$response], 0.1); + + $this->expectException(TransportExceptionInterface::class); + + foreach ($chunks as $r => $chunk) { + } + } + + public function testTimeoutWithActiveConcurrentStream() + { + $p1 = TestHttpServer::start(8067); + $p2 = TestHttpServer::start(8077); + + $client = $this->getHttpClient(__FUNCTION__); + $streamingResponse = $client->request('GET', 'http://localhost:8067/max-duration'); + $blockingResponse = $client->request('GET', 'http://localhost:8077/timeout-body', [ + 'timeout' => 0.25, + ]); + + $this->assertSame(200, $streamingResponse->getStatusCode()); + $this->assertSame(200, $blockingResponse->getStatusCode()); + + $this->expectException(TransportExceptionInterface::class); + + try { + $blockingResponse->getContent(); + } finally { + $p1->stop(); + $p2->stop(); + } + } + + public function testTimeoutOnInitialize() + { + $p1 = TestHttpServer::start(8067); + $p2 = TestHttpServer::start(8077); + + $client = $this->getHttpClient(__FUNCTION__); + $start = microtime(true); + $responses = []; + + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + + try { + foreach ($responses as $response) { + try { + $response->getContent(); + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + } + } + $responses = []; + + $duration = microtime(true) - $start; + + $this->assertLessThan(1.0, $duration); + } finally { + $p1->stop(); + $p2->stop(); + } + } + + public function testTimeoutOnDestruct() + { + $p1 = TestHttpServer::start(8067); + $p2 = TestHttpServer::start(8077); + + $client = $this->getHttpClient(__FUNCTION__); + $start = microtime(true); + $responses = []; + + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + + try { + while ($response = array_shift($responses)) { + try { + unset($response); + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + } + } + + $duration = microtime(true) - $start; + + $this->assertLessThan(1.0, $duration); + } finally { + $p1->stop(); + $p2->stop(); + } + } + + public function testDestruct() + { + $client = $this->getHttpClient(__FUNCTION__); + + $start = microtime(true); + $client->request('GET', 'http://localhost:8057/timeout-long'); + $client = null; + $duration = microtime(true) - $start; + + $this->assertGreaterThan(1, $duration); + $this->assertLessThan(4, $duration); + } + + public function testGetContentAfterDestruct() + { + $client = $this->getHttpClient(__FUNCTION__); + + try { + $client->request('GET', 'http://localhost:8057/404'); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + $this->assertSame('GET', $e->getResponse()->toArray(false)['REQUEST_METHOD']); + } + } + + public function testGetEncodedContentAfterDestruct() + { + $client = $this->getHttpClient(__FUNCTION__); + + try { + $client->request('GET', 'http://localhost:8057/404-gzipped'); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + $this->assertSame('some text', $e->getResponse()->getContent(false)); + } + } + + public function testProxy() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/', [ + 'proxy' => 'http://localhost:8057', + ]); + + $body = $response->toArray(); + $this->assertSame('localhost:8057', $body['HTTP_HOST']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); + + $response = $client->request('GET', 'http://localhost:8057/', [ + 'proxy' => 'http://foo:b%3Dar@localhost:8057', + ]); + + $body = $response->toArray(); + $this->assertSame('Basic Zm9vOmI9YXI=', $body['HTTP_PROXY_AUTHORIZATION']); + + $_SERVER['http_proxy'] = 'http://localhost:8057'; + try { + $response = $client->request('GET', 'http://localhost:8057/'); + $body = $response->toArray(); + $this->assertSame('localhost:8057', $body['HTTP_HOST']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); + } finally { + unset($_SERVER['http_proxy']); + } + } + + public function testNoProxy() + { + putenv('no_proxy='.$_SERVER['no_proxy'] = 'example.com, localhost'); + + try { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/', [ + 'proxy' => 'http://localhost:8057', + ]); + + $body = $response->toArray(); + + $this->assertSame('HTTP/1.1', $body['SERVER_PROTOCOL']); + $this->assertSame('/', $body['REQUEST_URI']); + $this->assertSame('GET', $body['REQUEST_METHOD']); + } finally { + putenv('no_proxy'); + unset($_SERVER['no_proxy']); + } + } + + /** + * @requires extension zlib + */ + public function testAutoEncodingRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057'); + + $this->assertSame(200, $response->getStatusCode()); + + $headers = $response->getHeaders(); + + $this->assertSame(['Accept-Encoding'], $headers['vary']); + $this->assertStringContainsString('gzip', $headers['content-encoding'][0]); + + $body = $response->toArray(); + + $this->assertStringContainsString('gzip', $body['HTTP_ACCEPT_ENCODING']); + } + + public function testBaseUri() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', '../404', [ + 'base_uri' => 'http://localhost:8057/abc/', + ]); + + $this->assertSame(404, $response->getStatusCode()); + $this->assertSame(['application/json'], $response->getHeaders(false)['content-type']); + } + + public function testQuery() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/?a=a', [ + 'query' => ['b' => 'b'], + ]); + + $body = $response->toArray(); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('/?a=a&b=b', $body['REQUEST_URI']); + } + + public function testInformationalResponse() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/103'); + + $this->assertSame('Here the body', $response->getContent()); + $this->assertSame(200, $response->getStatusCode()); + } + + public function testInformationalResponseStream() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/103'); + + $chunks = []; + foreach ($client->stream($response) as $chunk) { + $chunks[] = $chunk; + } + + $this->assertSame(103, $chunks[0]->getInformationalStatus()[0]); + $this->assertSame(['; rel=preload; as=style', '; rel=preload; as=script'], $chunks[0]->getInformationalStatus()[1]['link']); + $this->assertTrue($chunks[1]->isFirst()); + $this->assertSame('Here the body', $chunks[2]->getContent()); + $this->assertTrue($chunks[3]->isLast()); + $this->assertNull($chunks[3]->getInformationalStatus()); + + $this->assertSame(['date', 'content-length'], array_keys($response->getHeaders())); + $this->assertContains('Link: ; rel=preload; as=style', $response->getInfo('response_headers')); + } + + /** + * @requires extension zlib + */ + public function testUserlandEncodingRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'headers' => ['Accept-Encoding' => 'gzip'], + ]); + + $headers = $response->getHeaders(); + + $this->assertSame(['Accept-Encoding'], $headers['vary']); + $this->assertStringContainsString('gzip', $headers['content-encoding'][0]); + + $body = $response->getContent(); + $this->assertSame("\x1F", $body[0]); + + $body = json_decode(gzdecode($body), true); + $this->assertSame('gzip', $body['HTTP_ACCEPT_ENCODING']); + } + + /** + * @requires extension zlib + */ + public function testGzipBroken() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/gzip-broken'); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testMaxDuration() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/max-duration', [ + 'max_duration' => 0.1, + ]); + + $start = microtime(true); + + try { + $response->getContent(); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + $duration = microtime(true) - $start; + + $this->assertLessThan(10, $duration); + } + + public function testWithOptions() + { + $client = $this->getHttpClient(__FUNCTION__); + if (!method_exists($client, 'withOptions')) { + $this->markTestSkipped(sprintf('Not implementing "%s::withOptions()" is deprecated.', get_debug_type($client))); + } + + $client2 = $client->withOptions(['base_uri' => 'http://localhost:8057/']); + + $this->assertNotSame($client, $client2); + $this->assertSame(\get_class($client), \get_class($client2)); + + $response = $client2->request('GET', '/'); + $this->assertSame(200, $response->getStatusCode()); + } +} diff --git a/vendor/symfony/http-client-contracts/Test/TestHttpServer.php b/vendor/symfony/http-client-contracts/Test/TestHttpServer.php new file mode 100644 index 000000000..55a744aef --- /dev/null +++ b/vendor/symfony/http-client-contracts/Test/TestHttpServer.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Test; + +use Symfony\Component\Process\PhpExecutableFinder; +use Symfony\Component\Process\Process; + +class TestHttpServer +{ + private static $process = []; + + /** + * @return Process + */ + public static function start(int $port = 8057) + { + if (isset(self::$process[$port])) { + self::$process[$port]->stop(); + } else { + register_shutdown_function(static function () use ($port) { + self::$process[$port]->stop(); + }); + } + + $finder = new PhpExecutableFinder(); + $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port])); + $process->setWorkingDirectory(__DIR__.'/Fixtures/web'); + $process->start(); + self::$process[$port] = $process; + + do { + usleep(50000); + } while (!@fopen('http://127.0.0.1:'.$port, 'r')); + + return $process; + } +} diff --git a/vendor/symfony/http-client-contracts/composer.json b/vendor/symfony/http-client-contracts/composer.json new file mode 100644 index 000000000..b76cab852 --- /dev/null +++ b/vendor/symfony/http-client-contracts/composer.json @@ -0,0 +1,37 @@ +{ + "name": "symfony/http-client-contracts", + "type": "library", + "description": "Generic abstractions related to HTTP clients", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\HttpClient\\": "" } + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + } +} diff --git a/vendor/symfony/http-client/AmpHttpClient.php b/vendor/symfony/http-client/AmpHttpClient.php new file mode 100644 index 000000000..2ab7e27f7 --- /dev/null +++ b/vendor/symfony/http-client/AmpHttpClient.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Amp\CancelledException; +use Amp\Http\Client\DelegateHttpClient; +use Amp\Http\Client\InterceptedHttpClient; +use Amp\Http\Client\PooledHttpClient; +use Amp\Http\Client\Request; +use Amp\Http\Tunnel\Http1TunnelConnector; +use Amp\Promise; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\AmpClientState; +use Symfony\Component\HttpClient\Response\AmpResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +if (!interface_exists(DelegateHttpClient::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\AmpHttpClient" as the "amphp/http-client" package is not installed. Try running "composer require amphp/http-client:^4.2.1".'); +} + +if (!interface_exists(Promise::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\AmpHttpClient" as the installed "amphp/http-client" is not compatible with this version of "symfony/http-client". Try downgrading "amphp/http-client" to "^4.2.1".'); +} + +/** + * A portable implementation of the HttpClientInterface contracts based on Amp's HTTP client. + * + * @author Nicolas Grekas + */ +final class AmpHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + use LoggerAwareTrait; + + private $defaultOptions = self::OPTIONS_DEFAULTS; + private static $emptyDefaults = self::OPTIONS_DEFAULTS; + + /** @var AmpClientState */ + private $multi; + + /** + * @param array $defaultOptions Default requests' options + * @param callable|null $clientConfigurator A callable that builds a {@see DelegateHttpClient} from a {@see PooledHttpClient}; + * passing null builds an {@see InterceptedHttpClient} with 2 retries on failures + * @param int $maxHostConnections The maximum number of connections to a single host + * @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public function __construct(array $defaultOptions = [], callable $clientConfigurator = null, int $maxHostConnections = 6, int $maxPendingPushes = 50) + { + $this->defaultOptions['buffer'] = $this->defaultOptions['buffer'] ?? \Closure::fromCallable([__CLASS__, 'shouldBuffer']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + + $this->multi = new AmpClientState($clientConfigurator, $maxHostConnections, $maxPendingPushes, $this->logger); + } + + /** + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + * + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); + + $options['proxy'] = self::getProxy($options['proxy'], $url, $options['no_proxy']); + + if (null !== $options['proxy'] && !class_exists(Http1TunnelConnector::class)) { + throw new \LogicException('You cannot use the "proxy" option as the "amphp/http-tunnel" package is not installed. Try running "composer require amphp/http-tunnel".'); + } + + if ($options['bindto']) { + if (0 === strpos($options['bindto'], 'if!')) { + throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.'); + } + if (0 === strpos($options['bindto'], 'host!')) { + $options['bindto'] = substr($options['bindto'], 5); + } + } + + if (('' !== $options['body'] || 'POST' === $method || isset($options['normalized_headers']['content-length'])) && !isset($options['normalized_headers']['content-type'])) { + $options['headers'][] = 'Content-Type: application/x-www-form-urlencoded'; + } + + if (!isset($options['normalized_headers']['user-agent'])) { + $options['headers'][] = 'User-Agent: Symfony HttpClient/Amp'; + } + + if (0 < $options['max_duration']) { + $options['timeout'] = min($options['max_duration'], $options['timeout']); + } + + if ($options['resolve']) { + $this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCache; + } + + if ($options['peer_fingerprint'] && !isset($options['peer_fingerprint']['pin-sha256'])) { + throw new TransportException(__CLASS__.' supports only "pin-sha256" fingerprints.'); + } + + $request = new Request(implode('', $url), $method); + + if ($options['http_version']) { + switch ((float) $options['http_version']) { + case 1.0: $request->setProtocolVersions(['1.0']); break; + case 1.1: $request->setProtocolVersions(['1.1', '1.0']); break; + default: $request->setProtocolVersions(['2', '1.1', '1.0']); break; + } + } + + foreach ($options['headers'] as $v) { + $h = explode(': ', $v, 2); + $request->addHeader($h[0], $h[1]); + } + + $request->setTcpConnectTimeout(1000 * $options['timeout']); + $request->setTlsHandshakeTimeout(1000 * $options['timeout']); + $request->setTransferTimeout(1000 * $options['max_duration']); + if (method_exists($request, 'setInactivityTimeout')) { + $request->setInactivityTimeout(0); + } + + if ('' !== $request->getUri()->getUserInfo() && !$request->hasHeader('authorization')) { + $auth = explode(':', $request->getUri()->getUserInfo(), 2); + $auth = array_map('rawurldecode', $auth) + [1 => '']; + $request->setHeader('Authorization', 'Basic '.base64_encode(implode(':', $auth))); + } + + return new AmpResponse($this->multi, $request, $options, $this->logger); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof AmpResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of AmpResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(AmpResponse::stream($responses, $timeout)); + } + + public function reset() + { + $this->multi->dnsCache = []; + + foreach ($this->multi->pushedResponses as $authority => $pushedResponses) { + foreach ($pushedResponses as [$pushedUrl, $pushDeferred]) { + $pushDeferred->fail(new CancelledException()); + + if ($this->logger) { + $this->logger->debug(sprintf('Unused pushed response: "%s"', $pushedUrl)); + } + } + } + + $this->multi->pushedResponses = []; + } +} diff --git a/vendor/symfony/http-client/AsyncDecoratorTrait.php b/vendor/symfony/http-client/AsyncDecoratorTrait.php new file mode 100644 index 000000000..aff402d83 --- /dev/null +++ b/vendor/symfony/http-client/AsyncDecoratorTrait.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Response\AsyncResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; + +/** + * Eases with processing responses while streaming them. + * + * @author Nicolas Grekas + */ +trait AsyncDecoratorTrait +{ + use DecoratorTrait; + + /** + * {@inheritdoc} + * + * @return AsyncResponse + */ + abstract public function request(string $method, string $url, array $options = []): ResponseInterface; + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof AsyncResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of AsyncResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(AsyncResponse::stream($responses, $timeout, static::class)); + } +} diff --git a/vendor/symfony/http-client/CHANGELOG.md b/vendor/symfony/http-client/CHANGELOG.md new file mode 100644 index 000000000..7c2fc2273 --- /dev/null +++ b/vendor/symfony/http-client/CHANGELOG.md @@ -0,0 +1,54 @@ +CHANGELOG +========= + +5.4 +--- + + * Add `MockHttpClient::setResponseFactory()` method to be able to set response factory after client creating + +5.3 +--- + + * Implement `HttpClientInterface::withOptions()` from `symfony/contracts` v2.4 + * Add `DecoratorTrait` to ease writing simple decorators + +5.2.0 +----- + + * added `AsyncDecoratorTrait` to ease processing responses without breaking async + * added support for pausing responses with a new `pause_handler` callable exposed as an info item + * added `StreamableInterface` to ease turning responses into PHP streams + * added `MockResponse::getRequestMethod()` and `getRequestUrl()` to allow inspecting which request has been sent + * added `EventSourceHttpClient` a Server-Sent events stream implementing the [EventSource specification](https://www.w3.org/TR/eventsource/#eventsource) + * added option "extra.curl" to allow setting additional curl options in `CurlHttpClient` + * added `RetryableHttpClient` to automatically retry failed HTTP requests. + * added `extra.trace_content` option to `TraceableHttpClient` to prevent it from keeping the content in memory + +5.1.0 +----- + + * added `NoPrivateNetworkHttpClient` decorator + * added `AmpHttpClient`, a portable HTTP/2 implementation based on Amp + * added `LoggerAwareInterface` to `ScopingHttpClient` and `TraceableHttpClient` + * made `HttpClient::create()` return an `AmpHttpClient` when `amphp/http-client` is found but curl is not or too old + +4.4.0 +----- + + * added `canceled` to `ResponseInterface::getInfo()` + * added `HttpClient::createForBaseUri()` + * added `HttplugClient` with support for sync and async requests + * added `max_duration` option + * added support for NTLM authentication + * added `StreamWrapper` to cast any `ResponseInterface` instances to PHP streams. + * added `$response->toStream()` to cast responses to regular PHP streams + * made `Psr18Client` implement relevant PSR-17 factories and have streaming responses + * added `TraceableHttpClient`, `HttpClientDataCollector` and `HttpClientPass` to integrate with the web profiler + * allow enabling buffering conditionally with a Closure + * allow option "buffer" to be a stream resource + * allow arbitrary values for the "json" option + +4.3.0 +----- + + * added the component diff --git a/vendor/symfony/http-client/CachingHttpClient.php b/vendor/symfony/http-client/CachingHttpClient.php new file mode 100644 index 000000000..e1d7023d9 --- /dev/null +++ b/vendor/symfony/http-client/CachingHttpClient.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Response\MockResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpCache\HttpCache; +use Symfony\Component\HttpKernel\HttpCache\StoreInterface; +use Symfony\Component\HttpKernel\HttpClientKernel; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Adds caching on top of an HTTP client. + * + * The implementation buffers responses in memory and doesn't stream directly from the network. + * You can disable/enable this layer by setting option "no_cache" under "extra" to true/false. + * By default, caching is enabled unless the "buffer" option is set to false. + * + * @author Nicolas Grekas + */ +class CachingHttpClient implements HttpClientInterface, ResetInterface +{ + use HttpClientTrait; + + private $client; + private $cache; + private $defaultOptions = self::OPTIONS_DEFAULTS; + + public function __construct(HttpClientInterface $client, StoreInterface $store, array $defaultOptions = []) + { + if (!class_exists(HttpClientKernel::class)) { + throw new \LogicException(sprintf('Using "%s" requires that the HttpKernel component version 4.3 or higher is installed, try running "composer require symfony/http-kernel:^5.4".', __CLASS__)); + } + + $this->client = $client; + $kernel = new HttpClientKernel($client); + $this->cache = new HttpCache($kernel, $store, null, $defaultOptions); + + unset($defaultOptions['debug']); + unset($defaultOptions['default_ttl']); + unset($defaultOptions['private_headers']); + unset($defaultOptions['allow_reload']); + unset($defaultOptions['allow_revalidate']); + unset($defaultOptions['stale_while_revalidate']); + unset($defaultOptions['stale_if_error']); + unset($defaultOptions['trace_level']); + unset($defaultOptions['trace_header']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = $this->prepareRequest($method, $url, $options, $this->defaultOptions, true); + $url = implode('', $url); + + if (!empty($options['body']) || !empty($options['extra']['no_cache']) || !\in_array($method, ['GET', 'HEAD', 'OPTIONS'])) { + return $this->client->request($method, $url, $options); + } + + $request = Request::create($url, $method); + $request->attributes->set('http_client_options', $options); + + foreach ($options['normalized_headers'] as $name => $values) { + if ('cookie' !== $name) { + foreach ($values as $value) { + $request->headers->set($name, substr($value, 2 + \strlen($name)), false); + } + + continue; + } + + foreach ($values as $cookies) { + foreach (explode('; ', substr($cookies, \strlen('Cookie: '))) as $cookie) { + if ('' !== $cookie) { + $cookie = explode('=', $cookie, 2); + $request->cookies->set($cookie[0], $cookie[1] ?? ''); + } + } + } + } + + $response = $this->cache->handle($request); + $response = new MockResponse($response->getContent(), [ + 'http_code' => $response->getStatusCode(), + 'response_headers' => $response->headers->allPreserveCase(), + ]); + + return MockResponse::fromRequest($method, $url, $options, $response); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof ResponseInterface) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of ResponseInterface objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + $mockResponses = []; + $clientResponses = []; + + foreach ($responses as $response) { + if ($response instanceof MockResponse) { + $mockResponses[] = $response; + } else { + $clientResponses[] = $response; + } + } + + if (!$mockResponses) { + return $this->client->stream($clientResponses, $timeout); + } + + if (!$clientResponses) { + return new ResponseStream(MockResponse::stream($mockResponses, $timeout)); + } + + return new ResponseStream((function () use ($mockResponses, $clientResponses, $timeout) { + yield from MockResponse::stream($mockResponses, $timeout); + yield $this->client->stream($clientResponses, $timeout); + })()); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} diff --git a/vendor/symfony/http-client/Chunk/DataChunk.php b/vendor/symfony/http-client/Chunk/DataChunk.php new file mode 100644 index 000000000..37ca84854 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/DataChunk.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +use Symfony\Contracts\HttpClient\ChunkInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class DataChunk implements ChunkInterface +{ + private $offset = 0; + private $content = ''; + + public function __construct(int $offset = 0, string $content = '') + { + $this->offset = $offset; + $this->content = $content; + } + + /** + * {@inheritdoc} + */ + public function isTimeout(): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + public function isFirst(): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + public function isLast(): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + public function getInformationalStatus(): ?array + { + return null; + } + + /** + * {@inheritdoc} + */ + public function getContent(): string + { + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function getOffset(): int + { + return $this->offset; + } + + /** + * {@inheritdoc} + */ + public function getError(): ?string + { + return null; + } +} diff --git a/vendor/symfony/http-client/Chunk/ErrorChunk.php b/vendor/symfony/http-client/Chunk/ErrorChunk.php new file mode 100644 index 000000000..a19f43362 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/ErrorChunk.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +use Symfony\Component\HttpClient\Exception\TimeoutException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Contracts\HttpClient\ChunkInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class ErrorChunk implements ChunkInterface +{ + private $didThrow = false; + private $offset; + private $errorMessage; + private $error; + + /** + * @param \Throwable|string $error + */ + public function __construct(int $offset, $error) + { + $this->offset = $offset; + + if (\is_string($error)) { + $this->errorMessage = $error; + } else { + $this->error = $error; + $this->errorMessage = $error->getMessage(); + } + } + + /** + * {@inheritdoc} + */ + public function isTimeout(): bool + { + $this->didThrow = true; + + if (null !== $this->error) { + throw new TransportException($this->errorMessage, 0, $this->error); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function isFirst(): bool + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function isLast(): bool + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function getInformationalStatus(): ?array + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function getContent(): string + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function getOffset(): int + { + return $this->offset; + } + + /** + * {@inheritdoc} + */ + public function getError(): ?string + { + return $this->errorMessage; + } + + /** + * @return bool Whether the wrapped error has been thrown or not + */ + public function didThrow(bool $didThrow = null): bool + { + if (null !== $didThrow && $this->didThrow !== $didThrow) { + return !$this->didThrow = $didThrow; + } + + return $this->didThrow; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + if (!$this->didThrow) { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + } +} diff --git a/vendor/symfony/http-client/Chunk/FirstChunk.php b/vendor/symfony/http-client/Chunk/FirstChunk.php new file mode 100644 index 000000000..d891ca856 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/FirstChunk.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class FirstChunk extends DataChunk +{ + /** + * {@inheritdoc} + */ + public function isFirst(): bool + { + return true; + } +} diff --git a/vendor/symfony/http-client/Chunk/InformationalChunk.php b/vendor/symfony/http-client/Chunk/InformationalChunk.php new file mode 100644 index 000000000..c4452f15a --- /dev/null +++ b/vendor/symfony/http-client/Chunk/InformationalChunk.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class InformationalChunk extends DataChunk +{ + private $status; + + public function __construct(int $statusCode, array $headers) + { + $this->status = [$statusCode, $headers]; + } + + /** + * {@inheritdoc} + */ + public function getInformationalStatus(): ?array + { + return $this->status; + } +} diff --git a/vendor/symfony/http-client/Chunk/LastChunk.php b/vendor/symfony/http-client/Chunk/LastChunk.php new file mode 100644 index 000000000..84095d392 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/LastChunk.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class LastChunk extends DataChunk +{ + /** + * {@inheritdoc} + */ + public function isLast(): bool + { + return true; + } +} diff --git a/vendor/symfony/http-client/Chunk/ServerSentEvent.php b/vendor/symfony/http-client/Chunk/ServerSentEvent.php new file mode 100644 index 000000000..f7ff4b963 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/ServerSentEvent.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +use Symfony\Contracts\HttpClient\ChunkInterface; + +/** + * @author Antoine Bluchet + * @author Nicolas Grekas + */ +final class ServerSentEvent extends DataChunk implements ChunkInterface +{ + private $data = ''; + private $id = ''; + private $type = 'message'; + private $retry = 0; + + public function __construct(string $content) + { + parent::__construct(-1, $content); + + // remove BOM + if (0 === strpos($content, "\xEF\xBB\xBF")) { + $content = substr($content, 3); + } + + foreach (preg_split("/(?:\r\n|[\r\n])/", $content) as $line) { + if (0 === $i = strpos($line, ':')) { + continue; + } + + $i = false === $i ? \strlen($line) : $i; + $field = substr($line, 0, $i); + $i += 1 + (' ' === ($line[1 + $i] ?? '')); + + switch ($field) { + case 'id': $this->id = substr($line, $i); break; + case 'event': $this->type = substr($line, $i); break; + case 'data': $this->data .= ('' === $this->data ? '' : "\n").substr($line, $i); break; + case 'retry': + $retry = substr($line, $i); + + if ('' !== $retry && \strlen($retry) === strspn($retry, '0123456789')) { + $this->retry = $retry / 1000.0; + } + break; + } + } + } + + public function getId(): string + { + return $this->id; + } + + public function getType(): string + { + return $this->type; + } + + public function getData(): string + { + return $this->data; + } + + public function getRetry(): float + { + return $this->retry; + } +} diff --git a/vendor/symfony/http-client/CurlHttpClient.php b/vendor/symfony/http-client/CurlHttpClient.php new file mode 100644 index 000000000..ef6d700cc --- /dev/null +++ b/vendor/symfony/http-client/CurlHttpClient.php @@ -0,0 +1,552 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\CurlClientState; +use Symfony\Component\HttpClient\Internal\PushedResponse; +use Symfony\Component\HttpClient\Response\CurlResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * A performant implementation of the HttpClientInterface contracts based on the curl extension. + * + * This provides fully concurrent HTTP requests, with transparent + * HTTP/2 push when a curl version that supports it is installed. + * + * @author Nicolas Grekas + */ +final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + + private $defaultOptions = self::OPTIONS_DEFAULTS + [ + 'auth_ntlm' => null, // array|string - an array containing the username as first value, and optionally the + // password as the second one; or string like username:password - enabling NTLM auth + 'extra' => [ + 'curl' => [], // A list of extra curl options indexed by their corresponding CURLOPT_* + ], + ]; + private static $emptyDefaults = self::OPTIONS_DEFAULTS + ['auth_ntlm' => null]; + + /** + * @var LoggerInterface|null + */ + private $logger; + + /** + * An internal object to share state between the client and its responses. + * + * @var CurlClientState + */ + private $multi; + + /** + * @param array $defaultOptions Default request's options + * @param int $maxHostConnections The maximum number of connections to a single host + * @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public function __construct(array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50) + { + if (!\extension_loaded('curl')) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\CurlHttpClient" as the "curl" extension is not installed.'); + } + + $this->defaultOptions['buffer'] = $this->defaultOptions['buffer'] ?? \Closure::fromCallable([__CLASS__, 'shouldBuffer']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + + $this->multi = new CurlClientState($maxHostConnections, $maxPendingPushes); + } + + public function setLogger(LoggerInterface $logger): void + { + $this->logger = $this->multi->logger = $logger; + } + + /** + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + * + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); + $scheme = $url['scheme']; + $authority = $url['authority']; + $host = parse_url($authority, \PHP_URL_HOST); + $proxy = self::getProxyUrl($options['proxy'], $url); + $url = implode('', $url); + + if (!isset($options['normalized_headers']['user-agent'])) { + $options['headers'][] = 'User-Agent: Symfony HttpClient/Curl'; + } + + $curlopts = [ + \CURLOPT_URL => $url, + \CURLOPT_TCP_NODELAY => true, + \CURLOPT_PROTOCOLS => \CURLPROTO_HTTP | \CURLPROTO_HTTPS, + \CURLOPT_REDIR_PROTOCOLS => \CURLPROTO_HTTP | \CURLPROTO_HTTPS, + \CURLOPT_FOLLOWLOCATION => true, + \CURLOPT_MAXREDIRS => 0 < $options['max_redirects'] ? $options['max_redirects'] : 0, + \CURLOPT_COOKIEFILE => '', // Keep track of cookies during redirects + \CURLOPT_TIMEOUT => 0, + \CURLOPT_PROXY => $proxy, + \CURLOPT_NOPROXY => $options['no_proxy'] ?? $_SERVER['no_proxy'] ?? $_SERVER['NO_PROXY'] ?? '', + \CURLOPT_SSL_VERIFYPEER => $options['verify_peer'], + \CURLOPT_SSL_VERIFYHOST => $options['verify_host'] ? 2 : 0, + \CURLOPT_CAINFO => $options['cafile'], + \CURLOPT_CAPATH => $options['capath'], + \CURLOPT_SSL_CIPHER_LIST => $options['ciphers'], + \CURLOPT_SSLCERT => $options['local_cert'], + \CURLOPT_SSLKEY => $options['local_pk'], + \CURLOPT_KEYPASSWD => $options['passphrase'], + \CURLOPT_CERTINFO => $options['capture_peer_cert_chain'], + ]; + + if (1.0 === (float) $options['http_version']) { + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0; + } elseif (1.1 === (float) $options['http_version']) { + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; + } elseif (\defined('CURL_VERSION_HTTP2') && (\CURL_VERSION_HTTP2 & CurlClientState::$curlVersion['features']) && ('https:' === $scheme || 2.0 === (float) $options['http_version'])) { + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0; + } + + if (isset($options['auth_ntlm'])) { + $curlopts[\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM; + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; + + if (\is_array($options['auth_ntlm'])) { + $count = \count($options['auth_ntlm']); + if ($count <= 0 || $count > 2) { + throw new InvalidArgumentException(sprintf('Option "auth_ntlm" must contain 1 or 2 elements, %d given.', $count)); + } + + $options['auth_ntlm'] = implode(':', $options['auth_ntlm']); + } + + if (!\is_string($options['auth_ntlm'])) { + throw new InvalidArgumentException(sprintf('Option "auth_ntlm" must be a string or an array, "%s" given.', get_debug_type($options['auth_ntlm']))); + } + + $curlopts[\CURLOPT_USERPWD] = $options['auth_ntlm']; + } + + if (!\ZEND_THREAD_SAFE) { + $curlopts[\CURLOPT_DNS_USE_GLOBAL_CACHE] = false; + } + + if (\defined('CURLOPT_HEADEROPT') && \defined('CURLHEADER_SEPARATE')) { + $curlopts[\CURLOPT_HEADEROPT] = \CURLHEADER_SEPARATE; + } + + // curl's resolve feature varies by host:port but ours varies by host only, let's handle this with our own DNS map + if (isset($this->multi->dnsCache->hostnames[$host])) { + $options['resolve'] += [$host => $this->multi->dnsCache->hostnames[$host]]; + } + + if ($options['resolve'] || $this->multi->dnsCache->evictions) { + // First reset any old DNS cache entries then add the new ones + $resolve = $this->multi->dnsCache->evictions; + $this->multi->dnsCache->evictions = []; + $port = parse_url($authority, \PHP_URL_PORT) ?: ('http:' === $scheme ? 80 : 443); + + if ($resolve && 0x072A00 > CurlClientState::$curlVersion['version_number']) { + // DNS cache removals require curl 7.42 or higher + $this->multi->reset(); + } + + foreach ($options['resolve'] as $host => $ip) { + $resolve[] = null === $ip ? "-$host:$port" : "$host:$port:$ip"; + $this->multi->dnsCache->hostnames[$host] = $ip; + $this->multi->dnsCache->removals["-$host:$port"] = "-$host:$port"; + } + + $curlopts[\CURLOPT_RESOLVE] = $resolve; + } + + if ('POST' === $method) { + // Use CURLOPT_POST to have browser-like POST-to-GET redirects for 301, 302 and 303 + $curlopts[\CURLOPT_POST] = true; + } elseif ('HEAD' === $method) { + $curlopts[\CURLOPT_NOBODY] = true; + } else { + $curlopts[\CURLOPT_CUSTOMREQUEST] = $method; + } + + if ('\\' !== \DIRECTORY_SEPARATOR && $options['timeout'] < 1) { + $curlopts[\CURLOPT_NOSIGNAL] = true; + } + + if (\extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) { + $options['headers'][] = 'Accept-Encoding: gzip'; // Expose only one encoding, some servers mess up when more are provided + } + $body = $options['body']; + + foreach ($options['headers'] as $i => $header) { + if (\is_string($body) && '' !== $body && 0 === stripos($header, 'Content-Length: ')) { + // Let curl handle Content-Length headers + unset($options['headers'][$i]); + continue; + } + if (':' === $header[-2] && \strlen($header) - 2 === strpos($header, ': ')) { + // curl requires a special syntax to send empty headers + $curlopts[\CURLOPT_HTTPHEADER][] = substr_replace($header, ';', -2); + } else { + $curlopts[\CURLOPT_HTTPHEADER][] = $header; + } + } + + // Prevent curl from sending its default Accept and Expect headers + foreach (['accept', 'expect'] as $header) { + if (!isset($options['normalized_headers'][$header][0])) { + $curlopts[\CURLOPT_HTTPHEADER][] = $header.':'; + } + } + + if (!\is_string($body)) { + if (\is_resource($body)) { + $curlopts[\CURLOPT_INFILE] = $body; + } else { + $eof = false; + $buffer = ''; + $curlopts[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use ($body, &$buffer, &$eof) { + return self::readRequestBody($length, $body, $buffer, $eof); + }; + } + + if (isset($options['normalized_headers']['content-length'][0])) { + $curlopts[\CURLOPT_INFILESIZE] = (int) substr($options['normalized_headers']['content-length'][0], \strlen('Content-Length: ')); + } + if (!isset($options['normalized_headers']['transfer-encoding'])) { + $curlopts[\CURLOPT_HTTPHEADER][] = 'Transfer-Encoding:'.(isset($curlopts[\CURLOPT_INFILESIZE]) ? '' : ' chunked'); + } + + if ('POST' !== $method) { + $curlopts[\CURLOPT_UPLOAD] = true; + + if (!isset($options['normalized_headers']['content-type']) && 0 !== ($curlopts[\CURLOPT_INFILESIZE] ?? null)) { + $curlopts[\CURLOPT_HTTPHEADER][] = 'Content-Type: application/x-www-form-urlencoded'; + } + } + } elseif ('' !== $body || 'POST' === $method) { + $curlopts[\CURLOPT_POSTFIELDS] = $body; + } + + if ($options['peer_fingerprint']) { + if (!isset($options['peer_fingerprint']['pin-sha256'])) { + throw new TransportException(__CLASS__.' supports only "pin-sha256" fingerprints.'); + } + + $curlopts[\CURLOPT_PINNEDPUBLICKEY] = 'sha256//'.implode(';sha256//', $options['peer_fingerprint']['pin-sha256']); + } + + if ($options['bindto']) { + if (file_exists($options['bindto'])) { + $curlopts[\CURLOPT_UNIX_SOCKET_PATH] = $options['bindto']; + } elseif (!str_starts_with($options['bindto'], 'if!') && preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) { + $curlopts[\CURLOPT_INTERFACE] = $matches[1]; + $curlopts[\CURLOPT_LOCALPORT] = $matches[2]; + } else { + $curlopts[\CURLOPT_INTERFACE] = $options['bindto']; + } + } + + if (0 < $options['max_duration']) { + $curlopts[\CURLOPT_TIMEOUT_MS] = 1000 * $options['max_duration']; + } + + if (!empty($options['extra']['curl']) && \is_array($options['extra']['curl'])) { + $this->validateExtraCurlOptions($options['extra']['curl']); + $curlopts += $options['extra']['curl']; + } + + if ($pushedResponse = $this->multi->pushedResponses[$url] ?? null) { + unset($this->multi->pushedResponses[$url]); + + if (self::acceptPushForRequest($method, $options, $pushedResponse)) { + $this->logger && $this->logger->debug(sprintf('Accepting pushed response: "%s %s"', $method, $url)); + + // Reinitialize the pushed response with request's options + $ch = $pushedResponse->handle; + $pushedResponse = $pushedResponse->response; + $pushedResponse->__construct($this->multi, $url, $options, $this->logger); + } else { + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s"', $url)); + $pushedResponse = null; + } + } + + if (!$pushedResponse) { + $ch = curl_init(); + $this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url)); + $curlopts += [\CURLOPT_SHARE => $this->multi->share]; + } + + foreach ($curlopts as $opt => $value) { + if (null !== $value && !curl_setopt($ch, $opt, $value) && \CURLOPT_CERTINFO !== $opt && (!\defined('CURLOPT_HEADEROPT') || \CURLOPT_HEADEROPT !== $opt)) { + $constantName = $this->findConstantName($opt); + throw new TransportException(sprintf('Curl option "%s" is not supported.', $constantName ?? $opt)); + } + } + + return $pushedResponse ?? new CurlResponse($this->multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host), CurlClientState::$curlVersion['version_number']); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof CurlResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of CurlResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + if (\is_resource($this->multi->handle) || $this->multi->handle instanceof \CurlMultiHandle) { + $active = 0; + while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active)) { + } + } + + return new ResponseStream(CurlResponse::stream($responses, $timeout)); + } + + public function reset() + { + $this->multi->reset(); + } + + /** + * Accepts pushed responses only if their headers related to authentication match the request. + */ + private static function acceptPushForRequest(string $method, array $options, PushedResponse $pushedResponse): bool + { + if ('' !== $options['body'] || $method !== $pushedResponse->requestHeaders[':method'][0]) { + return false; + } + + foreach (['proxy', 'no_proxy', 'bindto', 'local_cert', 'local_pk'] as $k) { + if ($options[$k] !== $pushedResponse->parentOptions[$k]) { + return false; + } + } + + foreach (['authorization', 'cookie', 'range', 'proxy-authorization'] as $k) { + $normalizedHeaders = $options['normalized_headers'][$k] ?? []; + foreach ($normalizedHeaders as $i => $v) { + $normalizedHeaders[$i] = substr($v, \strlen($k) + 2); + } + + if (($pushedResponse->requestHeaders[$k] ?? []) !== $normalizedHeaders) { + return false; + } + } + + return true; + } + + /** + * Wraps the request's body callback to allow it to return strings longer than curl requested. + */ + private static function readRequestBody(int $length, \Closure $body, string &$buffer, bool &$eof): string + { + if (!$eof && \strlen($buffer) < $length) { + if (!\is_string($data = $body($length))) { + throw new TransportException(sprintf('The return value of the "body" option callback must be a string, "%s" returned.', get_debug_type($data))); + } + + $buffer .= $data; + $eof = '' === $data; + } + + $data = substr($buffer, 0, $length); + $buffer = substr($buffer, $length); + + return $data; + } + + /** + * Resolves relative URLs on redirects and deals with authentication headers. + * + * Work around CVE-2018-1000007: Authorization and Cookie headers should not follow redirects - fixed in Curl 7.64 + */ + private static function createRedirectResolver(array $options, string $host): \Closure + { + $redirectHeaders = []; + if (0 < $options['max_redirects']) { + $redirectHeaders['host'] = $host; + $redirectHeaders['with_auth'] = $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) { + return 0 !== stripos($h, 'Host:'); + }); + + if (isset($options['normalized_headers']['authorization'][0]) || isset($options['normalized_headers']['cookie'][0])) { + $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) { + return 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:'); + }); + } + } + + return static function ($ch, string $location, bool $noContent) use (&$redirectHeaders, $options) { + try { + $location = self::parseUrl($location); + } catch (InvalidArgumentException $e) { + return null; + } + + if ($noContent && $redirectHeaders) { + $filterContentHeaders = static function ($h) { + return 0 !== stripos($h, 'Content-Length:') && 0 !== stripos($h, 'Content-Type:') && 0 !== stripos($h, 'Transfer-Encoding:'); + }; + $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], $filterContentHeaders); + $redirectHeaders['with_auth'] = array_filter($redirectHeaders['with_auth'], $filterContentHeaders); + } + + if ($redirectHeaders && $host = parse_url('http:'.$location['authority'], \PHP_URL_HOST)) { + $requestHeaders = $redirectHeaders['host'] === $host ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth']; + curl_setopt($ch, \CURLOPT_HTTPHEADER, $requestHeaders); + } elseif ($noContent && $redirectHeaders) { + curl_setopt($ch, \CURLOPT_HTTPHEADER, $redirectHeaders['with_auth']); + } + + $url = self::parseUrl(curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL)); + $url = self::resolveUrl($location, $url); + + curl_setopt($ch, \CURLOPT_PROXY, self::getProxyUrl($options['proxy'], $url)); + + return implode('', $url); + }; + } + + private function findConstantName(int $opt): ?string + { + $constants = array_filter(get_defined_constants(), static function ($v, $k) use ($opt) { + return $v === $opt && 'C' === $k[0] && (str_starts_with($k, 'CURLOPT_') || str_starts_with($k, 'CURLINFO_')); + }, \ARRAY_FILTER_USE_BOTH); + + return key($constants); + } + + /** + * Prevents overriding options that are set internally throughout the request. + */ + private function validateExtraCurlOptions(array $options): void + { + $curloptsToConfig = [ + // options used in CurlHttpClient + \CURLOPT_HTTPAUTH => 'auth_ntlm', + \CURLOPT_USERPWD => 'auth_ntlm', + \CURLOPT_RESOLVE => 'resolve', + \CURLOPT_NOSIGNAL => 'timeout', + \CURLOPT_HTTPHEADER => 'headers', + \CURLOPT_INFILE => 'body', + \CURLOPT_READFUNCTION => 'body', + \CURLOPT_INFILESIZE => 'body', + \CURLOPT_POSTFIELDS => 'body', + \CURLOPT_UPLOAD => 'body', + \CURLOPT_INTERFACE => 'bindto', + \CURLOPT_TIMEOUT_MS => 'max_duration', + \CURLOPT_TIMEOUT => 'max_duration', + \CURLOPT_MAXREDIRS => 'max_redirects', + \CURLOPT_POSTREDIR => 'max_redirects', + \CURLOPT_PROXY => 'proxy', + \CURLOPT_NOPROXY => 'no_proxy', + \CURLOPT_SSL_VERIFYPEER => 'verify_peer', + \CURLOPT_SSL_VERIFYHOST => 'verify_host', + \CURLOPT_CAINFO => 'cafile', + \CURLOPT_CAPATH => 'capath', + \CURLOPT_SSL_CIPHER_LIST => 'ciphers', + \CURLOPT_SSLCERT => 'local_cert', + \CURLOPT_SSLKEY => 'local_pk', + \CURLOPT_KEYPASSWD => 'passphrase', + \CURLOPT_CERTINFO => 'capture_peer_cert_chain', + \CURLOPT_USERAGENT => 'normalized_headers', + \CURLOPT_REFERER => 'headers', + // options used in CurlResponse + \CURLOPT_NOPROGRESS => 'on_progress', + \CURLOPT_PROGRESSFUNCTION => 'on_progress', + ]; + + if (\defined('CURLOPT_UNIX_SOCKET_PATH')) { + $curloptsToConfig[\CURLOPT_UNIX_SOCKET_PATH] = 'bindto'; + } + + if (\defined('CURLOPT_PINNEDPUBLICKEY')) { + $curloptsToConfig[\CURLOPT_PINNEDPUBLICKEY] = 'peer_fingerprint'; + } + + $curloptsToCheck = [ + \CURLOPT_PRIVATE, + \CURLOPT_HEADERFUNCTION, + \CURLOPT_WRITEFUNCTION, + \CURLOPT_VERBOSE, + \CURLOPT_STDERR, + \CURLOPT_RETURNTRANSFER, + \CURLOPT_URL, + \CURLOPT_FOLLOWLOCATION, + \CURLOPT_HEADER, + \CURLOPT_CONNECTTIMEOUT, + \CURLOPT_CONNECTTIMEOUT_MS, + \CURLOPT_HTTP_VERSION, + \CURLOPT_PORT, + \CURLOPT_DNS_USE_GLOBAL_CACHE, + \CURLOPT_PROTOCOLS, + \CURLOPT_REDIR_PROTOCOLS, + \CURLOPT_COOKIEFILE, + \CURLINFO_REDIRECT_COUNT, + ]; + + if (\defined('CURLOPT_HTTP09_ALLOWED')) { + $curloptsToCheck[] = \CURLOPT_HTTP09_ALLOWED; + } + + if (\defined('CURLOPT_HEADEROPT')) { + $curloptsToCheck[] = \CURLOPT_HEADEROPT; + } + + $methodOpts = [ + \CURLOPT_POST, + \CURLOPT_PUT, + \CURLOPT_CUSTOMREQUEST, + \CURLOPT_HTTPGET, + \CURLOPT_NOBODY, + ]; + + foreach ($options as $opt => $optValue) { + if (isset($curloptsToConfig[$opt])) { + $constName = $this->findConstantName($opt) ?? $opt; + throw new InvalidArgumentException(sprintf('Cannot set "%s" with "extra.curl", use option "%s" instead.', $constName, $curloptsToConfig[$opt])); + } + + if (\in_array($opt, $methodOpts)) { + throw new InvalidArgumentException('The HTTP method cannot be overridden using "extra.curl".'); + } + + if (\in_array($opt, $curloptsToCheck)) { + $constName = $this->findConstantName($opt) ?? $opt; + throw new InvalidArgumentException(sprintf('Cannot set "%s" with "extra.curl".', $constName)); + } + } + } +} diff --git a/vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php b/vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php new file mode 100644 index 000000000..192578636 --- /dev/null +++ b/vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\DataCollector; + +use Symfony\Component\HttpClient\TraceableHttpClient; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; +use Symfony\Component\VarDumper\Caster\ImgStub; + +/** + * @author Jérémy Romey + */ +final class HttpClientDataCollector extends DataCollector implements LateDataCollectorInterface +{ + /** + * @var TraceableHttpClient[] + */ + private $clients = []; + + public function registerClient(string $name, TraceableHttpClient $client) + { + $this->clients[$name] = $client; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Throwable $exception = null) + { + $this->lateCollect(); + } + + public function lateCollect() + { + $this->data['request_count'] = $this->data['request_count'] ?? 0; + $this->data['error_count'] = $this->data['error_count'] ?? 0; + $this->data += ['clients' => []]; + + foreach ($this->clients as $name => $client) { + [$errorCount, $traces] = $this->collectOnClient($client); + + $this->data['clients'] += [ + $name => [ + 'traces' => [], + 'error_count' => 0, + ], + ]; + + $this->data['clients'][$name]['traces'] = array_merge($this->data['clients'][$name]['traces'], $traces); + $this->data['request_count'] += \count($traces); + $this->data['error_count'] += $errorCount; + $this->data['clients'][$name]['error_count'] += $errorCount; + + $client->reset(); + } + } + + public function getClients(): array + { + return $this->data['clients'] ?? []; + } + + public function getRequestCount(): int + { + return $this->data['request_count'] ?? 0; + } + + public function getErrorCount(): int + { + return $this->data['error_count'] ?? 0; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return 'http_client'; + } + + public function reset() + { + $this->data = [ + 'clients' => [], + 'request_count' => 0, + 'error_count' => 0, + ]; + } + + private function collectOnClient(TraceableHttpClient $client): array + { + $traces = $client->getTracedRequests(); + $errorCount = 0; + $baseInfo = [ + 'response_headers' => 1, + 'retry_count' => 1, + 'redirect_count' => 1, + 'redirect_url' => 1, + 'user_data' => 1, + 'error' => 1, + 'url' => 1, + ]; + + foreach ($traces as $i => $trace) { + if (400 <= ($trace['info']['http_code'] ?? 0)) { + ++$errorCount; + } + + $info = $trace['info']; + $traces[$i]['http_code'] = $info['http_code'] ?? 0; + + unset($info['filetime'], $info['http_code'], $info['ssl_verify_result'], $info['content_type']); + + if (($info['http_method'] ?? null) === $trace['method']) { + unset($info['http_method']); + } + + if (($info['url'] ?? null) === $trace['url']) { + unset($info['url']); + } + + foreach ($info as $k => $v) { + if (!$v || (is_numeric($v) && 0 > $v)) { + unset($info[$k]); + } + } + + if (\is_string($content = $trace['content'])) { + $contentType = 'application/octet-stream'; + + foreach ($info['response_headers'] ?? [] as $h) { + if (0 === stripos($h, 'content-type: ')) { + $contentType = substr($h, \strlen('content-type: ')); + break; + } + } + + if (0 === strpos($contentType, 'image/') && class_exists(ImgStub::class)) { + $content = new ImgStub($content, $contentType, ''); + } else { + $content = [$content]; + } + + $content = ['response_content' => $content]; + } elseif (\is_array($content)) { + $content = ['response_json' => $content]; + } else { + $content = []; + } + + if (isset($info['retry_count'])) { + $content['retries'] = $info['previous_info']; + unset($info['previous_info']); + } + + $debugInfo = array_diff_key($info, $baseInfo); + $info = ['info' => $debugInfo] + array_diff_key($info, $debugInfo) + $content; + unset($traces[$i]['info']); // break PHP reference used by TraceableHttpClient + $traces[$i]['info'] = $this->cloneVar($info); + $traces[$i]['options'] = $this->cloneVar($trace['options']); + } + + return [$errorCount, $traces]; + } +} diff --git a/vendor/symfony/http-client/DecoratorTrait.php b/vendor/symfony/http-client/DecoratorTrait.php new file mode 100644 index 000000000..790fc32a5 --- /dev/null +++ b/vendor/symfony/http-client/DecoratorTrait.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Eases with writing decorators. + * + * @author Nicolas Grekas + */ +trait DecoratorTrait +{ + private $client; + + public function __construct(HttpClientInterface $client = null) + { + $this->client = $client ?? HttpClient::create(); + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + return $this->client->request($method, $url, $options); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->client->stream($responses, $timeout); + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} diff --git a/vendor/symfony/http-client/DependencyInjection/HttpClientPass.php b/vendor/symfony/http-client/DependencyInjection/HttpClientPass.php new file mode 100644 index 000000000..8f3c3c534 --- /dev/null +++ b/vendor/symfony/http-client/DependencyInjection/HttpClientPass.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\HttpClient\TraceableHttpClient; + +final class HttpClientPass implements CompilerPassInterface +{ + private $clientTag; + + public function __construct(string $clientTag = 'http_client.client') + { + if (0 < \func_num_args()) { + trigger_deprecation('symfony/http-client', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); + } + + $this->clientTag = $clientTag; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('data_collector.http_client')) { + return; + } + + foreach ($container->findTaggedServiceIds($this->clientTag) as $id => $tags) { + $container->register('.debug.'.$id, TraceableHttpClient::class) + ->setArguments([new Reference('.debug.'.$id.'.inner'), new Reference('debug.stopwatch', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]) + ->addTag('kernel.reset', ['method' => 'reset']) + ->setDecoratedService($id, null, 5); + $container->getDefinition('data_collector.http_client') + ->addMethodCall('registerClient', [$id, new Reference('.debug.'.$id)]); + } + } +} diff --git a/vendor/symfony/http-client/EventSourceHttpClient.php b/vendor/symfony/http-client/EventSourceHttpClient.php new file mode 100644 index 000000000..60e4e821d --- /dev/null +++ b/vendor/symfony/http-client/EventSourceHttpClient.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Chunk\ServerSentEvent; +use Symfony\Component\HttpClient\Exception\EventSourceException; +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Component\HttpClient\Response\AsyncResponse; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * @author Antoine Bluchet + * @author Nicolas Grekas + */ +final class EventSourceHttpClient implements HttpClientInterface, ResetInterface +{ + use AsyncDecoratorTrait, HttpClientTrait { + AsyncDecoratorTrait::withOptions insteadof HttpClientTrait; + } + + private $reconnectionTime; + + public function __construct(HttpClientInterface $client = null, float $reconnectionTime = 10.0) + { + $this->client = $client ?? HttpClient::create(); + $this->reconnectionTime = $reconnectionTime; + } + + public function connect(string $url, array $options = []): ResponseInterface + { + return $this->request('GET', $url, self::mergeDefaultOptions($options, [ + 'buffer' => false, + 'headers' => [ + 'Accept' => 'text/event-stream', + 'Cache-Control' => 'no-cache', + ], + ], true)); + } + + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $state = new class() { + public $buffer = null; + public $lastEventId = null; + public $reconnectionTime; + public $lastError = null; + }; + $state->reconnectionTime = $this->reconnectionTime; + + if ($accept = self::normalizeHeaders($options['headers'] ?? [])['accept'] ?? []) { + $state->buffer = \in_array($accept, [['Accept: text/event-stream'], ['accept: text/event-stream']], true) ? '' : null; + + if (null !== $state->buffer) { + $options['extra']['trace_content'] = false; + } + } + + return new AsyncResponse($this->client, $method, $url, $options, static function (ChunkInterface $chunk, AsyncContext $context) use ($state, $method, $url, $options) { + if (null !== $state->buffer) { + $context->setInfo('reconnection_time', $state->reconnectionTime); + $isTimeout = false; + } + $lastError = $state->lastError; + $state->lastError = null; + + try { + $isTimeout = $chunk->isTimeout(); + + if (null !== $chunk->getInformationalStatus() || $context->getInfo('canceled')) { + yield $chunk; + + return; + } + } catch (TransportExceptionInterface $e) { + $state->lastError = $lastError ?? microtime(true); + + if (null === $state->buffer || ($isTimeout && microtime(true) - $state->lastError < $state->reconnectionTime)) { + yield $chunk; + } else { + $options['headers']['Last-Event-ID'] = $state->lastEventId; + $state->buffer = ''; + $state->lastError = microtime(true); + $context->getResponse()->cancel(); + $context->replaceRequest($method, $url, $options); + if ($isTimeout) { + yield $chunk; + } else { + $context->pause($state->reconnectionTime); + } + } + + return; + } + + if ($chunk->isFirst()) { + if (preg_match('/^text\/event-stream(;|$)/i', $context->getHeaders()['content-type'][0] ?? '')) { + $state->buffer = ''; + } elseif (null !== $lastError || (null !== $state->buffer && 200 === $context->getStatusCode())) { + throw new EventSourceException(sprintf('Response content-type is "%s" while "text/event-stream" was expected for "%s".', $context->getHeaders()['content-type'][0] ?? '', $context->getInfo('url'))); + } else { + $context->passthru(); + } + + if (null === $lastError) { + yield $chunk; + } + + return; + } + + $rx = '/((?:\r\n|[\r\n]){2,})/'; + $content = $state->buffer.$chunk->getContent(); + + if ($chunk->isLast()) { + $rx = substr_replace($rx, '|$', -2, 0); + } + $events = preg_split($rx, $content, -1, \PREG_SPLIT_DELIM_CAPTURE); + $state->buffer = array_pop($events); + + for ($i = 0; isset($events[$i]); $i += 2) { + $event = new ServerSentEvent($events[$i].$events[1 + $i]); + + if ('' !== $event->getId()) { + $context->setInfo('last_event_id', $state->lastEventId = $event->getId()); + } + + if ($event->getRetry()) { + $context->setInfo('reconnection_time', $state->reconnectionTime = $event->getRetry()); + } + + yield $event; + } + + if (preg_match('/^(?::[^\r\n]*+(?:\r\n|[\r\n]))+$/m', $state->buffer)) { + $content = $state->buffer; + $state->buffer = ''; + + yield $context->createChunk($content); + } + + if ($chunk->isLast()) { + yield $chunk; + } + }); + } +} diff --git a/vendor/symfony/http-client/Exception/ClientException.php b/vendor/symfony/http-client/Exception/ClientException.php new file mode 100644 index 000000000..4264534c0 --- /dev/null +++ b/vendor/symfony/http-client/Exception/ClientException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; + +/** + * Represents a 4xx response. + * + * @author Nicolas Grekas + */ +final class ClientException extends \RuntimeException implements ClientExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/symfony/http-client/Exception/EventSourceException.php b/vendor/symfony/http-client/Exception/EventSourceException.php new file mode 100644 index 000000000..30ab7957c --- /dev/null +++ b/vendor/symfony/http-client/Exception/EventSourceException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; + +/** + * @author Nicolas Grekas + */ +final class EventSourceException extends \RuntimeException implements DecodingExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/HttpExceptionTrait.php b/vendor/symfony/http-client/Exception/HttpExceptionTrait.php new file mode 100644 index 000000000..8cbaa1cd1 --- /dev/null +++ b/vendor/symfony/http-client/Exception/HttpExceptionTrait.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait HttpExceptionTrait +{ + private $response; + + public function __construct(ResponseInterface $response) + { + $this->response = $response; + $code = $response->getInfo('http_code'); + $url = $response->getInfo('url'); + $message = sprintf('HTTP %d returned for "%s".', $code, $url); + + $httpCodeFound = false; + $isJson = false; + foreach (array_reverse($response->getInfo('response_headers')) as $h) { + if (str_starts_with($h, 'HTTP/')) { + if ($httpCodeFound) { + break; + } + + $message = sprintf('%s returned for "%s".', $h, $url); + $httpCodeFound = true; + } + + if (0 === stripos($h, 'content-type:')) { + if (preg_match('/\bjson\b/i', $h)) { + $isJson = true; + } + + if ($httpCodeFound) { + break; + } + } + } + + // Try to guess a better error message using common API error formats + // The MIME type isn't explicitly checked because some formats inherit from others + // Ex: JSON:API follows RFC 7807 semantics, Hydra can be used in any JSON-LD-compatible format + if ($isJson && $body = json_decode($response->getContent(false), true)) { + if (isset($body['hydra:title']) || isset($body['hydra:description'])) { + // see http://www.hydra-cg.com/spec/latest/core/#description-of-http-status-codes-and-errors + $separator = isset($body['hydra:title'], $body['hydra:description']) ? "\n\n" : ''; + $message = ($body['hydra:title'] ?? '').$separator.($body['hydra:description'] ?? ''); + } elseif ((isset($body['title']) || isset($body['detail'])) + && (\is_scalar($body['title'] ?? '') && \is_scalar($body['detail'] ?? ''))) { + // see RFC 7807 and https://jsonapi.org/format/#error-objects + $separator = isset($body['title'], $body['detail']) ? "\n\n" : ''; + $message = ($body['title'] ?? '').$separator.($body['detail'] ?? ''); + } + } + + parent::__construct($message, $code); + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } +} diff --git a/vendor/symfony/http-client/Exception/InvalidArgumentException.php b/vendor/symfony/http-client/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..6c2fae76f --- /dev/null +++ b/vendor/symfony/http-client/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Nicolas Grekas + */ +final class InvalidArgumentException extends \InvalidArgumentException implements TransportExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/JsonException.php b/vendor/symfony/http-client/Exception/JsonException.php new file mode 100644 index 000000000..54502e626 --- /dev/null +++ b/vendor/symfony/http-client/Exception/JsonException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; + +/** + * Thrown by responses' toArray() method when their content cannot be JSON-decoded. + * + * @author Nicolas Grekas + */ +final class JsonException extends \JsonException implements DecodingExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/RedirectionException.php b/vendor/symfony/http-client/Exception/RedirectionException.php new file mode 100644 index 000000000..5b936702c --- /dev/null +++ b/vendor/symfony/http-client/Exception/RedirectionException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; + +/** + * Represents a 3xx response. + * + * @author Nicolas Grekas + */ +final class RedirectionException extends \RuntimeException implements RedirectionExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/symfony/http-client/Exception/ServerException.php b/vendor/symfony/http-client/Exception/ServerException.php new file mode 100644 index 000000000..c6f827310 --- /dev/null +++ b/vendor/symfony/http-client/Exception/ServerException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; + +/** + * Represents a 5xx response. + * + * @author Nicolas Grekas + */ +final class ServerException extends \RuntimeException implements ServerExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/symfony/http-client/Exception/TimeoutException.php b/vendor/symfony/http-client/Exception/TimeoutException.php new file mode 100644 index 000000000..a9155cc8f --- /dev/null +++ b/vendor/symfony/http-client/Exception/TimeoutException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\TimeoutExceptionInterface; + +/** + * @author Nicolas Grekas + */ +final class TimeoutException extends TransportException implements TimeoutExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/TransportException.php b/vendor/symfony/http-client/Exception/TransportException.php new file mode 100644 index 000000000..a3a80c6dc --- /dev/null +++ b/vendor/symfony/http-client/Exception/TransportException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Nicolas Grekas + */ +class TransportException extends \RuntimeException implements TransportExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/HttpClient.php b/vendor/symfony/http-client/HttpClient.php new file mode 100644 index 000000000..8de6f9f48 --- /dev/null +++ b/vendor/symfony/http-client/HttpClient.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Amp\Http\Client\Connection\ConnectionLimitingPool; +use Amp\Promise; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A factory to instantiate the best possible HTTP client for the runtime. + * + * @author Nicolas Grekas + */ +final class HttpClient +{ + /** + * @param array $defaultOptions Default request's options + * @param int $maxHostConnections The maximum number of connections to a single host + * @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public static function create(array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50): HttpClientInterface + { + if ($amp = class_exists(ConnectionLimitingPool::class) && interface_exists(Promise::class)) { + if (!\extension_loaded('curl')) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + + // Skip curl when HTTP/2 push is unsupported or buggy, see https://bugs.php.net/77535 + if (\PHP_VERSION_ID < 70217 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70304) || !\defined('CURLMOPT_PUSHFUNCTION')) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + + static $curlVersion = null; + $curlVersion = $curlVersion ?? curl_version(); + + // HTTP/2 push crashes before curl 7.61 + if (0x073D00 > $curlVersion['version_number'] || !(\CURL_VERSION_HTTP2 & $curlVersion['features'])) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + } + + if (\extension_loaded('curl')) { + if ('\\' !== \DIRECTORY_SEPARATOR || isset($defaultOptions['cafile']) || isset($defaultOptions['capath']) || \ini_get('curl.cainfo') || \ini_get('openssl.cafile') || \ini_get('openssl.capath')) { + return new CurlHttpClient($defaultOptions, $maxHostConnections, $maxPendingPushes); + } + + @trigger_error('Configure the "curl.cainfo", "openssl.cafile" or "openssl.capath" php.ini setting to enable the CurlHttpClient', \E_USER_WARNING); + } + + if ($amp) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + + @trigger_error((\extension_loaded('curl') ? 'Upgrade' : 'Install').' the curl extension or run "composer require amphp/http-client:^4.2.1" to perform async HTTP operations, including full HTTP/2 support', \E_USER_NOTICE); + + return new NativeHttpClient($defaultOptions, $maxHostConnections); + } + + /** + * Creates a client that adds options (e.g. authentication headers) only when the request URL matches the provided base URI. + */ + public static function createForBaseUri(string $baseUri, array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50): HttpClientInterface + { + $client = self::create([], $maxHostConnections, $maxPendingPushes); + + return ScopingHttpClient::forBaseUri($client, $baseUri, $defaultOptions); + } +} diff --git a/vendor/symfony/http-client/HttpClientTrait.php b/vendor/symfony/http-client/HttpClientTrait.php new file mode 100644 index 000000000..3d6044320 --- /dev/null +++ b/vendor/symfony/http-client/HttpClientTrait.php @@ -0,0 +1,710 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * Provides the common logic from writing HttpClientInterface implementations. + * + * All private methods are static to prevent implementers from creating memory leaks via circular references. + * + * @author Nicolas Grekas + */ +trait HttpClientTrait +{ + private static $CHUNK_SIZE = 16372; + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->defaultOptions = self::mergeDefaultOptions($options, $this->defaultOptions); + + return $clone; + } + + /** + * Validates and normalizes method, URL and options, and merges them with defaults. + * + * @throws InvalidArgumentException When a not-supported option is found + */ + private static function prepareRequest(?string $method, ?string $url, array $options, array $defaultOptions = [], bool $allowExtraOptions = false): array + { + if (null !== $method) { + if (\strlen($method) !== strspn($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')) { + throw new InvalidArgumentException(sprintf('Invalid HTTP method "%s", only uppercase letters are accepted.', $method)); + } + if (!$method) { + throw new InvalidArgumentException('The HTTP method cannot be empty.'); + } + } + + $options = self::mergeDefaultOptions($options, $defaultOptions, $allowExtraOptions); + + $buffer = $options['buffer'] ?? true; + + if ($buffer instanceof \Closure) { + $options['buffer'] = static function (array $headers) use ($buffer) { + if (!\is_bool($buffer = $buffer($headers))) { + if (!\is_array($bufferInfo = @stream_get_meta_data($buffer))) { + throw new \LogicException(sprintf('The closure passed as option "buffer" must return bool or stream resource, got "%s".', get_debug_type($buffer))); + } + + if (false === strpbrk($bufferInfo['mode'], 'acew+')) { + throw new \LogicException(sprintf('The stream returned by the closure passed as option "buffer" must be writeable, got mode "%s".', $bufferInfo['mode'])); + } + } + + return $buffer; + }; + } elseif (!\is_bool($buffer)) { + if (!\is_array($bufferInfo = @stream_get_meta_data($buffer))) { + throw new InvalidArgumentException(sprintf('Option "buffer" must be bool, stream resource or Closure, "%s" given.', get_debug_type($buffer))); + } + + if (false === strpbrk($bufferInfo['mode'], 'acew+')) { + throw new InvalidArgumentException(sprintf('The stream in option "buffer" must be writeable, mode "%s" given.', $bufferInfo['mode'])); + } + } + + if (isset($options['json'])) { + if (isset($options['body']) && '' !== $options['body']) { + throw new InvalidArgumentException('Define either the "json" or the "body" option, setting both is not supported.'); + } + $options['body'] = self::jsonEncode($options['json']); + unset($options['json']); + + if (!isset($options['normalized_headers']['content-type'])) { + $options['normalized_headers']['content-type'] = ['Content-Type: application/json']; + } + } + + if (!isset($options['normalized_headers']['accept'])) { + $options['normalized_headers']['accept'] = ['Accept: */*']; + } + + if (isset($options['body'])) { + $options['body'] = self::normalizeBody($options['body']); + + if (\is_string($options['body']) + && (string) \strlen($options['body']) !== substr($h = $options['normalized_headers']['content-length'][0] ?? '', 16) + && ('' !== $h || '' !== $options['body']) + ) { + if ('chunked' === substr($options['normalized_headers']['transfer-encoding'][0] ?? '', \strlen('Transfer-Encoding: '))) { + unset($options['normalized_headers']['transfer-encoding']); + $options['body'] = self::dechunk($options['body']); + } + + $options['normalized_headers']['content-length'] = [substr_replace($h ?: 'Content-Length: ', \strlen($options['body']), 16)]; + } + } + + if (isset($options['peer_fingerprint'])) { + $options['peer_fingerprint'] = self::normalizePeerFingerprint($options['peer_fingerprint']); + } + + // Validate on_progress + if (isset($options['on_progress']) && !\is_callable($onProgress = $options['on_progress'])) { + throw new InvalidArgumentException(sprintf('Option "on_progress" must be callable, "%s" given.', get_debug_type($onProgress))); + } + + if (\is_array($options['auth_basic'] ?? null)) { + $count = \count($options['auth_basic']); + if ($count <= 0 || $count > 2) { + throw new InvalidArgumentException(sprintf('Option "auth_basic" must contain 1 or 2 elements, "%s" given.', $count)); + } + + $options['auth_basic'] = implode(':', $options['auth_basic']); + } + + if (!\is_string($options['auth_basic'] ?? '')) { + throw new InvalidArgumentException(sprintf('Option "auth_basic" must be string or an array, "%s" given.', get_debug_type($options['auth_basic']))); + } + + if (isset($options['auth_bearer'])) { + if (!\is_string($options['auth_bearer'])) { + throw new InvalidArgumentException(sprintf('Option "auth_bearer" must be a string, "%s" given.', get_debug_type($options['auth_bearer']))); + } + if (preg_match('{[^\x21-\x7E]}', $options['auth_bearer'])) { + throw new InvalidArgumentException('Invalid character found in option "auth_bearer": '.json_encode($options['auth_bearer']).'.'); + } + } + + if (isset($options['auth_basic'], $options['auth_bearer'])) { + throw new InvalidArgumentException('Define either the "auth_basic" or the "auth_bearer" option, setting both is not supported.'); + } + + if (null !== $url) { + // Merge auth with headers + if (($options['auth_basic'] ?? false) && !($options['normalized_headers']['authorization'] ?? false)) { + $options['normalized_headers']['authorization'] = ['Authorization: Basic '.base64_encode($options['auth_basic'])]; + } + // Merge bearer with headers + if (($options['auth_bearer'] ?? false) && !($options['normalized_headers']['authorization'] ?? false)) { + $options['normalized_headers']['authorization'] = ['Authorization: Bearer '.$options['auth_bearer']]; + } + + unset($options['auth_basic'], $options['auth_bearer']); + + // Parse base URI + if (\is_string($options['base_uri'])) { + $options['base_uri'] = self::parseUrl($options['base_uri']); + } + + // Validate and resolve URL + $url = self::parseUrl($url, $options['query']); + $url = self::resolveUrl($url, $options['base_uri'], $defaultOptions['query'] ?? []); + } + + // Finalize normalization of options + $options['http_version'] = (string) ($options['http_version'] ?? '') ?: null; + if (0 > $options['timeout'] = (float) ($options['timeout'] ?? \ini_get('default_socket_timeout'))) { + $options['timeout'] = 172800.0; // 2 days + } + + $options['max_duration'] = isset($options['max_duration']) ? (float) $options['max_duration'] : 0; + $options['headers'] = array_merge(...array_values($options['normalized_headers'])); + + return [$url, $options]; + } + + /** + * @throws InvalidArgumentException When an invalid option is found + */ + private static function mergeDefaultOptions(array $options, array $defaultOptions, bool $allowExtraOptions = false): array + { + $options['normalized_headers'] = self::normalizeHeaders($options['headers'] ?? []); + + if ($defaultOptions['headers'] ?? false) { + $options['normalized_headers'] += self::normalizeHeaders($defaultOptions['headers']); + } + + $options['headers'] = array_merge(...array_values($options['normalized_headers']) ?: [[]]); + + if ($resolve = $options['resolve'] ?? false) { + $options['resolve'] = []; + foreach ($resolve as $k => $v) { + $options['resolve'][substr(self::parseUrl('http://'.$k)['authority'], 2)] = (string) $v; + } + } + + // Option "query" is never inherited from defaults + $options['query'] = $options['query'] ?? []; + + $options += $defaultOptions; + + if (isset(self::$emptyDefaults)) { + foreach (self::$emptyDefaults as $k => $v) { + if (!isset($options[$k])) { + $options[$k] = $v; + } + } + } + + if (isset($defaultOptions['extra'])) { + $options['extra'] += $defaultOptions['extra']; + } + + if ($resolve = $defaultOptions['resolve'] ?? false) { + foreach ($resolve as $k => $v) { + $options['resolve'] += [substr(self::parseUrl('http://'.$k)['authority'], 2) => (string) $v]; + } + } + + if ($allowExtraOptions || !$defaultOptions) { + return $options; + } + + // Look for unsupported options + foreach ($options as $name => $v) { + if (\array_key_exists($name, $defaultOptions) || 'normalized_headers' === $name) { + continue; + } + + if ('auth_ntlm' === $name) { + if (!\extension_loaded('curl')) { + $msg = 'try installing the "curl" extension to use "%s" instead.'; + } else { + $msg = 'try using "%s" instead.'; + } + + throw new InvalidArgumentException(sprintf('Option "auth_ntlm" is not supported by "%s", '.$msg, __CLASS__, CurlHttpClient::class)); + } + + $alternatives = []; + + foreach ($defaultOptions as $k => $v) { + if (levenshtein($name, $k) <= \strlen($name) / 3 || str_contains($k, $name)) { + $alternatives[] = $k; + } + } + + throw new InvalidArgumentException(sprintf('Unsupported option "%s" passed to "%s", did you mean "%s"?', $name, __CLASS__, implode('", "', $alternatives ?: array_keys($defaultOptions)))); + } + + return $options; + } + + /** + * @return string[][] + * + * @throws InvalidArgumentException When an invalid header is found + */ + private static function normalizeHeaders(array $headers): array + { + $normalizedHeaders = []; + + foreach ($headers as $name => $values) { + if (\is_object($values) && method_exists($values, '__toString')) { + $values = (string) $values; + } + + if (\is_int($name)) { + if (!\is_string($values)) { + throw new InvalidArgumentException(sprintf('Invalid value for header "%s": expected string, "%s" given.', $name, get_debug_type($values))); + } + [$name, $values] = explode(':', $values, 2); + $values = [ltrim($values)]; + } elseif (!is_iterable($values)) { + if (\is_object($values)) { + throw new InvalidArgumentException(sprintf('Invalid value for header "%s": expected string, "%s" given.', $name, get_debug_type($values))); + } + + $values = (array) $values; + } + + $lcName = strtolower($name); + $normalizedHeaders[$lcName] = []; + + foreach ($values as $value) { + $normalizedHeaders[$lcName][] = $value = $name.': '.$value; + + if (\strlen($value) !== strcspn($value, "\r\n\0")) { + throw new InvalidArgumentException(sprintf('Invalid header: CR/LF/NUL found in "%s".', $value)); + } + } + } + + return $normalizedHeaders; + } + + /** + * @param array|string|resource|\Traversable|\Closure $body + * + * @return string|resource|\Closure + * + * @throws InvalidArgumentException When an invalid body is passed + */ + private static function normalizeBody($body) + { + if (\is_array($body)) { + array_walk_recursive($body, $caster = static function (&$v) use (&$caster) { + if (\is_object($v)) { + if ($vars = get_object_vars($v)) { + array_walk_recursive($vars, $caster); + $v = $vars; + } elseif (method_exists($v, '__toString')) { + $v = (string) $v; + } + } + }); + + return http_build_query($body, '', '&'); + } + + if (\is_string($body)) { + return $body; + } + + $generatorToCallable = static function (\Generator $body): \Closure { + return static function () use ($body) { + while ($body->valid()) { + $chunk = $body->current(); + $body->next(); + + if ('' !== $chunk) { + return $chunk; + } + } + + return ''; + }; + }; + + if ($body instanceof \Generator) { + return $generatorToCallable($body); + } + + if ($body instanceof \Traversable) { + return $generatorToCallable((static function ($body) { yield from $body; })($body)); + } + + if ($body instanceof \Closure) { + $r = new \ReflectionFunction($body); + $body = $r->getClosure(); + + if ($r->isGenerator()) { + $body = $body(self::$CHUNK_SIZE); + + return $generatorToCallable($body); + } + + return $body; + } + + if (!\is_array(@stream_get_meta_data($body))) { + throw new InvalidArgumentException(sprintf('Option "body" must be string, stream resource, iterable or callable, "%s" given.', get_debug_type($body))); + } + + return $body; + } + + private static function dechunk(string $body): string + { + $h = fopen('php://temp', 'w+'); + stream_filter_append($h, 'dechunk', \STREAM_FILTER_WRITE); + fwrite($h, $body); + $body = stream_get_contents($h, -1, 0); + rewind($h); + ftruncate($h, 0); + + if (fwrite($h, '-') && '' !== stream_get_contents($h, -1, 0)) { + throw new TransportException('Request body has broken chunked encoding.'); + } + + return $body; + } + + /** + * @param string|string[] $fingerprint + * + * @throws InvalidArgumentException When an invalid fingerprint is passed + */ + private static function normalizePeerFingerprint($fingerprint): array + { + if (\is_string($fingerprint)) { + switch (\strlen($fingerprint = str_replace(':', '', $fingerprint))) { + case 32: $fingerprint = ['md5' => $fingerprint]; break; + case 40: $fingerprint = ['sha1' => $fingerprint]; break; + case 44: $fingerprint = ['pin-sha256' => [$fingerprint]]; break; + case 64: $fingerprint = ['sha256' => $fingerprint]; break; + default: throw new InvalidArgumentException(sprintf('Cannot auto-detect fingerprint algorithm for "%s".', $fingerprint)); + } + } elseif (\is_array($fingerprint)) { + foreach ($fingerprint as $algo => $hash) { + $fingerprint[$algo] = 'pin-sha256' === $algo ? (array) $hash : str_replace(':', '', $hash); + } + } else { + throw new InvalidArgumentException(sprintf('Option "peer_fingerprint" must be string or array, "%s" given.', get_debug_type($fingerprint))); + } + + return $fingerprint; + } + + /** + * @param mixed $value + * + * @throws InvalidArgumentException When the value cannot be json-encoded + */ + private static function jsonEncode($value, int $flags = null, int $maxDepth = 512): string + { + $flags = $flags ?? (\JSON_HEX_TAG | \JSON_HEX_APOS | \JSON_HEX_AMP | \JSON_HEX_QUOT | \JSON_PRESERVE_ZERO_FRACTION); + + try { + $value = json_encode($value, $flags | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0), $maxDepth); + } catch (\JsonException $e) { + throw new InvalidArgumentException('Invalid value for "json" option: '.$e->getMessage()); + } + + if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error() && (false === $value || !($flags & \JSON_PARTIAL_OUTPUT_ON_ERROR))) { + throw new InvalidArgumentException('Invalid value for "json" option: '.json_last_error_msg()); + } + + return $value; + } + + /** + * Resolves a URL against a base URI. + * + * @see https://tools.ietf.org/html/rfc3986#section-5.2.2 + * + * @throws InvalidArgumentException When an invalid URL is passed + */ + private static function resolveUrl(array $url, ?array $base, array $queryDefaults = []): array + { + if (null !== $base && '' === ($base['scheme'] ?? '').($base['authority'] ?? '')) { + throw new InvalidArgumentException(sprintf('Invalid "base_uri" option: host or scheme is missing in "%s".', implode('', $base))); + } + + if (null === $url['scheme'] && (null === $base || null === $base['scheme'])) { + throw new InvalidArgumentException(sprintf('Invalid URL: scheme is missing in "%s". Did you forget to add "http(s)://"?', implode('', $base ?? $url))); + } + + if (null === $base && '' === $url['scheme'].$url['authority']) { + throw new InvalidArgumentException(sprintf('Invalid URL: no "base_uri" option was provided and host or scheme is missing in "%s".', implode('', $url))); + } + + if (null !== $url['scheme']) { + $url['path'] = self::removeDotSegments($url['path'] ?? ''); + } else { + if (null !== $url['authority']) { + $url['path'] = self::removeDotSegments($url['path'] ?? ''); + } else { + if (null === $url['path']) { + $url['path'] = $base['path']; + $url['query'] = $url['query'] ?? $base['query']; + } else { + if ('/' !== $url['path'][0]) { + if (null === $base['path']) { + $url['path'] = '/'.$url['path']; + } else { + $segments = explode('/', $base['path']); + array_splice($segments, -1, 1, [$url['path']]); + $url['path'] = implode('/', $segments); + } + } + + $url['path'] = self::removeDotSegments($url['path']); + } + + $url['authority'] = $base['authority']; + + if ($queryDefaults) { + $url['query'] = '?'.self::mergeQueryString(substr($url['query'] ?? '', 1), $queryDefaults, false); + } + } + + $url['scheme'] = $base['scheme']; + } + + if ('' === ($url['path'] ?? '')) { + $url['path'] = '/'; + } + + if ('?' === ($url['query'] ?? '')) { + $url['query'] = null; + } + + return $url; + } + + /** + * Parses a URL and fixes its encoding if needed. + * + * @throws InvalidArgumentException When an invalid URL is passed + */ + private static function parseUrl(string $url, array $query = [], array $allowedSchemes = ['http' => 80, 'https' => 443]): array + { + if (false === $parts = parse_url($url)) { + throw new InvalidArgumentException(sprintf('Malformed URL "%s".', $url)); + } + + if ($query) { + $parts['query'] = self::mergeQueryString($parts['query'] ?? null, $query, true); + } + + $port = $parts['port'] ?? 0; + + if (null !== $scheme = $parts['scheme'] ?? null) { + if (!isset($allowedSchemes[$scheme = strtolower($scheme)])) { + throw new InvalidArgumentException(sprintf('Unsupported scheme in "%s".', $url)); + } + + $port = $allowedSchemes[$scheme] === $port ? 0 : $port; + $scheme .= ':'; + } + + if (null !== $host = $parts['host'] ?? null) { + if (!\defined('INTL_IDNA_VARIANT_UTS46') && preg_match('/[\x80-\xFF]/', $host)) { + throw new InvalidArgumentException(sprintf('Unsupported IDN "%s", try enabling the "intl" PHP extension or running "composer require symfony/polyfill-intl-idn".', $host)); + } + + $host = \defined('INTL_IDNA_VARIANT_UTS46') ? idn_to_ascii($host, \IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI | \IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46) ?: strtolower($host) : strtolower($host); + $host .= $port ? ':'.$port : ''; + } + + foreach (['user', 'pass', 'path', 'query', 'fragment'] as $part) { + if (!isset($parts[$part])) { + continue; + } + + if (str_contains($parts[$part], '%')) { + // https://tools.ietf.org/html/rfc3986#section-2.3 + $parts[$part] = preg_replace_callback('/%(?:2[DE]|3[0-9]|[46][1-9A-F]|5F|[57][0-9A]|7E)++/i', function ($m) { return rawurldecode($m[0]); }, $parts[$part]); + } + + // https://tools.ietf.org/html/rfc3986#section-3.3 + $parts[$part] = preg_replace_callback("#[^-A-Za-z0-9._~!$&/'()[\]*+,;=:@{}%]++#", function ($m) { return rawurlencode($m[0]); }, $parts[$part]); + } + + return [ + 'scheme' => $scheme, + 'authority' => null !== $host ? '//'.(isset($parts['user']) ? $parts['user'].(isset($parts['pass']) ? ':'.$parts['pass'] : '').'@' : '').$host : null, + 'path' => isset($parts['path'][0]) ? $parts['path'] : null, + 'query' => isset($parts['query']) ? '?'.$parts['query'] : null, + 'fragment' => isset($parts['fragment']) ? '#'.$parts['fragment'] : null, + ]; + } + + /** + * Removes dot-segments from a path. + * + * @see https://tools.ietf.org/html/rfc3986#section-5.2.4 + */ + private static function removeDotSegments(string $path) + { + $result = ''; + + while (!\in_array($path, ['', '.', '..'], true)) { + if ('.' === $path[0] && (str_starts_with($path, $p = '../') || str_starts_with($path, $p = './'))) { + $path = substr($path, \strlen($p)); + } elseif ('/.' === $path || str_starts_with($path, '/./')) { + $path = substr_replace($path, '/', 0, 3); + } elseif ('/..' === $path || str_starts_with($path, '/../')) { + $i = strrpos($result, '/'); + $result = $i ? substr($result, 0, $i) : ''; + $path = substr_replace($path, '/', 0, 4); + } else { + $i = strpos($path, '/', 1) ?: \strlen($path); + $result .= substr($path, 0, $i); + $path = substr($path, $i); + } + } + + return $result; + } + + /** + * Merges and encodes a query array with a query string. + * + * @throws InvalidArgumentException When an invalid query-string value is passed + */ + private static function mergeQueryString(?string $queryString, array $queryArray, bool $replace): ?string + { + if (!$queryArray) { + return $queryString; + } + + $query = []; + + if (null !== $queryString) { + foreach (explode('&', $queryString) as $v) { + if ('' !== $v) { + $k = urldecode(explode('=', $v, 2)[0]); + $query[$k] = (isset($query[$k]) ? $query[$k].'&' : '').$v; + } + } + } + + if ($replace) { + foreach ($queryArray as $k => $v) { + if (null === $v) { + unset($query[$k]); + } + } + } + + $queryString = http_build_query($queryArray, '', '&', \PHP_QUERY_RFC3986); + $queryArray = []; + + if ($queryString) { + if (str_contains($queryString, '%')) { + // https://tools.ietf.org/html/rfc3986#section-2.3 + some chars not encoded by browsers + $queryString = strtr($queryString, [ + '%21' => '!', + '%24' => '$', + '%28' => '(', + '%29' => ')', + '%2A' => '*', + '%2F' => '/', + '%3A' => ':', + '%3B' => ';', + '%40' => '@', + '%5B' => '[', + '%5D' => ']', + ]); + } + + foreach (explode('&', $queryString) as $v) { + $queryArray[rawurldecode(explode('=', $v, 2)[0])] = $v; + } + } + + return implode('&', $replace ? array_replace($query, $queryArray) : ($query + $queryArray)); + } + + /** + * Loads proxy configuration from the same environment variables as curl when no proxy is explicitly set. + */ + private static function getProxy(?string $proxy, array $url, ?string $noProxy): ?array + { + if (null === $proxy = self::getProxyUrl($proxy, $url)) { + return null; + } + + $proxy = (parse_url($proxy) ?: []) + ['scheme' => 'http']; + + if (!isset($proxy['host'])) { + throw new TransportException('Invalid HTTP proxy: host is missing.'); + } + + if ('http' === $proxy['scheme']) { + $proxyUrl = 'tcp://'.$proxy['host'].':'.($proxy['port'] ?? '80'); + } elseif ('https' === $proxy['scheme']) { + $proxyUrl = 'ssl://'.$proxy['host'].':'.($proxy['port'] ?? '443'); + } else { + throw new TransportException(sprintf('Unsupported proxy scheme "%s": "http" or "https" expected.', $proxy['scheme'])); + } + + $noProxy = $noProxy ?? $_SERVER['no_proxy'] ?? $_SERVER['NO_PROXY'] ?? ''; + $noProxy = $noProxy ? preg_split('/[\s,]+/', $noProxy) : []; + + return [ + 'url' => $proxyUrl, + 'auth' => isset($proxy['user']) ? 'Basic '.base64_encode(rawurldecode($proxy['user']).':'.rawurldecode($proxy['pass'] ?? '')) : null, + 'no_proxy' => $noProxy, + ]; + } + + private static function getProxyUrl(?string $proxy, array $url): ?string + { + if (null !== $proxy) { + return $proxy; + } + + // Ignore HTTP_PROXY except on the CLI to work around httpoxy set of vulnerabilities + $proxy = $_SERVER['http_proxy'] ?? (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? $_SERVER['HTTP_PROXY'] ?? null : null) ?? $_SERVER['all_proxy'] ?? $_SERVER['ALL_PROXY'] ?? null; + + if ('https:' === $url['scheme']) { + $proxy = $_SERVER['https_proxy'] ?? $_SERVER['HTTPS_PROXY'] ?? $proxy; + } + + return $proxy; + } + + private static function shouldBuffer(array $headers): bool + { + if (null === $contentType = $headers['content-type'][0] ?? null) { + return false; + } + + if (false !== $i = strpos($contentType, ';')) { + $contentType = substr($contentType, 0, $i); + } + + return $contentType && preg_match('#^(?:text/|application/(?:.+\+)?(?:json|xml)$)#i', $contentType); + } +} diff --git a/vendor/symfony/http-client/HttpOptions.php b/vendor/symfony/http-client/HttpOptions.php new file mode 100644 index 000000000..da55f9965 --- /dev/null +++ b/vendor/symfony/http-client/HttpOptions.php @@ -0,0 +1,331 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A helper providing autocompletion for available options. + * + * @see HttpClientInterface for a description of each options. + * + * @author Nicolas Grekas + */ +class HttpOptions +{ + private $options = []; + + public function toArray(): array + { + return $this->options; + } + + /** + * @return $this + */ + public function setAuthBasic(string $user, string $password = '') + { + $this->options['auth_basic'] = $user; + + if ('' !== $password) { + $this->options['auth_basic'] .= ':'.$password; + } + + return $this; + } + + /** + * @return $this + */ + public function setAuthBearer(string $token) + { + $this->options['auth_bearer'] = $token; + + return $this; + } + + /** + * @return $this + */ + public function setQuery(array $query) + { + $this->options['query'] = $query; + + return $this; + } + + /** + * @return $this + */ + public function setHeaders(iterable $headers) + { + $this->options['headers'] = $headers; + + return $this; + } + + /** + * @param array|string|resource|\Traversable|\Closure $body + * + * @return $this + */ + public function setBody($body) + { + $this->options['body'] = $body; + + return $this; + } + + /** + * @param mixed $json + * + * @return $this + */ + public function setJson($json) + { + $this->options['json'] = $json; + + return $this; + } + + /** + * @return $this + */ + public function setUserData($data) + { + $this->options['user_data'] = $data; + + return $this; + } + + /** + * @return $this + */ + public function setMaxRedirects(int $max) + { + $this->options['max_redirects'] = $max; + + return $this; + } + + /** + * @return $this + */ + public function setHttpVersion(string $version) + { + $this->options['http_version'] = $version; + + return $this; + } + + /** + * @return $this + */ + public function setBaseUri(string $uri) + { + $this->options['base_uri'] = $uri; + + return $this; + } + + /** + * @return $this + */ + public function buffer(bool $buffer) + { + $this->options['buffer'] = $buffer; + + return $this; + } + + /** + * @return $this + */ + public function setOnProgress(callable $callback) + { + $this->options['on_progress'] = $callback; + + return $this; + } + + /** + * @return $this + */ + public function resolve(array $hostIps) + { + $this->options['resolve'] = $hostIps; + + return $this; + } + + /** + * @return $this + */ + public function setProxy(string $proxy) + { + $this->options['proxy'] = $proxy; + + return $this; + } + + /** + * @return $this + */ + public function setNoProxy(string $noProxy) + { + $this->options['no_proxy'] = $noProxy; + + return $this; + } + + /** + * @return $this + */ + public function setTimeout(float $timeout) + { + $this->options['timeout'] = $timeout; + + return $this; + } + + /** + * @return $this + */ + public function setMaxDuration(float $maxDuration) + { + $this->options['max_duration'] = $maxDuration; + + return $this; + } + + /** + * @return $this + */ + public function bindTo(string $bindto) + { + $this->options['bindto'] = $bindto; + + return $this; + } + + /** + * @return $this + */ + public function verifyPeer(bool $verify) + { + $this->options['verify_peer'] = $verify; + + return $this; + } + + /** + * @return $this + */ + public function verifyHost(bool $verify) + { + $this->options['verify_host'] = $verify; + + return $this; + } + + /** + * @return $this + */ + public function setCaFile(string $cafile) + { + $this->options['cafile'] = $cafile; + + return $this; + } + + /** + * @return $this + */ + public function setCaPath(string $capath) + { + $this->options['capath'] = $capath; + + return $this; + } + + /** + * @return $this + */ + public function setLocalCert(string $cert) + { + $this->options['local_cert'] = $cert; + + return $this; + } + + /** + * @return $this + */ + public function setLocalPk(string $pk) + { + $this->options['local_pk'] = $pk; + + return $this; + } + + /** + * @return $this + */ + public function setPassphrase(string $passphrase) + { + $this->options['passphrase'] = $passphrase; + + return $this; + } + + /** + * @return $this + */ + public function setCiphers(string $ciphers) + { + $this->options['ciphers'] = $ciphers; + + return $this; + } + + /** + * @param string|array $fingerprint + * + * @return $this + */ + public function setPeerFingerprint($fingerprint) + { + $this->options['peer_fingerprint'] = $fingerprint; + + return $this; + } + + /** + * @return $this + */ + public function capturePeerCertChain(bool $capture) + { + $this->options['capture_peer_cert_chain'] = $capture; + + return $this; + } + + /** + * @return $this + */ + public function setExtra(string $name, $value) + { + $this->options['extra'][$name] = $value; + + return $this; + } +} diff --git a/vendor/symfony/http-client/HttplugClient.php b/vendor/symfony/http-client/HttplugClient.php new file mode 100644 index 000000000..2d9eec30f --- /dev/null +++ b/vendor/symfony/http-client/HttplugClient.php @@ -0,0 +1,276 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use GuzzleHttp\Promise\Promise as GuzzlePromise; +use GuzzleHttp\Promise\RejectedPromise; +use GuzzleHttp\Promise\Utils; +use Http\Client\Exception\NetworkException; +use Http\Client\Exception\RequestException; +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient as HttplugInterface; +use Http\Discovery\Exception\NotFoundException; +use Http\Discovery\Psr17FactoryDiscovery; +use Http\Message\RequestFactory; +use Http\Message\StreamFactory; +use Http\Message\UriFactory; +use Http\Promise\Promise; +use Nyholm\Psr7\Factory\Psr17Factory; +use Nyholm\Psr7\Request; +use Nyholm\Psr7\Uri; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriFactoryInterface; +use Psr\Http\Message\UriInterface; +use Symfony\Component\HttpClient\Internal\HttplugWaitLoop; +use Symfony\Component\HttpClient\Response\HttplugPromise; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\Service\ResetInterface; + +if (!interface_exists(HttplugInterface::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\HttplugClient" as the "php-http/httplug" package is not installed. Try running "composer require php-http/httplug".'); +} + +if (!interface_exists(RequestFactory::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\HttplugClient" as the "php-http/message-factory" package is not installed. Try running "composer require php-http/message-factory".'); +} + +/** + * An adapter to turn a Symfony HttpClientInterface into an Httplug client. + * + * Run "composer require nyholm/psr7" to install an efficient implementation of response + * and stream factories with flex-provided autowiring aliases. + * + * @author Nicolas Grekas + */ +final class HttplugClient implements HttplugInterface, HttpAsyncClient, RequestFactory, StreamFactory, UriFactory, ResetInterface +{ + private $client; + private $responseFactory; + private $streamFactory; + + /** + * @var \SplObjectStorage|null + */ + private $promisePool; + + private $waitLoop; + + public function __construct(HttpClientInterface $client = null, ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null) + { + $this->client = $client ?? HttpClient::create(); + $this->responseFactory = $responseFactory; + $this->streamFactory = $streamFactory ?? ($responseFactory instanceof StreamFactoryInterface ? $responseFactory : null); + $this->promisePool = class_exists(Utils::class) ? new \SplObjectStorage() : null; + + if (null === $this->responseFactory || null === $this->streamFactory) { + if (!class_exists(Psr17Factory::class) && !class_exists(Psr17FactoryDiscovery::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been provided. Try running "composer require nyholm/psr7".'); + } + + try { + $psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory() : null; + $this->responseFactory = $this->responseFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findResponseFactory(); + $this->streamFactory = $this->streamFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findStreamFactory(); + } catch (NotFoundException $e) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been found. Try running "composer require nyholm/psr7".', 0, $e); + } + } + + $this->waitLoop = new HttplugWaitLoop($this->client, $this->promisePool, $this->responseFactory, $this->streamFactory); + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request): Psr7ResponseInterface + { + try { + return $this->waitLoop->createPsr7Response($this->sendPsr7Request($request)); + } catch (TransportExceptionInterface $e) { + throw new NetworkException($e->getMessage(), $request, $e); + } + } + + /** + * {@inheritdoc} + * + * @return HttplugPromise + */ + public function sendAsyncRequest(RequestInterface $request): Promise + { + if (!$promisePool = $this->promisePool) { + throw new \LogicException(sprintf('You cannot use "%s()" as the "guzzlehttp/promises" package is not installed. Try running "composer require guzzlehttp/promises".', __METHOD__)); + } + + try { + $response = $this->sendPsr7Request($request, true); + } catch (NetworkException $e) { + return new HttplugPromise(new RejectedPromise($e)); + } + + $waitLoop = $this->waitLoop; + + $promise = new GuzzlePromise(static function () use ($response, $waitLoop) { + $waitLoop->wait($response); + }, static function () use ($response, $promisePool) { + $response->cancel(); + unset($promisePool[$response]); + }); + + $promisePool[$response] = [$request, $promise]; + + return new HttplugPromise($promise); + } + + /** + * Resolves pending promises that complete before the timeouts are reached. + * + * When $maxDuration is null and $idleTimeout is reached, promises are rejected. + * + * @return int The number of remaining pending promises + */ + public function wait(float $maxDuration = null, float $idleTimeout = null): int + { + return $this->waitLoop->wait(null, $maxDuration, $idleTimeout); + } + + /** + * {@inheritdoc} + */ + public function createRequest($method, $uri, array $headers = [], $body = null, $protocolVersion = '1.1'): RequestInterface + { + if ($this->responseFactory instanceof RequestFactoryInterface) { + $request = $this->responseFactory->createRequest($method, $uri); + } elseif (class_exists(Request::class)) { + $request = new Request($method, $uri); + } elseif (class_exists(Psr17FactoryDiscovery::class)) { + $request = Psr17FactoryDiscovery::findRequestFactory()->createRequest($method, $uri); + } else { + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + $request = $request + ->withProtocolVersion($protocolVersion) + ->withBody($this->createStream($body)) + ; + + foreach ($headers as $name => $value) { + $request = $request->withAddedHeader($name, $value); + } + + return $request; + } + + /** + * {@inheritdoc} + */ + public function createStream($body = null): StreamInterface + { + if ($body instanceof StreamInterface) { + return $body; + } + + if (\is_string($body ?? '')) { + $stream = $this->streamFactory->createStream($body ?? ''); + } elseif (\is_resource($body)) { + $stream = $this->streamFactory->createStreamFromResource($body); + } else { + throw new \InvalidArgumentException(sprintf('"%s()" expects string, resource or StreamInterface, "%s" given.', __METHOD__, get_debug_type($body))); + } + + if ($stream->isSeekable()) { + $stream->seek(0); + } + + return $stream; + } + + /** + * {@inheritdoc} + */ + public function createUri($uri): UriInterface + { + if ($uri instanceof UriInterface) { + return $uri; + } + + if ($this->responseFactory instanceof UriFactoryInterface) { + return $this->responseFactory->createUri($uri); + } + + if (class_exists(Uri::class)) { + return new Uri($uri); + } + + if (class_exists(Psr17FactoryDiscovery::class)) { + return Psr17FactoryDiscovery::findUrlFactory()->createUri($uri); + } + + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + $this->wait(); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } + + private function sendPsr7Request(RequestInterface $request, bool $buffer = null): ResponseInterface + { + try { + $body = $request->getBody(); + + if ($body->isSeekable()) { + $body->seek(0); + } + + $options = [ + 'headers' => $request->getHeaders(), + 'body' => $body->getContents(), + 'buffer' => $buffer, + ]; + + if ('1.0' === $request->getProtocolVersion()) { + $options['http_version'] = '1.0'; + } + + return $this->client->request($request->getMethod(), (string) $request->getUri(), $options); + } catch (\InvalidArgumentException $e) { + throw new RequestException($e->getMessage(), $request, $e); + } catch (TransportExceptionInterface $e) { + throw new NetworkException($e->getMessage(), $request, $e); + } + } +} diff --git a/vendor/symfony/http-client/Internal/AmpBody.php b/vendor/symfony/http-client/Internal/AmpBody.php new file mode 100644 index 000000000..b99742b13 --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpBody.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\ByteStream\InputStream; +use Amp\ByteStream\ResourceInputStream; +use Amp\Http\Client\RequestBody; +use Amp\Promise; +use Amp\Success; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class AmpBody implements RequestBody, InputStream +{ + private $body; + private $info; + private $onProgress; + private $offset = 0; + private $length = -1; + private $uploaded; + + public function __construct($body, &$info, \Closure $onProgress) + { + $this->body = $body; + $this->info = &$info; + $this->onProgress = $onProgress; + + if (\is_resource($body)) { + $this->offset = ftell($body); + $this->length = fstat($body)['size']; + $this->body = new ResourceInputStream($body); + } elseif (\is_string($body)) { + $this->length = \strlen($body); + } + } + + public function createBodyStream(): InputStream + { + if (null !== $this->uploaded) { + $this->uploaded = null; + + if (\is_string($this->body)) { + $this->offset = 0; + } elseif ($this->body instanceof ResourceInputStream) { + fseek($this->body->getResource(), $this->offset); + } + } + + return $this; + } + + public function getHeaders(): Promise + { + return new Success([]); + } + + public function getBodyLength(): Promise + { + return new Success($this->length - $this->offset); + } + + public function read(): Promise + { + $this->info['size_upload'] += $this->uploaded; + $this->uploaded = 0; + ($this->onProgress)(); + + $chunk = $this->doRead(); + $chunk->onResolve(function ($e, $data) { + if (null !== $data) { + $this->uploaded = \strlen($data); + } else { + $this->info['upload_content_length'] = $this->info['size_upload']; + } + }); + + return $chunk; + } + + public static function rewind(RequestBody $body): RequestBody + { + if (!$body instanceof self) { + return $body; + } + + $body->uploaded = null; + + if ($body->body instanceof ResourceInputStream) { + fseek($body->body->getResource(), $body->offset); + + return new $body($body->body, $body->info, $body->onProgress); + } + + if (\is_string($body->body)) { + $body->offset = 0; + } + + return $body; + } + + private function doRead(): Promise + { + if ($this->body instanceof ResourceInputStream) { + return $this->body->read(); + } + + if (null === $this->offset || !$this->length) { + return new Success(); + } + + if (\is_string($this->body)) { + $this->offset = null; + + return new Success($this->body); + } + + if ('' === $data = ($this->body)(16372)) { + $this->offset = null; + + return new Success(); + } + + if (!\is_string($data)) { + throw new TransportException(sprintf('Return value of the "body" option callback must be string, "%s" returned.', get_debug_type($data))); + } + + return new Success($data); + } +} diff --git a/vendor/symfony/http-client/Internal/AmpClientState.php b/vendor/symfony/http-client/Internal/AmpClientState.php new file mode 100644 index 000000000..3061f0802 --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpClientState.php @@ -0,0 +1,217 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\CancellationToken; +use Amp\Deferred; +use Amp\Http\Client\Connection\ConnectionLimitingPool; +use Amp\Http\Client\Connection\DefaultConnectionFactory; +use Amp\Http\Client\InterceptedHttpClient; +use Amp\Http\Client\Interceptor\RetryRequests; +use Amp\Http\Client\PooledHttpClient; +use Amp\Http\Client\Request; +use Amp\Http\Client\Response; +use Amp\Http\Tunnel\Http1TunnelConnector; +use Amp\Http\Tunnel\Https1TunnelConnector; +use Amp\Promise; +use Amp\Socket\Certificate; +use Amp\Socket\ClientTlsContext; +use Amp\Socket\ConnectContext; +use Amp\Socket\Connector; +use Amp\Socket\DnsConnector; +use Amp\Socket\SocketAddress; +use Amp\Success; +use Psr\Log\LoggerInterface; + +/** + * Internal representation of the Amp client's state. + * + * @author Nicolas Grekas + * + * @internal + */ +final class AmpClientState extends ClientState +{ + public $dnsCache = []; + public $responseCount = 0; + public $pushedResponses = []; + + private $clients = []; + private $clientConfigurator; + private $maxHostConnections; + private $maxPendingPushes; + private $logger; + + public function __construct(?callable $clientConfigurator, int $maxHostConnections, int $maxPendingPushes, ?LoggerInterface &$logger) + { + $this->clientConfigurator = $clientConfigurator ?? static function (PooledHttpClient $client) { + return new InterceptedHttpClient($client, new RetryRequests(2)); + }; + $this->maxHostConnections = $maxHostConnections; + $this->maxPendingPushes = $maxPendingPushes; + $this->logger = &$logger; + } + + /** + * @return Promise + */ + public function request(array $options, Request $request, CancellationToken $cancellation, array &$info, \Closure $onProgress, &$handle): Promise + { + if ($options['proxy']) { + if ($request->hasHeader('proxy-authorization')) { + $options['proxy']['auth'] = $request->getHeader('proxy-authorization'); + } + + // Matching "no_proxy" should follow the behavior of curl + $host = $request->getUri()->getHost(); + foreach ($options['proxy']['no_proxy'] as $rule) { + $dotRule = '.'.ltrim($rule, '.'); + + if ('*' === $rule || $host === $rule || substr($host, -\strlen($dotRule)) === $dotRule) { + $options['proxy'] = null; + break; + } + } + } + + $request = clone $request; + + if ($request->hasHeader('proxy-authorization')) { + $request->removeHeader('proxy-authorization'); + } + + if ($options['capture_peer_cert_chain']) { + $info['peer_certificate_chain'] = []; + } + + $request->addEventListener(new AmpListener($info, $options['peer_fingerprint']['pin-sha256'] ?? [], $onProgress, $handle)); + $request->setPushHandler(function ($request, $response) use ($options): Promise { + return $this->handlePush($request, $response, $options); + }); + + ($request->hasHeader('content-length') ? new Success((int) $request->getHeader('content-length')) : $request->getBody()->getBodyLength()) + ->onResolve(static function ($e, $bodySize) use (&$info) { + if (null !== $bodySize && 0 <= $bodySize) { + $info['upload_content_length'] = ((1 + $info['upload_content_length']) ?? 1) - 1 + $bodySize; + } + }); + + [$client, $connector] = $this->getClient($options); + $response = $client->request($request, $cancellation); + $response->onResolve(static function ($e) use ($connector, &$handle) { + if (null === $e) { + $handle = $connector->handle; + } + }); + + return $response; + } + + private function getClient(array $options): array + { + $options = [ + 'bindto' => $options['bindto'] ?: '0', + 'verify_peer' => $options['verify_peer'], + 'capath' => $options['capath'], + 'cafile' => $options['cafile'], + 'local_cert' => $options['local_cert'], + 'local_pk' => $options['local_pk'], + 'ciphers' => $options['ciphers'], + 'capture_peer_cert_chain' => $options['capture_peer_cert_chain'] || $options['peer_fingerprint'], + 'proxy' => $options['proxy'], + ]; + + $key = md5(serialize($options)); + + if (isset($this->clients[$key])) { + return $this->clients[$key]; + } + + $context = new ClientTlsContext(''); + $options['verify_peer'] || $context = $context->withoutPeerVerification(); + $options['cafile'] && $context = $context->withCaFile($options['cafile']); + $options['capath'] && $context = $context->withCaPath($options['capath']); + $options['local_cert'] && $context = $context->withCertificate(new Certificate($options['local_cert'], $options['local_pk'])); + $options['ciphers'] && $context = $context->withCiphers($options['ciphers']); + $options['capture_peer_cert_chain'] && $context = $context->withPeerCapturing(); + + $connector = $handleConnector = new class() implements Connector { + public $connector; + public $uri; + public $handle; + + public function connect(string $uri, ConnectContext $context = null, CancellationToken $token = null): Promise + { + $result = $this->connector->connect($this->uri ?? $uri, $context, $token); + $result->onResolve(function ($e, $socket) { + $this->handle = null !== $socket ? $socket->getResource() : false; + }); + + return $result; + } + }; + $connector->connector = new DnsConnector(new AmpResolver($this->dnsCache)); + + $context = (new ConnectContext()) + ->withTcpNoDelay() + ->withTlsContext($context); + + if ($options['bindto']) { + if (file_exists($options['bindto'])) { + $connector->uri = 'unix://'.$options['bindto']; + } else { + $context = $context->withBindTo($options['bindto']); + } + } + + if ($options['proxy']) { + $proxyUrl = parse_url($options['proxy']['url']); + $proxySocket = new SocketAddress($proxyUrl['host'], $proxyUrl['port']); + $proxyHeaders = $options['proxy']['auth'] ? ['Proxy-Authorization' => $options['proxy']['auth']] : []; + + if ('ssl' === $proxyUrl['scheme']) { + $connector = new Https1TunnelConnector($proxySocket, $context->getTlsContext(), $proxyHeaders, $connector); + } else { + $connector = new Http1TunnelConnector($proxySocket, $proxyHeaders, $connector); + } + } + + $maxHostConnections = 0 < $this->maxHostConnections ? $this->maxHostConnections : \PHP_INT_MAX; + $pool = new DefaultConnectionFactory($connector, $context); + $pool = ConnectionLimitingPool::byAuthority($maxHostConnections, $pool); + + return $this->clients[$key] = [($this->clientConfigurator)(new PooledHttpClient($pool)), $handleConnector]; + } + + private function handlePush(Request $request, Promise $response, array $options): Promise + { + $deferred = new Deferred(); + $authority = $request->getUri()->getAuthority(); + + if ($this->maxPendingPushes <= \count($this->pushedResponses[$authority] ?? [])) { + $fifoUrl = key($this->pushedResponses[$authority]); + unset($this->pushedResponses[$authority][$fifoUrl]); + $this->logger && $this->logger->debug(sprintf('Evicting oldest pushed response: "%s"', $fifoUrl)); + } + + $url = (string) $request->getUri(); + $this->logger && $this->logger->debug(sprintf('Queueing pushed response: "%s"', $url)); + $this->pushedResponses[$authority][] = [$url, $deferred, $request, $response, [ + 'proxy' => $options['proxy'], + 'bindto' => $options['bindto'], + 'local_cert' => $options['local_cert'], + 'local_pk' => $options['local_pk'], + ]]; + + return $deferred->promise(); + } +} diff --git a/vendor/symfony/http-client/Internal/AmpListener.php b/vendor/symfony/http-client/Internal/AmpListener.php new file mode 100644 index 000000000..cb3235bca --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpListener.php @@ -0,0 +1,183 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\Http\Client\Connection\Stream; +use Amp\Http\Client\EventListener; +use Amp\Http\Client\Request; +use Amp\Promise; +use Amp\Success; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class AmpListener implements EventListener +{ + private $info; + private $pinSha256; + private $onProgress; + private $handle; + + public function __construct(array &$info, array $pinSha256, \Closure $onProgress, &$handle) + { + $info += [ + 'connect_time' => 0.0, + 'pretransfer_time' => 0.0, + 'starttransfer_time' => 0.0, + 'total_time' => 0.0, + 'namelookup_time' => 0.0, + 'primary_ip' => '', + 'primary_port' => 0, + ]; + + $this->info = &$info; + $this->pinSha256 = $pinSha256; + $this->onProgress = $onProgress; + $this->handle = &$handle; + } + + public function startRequest(Request $request): Promise + { + $this->info['start_time'] = $this->info['start_time'] ?? microtime(true); + ($this->onProgress)(); + + return new Success(); + } + + public function startDnsResolution(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startConnectionCreation(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startTlsNegotiation(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startSendingRequest(Request $request, Stream $stream): Promise + { + $host = $stream->getRemoteAddress()->getHost(); + + if (false !== strpos($host, ':')) { + $host = '['.$host.']'; + } + + $this->info['primary_ip'] = $host; + $this->info['primary_port'] = $stream->getRemoteAddress()->getPort(); + $this->info['pretransfer_time'] = microtime(true) - $this->info['start_time']; + $this->info['debug'] .= sprintf("* Connected to %s (%s) port %d\n", $request->getUri()->getHost(), $host, $this->info['primary_port']); + + if ((isset($this->info['peer_certificate_chain']) || $this->pinSha256) && null !== $tlsInfo = $stream->getTlsInfo()) { + foreach ($tlsInfo->getPeerCertificates() as $cert) { + $this->info['peer_certificate_chain'][] = openssl_x509_read($cert->toPem()); + } + + if ($this->pinSha256) { + $pin = openssl_pkey_get_public($this->info['peer_certificate_chain'][0]); + $pin = openssl_pkey_get_details($pin)['key']; + $pin = \array_slice(explode("\n", $pin), 1, -2); + $pin = base64_decode(implode('', $pin)); + $pin = base64_encode(hash('sha256', $pin, true)); + + if (!\in_array($pin, $this->pinSha256, true)) { + throw new TransportException(sprintf('SSL public key does not match pinned public key for "%s".', $this->info['url'])); + } + } + } + ($this->onProgress)(); + + $uri = $request->getUri(); + $requestUri = $uri->getPath() ?: '/'; + + if ('' !== $query = $uri->getQuery()) { + $requestUri .= '?'.$query; + } + + if ('CONNECT' === $method = $request->getMethod()) { + $requestUri = $uri->getHost().': '.($uri->getPort() ?? ('https' === $uri->getScheme() ? 443 : 80)); + } + + $this->info['debug'] .= sprintf("> %s %s HTTP/%s \r\n", $method, $requestUri, $request->getProtocolVersions()[0]); + + foreach ($request->getRawHeaders() as [$name, $value]) { + $this->info['debug'] .= $name.': '.$value."\r\n"; + } + $this->info['debug'] .= "\r\n"; + + return new Success(); + } + + public function completeSendingRequest(Request $request, Stream $stream): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startReceivingResponse(Request $request, Stream $stream): Promise + { + $this->info['starttransfer_time'] = microtime(true) - $this->info['start_time']; + ($this->onProgress)(); + + return new Success(); + } + + public function completeReceivingResponse(Request $request, Stream $stream): Promise + { + $this->handle = null; + ($this->onProgress)(); + + return new Success(); + } + + public function completeDnsResolution(Request $request): Promise + { + $this->info['namelookup_time'] = microtime(true) - $this->info['start_time']; + ($this->onProgress)(); + + return new Success(); + } + + public function completeConnectionCreation(Request $request): Promise + { + $this->info['connect_time'] = microtime(true) - $this->info['start_time']; + ($this->onProgress)(); + + return new Success(); + } + + public function completeTlsNegotiation(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function abort(Request $request, \Throwable $cause): Promise + { + return new Success(); + } +} diff --git a/vendor/symfony/http-client/Internal/AmpResolver.php b/vendor/symfony/http-client/Internal/AmpResolver.php new file mode 100644 index 000000000..d31476a58 --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpResolver.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\Dns; +use Amp\Dns\Record; +use Amp\Promise; +use Amp\Success; + +/** + * Handles local overrides for the DNS resolver. + * + * @author Nicolas Grekas + * + * @internal + */ +class AmpResolver implements Dns\Resolver +{ + private $dnsMap; + + public function __construct(array &$dnsMap) + { + $this->dnsMap = &$dnsMap; + } + + public function resolve(string $name, int $typeRestriction = null): Promise + { + if (!isset($this->dnsMap[$name]) || !\in_array($typeRestriction, [Record::A, null], true)) { + return Dns\resolver()->resolve($name, $typeRestriction); + } + + return new Success([new Record($this->dnsMap[$name], Record::A, null)]); + } + + public function query(string $name, int $type): Promise + { + if (!isset($this->dnsMap[$name]) || Record::A !== $type) { + return Dns\resolver()->query($name, $type); + } + + return new Success([new Record($this->dnsMap[$name], Record::A, null)]); + } +} diff --git a/vendor/symfony/http-client/Internal/Canary.php b/vendor/symfony/http-client/Internal/Canary.php new file mode 100644 index 000000000..3d14b5fd1 --- /dev/null +++ b/vendor/symfony/http-client/Internal/Canary.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class Canary +{ + private $canceller; + + public function __construct(\Closure $canceller) + { + $this->canceller = $canceller; + } + + public function cancel() + { + if (($canceller = $this->canceller) instanceof \Closure) { + $this->canceller = null; + $canceller(); + } + } + + public function __destruct() + { + $this->cancel(); + } +} diff --git a/vendor/symfony/http-client/Internal/ClientState.php b/vendor/symfony/http-client/Internal/ClientState.php new file mode 100644 index 000000000..52fe3c8c0 --- /dev/null +++ b/vendor/symfony/http-client/Internal/ClientState.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * Internal representation of the client state. + * + * @author Alexander M. Turek + * + * @internal + */ +class ClientState +{ + public $handlesActivity = []; + public $openHandles = []; + public $lastTimeout; +} diff --git a/vendor/symfony/http-client/Internal/CurlClientState.php b/vendor/symfony/http-client/Internal/CurlClientState.php new file mode 100644 index 000000000..80473fee0 --- /dev/null +++ b/vendor/symfony/http-client/Internal/CurlClientState.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Response\CurlResponse; + +/** + * Internal representation of the cURL client's state. + * + * @author Alexander M. Turek + * + * @internal + */ +final class CurlClientState extends ClientState +{ + /** @var \CurlMultiHandle|resource|null */ + public $handle; + /** @var \CurlShareHandle|resource|null */ + public $share; + /** @var PushedResponse[] */ + public $pushedResponses = []; + /** @var DnsCache */ + public $dnsCache; + /** @var float[] */ + public $pauseExpiries = []; + public $execCounter = \PHP_INT_MIN; + /** @var LoggerInterface|null */ + public $logger; + public $performing = false; + + public static $curlVersion; + + public function __construct(int $maxHostConnections, int $maxPendingPushes) + { + self::$curlVersion = self::$curlVersion ?? curl_version(); + + $this->handle = curl_multi_init(); + $this->dnsCache = new DnsCache(); + $this->reset(); + + // Don't enable HTTP/1.1 pipelining: it forces responses to be sent in order + if (\defined('CURLPIPE_MULTIPLEX')) { + curl_multi_setopt($this->handle, \CURLMOPT_PIPELINING, \CURLPIPE_MULTIPLEX); + } + if (\defined('CURLMOPT_MAX_HOST_CONNECTIONS')) { + $maxHostConnections = curl_multi_setopt($this->handle, \CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX) ? 0 : $maxHostConnections; + } + if (\defined('CURLMOPT_MAXCONNECTS') && 0 < $maxHostConnections) { + curl_multi_setopt($this->handle, \CURLMOPT_MAXCONNECTS, $maxHostConnections); + } + + // Skip configuring HTTP/2 push when it's unsupported or buggy, see https://bugs.php.net/77535 + if (0 >= $maxPendingPushes || \PHP_VERSION_ID < 70217 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70304)) { + return; + } + + // HTTP/2 push crashes before curl 7.61 + if (!\defined('CURLMOPT_PUSHFUNCTION') || 0x073D00 > self::$curlVersion['version_number'] || !(\CURL_VERSION_HTTP2 & self::$curlVersion['features'])) { + return; + } + + // Clone to prevent a circular reference + $multi = clone $this; + $multi->handle = null; + $multi->share = null; + $multi->pushedResponses = &$this->pushedResponses; + $multi->logger = &$this->logger; + $multi->handlesActivity = &$this->handlesActivity; + $multi->openHandles = &$this->openHandles; + + curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION, static function ($parent, $pushed, array $requestHeaders) use ($multi, $maxPendingPushes) { + return $multi->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes); + }); + } + + public function reset() + { + foreach ($this->pushedResponses as $url => $response) { + $this->logger && $this->logger->debug(sprintf('Unused pushed response: "%s"', $url)); + curl_multi_remove_handle($this->handle, $response->handle); + curl_close($response->handle); + } + + $this->pushedResponses = []; + $this->dnsCache->evictions = $this->dnsCache->evictions ?: $this->dnsCache->removals; + $this->dnsCache->removals = $this->dnsCache->hostnames = []; + + $this->share = curl_share_init(); + + curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_DNS); + curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_SSL_SESSION); + + if (\defined('CURL_LOCK_DATA_CONNECT') && \PHP_VERSION_ID >= 80000) { + curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_CONNECT); + } + } + + private function handlePush($parent, $pushed, array $requestHeaders, int $maxPendingPushes): int + { + $headers = []; + $origin = curl_getinfo($parent, \CURLINFO_EFFECTIVE_URL); + + foreach ($requestHeaders as $h) { + if (false !== $i = strpos($h, ':', 1)) { + $headers[substr($h, 0, $i)][] = substr($h, 1 + $i); + } + } + + if (!isset($headers[':method']) || !isset($headers[':scheme']) || !isset($headers[':authority']) || !isset($headers[':path'])) { + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response from "%s": pushed headers are invalid', $origin)); + + return \CURL_PUSH_DENY; + } + + $url = $headers[':scheme'][0].'://'.$headers[':authority'][0]; + + // curl before 7.65 doesn't validate the pushed ":authority" header, + // but this is a MUST in the HTTP/2 RFC; let's restrict pushes to the original host, + // ignoring domains mentioned as alt-name in the certificate for now (same as curl). + if (!str_starts_with($origin, $url.'/')) { + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response from "%s": server is not authoritative for "%s"', $origin, $url)); + + return \CURL_PUSH_DENY; + } + + if ($maxPendingPushes <= \count($this->pushedResponses)) { + $fifoUrl = key($this->pushedResponses); + unset($this->pushedResponses[$fifoUrl]); + $this->logger && $this->logger->debug(sprintf('Evicting oldest pushed response: "%s"', $fifoUrl)); + } + + $url .= $headers[':path'][0]; + $this->logger && $this->logger->debug(sprintf('Queueing pushed response: "%s"', $url)); + + $this->pushedResponses[$url] = new PushedResponse(new CurlResponse($this, $pushed), $headers, $this->openHandles[(int) $parent][1] ?? [], $pushed); + + return \CURL_PUSH_OK; + } +} diff --git a/vendor/symfony/http-client/Internal/DnsCache.php b/vendor/symfony/http-client/Internal/DnsCache.php new file mode 100644 index 000000000..bd23f77f8 --- /dev/null +++ b/vendor/symfony/http-client/Internal/DnsCache.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * Cache for resolved DNS queries. + * + * @author Alexander M. Turek + * + * @internal + */ +final class DnsCache +{ + /** + * Resolved hostnames (hostname => IP address). + * + * @var string[] + */ + public $hostnames = []; + + /** + * @var string[] + */ + public $removals = []; + + /** + * @var string[] + */ + public $evictions = []; +} diff --git a/vendor/symfony/http-client/Internal/HttplugWaitLoop.php b/vendor/symfony/http-client/Internal/HttplugWaitLoop.php new file mode 100644 index 000000000..c61be22e3 --- /dev/null +++ b/vendor/symfony/http-client/Internal/HttplugWaitLoop.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Http\Client\Exception\NetworkException; +use Http\Promise\Promise; +use Psr\Http\Message\RequestInterface as Psr7RequestInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Symfony\Component\HttpClient\Response\StreamableInterface; +use Symfony\Component\HttpClient\Response\StreamWrapper; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class HttplugWaitLoop +{ + private $client; + private $promisePool; + private $responseFactory; + private $streamFactory; + + /** + * @param \SplObjectStorage|null $promisePool + */ + public function __construct(HttpClientInterface $client, ?\SplObjectStorage $promisePool, ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory) + { + $this->client = $client; + $this->promisePool = $promisePool; + $this->responseFactory = $responseFactory; + $this->streamFactory = $streamFactory; + } + + public function wait(?ResponseInterface $pendingResponse, float $maxDuration = null, float $idleTimeout = null): int + { + if (!$this->promisePool) { + return 0; + } + + $guzzleQueue = \GuzzleHttp\Promise\Utils::queue(); + + if (0.0 === $remainingDuration = $maxDuration) { + $idleTimeout = 0.0; + } elseif (null !== $maxDuration) { + $startTime = microtime(true); + $idleTimeout = max(0.0, min($maxDuration / 5, $idleTimeout ?? $maxDuration)); + } + + do { + foreach ($this->client->stream($this->promisePool, $idleTimeout) as $response => $chunk) { + try { + if (null !== $maxDuration && $chunk->isTimeout()) { + goto check_duration; + } + + if ($chunk->isFirst()) { + // Deactivate throwing on 3/4/5xx + $response->getStatusCode(); + } + + if (!$chunk->isLast()) { + goto check_duration; + } + + if ([, $promise] = $this->promisePool[$response] ?? null) { + unset($this->promisePool[$response]); + $promise->resolve($this->createPsr7Response($response, true)); + } + } catch (\Exception $e) { + if ([$request, $promise] = $this->promisePool[$response] ?? null) { + unset($this->promisePool[$response]); + + if ($e instanceof TransportExceptionInterface) { + $e = new NetworkException($e->getMessage(), $request, $e); + } + + $promise->reject($e); + } + } + + $guzzleQueue->run(); + + if ($pendingResponse === $response) { + return $this->promisePool->count(); + } + + check_duration: + if (null !== $maxDuration && $idleTimeout && $idleTimeout > $remainingDuration = max(0.0, $maxDuration - microtime(true) + $startTime)) { + $idleTimeout = $remainingDuration / 5; + break; + } + } + + if (!$count = $this->promisePool->count()) { + return 0; + } + } while (null === $maxDuration || 0 < $remainingDuration); + + return $count; + } + + public function createPsr7Response(ResponseInterface $response, bool $buffer = false): Psr7ResponseInterface + { + $psrResponse = $this->responseFactory->createResponse($response->getStatusCode()); + + foreach ($response->getHeaders(false) as $name => $values) { + foreach ($values as $value) { + try { + $psrResponse = $psrResponse->withAddedHeader($name, $value); + } catch (\InvalidArgumentException $e) { + // ignore invalid header + } + } + } + + if ($response instanceof StreamableInterface) { + $body = $this->streamFactory->createStreamFromResource($response->toStream(false)); + } elseif (!$buffer) { + $body = $this->streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $this->client)); + } else { + $body = $this->streamFactory->createStream($response->getContent(false)); + } + + if ($body->isSeekable()) { + $body->seek(0); + } + + return $psrResponse->withBody($body); + } +} diff --git a/vendor/symfony/http-client/Internal/NativeClientState.php b/vendor/symfony/http-client/Internal/NativeClientState.php new file mode 100644 index 000000000..20b2727f5 --- /dev/null +++ b/vendor/symfony/http-client/Internal/NativeClientState.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * Internal representation of the native client's state. + * + * @author Alexander M. Turek + * + * @internal + */ +final class NativeClientState extends ClientState +{ + /** @var int */ + public $id; + /** @var int */ + public $maxHostConnections = \PHP_INT_MAX; + /** @var int */ + public $responseCount = 0; + /** @var string[] */ + public $dnsCache = []; + /** @var bool */ + public $sleep = false; + /** @var int[] */ + public $hosts = []; + + public function __construct() + { + $this->id = random_int(\PHP_INT_MIN, \PHP_INT_MAX); + } + + public function reset() + { + $this->responseCount = 0; + $this->dnsCache = []; + $this->hosts = []; + } +} diff --git a/vendor/symfony/http-client/Internal/PushedResponse.php b/vendor/symfony/http-client/Internal/PushedResponse.php new file mode 100644 index 000000000..08fca60dc --- /dev/null +++ b/vendor/symfony/http-client/Internal/PushedResponse.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Symfony\Component\HttpClient\Response\CurlResponse; + +/** + * A pushed response with its request headers. + * + * @author Alexander M. Turek + * + * @internal + */ +final class PushedResponse +{ + public $response; + + /** @var string[] */ + public $requestHeaders; + + public $parentOptions = []; + + public $handle; + + public function __construct(CurlResponse $response, array $requestHeaders, array $parentOptions, $handle) + { + $this->response = $response; + $this->requestHeaders = $requestHeaders; + $this->parentOptions = $parentOptions; + $this->handle = $handle; + } +} diff --git a/vendor/symfony/http-client/LICENSE b/vendor/symfony/http-client/LICENSE new file mode 100644 index 000000000..7536caeae --- /dev/null +++ b/vendor/symfony/http-client/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/http-client/MockHttpClient.php b/vendor/symfony/http-client/MockHttpClient.php new file mode 100644 index 000000000..fecba0ee5 --- /dev/null +++ b/vendor/symfony/http-client/MockHttpClient.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Response\MockResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * A test-friendly HttpClient that doesn't make actual HTTP requests. + * + * @author Nicolas Grekas + */ +class MockHttpClient implements HttpClientInterface, ResetInterface +{ + use HttpClientTrait; + + private $responseFactory; + private $requestsCount = 0; + private $defaultOptions = []; + + /** + * @param callable|callable[]|ResponseInterface|ResponseInterface[]|iterable|null $responseFactory + */ + public function __construct($responseFactory = null, ?string $baseUri = 'https://example.com') + { + $this->setResponseFactory($responseFactory); + $this->defaultOptions['base_uri'] = $baseUri; + } + + /** + * @param callable|callable[]|ResponseInterface|ResponseInterface[]|iterable|null $responseFactory + */ + public function setResponseFactory($responseFactory): void + { + if ($responseFactory instanceof ResponseInterface) { + $responseFactory = [$responseFactory]; + } + + if (!$responseFactory instanceof \Iterator && null !== $responseFactory && !\is_callable($responseFactory)) { + $responseFactory = (static function () use ($responseFactory) { + yield from $responseFactory; + })(); + } + + $this->responseFactory = $responseFactory; + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = $this->prepareRequest($method, $url, $options, $this->defaultOptions, true); + $url = implode('', $url); + + if (null === $this->responseFactory) { + $response = new MockResponse(); + } elseif (\is_callable($this->responseFactory)) { + $response = ($this->responseFactory)($method, $url, $options); + } elseif (!$this->responseFactory->valid()) { + throw new TransportException('The response factory iterator passed to MockHttpClient is empty.'); + } else { + $responseFactory = $this->responseFactory->current(); + $response = \is_callable($responseFactory) ? $responseFactory($method, $url, $options) : $responseFactory; + $this->responseFactory->next(); + } + ++$this->requestsCount; + + if (!$response instanceof ResponseInterface) { + throw new TransportException(sprintf('The response factory passed to MockHttpClient must return/yield an instance of ResponseInterface, "%s" given.', \is_object($response) ? \get_class($response) : \gettype($response))); + } + + return MockResponse::fromRequest($method, $url, $options, $response); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof ResponseInterface) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of MockResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(MockResponse::stream($responses, $timeout)); + } + + public function getRequestsCount(): int + { + return $this->requestsCount; + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->defaultOptions = self::mergeDefaultOptions($options, $this->defaultOptions, true); + + return $clone; + } + + public function reset() + { + $this->requestsCount = 0; + } +} diff --git a/vendor/symfony/http-client/NativeHttpClient.php b/vendor/symfony/http-client/NativeHttpClient.php new file mode 100644 index 000000000..63fcc1ca9 --- /dev/null +++ b/vendor/symfony/http-client/NativeHttpClient.php @@ -0,0 +1,468 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\NativeClientState; +use Symfony\Component\HttpClient\Response\NativeResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * A portable implementation of the HttpClientInterface contracts based on PHP stream wrappers. + * + * PHP stream wrappers are able to fetch response bodies concurrently, + * but each request is opened synchronously. + * + * @author Nicolas Grekas + */ +final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + use LoggerAwareTrait; + + private $defaultOptions = self::OPTIONS_DEFAULTS; + private static $emptyDefaults = self::OPTIONS_DEFAULTS; + + /** @var NativeClientState */ + private $multi; + + /** + * @param array $defaultOptions Default request's options + * @param int $maxHostConnections The maximum number of connections to open + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public function __construct(array $defaultOptions = [], int $maxHostConnections = 6) + { + $this->defaultOptions['buffer'] = $this->defaultOptions['buffer'] ?? \Closure::fromCallable([__CLASS__, 'shouldBuffer']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + + $this->multi = new NativeClientState(); + $this->multi->maxHostConnections = 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX; + } + + /** + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + * + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); + + if ($options['bindto']) { + if (file_exists($options['bindto'])) { + throw new TransportException(__CLASS__.' cannot bind to local Unix sockets, use e.g. CurlHttpClient instead.'); + } + if (str_starts_with($options['bindto'], 'if!')) { + throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.'); + } + if (str_starts_with($options['bindto'], 'host!')) { + $options['bindto'] = substr($options['bindto'], 5); + } + } + + $hasContentLength = isset($options['normalized_headers']['content-length']); + $hasBody = '' !== $options['body'] || 'POST' === $method || $hasContentLength; + + $options['body'] = self::getBodyAsString($options['body']); + + if ('chunked' === substr($options['normalized_headers']['transfer-encoding'][0] ?? '', \strlen('Transfer-Encoding: '))) { + unset($options['normalized_headers']['transfer-encoding']); + $options['headers'] = array_merge(...array_values($options['normalized_headers'])); + $options['body'] = self::dechunk($options['body']); + } + if ('' === $options['body'] && $hasBody && !$hasContentLength) { + $options['headers'][] = 'Content-Length: 0'; + } + if ($hasBody && !isset($options['normalized_headers']['content-type'])) { + $options['headers'][] = 'Content-Type: application/x-www-form-urlencoded'; + } + + if (\extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) { + // gzip is the most widely available algo, no need to deal with deflate + $options['headers'][] = 'Accept-Encoding: gzip'; + } + + if ($options['peer_fingerprint']) { + if (isset($options['peer_fingerprint']['pin-sha256']) && 1 === \count($options['peer_fingerprint'])) { + throw new TransportException(__CLASS__.' cannot verify "pin-sha256" fingerprints, please provide a "sha256" one.'); + } + + unset($options['peer_fingerprint']['pin-sha256']); + } + + $info = [ + 'response_headers' => [], + 'url' => $url, + 'error' => null, + 'canceled' => false, + 'http_method' => $method, + 'http_code' => 0, + 'redirect_count' => 0, + 'start_time' => 0.0, + 'connect_time' => 0.0, + 'redirect_time' => 0.0, + 'pretransfer_time' => 0.0, + 'starttransfer_time' => 0.0, + 'total_time' => 0.0, + 'namelookup_time' => 0.0, + 'size_upload' => 0, + 'size_download' => 0, + 'size_body' => \strlen($options['body']), + 'primary_ip' => '', + 'primary_port' => 'http:' === $url['scheme'] ? 80 : 443, + 'debug' => \extension_loaded('curl') ? '' : "* Enable the curl extension for better performance\n", + ]; + + if ($onProgress = $options['on_progress']) { + // Memoize the last progress to ease calling the callback periodically when no network transfer happens + $lastProgress = [0, 0]; + $maxDuration = 0 < $options['max_duration'] ? $options['max_duration'] : \INF; + $onProgress = static function (...$progress) use ($onProgress, &$lastProgress, &$info, $maxDuration) { + if ($info['total_time'] >= $maxDuration) { + throw new TransportException(sprintf('Max duration was reached for "%s".', implode('', $info['url']))); + } + + $progressInfo = $info; + $progressInfo['url'] = implode('', $info['url']); + unset($progressInfo['size_body']); + + if ($progress && -1 === $progress[0]) { + // Response completed + $lastProgress[0] = max($lastProgress); + } else { + $lastProgress = $progress ?: $lastProgress; + } + + $onProgress($lastProgress[0], $lastProgress[1], $progressInfo); + }; + } elseif (0 < $options['max_duration']) { + $maxDuration = $options['max_duration']; + $onProgress = static function () use (&$info, $maxDuration): void { + if ($info['total_time'] >= $maxDuration) { + throw new TransportException(sprintf('Max duration was reached for "%s".', implode('', $info['url']))); + } + }; + } + + // Always register a notification callback to compute live stats about the response + $notification = static function (int $code, int $severity, ?string $msg, int $msgCode, int $dlNow, int $dlSize) use ($onProgress, &$info) { + $info['total_time'] = microtime(true) - $info['start_time']; + + if (\STREAM_NOTIFY_PROGRESS === $code) { + $info['starttransfer_time'] = $info['starttransfer_time'] ?: $info['total_time']; + $info['size_upload'] += $dlNow ? 0 : $info['size_body']; + $info['size_download'] = $dlNow; + } elseif (\STREAM_NOTIFY_CONNECT === $code) { + $info['connect_time'] = $info['total_time']; + $info['debug'] .= $info['request_header']; + unset($info['request_header']); + } else { + return; + } + + if ($onProgress) { + $onProgress($dlNow, $dlSize); + } + }; + + if ($options['resolve']) { + $this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCache; + } + + $this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, implode('', $url))); + + if (!isset($options['normalized_headers']['user-agent'])) { + $options['headers'][] = 'User-Agent: Symfony HttpClient/Native'; + } + + if (0 < $options['max_duration']) { + $options['timeout'] = min($options['max_duration'], $options['timeout']); + } + + $bindto = $options['bindto']; + if (!$bindto && (70322 === \PHP_VERSION_ID || 70410 === \PHP_VERSION_ID)) { + $bindto = '0:0'; + } + + $context = [ + 'http' => [ + 'protocol_version' => min($options['http_version'] ?: '1.1', '1.1'), + 'method' => $method, + 'content' => $options['body'], + 'ignore_errors' => true, + 'curl_verify_ssl_peer' => $options['verify_peer'], + 'curl_verify_ssl_host' => $options['verify_host'], + 'auto_decode' => false, // Disable dechunk filter, it's incompatible with stream_select() + 'timeout' => $options['timeout'], + 'follow_location' => false, // We follow redirects ourselves - the native logic is too limited + ], + 'ssl' => array_filter([ + 'verify_peer' => $options['verify_peer'], + 'verify_peer_name' => $options['verify_host'], + 'cafile' => $options['cafile'], + 'capath' => $options['capath'], + 'local_cert' => $options['local_cert'], + 'local_pk' => $options['local_pk'], + 'passphrase' => $options['passphrase'], + 'ciphers' => $options['ciphers'], + 'peer_fingerprint' => $options['peer_fingerprint'], + 'capture_peer_cert_chain' => $options['capture_peer_cert_chain'], + 'allow_self_signed' => (bool) $options['peer_fingerprint'], + 'SNI_enabled' => true, + 'disable_compression' => true, + ], static function ($v) { return null !== $v; }), + 'socket' => [ + 'bindto' => $bindto, + 'tcp_nodelay' => true, + ], + ]; + + $context = stream_context_create($context, ['notification' => $notification]); + + $resolver = static function ($multi) use ($context, $options, $url, &$info, $onProgress) { + [$host, $port] = self::parseHostPort($url, $info); + + if (!isset($options['normalized_headers']['host'])) { + $options['headers'][] = 'Host: '.$host.$port; + } + + $proxy = self::getProxy($options['proxy'], $url, $options['no_proxy']); + + if (!self::configureHeadersAndProxy($context, $host, $options['headers'], $proxy, 'https:' === $url['scheme'])) { + $ip = self::dnsResolve($host, $multi, $info, $onProgress); + $url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host)); + } + + return [self::createRedirectResolver($options, $host, $proxy, $info, $onProgress), implode('', $url)]; + }; + + return new NativeResponse($this->multi, $context, implode('', $url), $options, $info, $resolver, $onProgress, $this->logger); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof NativeResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of NativeResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(NativeResponse::stream($responses, $timeout)); + } + + public function reset() + { + $this->multi->reset(); + } + + private static function getBodyAsString($body): string + { + if (\is_resource($body)) { + return stream_get_contents($body); + } + + if (!$body instanceof \Closure) { + return $body; + } + + $result = ''; + + while ('' !== $data = $body(self::$CHUNK_SIZE)) { + if (!\is_string($data)) { + throw new TransportException(sprintf('Return value of the "body" option callback must be string, "%s" returned.', get_debug_type($data))); + } + + $result .= $data; + } + + return $result; + } + + /** + * Extracts the host and the port from the URL. + */ + private static function parseHostPort(array $url, array &$info): array + { + if ($port = parse_url($url['authority'], \PHP_URL_PORT) ?: '') { + $info['primary_port'] = $port; + $port = ':'.$port; + } else { + $info['primary_port'] = 'http:' === $url['scheme'] ? 80 : 443; + } + + return [parse_url($url['authority'], \PHP_URL_HOST), $port]; + } + + /** + * Resolves the IP of the host using the local DNS cache if possible. + */ + private static function dnsResolve($host, NativeClientState $multi, array &$info, ?\Closure $onProgress): string + { + if (null === $ip = $multi->dnsCache[$host] ?? null) { + $info['debug'] .= "* Hostname was NOT found in DNS cache\n"; + $now = microtime(true); + + if (!$ip = gethostbynamel($host)) { + throw new TransportException(sprintf('Could not resolve host "%s".', $host)); + } + + $info['namelookup_time'] = microtime(true) - ($info['start_time'] ?: $now); + $multi->dnsCache[$host] = $ip = $ip[0]; + $info['debug'] .= "* Added {$host}:0:{$ip} to DNS cache\n"; + } else { + $info['debug'] .= "* Hostname was found in DNS cache\n"; + } + + $info['primary_ip'] = $ip; + + if ($onProgress) { + // Notify DNS resolution + $onProgress(); + } + + return $ip; + } + + /** + * Handles redirects - the native logic is too buggy to be used. + */ + private static function createRedirectResolver(array $options, string $host, ?array $proxy, array &$info, ?\Closure $onProgress): \Closure + { + $redirectHeaders = []; + if (0 < $maxRedirects = $options['max_redirects']) { + $redirectHeaders = ['host' => $host]; + $redirectHeaders['with_auth'] = $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) { + return 0 !== stripos($h, 'Host:'); + }); + + if (isset($options['normalized_headers']['authorization']) || isset($options['normalized_headers']['cookie'])) { + $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], static function ($h) { + return 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:'); + }); + } + } + + return static function (NativeClientState $multi, ?string $location, $context) use (&$redirectHeaders, $proxy, &$info, $maxRedirects, $onProgress): ?string { + if (null === $location || $info['http_code'] < 300 || 400 <= $info['http_code']) { + $info['redirect_url'] = null; + + return null; + } + + try { + $url = self::parseUrl($location); + } catch (InvalidArgumentException $e) { + $info['redirect_url'] = null; + + return null; + } + + $url = self::resolveUrl($url, $info['url']); + $info['redirect_url'] = implode('', $url); + + if ($info['redirect_count'] >= $maxRedirects) { + return null; + } + + $info['url'] = $url; + ++$info['redirect_count']; + $info['redirect_time'] = microtime(true) - $info['start_time']; + + // Do like curl and browsers: turn POST to GET on 301, 302 and 303 + if (\in_array($info['http_code'], [301, 302, 303], true)) { + $options = stream_context_get_options($context)['http']; + + if ('POST' === $options['method'] || 303 === $info['http_code']) { + $info['http_method'] = $options['method'] = 'HEAD' === $options['method'] ? 'HEAD' : 'GET'; + $options['content'] = ''; + $filterContentHeaders = static function ($h) { + return 0 !== stripos($h, 'Content-Length:') && 0 !== stripos($h, 'Content-Type:') && 0 !== stripos($h, 'Transfer-Encoding:'); + }; + $options['header'] = array_filter($options['header'], $filterContentHeaders); + $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], $filterContentHeaders); + $redirectHeaders['with_auth'] = array_filter($redirectHeaders['with_auth'], $filterContentHeaders); + + stream_context_set_option($context, ['http' => $options]); + } + } + + [$host, $port] = self::parseHostPort($url, $info); + + if (false !== (parse_url($location, \PHP_URL_HOST) ?? false)) { + // Authorization and Cookie headers MUST NOT follow except for the initial host name + $requestHeaders = $redirectHeaders['host'] === $host ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth']; + $requestHeaders[] = 'Host: '.$host.$port; + $dnsResolve = !self::configureHeadersAndProxy($context, $host, $requestHeaders, $proxy, 'https:' === $url['scheme']); + } else { + $dnsResolve = isset(stream_context_get_options($context)['ssl']['peer_name']); + } + + if ($dnsResolve) { + $ip = self::dnsResolve($host, $multi, $info, $onProgress); + $url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host)); + } + + return implode('', $url); + }; + } + + private static function configureHeadersAndProxy($context, string $host, array $requestHeaders, ?array $proxy, bool $isSsl): bool + { + if (null === $proxy) { + stream_context_set_option($context, 'http', 'header', $requestHeaders); + stream_context_set_option($context, 'ssl', 'peer_name', $host); + + return false; + } + + // Matching "no_proxy" should follow the behavior of curl + + foreach ($proxy['no_proxy'] as $rule) { + $dotRule = '.'.ltrim($rule, '.'); + + if ('*' === $rule || $host === $rule || str_ends_with($host, $dotRule)) { + stream_context_set_option($context, 'http', 'proxy', null); + stream_context_set_option($context, 'http', 'request_fulluri', false); + stream_context_set_option($context, 'http', 'header', $requestHeaders); + stream_context_set_option($context, 'ssl', 'peer_name', $host); + + return false; + } + } + + if (null !== $proxy['auth']) { + $requestHeaders[] = 'Proxy-Authorization: '.$proxy['auth']; + } + + stream_context_set_option($context, 'http', 'proxy', $proxy['url']); + stream_context_set_option($context, 'http', 'request_fulluri', !$isSsl); + stream_context_set_option($context, 'http', 'header', $requestHeaders); + stream_context_set_option($context, 'ssl', 'peer_name', null); + + return true; + } +} diff --git a/vendor/symfony/http-client/NoPrivateNetworkHttpClient.php b/vendor/symfony/http-client/NoPrivateNetworkHttpClient.php new file mode 100644 index 000000000..911cce9da --- /dev/null +++ b/vendor/symfony/http-client/NoPrivateNetworkHttpClient.php @@ -0,0 +1,132 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpFoundation\IpUtils; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Decorator that blocks requests to private networks by default. + * + * @author Hallison Boaventura + */ +final class NoPrivateNetworkHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + + private const PRIVATE_SUBNETS = [ + '127.0.0.0/8', + '10.0.0.0/8', + '192.168.0.0/16', + '172.16.0.0/12', + '169.254.0.0/16', + '0.0.0.0/8', + '240.0.0.0/4', + '::1/128', + 'fc00::/7', + 'fe80::/10', + '::ffff:0:0/96', + '::/128', + ]; + + private $client; + private $subnets; + + /** + * @param string|array|null $subnets String or array of subnets using CIDR notation that will be used by IpUtils. + * If null is passed, the standard private subnets will be used. + */ + public function __construct(HttpClientInterface $client, $subnets = null) + { + if (!(\is_array($subnets) || \is_string($subnets) || null === $subnets)) { + throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be of the type array, string or null. "%s" given.', __METHOD__, get_debug_type($subnets))); + } + + if (!class_exists(IpUtils::class)) { + throw new \LogicException(sprintf('You cannot use "%s" if the HttpFoundation component is not installed. Try running "composer require symfony/http-foundation".', __CLASS__)); + } + + $this->client = $client; + $this->subnets = $subnets; + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $onProgress = $options['on_progress'] ?? null; + if (null !== $onProgress && !\is_callable($onProgress)) { + throw new InvalidArgumentException(sprintf('Option "on_progress" must be callable, "%s" given.', get_debug_type($onProgress))); + } + + $subnets = $this->subnets; + $lastPrimaryIp = ''; + + $options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use ($onProgress, $subnets, &$lastPrimaryIp): void { + if ($info['primary_ip'] !== $lastPrimaryIp) { + if ($info['primary_ip'] && IpUtils::checkIp($info['primary_ip'], $subnets ?? self::PRIVATE_SUBNETS)) { + throw new TransportException(sprintf('IP "%s" is blocked for "%s".', $info['primary_ip'], $info['url'])); + } + + $lastPrimaryIp = $info['primary_ip']; + } + + null !== $onProgress && $onProgress($dlNow, $dlSize, $info); + }; + + return $this->client->request($method, $url, $options); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->client->stream($responses, $timeout); + } + + /** + * {@inheritdoc} + */ + public function setLogger(LoggerInterface $logger): void + { + if ($this->client instanceof LoggerAwareInterface) { + $this->client->setLogger($logger); + } + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} diff --git a/vendor/symfony/http-client/Psr18Client.php b/vendor/symfony/http-client/Psr18Client.php new file mode 100644 index 000000000..2ec758ae4 --- /dev/null +++ b/vendor/symfony/http-client/Psr18Client.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Http\Discovery\Exception\NotFoundException; +use Http\Discovery\Psr17FactoryDiscovery; +use Nyholm\Psr7\Factory\Psr17Factory; +use Nyholm\Psr7\Request; +use Nyholm\Psr7\Uri; +use Psr\Http\Client\ClientInterface; +use Psr\Http\Client\NetworkExceptionInterface; +use Psr\Http\Client\RequestExceptionInterface; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriFactoryInterface; +use Psr\Http\Message\UriInterface; +use Symfony\Component\HttpClient\Response\StreamableInterface; +use Symfony\Component\HttpClient\Response\StreamWrapper; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\Service\ResetInterface; + +if (!interface_exists(RequestFactoryInterface::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as the "psr/http-factory" package is not installed. Try running "composer require nyholm/psr7".'); +} + +if (!interface_exists(ClientInterface::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as the "psr/http-client" package is not installed. Try running "composer require psr/http-client".'); +} + +/** + * An adapter to turn a Symfony HttpClientInterface into a PSR-18 ClientInterface. + * + * Run "composer require psr/http-client" to install the base ClientInterface. Run + * "composer require nyholm/psr7" to install an efficient implementation of response + * and stream factories with flex-provided autowiring aliases. + * + * @author Nicolas Grekas + */ +final class Psr18Client implements ClientInterface, RequestFactoryInterface, StreamFactoryInterface, UriFactoryInterface, ResetInterface +{ + private $client; + private $responseFactory; + private $streamFactory; + + public function __construct(HttpClientInterface $client = null, ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null) + { + $this->client = $client ?? HttpClient::create(); + $this->responseFactory = $responseFactory; + $this->streamFactory = $streamFactory ?? ($responseFactory instanceof StreamFactoryInterface ? $responseFactory : null); + + if (null !== $this->responseFactory && null !== $this->streamFactory) { + return; + } + + if (!class_exists(Psr17Factory::class) && !class_exists(Psr17FactoryDiscovery::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as no PSR-17 factories have been provided. Try running "composer require nyholm/psr7".'); + } + + try { + $psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory() : null; + $this->responseFactory = $this->responseFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findResponseFactory(); + $this->streamFactory = $this->streamFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findStreamFactory(); + } catch (NotFoundException $e) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been found. Try running "composer require nyholm/psr7".', 0, $e); + } + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request): ResponseInterface + { + try { + $body = $request->getBody(); + + if ($body->isSeekable()) { + $body->seek(0); + } + + $options = [ + 'headers' => $request->getHeaders(), + 'body' => $body->getContents(), + ]; + + if ('1.0' === $request->getProtocolVersion()) { + $options['http_version'] = '1.0'; + } + + $response = $this->client->request($request->getMethod(), (string) $request->getUri(), $options); + + $psrResponse = $this->responseFactory->createResponse($response->getStatusCode()); + + foreach ($response->getHeaders(false) as $name => $values) { + foreach ($values as $value) { + try { + $psrResponse = $psrResponse->withAddedHeader($name, $value); + } catch (\InvalidArgumentException $e) { + // ignore invalid header + } + } + } + + $body = $response instanceof StreamableInterface ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client); + $body = $this->streamFactory->createStreamFromResource($body); + + if ($body->isSeekable()) { + $body->seek(0); + } + + return $psrResponse->withBody($body); + } catch (TransportExceptionInterface $e) { + if ($e instanceof \InvalidArgumentException) { + throw new Psr18RequestException($e, $request); + } + + throw new Psr18NetworkException($e, $request); + } + } + + /** + * {@inheritdoc} + */ + public function createRequest(string $method, $uri): RequestInterface + { + if ($this->responseFactory instanceof RequestFactoryInterface) { + return $this->responseFactory->createRequest($method, $uri); + } + + if (class_exists(Request::class)) { + return new Request($method, $uri); + } + + if (class_exists(Psr17FactoryDiscovery::class)) { + return Psr17FactoryDiscovery::findRequestFactory()->createRequest($method, $uri); + } + + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function createStream(string $content = ''): StreamInterface + { + $stream = $this->streamFactory->createStream($content); + + if ($stream->isSeekable()) { + $stream->seek(0); + } + + return $stream; + } + + /** + * {@inheritdoc} + */ + public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface + { + return $this->streamFactory->createStreamFromFile($filename, $mode); + } + + /** + * {@inheritdoc} + */ + public function createStreamFromResource($resource): StreamInterface + { + return $this->streamFactory->createStreamFromResource($resource); + } + + /** + * {@inheritdoc} + */ + public function createUri(string $uri = ''): UriInterface + { + if ($this->responseFactory instanceof UriFactoryInterface) { + return $this->responseFactory->createUri($uri); + } + + if (class_exists(Uri::class)) { + return new Uri($uri); + } + + if (class_exists(Psr17FactoryDiscovery::class)) { + return Psr17FactoryDiscovery::findUrlFactory()->createUri($uri); + } + + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} + +/** + * @internal + */ +class Psr18NetworkException extends \RuntimeException implements NetworkExceptionInterface +{ + private $request; + + public function __construct(TransportExceptionInterface $e, RequestInterface $request) + { + parent::__construct($e->getMessage(), 0, $e); + $this->request = $request; + } + + public function getRequest(): RequestInterface + { + return $this->request; + } +} + +/** + * @internal + */ +class Psr18RequestException extends \InvalidArgumentException implements RequestExceptionInterface +{ + private $request; + + public function __construct(TransportExceptionInterface $e, RequestInterface $request) + { + parent::__construct($e->getMessage(), 0, $e); + $this->request = $request; + } + + public function getRequest(): RequestInterface + { + return $this->request; + } +} diff --git a/vendor/symfony/http-client/README.md b/vendor/symfony/http-client/README.md new file mode 100644 index 000000000..0c55ccc11 --- /dev/null +++ b/vendor/symfony/http-client/README.md @@ -0,0 +1,27 @@ +HttpClient component +==================== + +The HttpClient component provides powerful methods to fetch HTTP resources synchronously or asynchronously. + +Sponsor +------- + +The Httpclient component for Symfony 5.4/6.0 is [backed][1] by [Klaxoon][2]. + +Klaxoon is a platform that empowers organizations to run effective and +productive workshops easily in a hybrid environment. Anytime, Anywhere. + +Help Symfony by [sponsoring][3] its development! + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/http_client.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) + +[1]: https://symfony.com/backers +[2]: https://klaxoon.com +[3]: https://symfony.com/sponsor diff --git a/vendor/symfony/http-client/Response/AmpResponse.php b/vendor/symfony/http-client/Response/AmpResponse.php new file mode 100644 index 000000000..900c70d6e --- /dev/null +++ b/vendor/symfony/http-client/Response/AmpResponse.php @@ -0,0 +1,460 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Amp\ByteStream\StreamException; +use Amp\CancellationTokenSource; +use Amp\Coroutine; +use Amp\Deferred; +use Amp\Http\Client\HttpException; +use Amp\Http\Client\Request; +use Amp\Http\Client\Response; +use Amp\Loop; +use Amp\Promise; +use Amp\Success; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\InformationalChunk; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\HttpClientTrait; +use Symfony\Component\HttpClient\Internal\AmpBody; +use Symfony\Component\HttpClient\Internal\AmpClientState; +use Symfony\Component\HttpClient\Internal\Canary; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class AmpResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + use TransportResponseTrait; + + private static $nextId = 'a'; + + private $multi; + private $options; + private $onProgress; + + private static $delay; + + /** + * @internal + */ + public function __construct(AmpClientState $multi, Request $request, array $options, ?LoggerInterface $logger) + { + $this->multi = $multi; + $this->options = &$options; + $this->logger = $logger; + $this->timeout = $options['timeout']; + $this->shouldBuffer = $options['buffer']; + + if ($this->inflate = \extension_loaded('zlib') && !$request->hasHeader('accept-encoding')) { + $request->setHeader('Accept-Encoding', 'gzip'); + } + + $this->initializer = static function (self $response) { + return null !== $response->options; + }; + + $info = &$this->info; + $headers = &$this->headers; + $canceller = new CancellationTokenSource(); + $handle = &$this->handle; + + $info['url'] = (string) $request->getUri(); + $info['http_method'] = $request->getMethod(); + $info['start_time'] = null; + $info['redirect_url'] = null; + $info['redirect_time'] = 0.0; + $info['redirect_count'] = 0; + $info['size_upload'] = 0.0; + $info['size_download'] = 0.0; + $info['upload_content_length'] = -1.0; + $info['download_content_length'] = -1.0; + $info['user_data'] = $options['user_data']; + $info['max_duration'] = $options['max_duration']; + $info['debug'] = ''; + + $onProgress = $options['on_progress'] ?? static function () {}; + $onProgress = $this->onProgress = static function () use (&$info, $onProgress) { + $info['total_time'] = microtime(true) - $info['start_time']; + $onProgress((int) $info['size_download'], ((int) (1 + $info['download_content_length']) ?: 1) - 1, (array) $info); + }; + + $pauseDeferred = new Deferred(); + $pause = new Success(); + + $throttleWatcher = null; + + $this->id = $id = self::$nextId++; + Loop::defer(static function () use ($request, $multi, &$id, &$info, &$headers, $canceller, &$options, $onProgress, &$handle, $logger, &$pause) { + return new Coroutine(self::generateResponse($request, $multi, $id, $info, $headers, $canceller, $options, $onProgress, $handle, $logger, $pause)); + }); + + $info['pause_handler'] = static function (float $duration) use (&$throttleWatcher, &$pauseDeferred, &$pause) { + if (null !== $throttleWatcher) { + Loop::cancel($throttleWatcher); + } + + $pause = $pauseDeferred->promise(); + + if ($duration <= 0) { + $deferred = $pauseDeferred; + $pauseDeferred = new Deferred(); + $deferred->resolve(); + } else { + $throttleWatcher = Loop::delay(ceil(1000 * $duration), static function () use (&$pauseDeferred) { + $deferred = $pauseDeferred; + $pauseDeferred = new Deferred(); + $deferred->resolve(); + }); + } + }; + + $multi->lastTimeout = null; + $multi->openHandles[$id] = $id; + ++$multi->responseCount; + + $this->canary = new Canary(static function () use ($canceller, $multi, $id) { + $canceller->cancel(); + unset($multi->openHandles[$id], $multi->handlesActivity[$id]); + }); + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + return null !== $type ? $this->info[$type] ?? null : $this->info; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + try { + $this->doDestruct(); + } finally { + // Clear the DNS cache when all requests completed + if (0 >= --$this->multi->responseCount) { + $this->multi->responseCount = 0; + $this->multi->dnsCache = []; + } + } + } + + /** + * {@inheritdoc} + */ + private static function schedule(self $response, array &$runningResponses): void + { + if (isset($runningResponses[0])) { + $runningResponses[0][1][$response->id] = $response; + } else { + $runningResponses[0] = [$response->multi, [$response->id => $response]]; + } + + if (!isset($response->multi->openHandles[$response->id])) { + $response->multi->handlesActivity[$response->id][] = null; + $response->multi->handlesActivity[$response->id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } + } + + /** + * {@inheritdoc} + * + * @param AmpClientState $multi + */ + private static function perform(ClientState $multi, array &$responses = null): void + { + if ($responses) { + foreach ($responses as $response) { + try { + if ($response->info['start_time']) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + ($response->onProgress)(); + } + } catch (\Throwable $e) { + $multi->handlesActivity[$response->id][] = null; + $multi->handlesActivity[$response->id][] = $e; + } + } + } + } + + /** + * {@inheritdoc} + * + * @param AmpClientState $multi + */ + private static function select(ClientState $multi, float $timeout): int + { + $timeout += microtime(true); + self::$delay = Loop::defer(static function () use ($timeout) { + if (0 < $timeout -= microtime(true)) { + self::$delay = Loop::delay(ceil(1000 * $timeout), [Loop::class, 'stop']); + } else { + Loop::stop(); + } + }); + + Loop::run(); + + return null === self::$delay ? 1 : 0; + } + + private static function generateResponse(Request $request, AmpClientState $multi, string $id, array &$info, array &$headers, CancellationTokenSource $canceller, array &$options, \Closure $onProgress, &$handle, ?LoggerInterface $logger, Promise &$pause) + { + $request->setInformationalResponseHandler(static function (Response $response) use ($multi, $id, &$info, &$headers) { + self::addResponseHeaders($response, $info, $headers); + $multi->handlesActivity[$id][] = new InformationalChunk($response->getStatus(), $response->getHeaders()); + self::stopLoop(); + }); + + try { + /* @var Response $response */ + if (null === $response = yield from self::getPushedResponse($request, $multi, $info, $headers, $options, $logger)) { + $logger && $logger->info(sprintf('Request: "%s %s"', $info['http_method'], $info['url'])); + + $response = yield from self::followRedirects($request, $multi, $info, $headers, $canceller, $options, $onProgress, $handle, $logger, $pause); + } + + $options = null; + + $multi->handlesActivity[$id][] = new FirstChunk(); + + if ('HEAD' === $response->getRequest()->getMethod() || \in_array($info['http_code'], [204, 304], true)) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null; + self::stopLoop(); + + return; + } + + if ($response->hasHeader('content-length')) { + $info['download_content_length'] = (float) $response->getHeader('content-length'); + } + + $body = $response->getBody(); + + while (true) { + self::stopLoop(); + + yield $pause; + + if (null === $data = yield $body->read()) { + break; + } + + $info['size_download'] += \strlen($data); + $multi->handlesActivity[$id][] = $data; + } + + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null; + } catch (\Throwable $e) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = $e; + } finally { + $info['download_content_length'] = $info['size_download']; + } + + self::stopLoop(); + } + + private static function followRedirects(Request $originRequest, AmpClientState $multi, array &$info, array &$headers, CancellationTokenSource $canceller, array $options, \Closure $onProgress, &$handle, ?LoggerInterface $logger, Promise &$pause) + { + yield $pause; + + $originRequest->setBody(new AmpBody($options['body'], $info, $onProgress)); + $response = yield $multi->request($options, $originRequest, $canceller->getToken(), $info, $onProgress, $handle); + $previousUrl = null; + + while (true) { + self::addResponseHeaders($response, $info, $headers); + $status = $response->getStatus(); + + if (!\in_array($status, [301, 302, 303, 307, 308], true) || null === $location = $response->getHeader('location')) { + return $response; + } + + $urlResolver = new class() { + use HttpClientTrait { + parseUrl as public; + resolveUrl as public; + } + }; + + try { + $previousUrl = $previousUrl ?? $urlResolver::parseUrl($info['url']); + $location = $urlResolver::parseUrl($location); + $location = $urlResolver::resolveUrl($location, $previousUrl); + $info['redirect_url'] = implode('', $location); + } catch (InvalidArgumentException $e) { + return $response; + } + + if (0 >= $options['max_redirects'] || $info['redirect_count'] >= $options['max_redirects']) { + return $response; + } + + $logger && $logger->info(sprintf('Redirecting: "%s %s"', $status, $info['url'])); + + try { + // Discard body of redirects + while (null !== yield $response->getBody()->read()) { + } + } catch (HttpException|StreamException $e) { + // Ignore streaming errors on previous responses + } + + ++$info['redirect_count']; + $info['url'] = $info['redirect_url']; + $info['redirect_url'] = null; + $previousUrl = $location; + + $request = new Request($info['url'], $info['http_method']); + $request->setProtocolVersions($originRequest->getProtocolVersions()); + $request->setTcpConnectTimeout($originRequest->getTcpConnectTimeout()); + $request->setTlsHandshakeTimeout($originRequest->getTlsHandshakeTimeout()); + $request->setTransferTimeout($originRequest->getTransferTimeout()); + + if (\in_array($status, [301, 302, 303], true)) { + $originRequest->removeHeader('transfer-encoding'); + $originRequest->removeHeader('content-length'); + $originRequest->removeHeader('content-type'); + + // Do like curl and browsers: turn POST to GET on 301, 302 and 303 + if ('POST' === $response->getRequest()->getMethod() || 303 === $status) { + $info['http_method'] = 'HEAD' === $response->getRequest()->getMethod() ? 'HEAD' : 'GET'; + $request->setMethod($info['http_method']); + } + } else { + $request->setBody(AmpBody::rewind($response->getRequest()->getBody())); + } + + foreach ($originRequest->getRawHeaders() as [$name, $value]) { + $request->addHeader($name, $value); + } + + if ($request->getUri()->getAuthority() !== $originRequest->getUri()->getAuthority()) { + $request->removeHeader('authorization'); + $request->removeHeader('cookie'); + $request->removeHeader('host'); + } + + yield $pause; + + $response = yield $multi->request($options, $request, $canceller->getToken(), $info, $onProgress, $handle); + $info['redirect_time'] = microtime(true) - $info['start_time']; + } + } + + private static function addResponseHeaders(Response $response, array &$info, array &$headers): void + { + $info['http_code'] = $response->getStatus(); + + if ($headers) { + $info['debug'] .= "< \r\n"; + $headers = []; + } + + $h = sprintf('HTTP/%s %s %s', $response->getProtocolVersion(), $response->getStatus(), $response->getReason()); + $info['debug'] .= "< {$h}\r\n"; + $info['response_headers'][] = $h; + + foreach ($response->getRawHeaders() as [$name, $value]) { + $headers[strtolower($name)][] = $value; + $h = $name.': '.$value; + $info['debug'] .= "< {$h}\r\n"; + $info['response_headers'][] = $h; + } + + $info['debug'] .= "< \r\n"; + } + + /** + * Accepts pushed responses only if their headers related to authentication match the request. + */ + private static function getPushedResponse(Request $request, AmpClientState $multi, array &$info, array &$headers, array $options, ?LoggerInterface $logger) + { + if ('' !== $options['body']) { + return null; + } + + $authority = $request->getUri()->getAuthority(); + + foreach ($multi->pushedResponses[$authority] ?? [] as $i => [$pushedUrl, $pushDeferred, $pushedRequest, $pushedResponse, $parentOptions]) { + if ($info['url'] !== $pushedUrl || $info['http_method'] !== $pushedRequest->getMethod()) { + continue; + } + + foreach ($parentOptions as $k => $v) { + if ($options[$k] !== $v) { + continue 2; + } + } + + foreach (['authorization', 'cookie', 'range', 'proxy-authorization'] as $k) { + if ($pushedRequest->getHeaderArray($k) !== $request->getHeaderArray($k)) { + continue 2; + } + } + + $response = yield $pushedResponse; + + foreach ($response->getHeaderArray('vary') as $vary) { + foreach (preg_split('/\s*+,\s*+/', $vary) as $v) { + if ('*' === $v || ($pushedRequest->getHeaderArray($v) !== $request->getHeaderArray($v) && 'accept-encoding' !== strtolower($v))) { + $logger && $logger->debug(sprintf('Skipping pushed response: "%s"', $info['url'])); + continue 3; + } + } + } + + $pushDeferred->resolve(); + $logger && $logger->debug(sprintf('Accepting pushed response: "%s %s"', $info['http_method'], $info['url'])); + self::addResponseHeaders($response, $info, $headers); + unset($multi->pushedResponses[$authority][$i]); + + if (!$multi->pushedResponses[$authority]) { + unset($multi->pushedResponses[$authority]); + } + + return $response; + } + } + + private static function stopLoop(): void + { + if (null !== self::$delay) { + Loop::cancel(self::$delay); + self::$delay = null; + } + + Loop::defer([Loop::class, 'stop']); + } +} diff --git a/vendor/symfony/http-client/Response/AsyncContext.php b/vendor/symfony/http-client/Response/AsyncContext.php new file mode 100644 index 000000000..646458e13 --- /dev/null +++ b/vendor/symfony/http-client/Response/AsyncContext.php @@ -0,0 +1,195 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\DataChunk; +use Symfony\Component\HttpClient\Chunk\LastChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * A DTO to work with AsyncResponse. + * + * @author Nicolas Grekas + */ +final class AsyncContext +{ + private $passthru; + private $client; + private $response; + private $info = []; + private $content; + private $offset; + + public function __construct(&$passthru, HttpClientInterface $client, ResponseInterface &$response, array &$info, $content, int $offset) + { + $this->passthru = &$passthru; + $this->client = $client; + $this->response = &$response; + $this->info = &$info; + $this->content = $content; + $this->offset = $offset; + } + + /** + * Returns the HTTP status without consuming the response. + */ + public function getStatusCode(): int + { + return $this->response->getInfo('http_code'); + } + + /** + * Returns the headers without consuming the response. + */ + public function getHeaders(): array + { + $headers = []; + + foreach ($this->response->getInfo('response_headers') as $h) { + if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? ([123456789]\d\d)(?: |$)#', $h, $m)) { + $headers = []; + } elseif (2 === \count($m = explode(':', $h, 2))) { + $headers[strtolower($m[0])][] = ltrim($m[1]); + } + } + + return $headers; + } + + /** + * @return resource|null The PHP stream resource where the content is buffered, if it is + */ + public function getContent() + { + return $this->content; + } + + /** + * Creates a new chunk of content. + */ + public function createChunk(string $data): ChunkInterface + { + return new DataChunk($this->offset, $data); + } + + /** + * Pauses the request for the given number of seconds. + */ + public function pause(float $duration): void + { + if (\is_callable($pause = $this->response->getInfo('pause_handler'))) { + $pause($duration); + } elseif (0 < $duration) { + usleep(1E6 * $duration); + } + } + + /** + * Cancels the request and returns the last chunk to yield. + */ + public function cancel(): ChunkInterface + { + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + $this->response->cancel(); + + return new LastChunk(); + } + + /** + * Returns the current info of the response. + */ + public function getInfo(string $type = null) + { + if (null !== $type) { + return $this->info[$type] ?? $this->response->getInfo($type); + } + + return $this->info + $this->response->getInfo(); + } + + /** + * Attaches an info to the response. + * + * @return $this + */ + public function setInfo(string $type, $value): self + { + if ('canceled' === $type && $value !== $this->info['canceled']) { + throw new \LogicException('You cannot set the "canceled" info directly.'); + } + + if (null === $value) { + unset($this->info[$type]); + } else { + $this->info[$type] = $value; + } + + return $this; + } + + /** + * Returns the currently processed response. + */ + public function getResponse(): ResponseInterface + { + return $this->response; + } + + /** + * Replaces the currently processed response by doing a new request. + */ + public function replaceRequest(string $method, string $url, array $options = []): ResponseInterface + { + $this->info['previous_info'][] = $info = $this->response->getInfo(); + if (null !== $onProgress = $options['on_progress'] ?? null) { + $thisInfo = &$this->info; + $options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) { + $onProgress($dlNow, $dlSize, $thisInfo + $info); + }; + } + if (0 < ($info['max_duration'] ?? 0) && 0 < ($info['total_time'] ?? 0)) { + if (0 >= $options['max_duration'] = $info['max_duration'] - $info['total_time']) { + throw new TransportException(sprintf('Max duration was reached for "%s".', $info['url'])); + } + } + + return $this->response = $this->client->request($method, $url, ['buffer' => false] + $options); + } + + /** + * Replaces the currently processed response by another one. + */ + public function replaceResponse(ResponseInterface $response): ResponseInterface + { + $this->info['previous_info'][] = $this->response->getInfo(); + + return $this->response = $response; + } + + /** + * Replaces or removes the chunk filter iterator. + * + * @param ?callable(ChunkInterface, self): ?\Iterator $passthru + */ + public function passthru(callable $passthru = null): void + { + $this->passthru = $passthru ?? static function ($chunk, $context) { + $context->passthru = null; + + yield $chunk; + }; + } +} diff --git a/vendor/symfony/http-client/Response/AsyncResponse.php b/vendor/symfony/http-client/Response/AsyncResponse.php new file mode 100644 index 000000000..80c9f7da3 --- /dev/null +++ b/vendor/symfony/http-client/Response/AsyncResponse.php @@ -0,0 +1,478 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\LastChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * Provides a single extension point to process a response's content stream. + * + * @author Nicolas Grekas + */ +final class AsyncResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + + private const FIRST_CHUNK_YIELDED = 1; + private const LAST_CHUNK_YIELDED = 2; + + private $client; + private $response; + private $info = ['canceled' => false]; + private $passthru; + private $stream; + private $yieldedState; + + /** + * @param ?callable(ChunkInterface, AsyncContext): ?\Iterator $passthru + */ + public function __construct(HttpClientInterface $client, string $method, string $url, array $options, callable $passthru = null) + { + $this->client = $client; + $this->shouldBuffer = $options['buffer'] ?? true; + + if (null !== $onProgress = $options['on_progress'] ?? null) { + $thisInfo = &$this->info; + $options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) { + $onProgress($dlNow, $dlSize, $thisInfo + $info); + }; + } + $this->response = $client->request($method, $url, ['buffer' => false] + $options); + $this->passthru = $passthru; + $this->initializer = static function (self $response, float $timeout = null) { + if (null === $response->shouldBuffer) { + return false; + } + + while (true) { + foreach (self::stream([$response], $timeout) as $chunk) { + if ($chunk->isTimeout() && $response->passthru) { + foreach (self::passthru($response->client, $response, new ErrorChunk($response->offset, new TransportException($chunk->getError()))) as $chunk) { + if ($chunk->isFirst()) { + return false; + } + } + + continue 2; + } + + if ($chunk->isFirst()) { + return false; + } + } + + return false; + } + }; + if (\array_key_exists('user_data', $options)) { + $this->info['user_data'] = $options['user_data']; + } + if (\array_key_exists('max_duration', $options)) { + $this->info['max_duration'] = $options['max_duration']; + } + } + + public function getStatusCode(): int + { + if ($this->initializer) { + self::initialize($this); + } + + return $this->response->getStatusCode(); + } + + public function getHeaders(bool $throw = true): array + { + if ($this->initializer) { + self::initialize($this); + } + + $headers = $this->response->getHeaders(false); + + if ($throw) { + $this->checkStatusCode(); + } + + return $headers; + } + + public function getInfo(string $type = null) + { + if (null !== $type) { + return $this->info[$type] ?? $this->response->getInfo($type); + } + + return $this->info + $this->response->getInfo(); + } + + /** + * {@inheritdoc} + */ + public function toStream(bool $throw = true) + { + if ($throw) { + // Ensure headers arrived + $this->getHeaders(true); + } + + $handle = function () { + $stream = $this->response instanceof StreamableInterface ? $this->response->toStream(false) : StreamWrapper::createResource($this->response); + + return stream_get_meta_data($stream)['wrapper_data']->stream_cast(\STREAM_CAST_FOR_SELECT); + }; + + $stream = StreamWrapper::createResource($this); + stream_get_meta_data($stream)['wrapper_data'] + ->bindHandles($handle, $this->content); + + return $stream; + } + + /** + * {@inheritdoc} + */ + public function cancel(): void + { + if ($this->info['canceled']) { + return; + } + + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + $this->close(); + $client = $this->client; + $this->client = null; + + if (!$this->passthru) { + return; + } + + try { + foreach (self::passthru($client, $this, new LastChunk()) as $chunk) { + // no-op + } + + $this->passthru = null; + } catch (ExceptionInterface $e) { + // ignore any errors when canceling + } + } + + public function __destruct() + { + $httpException = null; + + if ($this->initializer && null === $this->getInfo('error')) { + try { + self::initialize($this, -0.0); + $this->getHeaders(true); + } catch (HttpExceptionInterface $httpException) { + // no-op + } + } + + if ($this->passthru && null === $this->getInfo('error')) { + $this->info['canceled'] = true; + + try { + foreach (self::passthru($this->client, $this, new LastChunk()) as $chunk) { + // no-op + } + } catch (ExceptionInterface $e) { + // ignore any errors when destructing + } + } + + if (null !== $httpException) { + throw $httpException; + } + } + + /** + * @internal + */ + public static function stream(iterable $responses, float $timeout = null, string $class = null): \Generator + { + while ($responses) { + $wrappedResponses = []; + $asyncMap = new \SplObjectStorage(); + $client = null; + + foreach ($responses as $r) { + if (!$r instanceof self) { + throw new \TypeError(sprintf('"%s::stream()" expects parameter 1 to be an iterable of AsyncResponse objects, "%s" given.', $class ?? static::class, get_debug_type($r))); + } + + if (null !== $e = $r->info['error'] ?? null) { + yield $r => $chunk = new ErrorChunk($r->offset, new TransportException($e)); + $chunk->didThrow() ?: $chunk->getContent(); + continue; + } + + if (null === $client) { + $client = $r->client; + } elseif ($r->client !== $client) { + throw new TransportException('Cannot stream AsyncResponse objects with many clients.'); + } + + $asyncMap[$r->response] = $r; + $wrappedResponses[] = $r->response; + + if ($r->stream) { + yield from self::passthruStream($response = $r->response, $r, new FirstChunk(), $asyncMap); + + if (!isset($asyncMap[$response])) { + array_pop($wrappedResponses); + } + + if ($r->response !== $response && !isset($asyncMap[$r->response])) { + $asyncMap[$r->response] = $r; + $wrappedResponses[] = $r->response; + } + } + } + + if (!$client || !$wrappedResponses) { + return; + } + + foreach ($client->stream($wrappedResponses, $timeout) as $response => $chunk) { + $r = $asyncMap[$response]; + + if (null === $chunk->getError()) { + if ($chunk->isFirst()) { + // Ensure no exception is thrown on destruct for the wrapped response + $r->response->getStatusCode(); + } elseif (0 === $r->offset && null === $r->content && $chunk->isLast()) { + $r->content = fopen('php://memory', 'w+'); + } + } + + if (!$r->passthru) { + if (null !== $chunk->getError() || $chunk->isLast()) { + unset($asyncMap[$response]); + } elseif (null !== $r->content && '' !== ($content = $chunk->getContent()) && \strlen($content) !== fwrite($r->content, $content)) { + $chunk = new ErrorChunk($r->offset, new TransportException(sprintf('Failed writing %d bytes to the response buffer.', \strlen($content)))); + $r->info['error'] = $chunk->getError(); + $r->response->cancel(); + } + + yield $r => $chunk; + continue; + } + + if (null !== $chunk->getError()) { + // no-op + } elseif ($chunk->isFirst()) { + $r->yieldedState = self::FIRST_CHUNK_YIELDED; + } elseif (self::FIRST_CHUNK_YIELDED !== $r->yieldedState && null === $chunk->getInformationalStatus()) { + throw new \LogicException(sprintf('Instance of "%s" is already consumed and cannot be managed by "%s". A decorated client should not call any of the response\'s methods in its "request()" method.', get_debug_type($response), $class ?? static::class)); + } + + foreach (self::passthru($r->client, $r, $chunk, $asyncMap) as $chunk) { + yield $r => $chunk; + } + + if ($r->response !== $response && isset($asyncMap[$response])) { + break; + } + } + + if (null === $chunk->getError() && $chunk->isLast()) { + $r->yieldedState = self::LAST_CHUNK_YIELDED; + } + if (null === $chunk->getError() && self::LAST_CHUNK_YIELDED !== $r->yieldedState && $r->response === $response && null !== $r->client) { + throw new \LogicException('A chunk passthru must yield an "isLast()" chunk before ending a stream.'); + } + + $responses = []; + foreach ($asyncMap as $response) { + $r = $asyncMap[$response]; + + if (null !== $r->client) { + $responses[] = $asyncMap[$response]; + } + } + } + } + + /** + * @param \SplObjectStorage|null $asyncMap + */ + private static function passthru(HttpClientInterface $client, self $r, ChunkInterface $chunk, \SplObjectStorage $asyncMap = null): \Generator + { + $r->stream = null; + $response = $r->response; + $context = new AsyncContext($r->passthru, $client, $r->response, $r->info, $r->content, $r->offset); + if (null === $stream = ($r->passthru)($chunk, $context)) { + if ($r->response === $response && (null !== $chunk->getError() || $chunk->isLast())) { + throw new \LogicException('A chunk passthru cannot swallow the last chunk.'); + } + + return; + } + + if (!$stream instanceof \Iterator) { + throw new \LogicException(sprintf('A chunk passthru must return an "Iterator", "%s" returned.', get_debug_type($stream))); + } + $r->stream = $stream; + + yield from self::passthruStream($response, $r, null, $asyncMap); + } + + /** + * @param \SplObjectStorage|null $asyncMap + */ + private static function passthruStream(ResponseInterface $response, self $r, ?ChunkInterface $chunk, ?\SplObjectStorage $asyncMap): \Generator + { + while (true) { + try { + if (null !== $chunk && $r->stream) { + $r->stream->next(); + } + + if (!$r->stream || !$r->stream->valid() || !$r->stream) { + $r->stream = null; + break; + } + } catch (\Throwable $e) { + unset($asyncMap[$response]); + $r->stream = null; + $r->info['error'] = $e->getMessage(); + $r->response->cancel(); + + yield $r => $chunk = new ErrorChunk($r->offset, $e); + $chunk->didThrow() ?: $chunk->getContent(); + break; + } + + $chunk = $r->stream->current(); + + if (!$chunk instanceof ChunkInterface) { + throw new \LogicException(sprintf('A chunk passthru must yield instances of "%s", "%s" yielded.', ChunkInterface::class, get_debug_type($chunk))); + } + + if (null !== $chunk->getError()) { + // no-op + } elseif ($chunk->isFirst()) { + $e = $r->openBuffer(); + + yield $r => $chunk; + + if ($r->initializer && null === $r->getInfo('error')) { + // Ensure the HTTP status code is always checked + $r->getHeaders(true); + } + + if (null === $e) { + continue; + } + + $r->response->cancel(); + $chunk = new ErrorChunk($r->offset, $e); + } elseif ('' !== $content = $chunk->getContent()) { + if (null !== $r->shouldBuffer) { + throw new \LogicException('A chunk passthru must yield an "isFirst()" chunk before any content chunk.'); + } + + if (null !== $r->content && \strlen($content) !== fwrite($r->content, $content)) { + $chunk = new ErrorChunk($r->offset, new TransportException(sprintf('Failed writing %d bytes to the response buffer.', \strlen($content)))); + $r->info['error'] = $chunk->getError(); + $r->response->cancel(); + } + } + + if (null !== $chunk->getError() || $chunk->isLast()) { + $stream = $r->stream; + $r->stream = null; + unset($asyncMap[$response]); + } + + if (null === $chunk->getError()) { + $r->offset += \strlen($content); + + yield $r => $chunk; + + if (!$chunk->isLast()) { + continue; + } + + $stream->next(); + + if ($stream->valid()) { + throw new \LogicException('A chunk passthru cannot yield after an "isLast()" chunk.'); + } + + $r->passthru = null; + } else { + if ($chunk instanceof ErrorChunk) { + $chunk->didThrow(false); + } else { + try { + $chunk = new ErrorChunk($chunk->getOffset(), !$chunk->isTimeout() ?: $chunk->getError()); + } catch (TransportExceptionInterface $e) { + $chunk = new ErrorChunk($chunk->getOffset(), $e); + } + } + + yield $r => $chunk; + $chunk->didThrow() ?: $chunk->getContent(); + } + + break; + } + } + + private function openBuffer(): ?\Throwable + { + if (null === $shouldBuffer = $this->shouldBuffer) { + throw new \LogicException('A chunk passthru cannot yield more than one "isFirst()" chunk.'); + } + + $e = $this->shouldBuffer = null; + + if ($shouldBuffer instanceof \Closure) { + try { + $shouldBuffer = $shouldBuffer($this->getHeaders(false)); + + if (null !== $e = $this->response->getInfo('error')) { + throw new TransportException($e); + } + } catch (\Throwable $e) { + $this->info['error'] = $e->getMessage(); + $this->response->cancel(); + } + } + + if (true === $shouldBuffer) { + $this->content = fopen('php://temp', 'w+'); + } elseif (\is_resource($shouldBuffer)) { + $this->content = $shouldBuffer; + } + + return $e; + } + + private function close(): void + { + $this->response->cancel(); + } +} diff --git a/vendor/symfony/http-client/Response/CommonResponseTrait.php b/vendor/symfony/http-client/Response/CommonResponseTrait.php new file mode 100644 index 000000000..11a8d6ca7 --- /dev/null +++ b/vendor/symfony/http-client/Response/CommonResponseTrait.php @@ -0,0 +1,185 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Exception\ClientException; +use Symfony\Component\HttpClient\Exception\JsonException; +use Symfony\Component\HttpClient\Exception\RedirectionException; +use Symfony\Component\HttpClient\Exception\ServerException; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * Implements common logic for response classes. + * + * @author Nicolas Grekas + * + * @internal + */ +trait CommonResponseTrait +{ + /** + * @var callable|null A callback that tells whether we're waiting for response headers + */ + private $initializer; + private $shouldBuffer; + private $content; + private $offset = 0; + private $jsonData; + + /** + * {@inheritdoc} + */ + public function getContent(bool $throw = true): string + { + if ($this->initializer) { + self::initialize($this); + } + + if ($throw) { + $this->checkStatusCode(); + } + + if (null === $this->content) { + $content = null; + + foreach (self::stream([$this]) as $chunk) { + if (!$chunk->isLast()) { + $content .= $chunk->getContent(); + } + } + + if (null !== $content) { + return $content; + } + + if (null === $this->content) { + throw new TransportException('Cannot get the content of the response twice: buffering is disabled.'); + } + } else { + foreach (self::stream([$this]) as $chunk) { + // Chunks are buffered in $this->content already + } + } + + rewind($this->content); + + return stream_get_contents($this->content); + } + + /** + * {@inheritdoc} + */ + public function toArray(bool $throw = true): array + { + if ('' === $content = $this->getContent($throw)) { + throw new JsonException('Response body is empty.'); + } + + if (null !== $this->jsonData) { + return $this->jsonData; + } + + try { + $content = json_decode($content, true, 512, \JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0)); + } catch (\JsonException $e) { + throw new JsonException($e->getMessage().sprintf(' for "%s".', $this->getInfo('url')), $e->getCode()); + } + + if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error()) { + throw new JsonException(json_last_error_msg().sprintf(' for "%s".', $this->getInfo('url')), json_last_error()); + } + + if (!\is_array($content)) { + throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned for "%s".', get_debug_type($content), $this->getInfo('url'))); + } + + if (null !== $this->content) { + // Option "buffer" is true + return $this->jsonData = $content; + } + + return $content; + } + + /** + * {@inheritdoc} + */ + public function toStream(bool $throw = true) + { + if ($throw) { + // Ensure headers arrived + $this->getHeaders($throw); + } + + $stream = StreamWrapper::createResource($this); + stream_get_meta_data($stream)['wrapper_data'] + ->bindHandles($this->handle, $this->content); + + return $stream; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + /** + * Closes the response and all its network handles. + */ + abstract protected function close(): void; + + private static function initialize(self $response): void + { + if (null !== $response->getInfo('error')) { + throw new TransportException($response->getInfo('error')); + } + + try { + if (($response->initializer)($response, -0.0)) { + foreach (self::stream([$response], -0.0) as $chunk) { + if ($chunk->isFirst()) { + break; + } + } + } + } catch (\Throwable $e) { + // Persist timeouts thrown during initialization + $response->info['error'] = $e->getMessage(); + $response->close(); + throw $e; + } + + $response->initializer = null; + } + + private function checkStatusCode() + { + $code = $this->getInfo('http_code'); + + if (500 <= $code) { + throw new ServerException($this); + } + + if (400 <= $code) { + throw new ClientException($this); + } + + if (300 <= $code) { + throw new RedirectionException($this); + } + } +} diff --git a/vendor/symfony/http-client/Response/CurlResponse.php b/vendor/symfony/http-client/Response/CurlResponse.php new file mode 100644 index 000000000..241820306 --- /dev/null +++ b/vendor/symfony/http-client/Response/CurlResponse.php @@ -0,0 +1,473 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\InformationalChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\Canary; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Component\HttpClient\Internal\CurlClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class CurlResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait { + getContent as private doGetContent; + } + use TransportResponseTrait; + + private $multi; + private $debugBuffer; + + /** + * @param \CurlHandle|resource|string $ch + * + * @internal + */ + public function __construct(CurlClientState $multi, $ch, array $options = null, LoggerInterface $logger = null, string $method = 'GET', callable $resolveRedirect = null, int $curlVersion = null) + { + $this->multi = $multi; + + if (\is_resource($ch) || $ch instanceof \CurlHandle) { + $this->handle = $ch; + $this->debugBuffer = fopen('php://temp', 'w+'); + if (0x074000 === $curlVersion) { + fwrite($this->debugBuffer, 'Due to a bug in curl 7.64.0, the debug log is disabled; use another version to work around the issue.'); + } else { + curl_setopt($ch, \CURLOPT_VERBOSE, true); + curl_setopt($ch, \CURLOPT_STDERR, $this->debugBuffer); + } + } else { + $this->info['url'] = $ch; + $ch = $this->handle; + } + + $this->id = $id = (int) $ch; + $this->logger = $logger; + $this->shouldBuffer = $options['buffer'] ?? true; + $this->timeout = $options['timeout'] ?? null; + $this->info['http_method'] = $method; + $this->info['user_data'] = $options['user_data'] ?? null; + $this->info['max_duration'] = $options['max_duration'] ?? null; + $this->info['start_time'] = $this->info['start_time'] ?? microtime(true); + $info = &$this->info; + $headers = &$this->headers; + $debugBuffer = $this->debugBuffer; + + if (!$info['response_headers']) { + // Used to keep track of what we're waiting for + curl_setopt($ch, \CURLOPT_PRIVATE, \in_array($method, ['GET', 'HEAD', 'OPTIONS', 'TRACE'], true) && 1.0 < (float) ($options['http_version'] ?? 1.1) ? 'H2' : 'H0'); // H = headers + retry counter + } + + curl_setopt($ch, \CURLOPT_HEADERFUNCTION, static function ($ch, string $data) use (&$info, &$headers, $options, $multi, $id, &$location, $resolveRedirect, $logger): int { + return self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger); + }); + + if (null === $options) { + // Pushed response: buffer until requested + curl_setopt($ch, \CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int { + $multi->handlesActivity[$id][] = $data; + curl_pause($ch, \CURLPAUSE_RECV); + + return \strlen($data); + }); + + return; + } + + $execCounter = $multi->execCounter; + $this->info['pause_handler'] = static function (float $duration) use ($ch, $multi, $execCounter) { + if (0 < $duration) { + if ($execCounter === $multi->execCounter) { + $multi->execCounter = !\is_float($execCounter) ? 1 + $execCounter : \PHP_INT_MIN; + curl_multi_remove_handle($multi->handle, $ch); + } + + $lastExpiry = end($multi->pauseExpiries); + $multi->pauseExpiries[(int) $ch] = $duration += microtime(true); + if (false !== $lastExpiry && $lastExpiry > $duration) { + asort($multi->pauseExpiries); + } + curl_pause($ch, \CURLPAUSE_ALL); + } else { + unset($multi->pauseExpiries[(int) $ch]); + curl_pause($ch, \CURLPAUSE_CONT); + curl_multi_add_handle($multi->handle, $ch); + } + }; + + $this->inflate = !isset($options['normalized_headers']['accept-encoding']); + curl_pause($ch, \CURLPAUSE_CONT); + + if ($onProgress = $options['on_progress']) { + $url = isset($info['url']) ? ['url' => $info['url']] : []; + curl_setopt($ch, \CURLOPT_NOPROGRESS, false); + curl_setopt($ch, \CURLOPT_PROGRESSFUNCTION, static function ($ch, $dlSize, $dlNow) use ($onProgress, &$info, $url, $multi, $debugBuffer) { + try { + rewind($debugBuffer); + $debug = ['debug' => stream_get_contents($debugBuffer)]; + $onProgress($dlNow, $dlSize, $url + curl_getinfo($ch) + $info + $debug); + } catch (\Throwable $e) { + $multi->handlesActivity[(int) $ch][] = null; + $multi->handlesActivity[(int) $ch][] = $e; + + return 1; // Abort the request + } + + return null; + }); + } + + curl_setopt($ch, \CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int { + if ('H' === (curl_getinfo($ch, \CURLINFO_PRIVATE)[0] ?? null)) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = new TransportException(sprintf('Unsupported protocol for "%s"', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL))); + + return 0; + } + + curl_setopt($ch, \CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int { + $multi->handlesActivity[$id][] = $data; + + return \strlen($data); + }); + + $multi->handlesActivity[$id][] = $data; + + return \strlen($data); + }); + + $this->initializer = static function (self $response) { + $waitFor = curl_getinfo($ch = $response->handle, \CURLINFO_PRIVATE); + + return 'H' === $waitFor[0]; + }; + + // Schedule the request in a non-blocking way + $multi->lastTimeout = null; + $multi->openHandles[$id] = [$ch, $options]; + curl_multi_add_handle($multi->handle, $ch); + + $this->canary = new Canary(static function () use ($ch, $multi, $id) { + unset($multi->pauseExpiries[$id], $multi->openHandles[$id], $multi->handlesActivity[$id]); + curl_setopt($ch, \CURLOPT_PRIVATE, '_0'); + + if ($multi->performing) { + return; + } + + curl_multi_remove_handle($multi->handle, $ch); + curl_setopt_array($ch, [ + \CURLOPT_NOPROGRESS => true, + \CURLOPT_PROGRESSFUNCTION => null, + \CURLOPT_HEADERFUNCTION => null, + \CURLOPT_WRITEFUNCTION => null, + \CURLOPT_READFUNCTION => null, + \CURLOPT_INFILE => null, + ]); + + if (!$multi->openHandles) { + // Schedule DNS cache eviction for the next request + $multi->dnsCache->evictions = $multi->dnsCache->evictions ?: $multi->dnsCache->removals; + $multi->dnsCache->removals = $multi->dnsCache->hostnames = []; + } + }); + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + if (!$info = $this->finalInfo) { + $info = array_merge($this->info, curl_getinfo($this->handle)); + $info['url'] = $this->info['url'] ?? $info['url']; + $info['redirect_url'] = $this->info['redirect_url'] ?? null; + + // workaround curl not subtracting the time offset for pushed responses + if (isset($this->info['url']) && $info['start_time'] / 1000 < $info['total_time']) { + $info['total_time'] -= $info['starttransfer_time'] ?: $info['total_time']; + $info['starttransfer_time'] = 0.0; + } + + rewind($this->debugBuffer); + $info['debug'] = stream_get_contents($this->debugBuffer); + $waitFor = curl_getinfo($this->handle, \CURLINFO_PRIVATE); + + if ('H' !== $waitFor[0] && 'C' !== $waitFor[0]) { + curl_setopt($this->handle, \CURLOPT_VERBOSE, false); + rewind($this->debugBuffer); + ftruncate($this->debugBuffer, 0); + $this->finalInfo = $info; + } + } + + return null !== $type ? $info[$type] ?? null : $info; + } + + /** + * {@inheritdoc} + */ + public function getContent(bool $throw = true): string + { + $performing = $this->multi->performing; + $this->multi->performing = $performing || '_0' === curl_getinfo($this->handle, \CURLINFO_PRIVATE); + + try { + return $this->doGetContent($throw); + } finally { + $this->multi->performing = $performing; + } + } + + public function __destruct() + { + try { + if (null === $this->timeout) { + return; // Unused pushed response + } + + $this->doDestruct(); + } finally { + if (\is_resource($this->handle) || $this->handle instanceof \CurlHandle) { + curl_setopt($this->handle, \CURLOPT_VERBOSE, false); + } + } + } + + /** + * {@inheritdoc} + */ + private static function schedule(self $response, array &$runningResponses): void + { + if (isset($runningResponses[$i = (int) $response->multi->handle])) { + $runningResponses[$i][1][$response->id] = $response; + } else { + $runningResponses[$i] = [$response->multi, [$response->id => $response]]; + } + + if ('_0' === curl_getinfo($ch = $response->handle, \CURLINFO_PRIVATE)) { + // Response already completed + $response->multi->handlesActivity[$response->id][] = null; + $response->multi->handlesActivity[$response->id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } + } + + /** + * {@inheritdoc} + * + * @param CurlClientState $multi + */ + private static function perform(ClientState $multi, array &$responses = null): void + { + if ($multi->performing) { + if ($responses) { + $response = current($responses); + $multi->handlesActivity[(int) $response->handle][] = null; + $multi->handlesActivity[(int) $response->handle][] = new TransportException(sprintf('Userland callback cannot use the client nor the response while processing "%s".', curl_getinfo($response->handle, \CURLINFO_EFFECTIVE_URL))); + } + + return; + } + + try { + $multi->performing = true; + ++$multi->execCounter; + $active = 0; + while (\CURLM_CALL_MULTI_PERFORM === ($err = curl_multi_exec($multi->handle, $active))) { + } + + if (\CURLM_OK !== $err) { + throw new TransportException(curl_multi_strerror($err)); + } + + while ($info = curl_multi_info_read($multi->handle)) { + if (\CURLMSG_DONE !== $info['msg']) { + continue; + } + $result = $info['result']; + $id = (int) $ch = $info['handle']; + $waitFor = @curl_getinfo($ch, \CURLINFO_PRIVATE) ?: '_0'; + + if (\in_array($result, [\CURLE_SEND_ERROR, \CURLE_RECV_ERROR, /* CURLE_HTTP2 */ 16, /* CURLE_HTTP2_STREAM */ 92], true) && $waitFor[1] && 'C' !== $waitFor[0]) { + curl_multi_remove_handle($multi->handle, $ch); + $waitFor[1] = (string) ((int) $waitFor[1] - 1); // decrement the retry counter + curl_setopt($ch, \CURLOPT_PRIVATE, $waitFor); + curl_setopt($ch, \CURLOPT_FORBID_REUSE, true); + + if (0 === curl_multi_add_handle($multi->handle, $ch)) { + continue; + } + } + + if (\CURLE_RECV_ERROR === $result && 'H' === $waitFor[0] && 400 <= ($responses[(int) $ch]->info['http_code'] ?? 0)) { + $multi->handlesActivity[$id][] = new FirstChunk(); + } + + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = \in_array($result, [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || '_0' === $waitFor || curl_getinfo($ch, \CURLINFO_SIZE_DOWNLOAD) === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL))); + } + } finally { + $multi->performing = false; + } + } + + /** + * {@inheritdoc} + * + * @param CurlClientState $multi + */ + private static function select(ClientState $multi, float $timeout): int + { + if (\PHP_VERSION_ID < 70211) { + // workaround https://bugs.php.net/76480 + $timeout = min($timeout, 0.01); + } + + if ($multi->pauseExpiries) { + $now = microtime(true); + + foreach ($multi->pauseExpiries as $id => $pauseExpiry) { + if ($now < $pauseExpiry) { + $timeout = min($timeout, $pauseExpiry - $now); + break; + } + + unset($multi->pauseExpiries[$id]); + curl_pause($multi->openHandles[$id][0], \CURLPAUSE_CONT); + curl_multi_add_handle($multi->handle, $multi->openHandles[$id][0]); + } + } + + if (0 !== $selected = curl_multi_select($multi->handle, $timeout)) { + return $selected; + } + + if ($multi->pauseExpiries && 0 < $timeout -= microtime(true) - $now) { + usleep((int) (1E6 * $timeout)); + } + + return 0; + } + + /** + * Parses header lines as curl yields them to us. + */ + private static function parseHeaderLine($ch, string $data, array &$info, array &$headers, ?array $options, CurlClientState $multi, int $id, ?string &$location, ?callable $resolveRedirect, ?LoggerInterface $logger): int + { + if (!str_ends_with($data, "\r\n")) { + return 0; + } + + $waitFor = @curl_getinfo($ch, \CURLINFO_PRIVATE) ?: '_0'; + + if ('H' !== $waitFor[0]) { + return \strlen($data); // Ignore HTTP trailers + } + + $statusCode = curl_getinfo($ch, \CURLINFO_RESPONSE_CODE); + + if ($statusCode !== $info['http_code'] && !preg_match("#^HTTP/\d+(?:\.\d+)? {$statusCode}(?: |\r\n$)#", $data)) { + return \strlen($data); // Ignore headers from responses to CONNECT requests + } + + if ("\r\n" !== $data) { + // Regular header line: add it to the list + self::addResponseHeaders([substr($data, 0, -2)], $info, $headers); + + if (!str_starts_with($data, 'HTTP/')) { + if (0 === stripos($data, 'Location:')) { + $location = trim(substr($data, 9, -2)); + } + + return \strlen($data); + } + + if (\function_exists('openssl_x509_read') && $certinfo = curl_getinfo($ch, \CURLINFO_CERTINFO)) { + $info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert')); + } + + if (300 <= $info['http_code'] && $info['http_code'] < 400) { + if (curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { + curl_setopt($ch, \CURLOPT_FOLLOWLOCATION, false); + } elseif (303 === $info['http_code'] || ('POST' === $info['http_method'] && \in_array($info['http_code'], [301, 302], true))) { + curl_setopt($ch, \CURLOPT_POSTFIELDS, ''); + } + } + + return \strlen($data); + } + + // End of headers: handle informational responses, redirects, etc. + + if (200 > $statusCode) { + $multi->handlesActivity[$id][] = new InformationalChunk($statusCode, $headers); + $location = null; + + return \strlen($data); + } + + $info['redirect_url'] = null; + + if (300 <= $statusCode && $statusCode < 400 && null !== $location) { + if ($noContent = 303 === $statusCode || ('POST' === $info['http_method'] && \in_array($statusCode, [301, 302], true))) { + $info['http_method'] = 'HEAD' === $info['http_method'] ? 'HEAD' : 'GET'; + curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, $info['http_method']); + } + + if (null === $info['redirect_url'] = $resolveRedirect($ch, $location, $noContent)) { + $options['max_redirects'] = curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT); + curl_setopt($ch, \CURLOPT_FOLLOWLOCATION, false); + curl_setopt($ch, \CURLOPT_MAXREDIRS, $options['max_redirects']); + } else { + $url = parse_url($location ?? ':'); + + if (isset($url['host']) && null !== $ip = $multi->dnsCache->hostnames[$url['host'] = strtolower($url['host'])] ?? null) { + // Populate DNS cache for redirects if needed + $port = $url['port'] ?? ('http' === ($url['scheme'] ?? parse_url(curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL), \PHP_URL_SCHEME)) ? 80 : 443); + curl_setopt($ch, \CURLOPT_RESOLVE, ["{$url['host']}:$port:$ip"]); + $multi->dnsCache->removals["-{$url['host']}:$port"] = "-{$url['host']}:$port"; + } + } + } + + if (401 === $statusCode && isset($options['auth_ntlm']) && 0 === strncasecmp($headers['www-authenticate'][0] ?? '', 'NTLM ', 5)) { + // Continue with NTLM auth + } elseif ($statusCode < 300 || 400 <= $statusCode || null === $location || curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { + // Headers and redirects completed, time to get the response's content + $multi->handlesActivity[$id][] = new FirstChunk(); + + if ('HEAD' === $info['http_method'] || \in_array($statusCode, [204, 304], true)) { + $waitFor = '_0'; // no content expected + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null; + } else { + $waitFor[0] = 'C'; // C = content + } + + curl_setopt($ch, \CURLOPT_PRIVATE, $waitFor); + } elseif (null !== $info['redirect_url'] && $logger) { + $logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url'])); + } + + $location = null; + + return \strlen($data); + } +} diff --git a/vendor/symfony/http-client/Response/HttplugPromise.php b/vendor/symfony/http-client/Response/HttplugPromise.php new file mode 100644 index 000000000..2efacca76 --- /dev/null +++ b/vendor/symfony/http-client/Response/HttplugPromise.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use GuzzleHttp\Promise\Create; +use GuzzleHttp\Promise\PromiseInterface as GuzzlePromiseInterface; +use Http\Promise\Promise as HttplugPromiseInterface; +use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface; + +/** + * @author Tobias Nyholm + * + * @internal + */ +final class HttplugPromise implements HttplugPromiseInterface +{ + private $promise; + + public function __construct(GuzzlePromiseInterface $promise) + { + $this->promise = $promise; + } + + public function then(callable $onFulfilled = null, callable $onRejected = null): self + { + return new self($this->promise->then( + $this->wrapThenCallback($onFulfilled), + $this->wrapThenCallback($onRejected) + )); + } + + public function cancel(): void + { + $this->promise->cancel(); + } + + /** + * {@inheritdoc} + */ + public function getState(): string + { + return $this->promise->getState(); + } + + /** + * {@inheritdoc} + * + * @return Psr7ResponseInterface|mixed + */ + public function wait($unwrap = true) + { + $result = $this->promise->wait($unwrap); + + while ($result instanceof HttplugPromiseInterface || $result instanceof GuzzlePromiseInterface) { + $result = $result->wait($unwrap); + } + + return $result; + } + + private function wrapThenCallback(?callable $callback): ?callable + { + if (null === $callback) { + return null; + } + + return static function ($value) use ($callback) { + return Create::promiseFor($callback($value)); + }; + } +} diff --git a/vendor/symfony/http-client/Response/MockResponse.php b/vendor/symfony/http-client/Response/MockResponse.php new file mode 100644 index 000000000..2c0010875 --- /dev/null +++ b/vendor/symfony/http-client/Response/MockResponse.php @@ -0,0 +1,343 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * A test-friendly response. + * + * @author Nicolas Grekas + */ +class MockResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + use TransportResponseTrait { + doDestruct as public __destruct; + } + + private $body; + private $requestOptions = []; + private $requestUrl; + private $requestMethod; + + private static $mainMulti; + private static $idSequence = 0; + + /** + * @param string|string[]|iterable $body The response body as a string or an iterable of strings, + * yielding an empty string simulates an idle timeout, + * throwing an exception yields an ErrorChunk + * + * @see ResponseInterface::getInfo() for possible info, e.g. "response_headers" + */ + public function __construct($body = '', array $info = []) + { + $this->body = is_iterable($body) ? $body : (string) $body; + $this->info = $info + ['http_code' => 200] + $this->info; + + if (!isset($info['response_headers'])) { + return; + } + + $responseHeaders = []; + + foreach ($info['response_headers'] as $k => $v) { + foreach ((array) $v as $v) { + $responseHeaders[] = (\is_string($k) ? $k.': ' : '').$v; + } + } + + $this->info['response_headers'] = []; + self::addResponseHeaders($responseHeaders, $this->info, $this->headers); + } + + /** + * Returns the options used when doing the request. + */ + public function getRequestOptions(): array + { + return $this->requestOptions; + } + + /** + * Returns the URL used when doing the request. + */ + public function getRequestUrl(): string + { + return $this->requestUrl; + } + + /** + * Returns the method used when doing the request. + */ + public function getRequestMethod(): string + { + return $this->requestMethod; + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + return null !== $type ? $this->info[$type] ?? null : $this->info; + } + + /** + * {@inheritdoc} + */ + public function cancel(): void + { + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + try { + $this->body = null; + } catch (TransportException $e) { + // ignore errors when canceling + } + + $onProgress = $this->requestOptions['on_progress'] ?? static function () {}; + $dlSize = isset($this->headers['content-encoding']) || 'HEAD' === ($this->info['http_method'] ?? null) || \in_array($this->info['http_code'], [204, 304], true) ? 0 : (int) ($this->headers['content-length'][0] ?? 0); + $onProgress($this->offset, $dlSize, $this->info); + } + + /** + * {@inheritdoc} + */ + protected function close(): void + { + $this->inflate = null; + $this->body = []; + } + + /** + * @internal + */ + public static function fromRequest(string $method, string $url, array $options, ResponseInterface $mock): self + { + $response = new self([]); + $response->requestOptions = $options; + $response->id = ++self::$idSequence; + $response->shouldBuffer = $options['buffer'] ?? true; + $response->initializer = static function (self $response) { + return \is_array($response->body[0] ?? null); + }; + + $response->info['redirect_count'] = 0; + $response->info['redirect_url'] = null; + $response->info['start_time'] = microtime(true); + $response->info['http_method'] = $method; + $response->info['http_code'] = 0; + $response->info['user_data'] = $options['user_data'] ?? null; + $response->info['max_duration'] = $options['max_duration'] ?? null; + $response->info['url'] = $url; + + if ($mock instanceof self) { + $mock->requestOptions = $response->requestOptions; + $mock->requestMethod = $method; + $mock->requestUrl = $url; + } + + self::writeRequest($response, $options, $mock); + $response->body[] = [$options, $mock]; + + return $response; + } + + /** + * {@inheritdoc} + */ + protected static function schedule(self $response, array &$runningResponses): void + { + if (!$response->id) { + throw new InvalidArgumentException('MockResponse instances must be issued by MockHttpClient before processing.'); + } + + $multi = self::$mainMulti ?? self::$mainMulti = new ClientState(); + + if (!isset($runningResponses[0])) { + $runningResponses[0] = [$multi, []]; + } + + $runningResponses[0][1][$response->id] = $response; + } + + /** + * {@inheritdoc} + */ + protected static function perform(ClientState $multi, array &$responses): void + { + foreach ($responses as $response) { + $id = $response->id; + + if (null === $response->body) { + // Canceled response + $response->body = []; + } elseif ([] === $response->body) { + // Error chunk + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } elseif (null === $chunk = array_shift($response->body)) { + // Last chunk + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = array_shift($response->body); + } elseif (\is_array($chunk)) { + // First chunk + try { + $offset = 0; + $chunk[1]->getStatusCode(); + $chunk[1]->getHeaders(false); + self::readResponse($response, $chunk[0], $chunk[1], $offset); + $multi->handlesActivity[$id][] = new FirstChunk(); + $buffer = $response->requestOptions['buffer'] ?? null; + + if ($buffer instanceof \Closure && $response->content = $buffer($response->headers) ?: null) { + $response->content = \is_resource($response->content) ? $response->content : fopen('php://temp', 'w+'); + } + } catch (\Throwable $e) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = $e; + } + } elseif ($chunk instanceof \Throwable) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = $chunk; + } else { + // Data or timeout chunk + $multi->handlesActivity[$id][] = $chunk; + } + } + } + + /** + * {@inheritdoc} + */ + protected static function select(ClientState $multi, float $timeout): int + { + return 42; + } + + /** + * Simulates sending the request. + */ + private static function writeRequest(self $response, array $options, ResponseInterface $mock) + { + $onProgress = $options['on_progress'] ?? static function () {}; + $response->info += $mock->getInfo() ?: []; + + // simulate "size_upload" if it is set + if (isset($response->info['size_upload'])) { + $response->info['size_upload'] = 0.0; + } + + // simulate "total_time" if it is not set + if (!isset($response->info['total_time'])) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + } + + // "notify" DNS resolution + $onProgress(0, 0, $response->info); + + // consume the request body + if (\is_resource($body = $options['body'] ?? '')) { + $data = stream_get_contents($body); + if (isset($response->info['size_upload'])) { + $response->info['size_upload'] += \strlen($data); + } + } elseif ($body instanceof \Closure) { + while ('' !== $data = $body(16372)) { + if (!\is_string($data)) { + throw new TransportException(sprintf('Return value of the "body" option callback must be string, "%s" returned.', get_debug_type($data))); + } + + // "notify" upload progress + if (isset($response->info['size_upload'])) { + $response->info['size_upload'] += \strlen($data); + } + + $onProgress(0, 0, $response->info); + } + } + } + + /** + * Simulates reading the response. + */ + private static function readResponse(self $response, array $options, ResponseInterface $mock, int &$offset) + { + $onProgress = $options['on_progress'] ?? static function () {}; + + // populate info related to headers + $info = $mock->getInfo() ?: []; + $response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode() ?: 200; + $response->addResponseHeaders($info['response_headers'] ?? [], $response->info, $response->headers); + $dlSize = isset($response->headers['content-encoding']) || 'HEAD' === $response->info['http_method'] || \in_array($response->info['http_code'], [204, 304], true) ? 0 : (int) ($response->headers['content-length'][0] ?? 0); + + $response->info = [ + 'start_time' => $response->info['start_time'], + 'user_data' => $response->info['user_data'], + 'max_duration' => $response->info['max_duration'], + 'http_code' => $response->info['http_code'], + ] + $info + $response->info; + + if (null !== $response->info['error']) { + throw new TransportException($response->info['error']); + } + + if (!isset($response->info['total_time'])) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + } + + // "notify" headers arrival + $onProgress(0, $dlSize, $response->info); + + // cast response body to activity list + $body = $mock instanceof self ? $mock->body : $mock->getContent(false); + + if (!\is_string($body)) { + try { + foreach ($body as $chunk) { + if ('' === $chunk = (string) $chunk) { + // simulate an idle timeout + $response->body[] = new ErrorChunk($offset, sprintf('Idle timeout reached for "%s".', $response->info['url'])); + } else { + $response->body[] = $chunk; + $offset += \strlen($chunk); + // "notify" download progress + $onProgress($offset, $dlSize, $response->info); + } + } + } catch (\Throwable $e) { + $response->body[] = $e; + } + } elseif ('' !== $body) { + $response->body[] = $body; + $offset = \strlen($body); + } + + if (!isset($response->info['total_time'])) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + } + + // "notify" completion + $onProgress($offset, $dlSize, $response->info); + + if ($dlSize && $offset !== $dlSize) { + throw new TransportException(sprintf('Transfer closed with %d bytes remaining to read.', $dlSize - $offset)); + } + } +} diff --git a/vendor/symfony/http-client/Response/NativeResponse.php b/vendor/symfony/http-client/Response/NativeResponse.php new file mode 100644 index 000000000..c00e946f6 --- /dev/null +++ b/vendor/symfony/http-client/Response/NativeResponse.php @@ -0,0 +1,376 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\Canary; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Component\HttpClient\Internal\NativeClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class NativeResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + use TransportResponseTrait; + + private $context; + private $url; + private $resolver; + private $onProgress; + private $remaining; + private $buffer; + private $multi; + private $pauseExpiry = 0; + + /** + * @internal + */ + public function __construct(NativeClientState $multi, $context, string $url, array $options, array &$info, callable $resolver, ?callable $onProgress, ?LoggerInterface $logger) + { + $this->multi = $multi; + $this->id = $id = (int) $context; + $this->context = $context; + $this->url = $url; + $this->logger = $logger; + $this->timeout = $options['timeout']; + $this->info = &$info; + $this->resolver = $resolver; + $this->onProgress = $onProgress; + $this->inflate = !isset($options['normalized_headers']['accept-encoding']); + $this->shouldBuffer = $options['buffer'] ?? true; + + // Temporary resource to dechunk the response stream + $this->buffer = fopen('php://temp', 'w+'); + + $info['user_data'] = $options['user_data']; + $info['max_duration'] = $options['max_duration']; + ++$multi->responseCount; + + $this->initializer = static function (self $response) { + return null === $response->remaining; + }; + + $pauseExpiry = &$this->pauseExpiry; + $info['pause_handler'] = static function (float $duration) use (&$pauseExpiry) { + $pauseExpiry = 0 < $duration ? microtime(true) + $duration : 0; + }; + + $this->canary = new Canary(static function () use ($multi, $id) { + if (null !== ($host = $multi->openHandles[$id][6] ?? null) && 0 >= --$multi->hosts[$host]) { + unset($multi->hosts[$host]); + } + unset($multi->openHandles[$id], $multi->handlesActivity[$id]); + }); + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + if (!$info = $this->finalInfo) { + $info = $this->info; + $info['url'] = implode('', $info['url']); + unset($info['size_body'], $info['request_header']); + + if (null === $this->buffer) { + $this->finalInfo = $info; + } + } + + return null !== $type ? $info[$type] ?? null : $info; + } + + public function __destruct() + { + try { + $this->doDestruct(); + } finally { + // Clear the DNS cache when all requests completed + if (0 >= --$this->multi->responseCount) { + $this->multi->responseCount = 0; + $this->multi->dnsCache = []; + } + } + } + + private function open(): void + { + $url = $this->url; + + set_error_handler(function ($type, $msg) use (&$url) { + if (\E_NOTICE !== $type || 'fopen(): Content-type not specified assuming application/x-www-form-urlencoded' !== $msg) { + throw new TransportException($msg); + } + + $this->logger && $this->logger->info(sprintf('%s for "%s".', $msg, $url ?? $this->url)); + }); + + try { + $this->info['start_time'] = microtime(true); + + [$resolver, $url] = ($this->resolver)($this->multi); + + while (true) { + $context = stream_context_get_options($this->context); + + if ($proxy = $context['http']['proxy'] ?? null) { + $this->info['debug'] .= "* Establish HTTP proxy tunnel to {$proxy}\n"; + $this->info['request_header'] = $url; + } else { + $this->info['debug'] .= "* Trying {$this->info['primary_ip']}...\n"; + $this->info['request_header'] = $this->info['url']['path'].$this->info['url']['query']; + } + + $this->info['request_header'] = sprintf("> %s %s HTTP/%s \r\n", $context['http']['method'], $this->info['request_header'], $context['http']['protocol_version']); + $this->info['request_header'] .= implode("\r\n", $context['http']['header'])."\r\n\r\n"; + + if (\array_key_exists('peer_name', $context['ssl']) && null === $context['ssl']['peer_name']) { + unset($context['ssl']['peer_name']); + $this->context = stream_context_create([], ['options' => $context] + stream_context_get_params($this->context)); + } + + // Send request and follow redirects when needed + $this->handle = $h = fopen($url, 'r', false, $this->context); + self::addResponseHeaders(stream_get_meta_data($h)['wrapper_data'], $this->info, $this->headers, $this->info['debug']); + $url = $resolver($this->multi, $this->headers['location'][0] ?? null, $this->context); + + if (null === $url) { + break; + } + + $this->logger && $this->logger->info(sprintf('Redirecting: "%s %s"', $this->info['http_code'], $url ?? $this->url)); + } + } catch (\Throwable $e) { + $this->close(); + $this->multi->handlesActivity[$this->id][] = null; + $this->multi->handlesActivity[$this->id][] = $e; + + return; + } finally { + $this->info['pretransfer_time'] = $this->info['total_time'] = microtime(true) - $this->info['start_time']; + restore_error_handler(); + } + + if (isset($context['ssl']['capture_peer_cert_chain']) && isset(($context = stream_context_get_options($this->context))['ssl']['peer_certificate_chain'])) { + $this->info['peer_certificate_chain'] = $context['ssl']['peer_certificate_chain']; + } + + stream_set_blocking($h, false); + $this->context = $this->resolver = null; + + // Create dechunk buffers + if (isset($this->headers['content-length'])) { + $this->remaining = (int) $this->headers['content-length'][0]; + } elseif ('chunked' === ($this->headers['transfer-encoding'][0] ?? null)) { + stream_filter_append($this->buffer, 'dechunk', \STREAM_FILTER_WRITE); + $this->remaining = -1; + } else { + $this->remaining = -2; + } + + $this->multi->handlesActivity[$this->id] = [new FirstChunk()]; + + if ('HEAD' === $context['http']['method'] || \in_array($this->info['http_code'], [204, 304], true)) { + $this->multi->handlesActivity[$this->id][] = null; + $this->multi->handlesActivity[$this->id][] = null; + + return; + } + + $host = parse_url($this->info['redirect_url'] ?? $this->url, \PHP_URL_HOST); + $this->multi->lastTimeout = null; + $this->multi->openHandles[$this->id] = [&$this->pauseExpiry, $h, $this->buffer, $this->onProgress, &$this->remaining, &$this->info, $host]; + $this->multi->hosts[$host] = 1 + ($this->multi->hosts[$host] ?? 0); + } + + /** + * {@inheritdoc} + */ + private function close(): void + { + $this->canary->cancel(); + $this->handle = $this->buffer = $this->inflate = $this->onProgress = null; + } + + /** + * {@inheritdoc} + */ + private static function schedule(self $response, array &$runningResponses): void + { + if (!isset($runningResponses[$i = $response->multi->id])) { + $runningResponses[$i] = [$response->multi, []]; + } + + $runningResponses[$i][1][$response->id] = $response; + + if (null === $response->buffer) { + // Response already completed + $response->multi->handlesActivity[$response->id][] = null; + $response->multi->handlesActivity[$response->id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } + } + + /** + * {@inheritdoc} + * + * @param NativeClientState $multi + */ + private static function perform(ClientState $multi, array &$responses = null): void + { + foreach ($multi->openHandles as $i => [$pauseExpiry, $h, $buffer, $onProgress]) { + if ($pauseExpiry) { + if (microtime(true) < $pauseExpiry) { + continue; + } + + $multi->openHandles[$i][0] = 0; + } + + $hasActivity = false; + $remaining = &$multi->openHandles[$i][4]; + $info = &$multi->openHandles[$i][5]; + $e = null; + + // Read incoming buffer and write it to the dechunk one + try { + if ($remaining && '' !== $data = (string) fread($h, 0 > $remaining ? 16372 : $remaining)) { + fwrite($buffer, $data); + $hasActivity = true; + $multi->sleep = false; + + if (-1 !== $remaining) { + $remaining -= \strlen($data); + } + } + } catch (\Throwable $e) { + $hasActivity = $onProgress = false; + } + + if (!$hasActivity) { + if ($onProgress) { + try { + // Notify the progress callback so that it can e.g. cancel + // the request if the stream is inactive for too long + $info['total_time'] = microtime(true) - $info['start_time']; + $onProgress(); + } catch (\Throwable $e) { + // no-op + } + } + } elseif ('' !== $data = stream_get_contents($buffer, -1, 0)) { + rewind($buffer); + ftruncate($buffer, 0); + + if (null === $e) { + $multi->handlesActivity[$i][] = $data; + } + } + + if (null !== $e || !$remaining || feof($h)) { + // Stream completed + $info['total_time'] = microtime(true) - $info['start_time']; + $info['starttransfer_time'] = $info['starttransfer_time'] ?: $info['total_time']; + + if ($onProgress) { + try { + $onProgress(-1); + } catch (\Throwable $e) { + // no-op + } + } + + if (null === $e) { + if (0 < $remaining) { + $e = new TransportException(sprintf('Transfer closed with %s bytes remaining to read.', $remaining)); + } elseif (-1 === $remaining && fwrite($buffer, '-') && '' !== stream_get_contents($buffer, -1, 0)) { + $e = new TransportException('Transfer closed with outstanding data remaining from chunked response.'); + } + } + + $multi->handlesActivity[$i][] = null; + $multi->handlesActivity[$i][] = $e; + if (null !== ($host = $multi->openHandles[$i][6] ?? null) && 0 >= --$multi->hosts[$host]) { + unset($multi->hosts[$host]); + } + unset($multi->openHandles[$i]); + $multi->sleep = false; + } + } + + if (null === $responses) { + return; + } + + $maxHosts = $multi->maxHostConnections; + + foreach ($responses as $i => $response) { + if (null !== $response->remaining || null === $response->buffer) { + continue; + } + + if ($response->pauseExpiry && microtime(true) < $response->pauseExpiry) { + // Create empty open handles to tell we still have pending requests + $multi->openHandles[$i] = [\INF, null, null, null]; + } elseif ($maxHosts && $maxHosts > ($multi->hosts[parse_url($response->url, \PHP_URL_HOST)] ?? 0)) { + // Open the next pending request - this is a blocking operation so we do only one of them + $response->open(); + $multi->sleep = false; + self::perform($multi); + $maxHosts = 0; + } + } + } + + /** + * {@inheritdoc} + * + * @param NativeClientState $multi + */ + private static function select(ClientState $multi, float $timeout): int + { + if (!$multi->sleep = !$multi->sleep) { + return -1; + } + + $_ = $handles = []; + $now = null; + + foreach ($multi->openHandles as [$pauseExpiry, $h]) { + if (null === $h) { + continue; + } + + if ($pauseExpiry && ($now ?? $now = microtime(true)) < $pauseExpiry) { + $timeout = min($timeout, $pauseExpiry - $now); + continue; + } + + $handles[] = $h; + } + + if (!$handles) { + usleep((int) (1E6 * $timeout)); + + return 0; + } + + return stream_select($handles, $_, $_, (int) $timeout, (int) (1E6 * ($timeout - (int) $timeout))); + } +} diff --git a/vendor/symfony/http-client/Response/ResponseStream.php b/vendor/symfony/http-client/Response/ResponseStream.php new file mode 100644 index 000000000..f86d2d407 --- /dev/null +++ b/vendor/symfony/http-client/Response/ResponseStream.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; + +/** + * @author Nicolas Grekas + */ +final class ResponseStream implements ResponseStreamInterface +{ + private $generator; + + public function __construct(\Generator $generator) + { + $this->generator = $generator; + } + + public function key(): ResponseInterface + { + return $this->generator->key(); + } + + public function current(): ChunkInterface + { + return $this->generator->current(); + } + + public function next(): void + { + $this->generator->next(); + } + + public function rewind(): void + { + $this->generator->rewind(); + } + + public function valid(): bool + { + return $this->generator->valid(); + } +} diff --git a/vendor/symfony/http-client/Response/StreamWrapper.php b/vendor/symfony/http-client/Response/StreamWrapper.php new file mode 100644 index 000000000..50a7c3662 --- /dev/null +++ b/vendor/symfony/http-client/Response/StreamWrapper.php @@ -0,0 +1,313 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * Allows turning ResponseInterface instances to PHP streams. + * + * @author Nicolas Grekas + */ +class StreamWrapper +{ + /** @var resource|null */ + public $context; + + /** @var HttpClientInterface */ + private $client; + + /** @var ResponseInterface */ + private $response; + + /** @var resource|string|null */ + private $content; + + /** @var resource|null */ + private $handle; + + private $blocking = true; + private $timeout; + private $eof = false; + private $offset = 0; + + /** + * Creates a PHP stream resource from a ResponseInterface. + * + * @return resource + */ + public static function createResource(ResponseInterface $response, HttpClientInterface $client = null) + { + if ($response instanceof StreamableInterface) { + $stack = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 2); + + if ($response !== ($stack[1]['object'] ?? null)) { + return $response->toStream(false); + } + } + + if (null === $client && !method_exists($response, 'stream')) { + throw new \InvalidArgumentException(sprintf('Providing a client to "%s()" is required when the response doesn\'t have any "stream()" method.', __CLASS__)); + } + + static $registered = false; + + if (!$registered = $registered || stream_wrapper_register(strtr(__CLASS__, '\\', '-'), __CLASS__)) { + throw new \RuntimeException(error_get_last()['message'] ?? 'Registering the "symfony" stream wrapper failed.'); + } + + $context = [ + 'client' => $client ?? $response, + 'response' => $response, + ]; + + return fopen(strtr(__CLASS__, '\\', '-').'://'.$response->getInfo('url'), 'r', false, stream_context_create(['symfony' => $context])); + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } + + /** + * @param resource|callable|null $handle The resource handle that should be monitored when + * stream_select() is used on the created stream + * @param resource|null $content The seekable resource where the response body is buffered + */ + public function bindHandles(&$handle, &$content): void + { + $this->handle = &$handle; + $this->content = &$content; + $this->offset = null; + } + + public function stream_open(string $path, string $mode, int $options): bool + { + if ('r' !== $mode) { + if ($options & \STREAM_REPORT_ERRORS) { + trigger_error(sprintf('Invalid mode "%s": only "r" is supported.', $mode), \E_USER_WARNING); + } + + return false; + } + + $context = stream_context_get_options($this->context)['symfony'] ?? null; + $this->client = $context['client'] ?? null; + $this->response = $context['response'] ?? null; + $this->context = null; + + if (null !== $this->client && null !== $this->response) { + return true; + } + + if ($options & \STREAM_REPORT_ERRORS) { + trigger_error('Missing options "client" or "response" in "symfony" stream context.', \E_USER_WARNING); + } + + return false; + } + + public function stream_read(int $count) + { + if (\is_resource($this->content)) { + // Empty the internal activity list + foreach ($this->client->stream([$this->response], 0) as $chunk) { + try { + if (!$chunk->isTimeout() && $chunk->isFirst()) { + $this->response->getStatusCode(); // ignore 3/4/5xx + } + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + + return false; + } + } + + if (0 !== fseek($this->content, $this->offset ?? 0)) { + return false; + } + + if ('' !== $data = fread($this->content, $count)) { + fseek($this->content, 0, \SEEK_END); + $this->offset += \strlen($data); + + return $data; + } + } + + if (\is_string($this->content)) { + if (\strlen($this->content) <= $count) { + $data = $this->content; + $this->content = null; + } else { + $data = substr($this->content, 0, $count); + $this->content = substr($this->content, $count); + } + $this->offset += \strlen($data); + + return $data; + } + + foreach ($this->client->stream([$this->response], $this->blocking ? $this->timeout : 0) as $chunk) { + try { + $this->eof = true; + $this->eof = !$chunk->isTimeout(); + + if (!$this->eof && !$this->blocking) { + return ''; + } + + $this->eof = $chunk->isLast(); + + if ($chunk->isFirst()) { + $this->response->getStatusCode(); // ignore 3/4/5xx + } + + if ('' !== $data = $chunk->getContent()) { + if (\strlen($data) > $count) { + if (null === $this->content) { + $this->content = substr($data, $count); + } + $data = substr($data, 0, $count); + } + $this->offset += \strlen($data); + + return $data; + } + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + + return false; + } + } + + return ''; + } + + public function stream_set_option(int $option, int $arg1, ?int $arg2): bool + { + if (\STREAM_OPTION_BLOCKING === $option) { + $this->blocking = (bool) $arg1; + } elseif (\STREAM_OPTION_READ_TIMEOUT === $option) { + $this->timeout = $arg1 + $arg2 / 1e6; + } else { + return false; + } + + return true; + } + + public function stream_tell(): int + { + return $this->offset ?? 0; + } + + public function stream_eof(): bool + { + return $this->eof && !\is_string($this->content); + } + + public function stream_seek(int $offset, int $whence = \SEEK_SET): bool + { + if (null === $this->content && null === $this->offset) { + $this->response->getStatusCode(); + $this->offset = 0; + } + + if (!\is_resource($this->content) || 0 !== fseek($this->content, 0, \SEEK_END)) { + return false; + } + + $size = ftell($this->content); + + if (\SEEK_CUR === $whence) { + $offset += $this->offset ?? 0; + } + + if (\SEEK_END === $whence || $size < $offset) { + foreach ($this->client->stream([$this->response]) as $chunk) { + try { + if ($chunk->isFirst()) { + $this->response->getStatusCode(); // ignore 3/4/5xx + } + + // Chunks are buffered in $this->content already + $size += \strlen($chunk->getContent()); + + if (\SEEK_END !== $whence && $offset <= $size) { + break; + } + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + + return false; + } + } + + if (\SEEK_END === $whence) { + $offset += $size; + } + } + + if (0 <= $offset && $offset <= $size) { + $this->eof = false; + $this->offset = $offset; + + return true; + } + + return false; + } + + public function stream_cast(int $castAs) + { + if (\STREAM_CAST_FOR_SELECT === $castAs) { + $this->response->getHeaders(false); + + return (\is_callable($this->handle) ? ($this->handle)() : $this->handle) ?? false; + } + + return false; + } + + public function stream_stat(): array + { + try { + $headers = $this->response->getHeaders(false); + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + $headers = []; + } + + return [ + 'dev' => 0, + 'ino' => 0, + 'mode' => 33060, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => (int) ($headers['content-length'][0] ?? -1), + 'atime' => 0, + 'mtime' => strtotime($headers['last-modified'][0] ?? '') ?: 0, + 'ctime' => 0, + 'blksize' => 0, + 'blocks' => 0, + ]; + } + + private function __construct() + { + } +} diff --git a/vendor/symfony/http-client/Response/StreamableInterface.php b/vendor/symfony/http-client/Response/StreamableInterface.php new file mode 100644 index 000000000..eb1f9335c --- /dev/null +++ b/vendor/symfony/http-client/Response/StreamableInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Nicolas Grekas + */ +interface StreamableInterface +{ + /** + * Casts the response to a PHP stream resource. + * + * @return resource + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function toStream(bool $throw = true); +} diff --git a/vendor/symfony/http-client/Response/TraceableResponse.php b/vendor/symfony/http-client/Response/TraceableResponse.php new file mode 100644 index 000000000..d656c0a5f --- /dev/null +++ b/vendor/symfony/http-client/Response/TraceableResponse.php @@ -0,0 +1,219 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Exception\ClientException; +use Symfony\Component\HttpClient\Exception\RedirectionException; +use Symfony\Component\HttpClient\Exception\ServerException; +use Symfony\Component\HttpClient\TraceableHttpClient; +use Symfony\Component\Stopwatch\StopwatchEvent; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class TraceableResponse implements ResponseInterface, StreamableInterface +{ + private $client; + private $response; + private $content; + private $event; + + public function __construct(HttpClientInterface $client, ResponseInterface $response, &$content, StopwatchEvent $event = null) + { + $this->client = $client; + $this->response = $response; + $this->content = &$content; + $this->event = $event; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + try { + $this->response->__destruct(); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + } + } + + public function getStatusCode(): int + { + try { + return $this->response->getStatusCode(); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->lap(); + } + } + } + + public function getHeaders(bool $throw = true): array + { + try { + return $this->response->getHeaders($throw); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->lap(); + } + } + } + + public function getContent(bool $throw = true): string + { + try { + if (false === $this->content) { + return $this->response->getContent($throw); + } + + return $this->content = $this->response->getContent(false); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + if ($throw) { + $this->checkStatusCode($this->response->getStatusCode()); + } + } + } + + public function toArray(bool $throw = true): array + { + try { + if (false === $this->content) { + return $this->response->toArray($throw); + } + + return $this->content = $this->response->toArray(false); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + if ($throw) { + $this->checkStatusCode($this->response->getStatusCode()); + } + } + } + + public function cancel(): void + { + $this->response->cancel(); + + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + } + + public function getInfo(string $type = null) + { + return $this->response->getInfo($type); + } + + /** + * Casts the response to a PHP stream resource. + * + * @return resource + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function toStream(bool $throw = true) + { + if ($throw) { + // Ensure headers arrived + $this->response->getHeaders(true); + } + + if ($this->response instanceof StreamableInterface) { + return $this->response->toStream(false); + } + + return StreamWrapper::createResource($this->response, $this->client); + } + + /** + * @internal + */ + public static function stream(HttpClientInterface $client, iterable $responses, ?float $timeout): \Generator + { + $wrappedResponses = []; + $traceableMap = new \SplObjectStorage(); + + foreach ($responses as $r) { + if (!$r instanceof self) { + throw new \TypeError(sprintf('"%s::stream()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', TraceableHttpClient::class, get_debug_type($r))); + } + + $traceableMap[$r->response] = $r; + $wrappedResponses[] = $r->response; + if ($r->event && !$r->event->isStarted()) { + $r->event->start(); + } + } + + foreach ($client->stream($wrappedResponses, $timeout) as $r => $chunk) { + if ($traceableMap[$r]->event && $traceableMap[$r]->event->isStarted()) { + try { + if ($chunk->isTimeout() || !$chunk->isLast()) { + $traceableMap[$r]->event->lap(); + } else { + $traceableMap[$r]->event->stop(); + } + } catch (TransportExceptionInterface $e) { + $traceableMap[$r]->event->stop(); + if ($chunk instanceof ErrorChunk) { + $chunk->didThrow(false); + } else { + $chunk = new ErrorChunk($chunk->getOffset(), $e); + } + } + } + yield $traceableMap[$r] => $chunk; + } + } + + private function checkStatusCode(int $code) + { + if (500 <= $code) { + throw new ServerException($this); + } + + if (400 <= $code) { + throw new ClientException($this); + } + + if (300 <= $code) { + throw new RedirectionException($this); + } + } +} diff --git a/vendor/symfony/http-client/Response/TransportResponseTrait.php b/vendor/symfony/http-client/Response/TransportResponseTrait.php new file mode 100644 index 000000000..566d61e17 --- /dev/null +++ b/vendor/symfony/http-client/Response/TransportResponseTrait.php @@ -0,0 +1,312 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\DataChunk; +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\LastChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\ClientState; + +/** + * Implements common logic for transport-level response classes. + * + * @author Nicolas Grekas + * + * @internal + */ +trait TransportResponseTrait +{ + private $canary; + private $headers = []; + private $info = [ + 'response_headers' => [], + 'http_code' => 0, + 'error' => null, + 'canceled' => false, + ]; + + /** @var object|resource */ + private $handle; + private $id; + private $timeout = 0; + private $inflate; + private $finalInfo; + private $logger; + + /** + * {@inheritdoc} + */ + public function getStatusCode(): int + { + if ($this->initializer) { + self::initialize($this); + } + + return $this->info['http_code']; + } + + /** + * {@inheritdoc} + */ + public function getHeaders(bool $throw = true): array + { + if ($this->initializer) { + self::initialize($this); + } + + if ($throw) { + $this->checkStatusCode(); + } + + return $this->headers; + } + + /** + * {@inheritdoc} + */ + public function cancel(): void + { + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + $this->close(); + } + + /** + * Closes the response and all its network handles. + */ + protected function close(): void + { + $this->canary->cancel(); + $this->inflate = null; + } + + /** + * Adds pending responses to the activity list. + */ + abstract protected static function schedule(self $response, array &$runningResponses): void; + + /** + * Performs all pending non-blocking operations. + */ + abstract protected static function perform(ClientState $multi, array &$responses): void; + + /** + * Waits for network activity. + */ + abstract protected static function select(ClientState $multi, float $timeout): int; + + private static function addResponseHeaders(array $responseHeaders, array &$info, array &$headers, string &$debug = ''): void + { + foreach ($responseHeaders as $h) { + if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? (\d\d\d)(?: |$)#', $h, $m)) { + if ($headers) { + $debug .= "< \r\n"; + $headers = []; + } + $info['http_code'] = (int) $m[1]; + } elseif (2 === \count($m = explode(':', $h, 2))) { + $headers[strtolower($m[0])][] = ltrim($m[1]); + } + + $debug .= "< {$h}\r\n"; + $info['response_headers'][] = $h; + } + + $debug .= "< \r\n"; + } + + /** + * Ensures the request is always sent and that the response code was checked. + */ + private function doDestruct() + { + $this->shouldBuffer = true; + + if ($this->initializer && null === $this->info['error']) { + self::initialize($this); + $this->checkStatusCode(); + } + } + + /** + * Implements an event loop based on a buffer activity queue. + * + * @param iterable $responses + * + * @internal + */ + public static function stream(iterable $responses, float $timeout = null): \Generator + { + $runningResponses = []; + + foreach ($responses as $response) { + self::schedule($response, $runningResponses); + } + + $lastActivity = microtime(true); + $elapsedTimeout = 0; + + if ($fromLastTimeout = 0.0 === $timeout && '-0' === (string) $timeout) { + $timeout = null; + } elseif ($fromLastTimeout = 0 > $timeout) { + $timeout = -$timeout; + } + + while (true) { + $hasActivity = false; + $timeoutMax = 0; + $timeoutMin = $timeout ?? \INF; + + /** @var ClientState $multi */ + foreach ($runningResponses as $i => [$multi]) { + $responses = &$runningResponses[$i][1]; + self::perform($multi, $responses); + + foreach ($responses as $j => $response) { + $timeoutMax = $timeout ?? max($timeoutMax, $response->timeout); + $timeoutMin = min($timeoutMin, $response->timeout, 1); + $chunk = false; + + if ($fromLastTimeout && null !== $multi->lastTimeout) { + $elapsedTimeout = microtime(true) - $multi->lastTimeout; + } + + if (isset($multi->handlesActivity[$j])) { + $multi->lastTimeout = null; + } elseif (!isset($multi->openHandles[$j])) { + unset($responses[$j]); + continue; + } elseif ($elapsedTimeout >= $timeoutMax) { + $multi->handlesActivity[$j] = [new ErrorChunk($response->offset, sprintf('Idle timeout reached for "%s".', $response->getInfo('url')))]; + $multi->lastTimeout ?? $multi->lastTimeout = $lastActivity; + } else { + continue; + } + + while ($multi->handlesActivity[$j] ?? false) { + $hasActivity = true; + $elapsedTimeout = 0; + + if (\is_string($chunk = array_shift($multi->handlesActivity[$j]))) { + if (null !== $response->inflate && false === $chunk = @inflate_add($response->inflate, $chunk)) { + $multi->handlesActivity[$j] = [null, new TransportException(sprintf('Error while processing content unencoding for "%s".', $response->getInfo('url')))]; + continue; + } + + if ('' !== $chunk && null !== $response->content && \strlen($chunk) !== fwrite($response->content, $chunk)) { + $multi->handlesActivity[$j] = [null, new TransportException(sprintf('Failed writing %d bytes to the response buffer.', \strlen($chunk)))]; + continue; + } + + $chunkLen = \strlen($chunk); + $chunk = new DataChunk($response->offset, $chunk); + $response->offset += $chunkLen; + } elseif (null === $chunk) { + $e = $multi->handlesActivity[$j][0]; + unset($responses[$j], $multi->handlesActivity[$j]); + $response->close(); + + if (null !== $e) { + $response->info['error'] = $e->getMessage(); + + if ($e instanceof \Error) { + throw $e; + } + + $chunk = new ErrorChunk($response->offset, $e); + } else { + if (0 === $response->offset && null === $response->content) { + $response->content = fopen('php://memory', 'w+'); + } + + $chunk = new LastChunk($response->offset); + } + } elseif ($chunk instanceof ErrorChunk) { + unset($responses[$j]); + $elapsedTimeout = $timeoutMax; + } elseif ($chunk instanceof FirstChunk) { + if ($response->logger) { + $info = $response->getInfo(); + $response->logger->info(sprintf('Response: "%s %s"', $info['http_code'], $info['url'])); + } + + $response->inflate = \extension_loaded('zlib') && $response->inflate && 'gzip' === ($response->headers['content-encoding'][0] ?? null) ? inflate_init(\ZLIB_ENCODING_GZIP) : null; + + if ($response->shouldBuffer instanceof \Closure) { + try { + $response->shouldBuffer = ($response->shouldBuffer)($response->headers); + + if (null !== $response->info['error']) { + throw new TransportException($response->info['error']); + } + } catch (\Throwable $e) { + $response->close(); + $multi->handlesActivity[$j] = [null, $e]; + } + } + + if (true === $response->shouldBuffer) { + $response->content = fopen('php://temp', 'w+'); + } elseif (\is_resource($response->shouldBuffer)) { + $response->content = $response->shouldBuffer; + } + $response->shouldBuffer = null; + + yield $response => $chunk; + + if ($response->initializer && null === $response->info['error']) { + // Ensure the HTTP status code is always checked + $response->getHeaders(true); + } + + continue; + } + + yield $response => $chunk; + } + + unset($multi->handlesActivity[$j]); + + if ($chunk instanceof ErrorChunk && !$chunk->didThrow()) { + // Ensure transport exceptions are always thrown + $chunk->getContent(); + } + } + + if (!$responses) { + unset($runningResponses[$i]); + } + + // Prevent memory leaks + $multi->handlesActivity = $multi->handlesActivity ?: []; + $multi->openHandles = $multi->openHandles ?: []; + } + + if (!$runningResponses) { + break; + } + + if ($hasActivity) { + $lastActivity = microtime(true); + continue; + } + + if (-1 === self::select($multi, min($timeoutMin, $timeoutMax - $elapsedTimeout))) { + usleep(min(500, 1E6 * $timeoutMin)); + } + + $elapsedTimeout = microtime(true) - $lastActivity; + } + } +} diff --git a/vendor/symfony/http-client/Retry/GenericRetryStrategy.php b/vendor/symfony/http-client/Retry/GenericRetryStrategy.php new file mode 100644 index 000000000..3241a5eb2 --- /dev/null +++ b/vendor/symfony/http-client/Retry/GenericRetryStrategy.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Retry; + +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * Decides to retry the request when HTTP status codes belong to the given list of codes. + * + * @author Jérémy Derussé + */ +class GenericRetryStrategy implements RetryStrategyInterface +{ + public const IDEMPOTENT_METHODS = ['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']; + public const DEFAULT_RETRY_STATUS_CODES = [ + 0 => self::IDEMPOTENT_METHODS, // for transport exceptions + 423, + 425, + 429, + 500 => self::IDEMPOTENT_METHODS, + 502, + 503, + 504 => self::IDEMPOTENT_METHODS, + 507 => self::IDEMPOTENT_METHODS, + 510 => self::IDEMPOTENT_METHODS, + ]; + + private $statusCodes; + private $delayMs; + private $multiplier; + private $maxDelayMs; + private $jitter; + + /** + * @param array $statusCodes List of HTTP status codes that trigger a retry + * @param int $delayMs Amount of time to delay (or the initial value when multiplier is used) + * @param float $multiplier Multiplier to apply to the delay each time a retry occurs + * @param int $maxDelayMs Maximum delay to allow (0 means no maximum) + * @param float $jitter Probability of randomness int delay (0 = none, 1 = 100% random) + */ + public function __construct(array $statusCodes = self::DEFAULT_RETRY_STATUS_CODES, int $delayMs = 1000, float $multiplier = 2.0, int $maxDelayMs = 0, float $jitter = 0.1) + { + $this->statusCodes = $statusCodes; + + if ($delayMs < 0) { + throw new InvalidArgumentException(sprintf('Delay must be greater than or equal to zero: "%s" given.', $delayMs)); + } + $this->delayMs = $delayMs; + + if ($multiplier < 1) { + throw new InvalidArgumentException(sprintf('Multiplier must be greater than or equal to one: "%s" given.', $multiplier)); + } + $this->multiplier = $multiplier; + + if ($maxDelayMs < 0) { + throw new InvalidArgumentException(sprintf('Max delay must be greater than or equal to zero: "%s" given.', $maxDelayMs)); + } + $this->maxDelayMs = $maxDelayMs; + + if ($jitter < 0 || $jitter > 1) { + throw new InvalidArgumentException(sprintf('Jitter must be between 0 and 1: "%s" given.', $jitter)); + } + $this->jitter = $jitter; + } + + public function shouldRetry(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): ?bool + { + $statusCode = $context->getStatusCode(); + if (\in_array($statusCode, $this->statusCodes, true)) { + return true; + } + if (isset($this->statusCodes[$statusCode]) && \is_array($this->statusCodes[$statusCode])) { + return \in_array($context->getInfo('http_method'), $this->statusCodes[$statusCode], true); + } + if (null === $exception) { + return false; + } + + if (\in_array(0, $this->statusCodes, true)) { + return true; + } + if (isset($this->statusCodes[0]) && \is_array($this->statusCodes[0])) { + return \in_array($context->getInfo('http_method'), $this->statusCodes[0], true); + } + + return false; + } + + public function getDelay(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): int + { + $delay = $this->delayMs * $this->multiplier ** $context->getInfo('retry_count'); + + if ($this->jitter > 0) { + $randomness = (int) ($delay * $this->jitter); + $delay = $delay + random_int(-$randomness, +$randomness); + } + + if ($delay > $this->maxDelayMs && 0 !== $this->maxDelayMs) { + return $this->maxDelayMs; + } + + return (int) $delay; + } +} diff --git a/vendor/symfony/http-client/Retry/RetryStrategyInterface.php b/vendor/symfony/http-client/Retry/RetryStrategyInterface.php new file mode 100644 index 000000000..25764336e --- /dev/null +++ b/vendor/symfony/http-client/Retry/RetryStrategyInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Retry; + +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Jérémy Derussé + * @author Nicolas Grekas + */ +interface RetryStrategyInterface +{ + /** + * Returns whether the request should be retried. + * + * @param ?string $responseContent Null is passed when the body did not arrive yet + * + * @return bool|null Returns null to signal that the body is required to take a decision + */ + public function shouldRetry(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): ?bool; + + /** + * Returns the time to wait in milliseconds. + */ + public function getDelay(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): int; +} diff --git a/vendor/symfony/http-client/RetryableHttpClient.php b/vendor/symfony/http-client/RetryableHttpClient.php new file mode 100644 index 000000000..bec13784b --- /dev/null +++ b/vendor/symfony/http-client/RetryableHttpClient.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Component\HttpClient\Response\AsyncResponse; +use Symfony\Component\HttpClient\Retry\GenericRetryStrategy; +use Symfony\Component\HttpClient\Retry\RetryStrategyInterface; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Automatically retries failing HTTP requests. + * + * @author Jérémy Derussé + */ +class RetryableHttpClient implements HttpClientInterface, ResetInterface +{ + use AsyncDecoratorTrait; + + private $strategy; + private $maxRetries; + private $logger; + + /** + * @param int $maxRetries The maximum number of times to retry + */ + public function __construct(HttpClientInterface $client, RetryStrategyInterface $strategy = null, int $maxRetries = 3, LoggerInterface $logger = null) + { + $this->client = $client; + $this->strategy = $strategy ?? new GenericRetryStrategy(); + $this->maxRetries = $maxRetries; + $this->logger = $logger ?? new NullLogger(); + } + + public function request(string $method, string $url, array $options = []): ResponseInterface + { + if ($this->maxRetries <= 0) { + return new AsyncResponse($this->client, $method, $url, $options); + } + + $retryCount = 0; + $content = ''; + $firstChunk = null; + + return new AsyncResponse($this->client, $method, $url, $options, function (ChunkInterface $chunk, AsyncContext $context) use ($method, $url, $options, &$retryCount, &$content, &$firstChunk) { + $exception = null; + try { + if ($context->getInfo('canceled') || $chunk->isTimeout() || null !== $chunk->getInformationalStatus()) { + yield $chunk; + + return; + } + } catch (TransportExceptionInterface $exception) { + // catch TransportExceptionInterface to send it to the strategy + } + if (null !== $exception) { + // always retry request that fail to resolve DNS + if ('' !== $context->getInfo('primary_ip')) { + $shouldRetry = $this->strategy->shouldRetry($context, null, $exception); + if (null === $shouldRetry) { + throw new \LogicException(sprintf('The "%s::shouldRetry()" method must not return null when called with an exception.', \get_class($this->strategy))); + } + + if (false === $shouldRetry) { + yield from $this->passthru($context, $firstChunk, $content, $chunk); + + return; + } + } + } elseif ($chunk->isFirst()) { + if (false === $shouldRetry = $this->strategy->shouldRetry($context, null, null)) { + yield from $this->passthru($context, $firstChunk, $content, $chunk); + + return; + } + + // Body is needed to decide + if (null === $shouldRetry) { + $firstChunk = $chunk; + $content = ''; + + return; + } + } else { + if (!$chunk->isLast()) { + $content .= $chunk->getContent(); + + return; + } + + if (null === $shouldRetry = $this->strategy->shouldRetry($context, $content, null)) { + throw new \LogicException(sprintf('The "%s::shouldRetry()" method must not return null when called with a body.', \get_class($this->strategy))); + } + + if (false === $shouldRetry) { + yield from $this->passthru($context, $firstChunk, $content, $chunk); + + return; + } + } + + $context->getResponse()->cancel(); + + $delay = $this->getDelayFromHeader($context->getHeaders()) ?? $this->strategy->getDelay($context, !$exception && $chunk->isLast() ? $content : null, $exception); + ++$retryCount; + $content = ''; + $firstChunk = null; + + $this->logger->info('Try #{count} after {delay}ms'.($exception ? ': '.$exception->getMessage() : ', status code: '.$context->getStatusCode()), [ + 'count' => $retryCount, + 'delay' => $delay, + ]); + + $context->setInfo('retry_count', $retryCount); + $context->replaceRequest($method, $url, $options); + $context->pause($delay / 1000); + + if ($retryCount >= $this->maxRetries) { + $context->passthru(); + } + }); + } + + private function getDelayFromHeader(array $headers): ?int + { + if (null !== $after = $headers['retry-after'][0] ?? null) { + if (is_numeric($after)) { + return (int) ($after * 1000); + } + + if (false !== $time = strtotime($after)) { + return max(0, $time - time()) * 1000; + } + } + + return null; + } + + private function passthru(AsyncContext $context, ?ChunkInterface $firstChunk, string &$content, ChunkInterface $lastChunk): \Generator + { + $context->passthru(); + + if (null !== $firstChunk) { + yield $firstChunk; + } + + if ('' !== $content) { + $chunk = $context->createChunk($content); + $content = ''; + + yield $chunk; + } + + yield $lastChunk; + } +} diff --git a/vendor/symfony/http-client/ScopingHttpClient.php b/vendor/symfony/http-client/ScopingHttpClient.php new file mode 100644 index 000000000..85fa26acd --- /dev/null +++ b/vendor/symfony/http-client/ScopingHttpClient.php @@ -0,0 +1,131 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Auto-configure the default options based on the requested URL. + * + * @author Anthony Martin + */ +class ScopingHttpClient implements HttpClientInterface, ResetInterface, LoggerAwareInterface +{ + use HttpClientTrait; + + private $client; + private $defaultOptionsByRegexp; + private $defaultRegexp; + + public function __construct(HttpClientInterface $client, array $defaultOptionsByRegexp, string $defaultRegexp = null) + { + $this->client = $client; + $this->defaultOptionsByRegexp = $defaultOptionsByRegexp; + $this->defaultRegexp = $defaultRegexp; + + if (null !== $defaultRegexp && !isset($defaultOptionsByRegexp[$defaultRegexp])) { + throw new InvalidArgumentException(sprintf('No options are mapped to the provided "%s" default regexp.', $defaultRegexp)); + } + } + + public static function forBaseUri(HttpClientInterface $client, string $baseUri, array $defaultOptions = [], string $regexp = null): self + { + if (null === $regexp) { + $regexp = preg_quote(implode('', self::resolveUrl(self::parseUrl('.'), self::parseUrl($baseUri)))); + } + + $defaultOptions['base_uri'] = $baseUri; + + return new self($client, [$regexp => $defaultOptions], $regexp); + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $e = null; + $url = self::parseUrl($url, $options['query'] ?? []); + + if (\is_string($options['base_uri'] ?? null)) { + $options['base_uri'] = self::parseUrl($options['base_uri']); + } + + try { + $url = implode('', self::resolveUrl($url, $options['base_uri'] ?? null)); + } catch (InvalidArgumentException $e) { + if (null === $this->defaultRegexp) { + throw $e; + } + + $defaultOptions = $this->defaultOptionsByRegexp[$this->defaultRegexp]; + $options = self::mergeDefaultOptions($options, $defaultOptions, true); + if (\is_string($options['base_uri'] ?? null)) { + $options['base_uri'] = self::parseUrl($options['base_uri']); + } + $url = implode('', self::resolveUrl($url, $options['base_uri'] ?? null, $defaultOptions['query'] ?? [])); + } + + foreach ($this->defaultOptionsByRegexp as $regexp => $defaultOptions) { + if (preg_match("{{$regexp}}A", $url)) { + if (null === $e || $regexp !== $this->defaultRegexp) { + $options = self::mergeDefaultOptions($options, $defaultOptions, true); + } + break; + } + } + + return $this->client->request($method, $url, $options); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->client->stream($responses, $timeout); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } + + /** + * {@inheritdoc} + */ + public function setLogger(LoggerInterface $logger): void + { + if ($this->client instanceof LoggerAwareInterface) { + $this->client->setLogger($logger); + } + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } +} diff --git a/vendor/symfony/http-client/TraceableHttpClient.php b/vendor/symfony/http-client/TraceableHttpClient.php new file mode 100644 index 000000000..76c928224 --- /dev/null +++ b/vendor/symfony/http-client/TraceableHttpClient.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Component\HttpClient\Response\TraceableResponse; +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * @author Jérémy Romey + */ +final class TraceableHttpClient implements HttpClientInterface, ResetInterface, LoggerAwareInterface +{ + private $client; + private $stopwatch; + private $tracedRequests; + + public function __construct(HttpClientInterface $client, Stopwatch $stopwatch = null) + { + $this->client = $client; + $this->stopwatch = $stopwatch; + $this->tracedRequests = new \ArrayObject(); + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $content = null; + $traceInfo = []; + $this->tracedRequests[] = [ + 'method' => $method, + 'url' => $url, + 'options' => $options, + 'info' => &$traceInfo, + 'content' => &$content, + ]; + $onProgress = $options['on_progress'] ?? null; + + if (false === ($options['extra']['trace_content'] ?? true)) { + unset($content); + $content = false; + } + + $options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use (&$traceInfo, $onProgress) { + $traceInfo = $info; + + if (null !== $onProgress) { + $onProgress($dlNow, $dlSize, $info); + } + }; + + return new TraceableResponse($this->client, $this->client->request($method, $url, $options), $content, null === $this->stopwatch ? null : $this->stopwatch->start("$method $url", 'http_client')); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof TraceableResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(TraceableResponse::stream($this->client, $responses, $timeout)); + } + + public function getTracedRequests(): array + { + return $this->tracedRequests->getArrayCopy(); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + + $this->tracedRequests->exchangeArray([]); + } + + /** + * {@inheritdoc} + */ + public function setLogger(LoggerInterface $logger): void + { + if ($this->client instanceof LoggerAwareInterface) { + $this->client->setLogger($logger); + } + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } +} diff --git a/vendor/symfony/http-client/composer.json b/vendor/symfony/http-client/composer.json new file mode 100644 index 000000000..7f546b3a2 --- /dev/null +++ b/vendor/symfony/http-client/composer.json @@ -0,0 +1,55 @@ +{ + "name": "symfony/http-client", + "type": "library", + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "keywords": ["http"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "2.4" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.4", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\HttpClient\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/vendor/symfony/polyfill-php73/LICENSE b/vendor/symfony/polyfill-php73/LICENSE new file mode 100644 index 000000000..7536caeae --- /dev/null +++ b/vendor/symfony/polyfill-php73/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-php73/Php73.php b/vendor/symfony/polyfill-php73/Php73.php new file mode 100644 index 000000000..65c35a6a1 --- /dev/null +++ b/vendor/symfony/polyfill-php73/Php73.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php73; + +/** + * @author Gabriel Caruso + * @author Ion Bazan + * + * @internal + */ +final class Php73 +{ + public static $startAt = 1533462603; + + /** + * @param bool $asNum + * + * @return array|float|int + */ + public static function hrtime($asNum = false) + { + $ns = microtime(false); + $s = substr($ns, 11) - self::$startAt; + $ns = 1E9 * (float) $ns; + + if ($asNum) { + $ns += $s * 1E9; + + return \PHP_INT_SIZE === 4 ? $ns : (int) $ns; + } + + return [$s, (int) $ns]; + } +} diff --git a/vendor/symfony/polyfill-php73/README.md b/vendor/symfony/polyfill-php73/README.md new file mode 100644 index 000000000..032fafbda --- /dev/null +++ b/vendor/symfony/polyfill-php73/README.md @@ -0,0 +1,18 @@ +Symfony Polyfill / Php73 +======================== + +This component provides functions added to PHP 7.3 core: + +- [`array_key_first`](https://php.net/array_key_first) +- [`array_key_last`](https://php.net/array_key_last) +- [`hrtime`](https://php.net/function.hrtime) +- [`is_countable`](https://php.net/is_countable) +- [`JsonException`](https://php.net/JsonException) + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php b/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php new file mode 100644 index 000000000..f06d6c269 --- /dev/null +++ b/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 70300) { + class JsonException extends Exception + { + } +} diff --git a/vendor/symfony/polyfill-php73/bootstrap.php b/vendor/symfony/polyfill-php73/bootstrap.php new file mode 100644 index 000000000..d6b215382 --- /dev/null +++ b/vendor/symfony/polyfill-php73/bootstrap.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php73 as p; + +if (\PHP_VERSION_ID >= 70300) { + return; +} + +if (!function_exists('is_countable')) { + function is_countable($value) { return is_array($value) || $value instanceof Countable || $value instanceof ResourceBundle || $value instanceof SimpleXmlElement; } +} +if (!function_exists('hrtime')) { + require_once __DIR__.'/Php73.php'; + p\Php73::$startAt = (int) microtime(true); + function hrtime($as_number = false) { return p\Php73::hrtime($as_number); } +} +if (!function_exists('array_key_first')) { + function array_key_first(array $array) { foreach ($array as $key => $value) { return $key; } } +} +if (!function_exists('array_key_last')) { + function array_key_last(array $array) { return key(array_slice($array, -1, 1, true)); } +} diff --git a/vendor/symfony/polyfill-php73/composer.json b/vendor/symfony/polyfill-php73/composer.json new file mode 100644 index 000000000..48295ef97 --- /dev/null +++ b/vendor/symfony/polyfill-php73/composer.json @@ -0,0 +1,36 @@ +{ + "name": "symfony/polyfill-php73", + "type": "library", + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php73\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/vendor/symfony/polyfill-php80/LICENSE b/vendor/symfony/polyfill-php80/LICENSE new file mode 100644 index 000000000..0ed3a2465 --- /dev/null +++ b/vendor/symfony/polyfill-php80/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-php80/Php80.php b/vendor/symfony/polyfill-php80/Php80.php new file mode 100644 index 000000000..362dd1a95 --- /dev/null +++ b/vendor/symfony/polyfill-php80/Php80.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php80; + +/** + * @author Ion Bazan + * @author Nico Oelgart + * @author Nicolas Grekas + * + * @internal + */ +final class Php80 +{ + public static function fdiv(float $dividend, float $divisor): float + { + return @($dividend / $divisor); + } + + public static function get_debug_type($value): string + { + switch (true) { + case null === $value: return 'null'; + case \is_bool($value): return 'bool'; + case \is_string($value): return 'string'; + case \is_array($value): return 'array'; + case \is_int($value): return 'int'; + case \is_float($value): return 'float'; + case \is_object($value): break; + case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class'; + default: + if (null === $type = @get_resource_type($value)) { + return 'unknown'; + } + + if ('Unknown' === $type) { + $type = 'closed'; + } + + return "resource ($type)"; + } + + $class = \get_class($value); + + if (false === strpos($class, '@')) { + return $class; + } + + return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous'; + } + + public static function get_resource_id($res): int + { + if (!\is_resource($res) && null === @get_resource_type($res)) { + throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res))); + } + + return (int) $res; + } + + public static function preg_last_error_msg(): string + { + switch (preg_last_error()) { + case \PREG_INTERNAL_ERROR: + return 'Internal error'; + case \PREG_BAD_UTF8_ERROR: + return 'Malformed UTF-8 characters, possibly incorrectly encoded'; + case \PREG_BAD_UTF8_OFFSET_ERROR: + return 'The offset did not correspond to the beginning of a valid UTF-8 code point'; + case \PREG_BACKTRACK_LIMIT_ERROR: + return 'Backtrack limit exhausted'; + case \PREG_RECURSION_LIMIT_ERROR: + return 'Recursion limit exhausted'; + case \PREG_JIT_STACKLIMIT_ERROR: + return 'JIT stack limit exhausted'; + case \PREG_NO_ERROR: + return 'No error'; + default: + return 'Unknown error'; + } + } + + public static function str_contains(string $haystack, string $needle): bool + { + return '' === $needle || false !== strpos($haystack, $needle); + } + + public static function str_starts_with(string $haystack, string $needle): bool + { + return 0 === strncmp($haystack, $needle, \strlen($needle)); + } + + public static function str_ends_with(string $haystack, string $needle): bool + { + if ('' === $needle || $needle === $haystack) { + return true; + } + + if ('' === $haystack) { + return false; + } + + $needleLength = \strlen($needle); + + return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength); + } +} diff --git a/vendor/symfony/polyfill-php80/PhpToken.php b/vendor/symfony/polyfill-php80/PhpToken.php new file mode 100644 index 000000000..fe6e69105 --- /dev/null +++ b/vendor/symfony/polyfill-php80/PhpToken.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php80; + +/** + * @author Fedonyuk Anton + * + * @internal + */ +class PhpToken implements \Stringable +{ + /** + * @var int + */ + public $id; + + /** + * @var string + */ + public $text; + + /** + * @var int + */ + public $line; + + /** + * @var int + */ + public $pos; + + public function __construct(int $id, string $text, int $line = -1, int $position = -1) + { + $this->id = $id; + $this->text = $text; + $this->line = $line; + $this->pos = $position; + } + + public function getTokenName(): ?string + { + if ('UNKNOWN' === $name = token_name($this->id)) { + $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text; + } + + return $name; + } + + /** + * @param int|string|array $kind + */ + public function is($kind): bool + { + foreach ((array) $kind as $value) { + if (\in_array($value, [$this->id, $this->text], true)) { + return true; + } + } + + return false; + } + + public function isIgnorable(): bool + { + return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true); + } + + public function __toString(): string + { + return (string) $this->text; + } + + /** + * @return static[] + */ + public static function tokenize(string $code, int $flags = 0): array + { + $line = 1; + $position = 0; + $tokens = token_get_all($code, $flags); + foreach ($tokens as $index => $token) { + if (\is_string($token)) { + $id = \ord($token); + $text = $token; + } else { + [$id, $text, $line] = $token; + } + $tokens[$index] = new static($id, $text, $line, $position); + $position += \strlen($text); + } + + return $tokens; + } +} diff --git a/vendor/symfony/polyfill-php80/README.md b/vendor/symfony/polyfill-php80/README.md new file mode 100644 index 000000000..3816c559d --- /dev/null +++ b/vendor/symfony/polyfill-php80/README.md @@ -0,0 +1,25 @@ +Symfony Polyfill / Php80 +======================== + +This component provides features added to PHP 8.0 core: + +- [`Stringable`](https://php.net/stringable) interface +- [`fdiv`](https://php.net/fdiv) +- [`ValueError`](https://php.net/valueerror) class +- [`UnhandledMatchError`](https://php.net/unhandledmatcherror) class +- `FILTER_VALIDATE_BOOL` constant +- [`get_debug_type`](https://php.net/get_debug_type) +- [`PhpToken`](https://php.net/phptoken) class +- [`preg_last_error_msg`](https://php.net/preg_last_error_msg) +- [`str_contains`](https://php.net/str_contains) +- [`str_starts_with`](https://php.net/str_starts_with) +- [`str_ends_with`](https://php.net/str_ends_with) +- [`get_resource_id`](https://php.net/get_resource_id) + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php new file mode 100644 index 000000000..2b955423f --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#[Attribute(Attribute::TARGET_CLASS)] +final class Attribute +{ + public const TARGET_CLASS = 1; + public const TARGET_FUNCTION = 2; + public const TARGET_METHOD = 4; + public const TARGET_PROPERTY = 8; + public const TARGET_CLASS_CONSTANT = 16; + public const TARGET_PARAMETER = 32; + public const TARGET_ALL = 63; + public const IS_REPEATABLE = 64; + + /** @var int */ + public $flags; + + public function __construct(int $flags = self::TARGET_ALL) + { + $this->flags = $flags; + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php new file mode 100644 index 000000000..bd1212f6e --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) { + class PhpToken extends Symfony\Polyfill\Php80\PhpToken + { + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php new file mode 100644 index 000000000..7c62d7508 --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + interface Stringable + { + /** + * @return string + */ + public function __toString(); + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php new file mode 100644 index 000000000..01c6c6c8a --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + class UnhandledMatchError extends Error + { + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php new file mode 100644 index 000000000..783dbc28c --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + class ValueError extends Error + { + } +} diff --git a/vendor/symfony/polyfill-php80/bootstrap.php b/vendor/symfony/polyfill-php80/bootstrap.php new file mode 100644 index 000000000..e5f7dbc1a --- /dev/null +++ b/vendor/symfony/polyfill-php80/bootstrap.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php80 as p; + +if (\PHP_VERSION_ID >= 80000) { + return; +} + +if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) { + define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN); +} + +if (!function_exists('fdiv')) { + function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); } +} +if (!function_exists('preg_last_error_msg')) { + function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); } +} +if (!function_exists('str_contains')) { + function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('str_starts_with')) { + function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('str_ends_with')) { + function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('get_debug_type')) { + function get_debug_type($value): string { return p\Php80::get_debug_type($value); } +} +if (!function_exists('get_resource_id')) { + function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); } +} diff --git a/vendor/symfony/polyfill-php80/composer.json b/vendor/symfony/polyfill-php80/composer.json new file mode 100644 index 000000000..f1801f403 --- /dev/null +++ b/vendor/symfony/polyfill-php80/composer.json @@ -0,0 +1,40 @@ +{ + "name": "symfony/polyfill-php80", + "type": "library", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/vendor/symfony/service-contracts/.gitignore b/vendor/symfony/service-contracts/.gitignore new file mode 100644 index 000000000..c49a5d8df --- /dev/null +++ b/vendor/symfony/service-contracts/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/vendor/symfony/service-contracts/Attribute/Required.php b/vendor/symfony/service-contracts/Attribute/Required.php new file mode 100644 index 000000000..9df851189 --- /dev/null +++ b/vendor/symfony/service-contracts/Attribute/Required.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Attribute; + +/** + * A required dependency. + * + * This attribute indicates that a property holds a required dependency. The annotated property or method should be + * considered during the instantiation process of the containing class. + * + * @author Alexander M. Turek + */ +#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)] +final class Required +{ +} diff --git a/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/vendor/symfony/service-contracts/Attribute/SubscribedService.php new file mode 100644 index 000000000..10d1bc38e --- /dev/null +++ b/vendor/symfony/service-contracts/Attribute/SubscribedService.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Attribute; + +use Symfony\Contracts\Service\ServiceSubscriberTrait; + +/** + * Use with {@see ServiceSubscriberTrait} to mark a method's return type + * as a subscribed service. + * + * @author Kevin Bond + */ +#[\Attribute(\Attribute::TARGET_METHOD)] +final class SubscribedService +{ + /** + * @param string|null $key The key to use for the service + * If null, use "ClassName::methodName" + */ + public function __construct( + public ?string $key = null + ) { + } +} diff --git a/vendor/symfony/service-contracts/CHANGELOG.md b/vendor/symfony/service-contracts/CHANGELOG.md new file mode 100644 index 000000000..7932e2613 --- /dev/null +++ b/vendor/symfony/service-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/vendor/symfony/service-contracts/LICENSE b/vendor/symfony/service-contracts/LICENSE new file mode 100644 index 000000000..74cdc2dbf --- /dev/null +++ b/vendor/symfony/service-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/service-contracts/README.md b/vendor/symfony/service-contracts/README.md new file mode 100644 index 000000000..41e054a10 --- /dev/null +++ b/vendor/symfony/service-contracts/README.md @@ -0,0 +1,9 @@ +Symfony Service Contracts +========================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful - and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/main/README.md for more information. diff --git a/vendor/symfony/service-contracts/ResetInterface.php b/vendor/symfony/service-contracts/ResetInterface.php new file mode 100644 index 000000000..1af1075ee --- /dev/null +++ b/vendor/symfony/service-contracts/ResetInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * Provides a way to reset an object to its initial state. + * + * When calling the "reset()" method on an object, it should be put back to its + * initial state. This usually means clearing any internal buffers and forwarding + * the call to internal dependencies. All properties of the object should be put + * back to the same state it had when it was first ready to use. + * + * This method could be called, for example, to recycle objects that are used as + * services, so that they can be used to handle several requests in the same + * process loop (note that we advise making your services stateless instead of + * implementing this interface when possible.) + */ +interface ResetInterface +{ + public function reset(); +} diff --git a/vendor/symfony/service-contracts/ServiceLocatorTrait.php b/vendor/symfony/service-contracts/ServiceLocatorTrait.php new file mode 100644 index 000000000..74dfa4362 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceLocatorTrait.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; + +// Help opcache.preload discover always-needed symbols +class_exists(ContainerExceptionInterface::class); +class_exists(NotFoundExceptionInterface::class); + +/** + * A trait to help implement ServiceProviderInterface. + * + * @author Robin Chalas + * @author Nicolas Grekas + */ +trait ServiceLocatorTrait +{ + private $factories; + private $loading = []; + private $providedTypes; + + /** + * @param callable[] $factories + */ + public function __construct(array $factories) + { + $this->factories = $factories; + } + + /** + * {@inheritdoc} + * + * @return bool + */ + public function has(string $id) + { + return isset($this->factories[$id]); + } + + /** + * {@inheritdoc} + * + * @return mixed + */ + public function get(string $id) + { + if (!isset($this->factories[$id])) { + throw $this->createNotFoundException($id); + } + + if (isset($this->loading[$id])) { + $ids = array_values($this->loading); + $ids = \array_slice($this->loading, array_search($id, $ids)); + $ids[] = $id; + + throw $this->createCircularReferenceException($id, $ids); + } + + $this->loading[$id] = $id; + try { + return $this->factories[$id]($this); + } finally { + unset($this->loading[$id]); + } + } + + /** + * {@inheritdoc} + */ + public function getProvidedServices(): array + { + if (null === $this->providedTypes) { + $this->providedTypes = []; + + foreach ($this->factories as $name => $factory) { + if (!\is_callable($factory)) { + $this->providedTypes[$name] = '?'; + } else { + $type = (new \ReflectionFunction($factory))->getReturnType(); + + $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?'; + } + } + } + + return $this->providedTypes; + } + + private function createNotFoundException(string $id): NotFoundExceptionInterface + { + if (!$alternatives = array_keys($this->factories)) { + $message = 'is empty...'; + } else { + $last = array_pop($alternatives); + if ($alternatives) { + $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last); + } else { + $message = sprintf('only knows about the "%s" service.', $last); + } + } + + if ($this->loading) { + $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message); + } else { + $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message); + } + + return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface { + }; + } + + private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface + { + return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface { + }; + } +} diff --git a/vendor/symfony/service-contracts/ServiceProviderInterface.php b/vendor/symfony/service-contracts/ServiceProviderInterface.php new file mode 100644 index 000000000..c60ad0bd4 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceProviderInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; + +/** + * A ServiceProviderInterface exposes the identifiers and the types of services provided by a container. + * + * @author Nicolas Grekas + * @author Mateusz Sip + */ +interface ServiceProviderInterface extends ContainerInterface +{ + /** + * Returns an associative array of service types keyed by the identifiers provided by the current container. + * + * Examples: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface + * * ['foo' => '?'] means the container provides service name "foo" of unspecified type + * * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null + * + * @return string[] The provided service types, keyed by service names + */ + public function getProvidedServices(): array; +} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberInterface.php b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php new file mode 100644 index 000000000..098ab908c --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method. + * + * The getSubscribedServices method returns an array of service types required by such instances, + * optionally keyed by the service names used internally. Service types that start with an interrogation + * mark "?" are optional, while the other ones are mandatory service dependencies. + * + * The injected service locators SHOULD NOT allow access to any other services not specified by the method. + * + * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally. + * This interface does not dictate any injection method for these service locators, although constructor + * injection is recommended. + * + * @author Nicolas Grekas + */ +interface ServiceSubscriberInterface +{ + /** + * Returns an array of service types required by such instances, optionally keyed by the service names used internally. + * + * For mandatory dependencies: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name + * internally to fetch a service which must implement Psr\Log\LoggerInterface. + * * ['loggers' => 'Psr\Log\LoggerInterface[]'] means the objects use the "loggers" name + * internally to fetch an iterable of Psr\Log\LoggerInterface instances. + * * ['Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface'] + * + * otherwise: + * + * * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency + * * ['loggers' => '?Psr\Log\LoggerInterface[]'] denotes an optional iterable dependency + * * ['?Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface'] + * + * @return string[] The required service types, optionally keyed by service names + */ + public static function getSubscribedServices(); +} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php new file mode 100644 index 000000000..16e3eb2c1 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\Attribute\SubscribedService; + +/** + * Implementation of ServiceSubscriberInterface that determines subscribed services from + * method return types. Service ids are available as "ClassName::methodName". + * + * @author Kevin Bond + */ +trait ServiceSubscriberTrait +{ + /** @var ContainerInterface */ + protected $container; + + /** + * {@inheritdoc} + */ + public static function getSubscribedServices(): array + { + $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; + $attributeOptIn = false; + + if (\PHP_VERSION_ID >= 80000) { + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + + if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) { + continue; + } + + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + throw new \LogicException(sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); + } + + if (!$returnType = $method->getReturnType()) { + throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); + } + + $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; + + if ($returnType->allowsNull()) { + $serviceId = '?'.$serviceId; + } + + $services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId; + $attributeOptIn = true; + } + } + + if (!$attributeOptIn) { + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + continue; + } + + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + + if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) { + continue; + } + + if ($returnType->isBuiltin()) { + continue; + } + + if (\PHP_VERSION_ID >= 80000) { + trigger_deprecation('symfony/service-contracts', '2.5', 'Using "%s" in "%s" without using the "%s" attribute on any method is deprecated.', ServiceSubscriberTrait::class, self::class, SubscribedService::class); + } + + $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType); + } + } + + return $services; + } + + /** + * @required + * + * @return ContainerInterface|null + */ + public function setContainer(ContainerInterface $container) + { + $this->container = $container; + + if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) { + return parent::setContainer($container); + } + + return null; + } +} diff --git a/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php new file mode 100644 index 000000000..2a1b565f5 --- /dev/null +++ b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Test; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceLocatorTrait; + +abstract class ServiceLocatorTest extends TestCase +{ + /** + * @return ContainerInterface + */ + protected function getServiceLocator(array $factories) + { + return new class($factories) implements ContainerInterface { + use ServiceLocatorTrait; + }; + } + + public function testHas() + { + $locator = $this->getServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + function () { return 'dummy'; }, + ]); + + $this->assertTrue($locator->has('foo')); + $this->assertTrue($locator->has('bar')); + $this->assertFalse($locator->has('dummy')); + } + + public function testGet() + { + $locator = $this->getServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('baz', $locator->get('bar')); + } + + public function testGetDoesNotMemoize() + { + $i = 0; + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$i) { + ++$i; + + return 'bar'; + }, + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame(2, $i); + } + + public function testThrowsOnUndefinedInternalService() + { + if (!$this->getExpectedException()) { + $this->expectException(\Psr\Container\NotFoundExceptionInterface::class); + $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.'); + } + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $locator->get('foo'); + } + + public function testThrowsOnCircularReference() + { + $this->expectException(\Psr\Container\ContainerExceptionInterface::class); + $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".'); + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + 'bar' => function () use (&$locator) { return $locator->get('baz'); }, + 'baz' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $locator->get('foo'); + } +} diff --git a/vendor/symfony/service-contracts/composer.json b/vendor/symfony/service-contracts/composer.json new file mode 100644 index 000000000..f05863701 --- /dev/null +++ b/vendor/symfony/service-contracts/composer.json @@ -0,0 +1,42 @@ +{ + "name": "symfony/service-contracts", + "type": "library", + "description": "Generic abstractions related to writing services", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\Service\\": "" } + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + } +} From af608d9268e92ae2ded54fe5e391df23ca3f53b4 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 10:00:31 +0200 Subject: [PATCH 2/9] spaces: use asyncAws s3 --- composer.json | 3 +- composer.lock | 696 +- models/digitalocean-spaces-browser.class.php | 64 +- models/media-browser.php | 6 + package-lock.json | 12651 ---------------- vendor/async-aws/core/CHANGELOG.md | 433 + vendor/async-aws/core/LICENSE | 21 + vendor/async-aws/core/README.md | 21 + vendor/async-aws/core/composer.json | 44 + vendor/async-aws/core/roave-bc-check.yaml | 3 + vendor/async-aws/core/src/AbstractApi.php | 358 + .../async-aws/core/src/AwsClientFactory.php | 631 + .../async-aws/core/src/AwsError/AwsError.php | 54 + .../AwsErrorFactoryFromResponseTrait.php | 16 + .../src/AwsError/AwsErrorFactoryInterface.php | 15 + .../src/AwsError/ChainAwsErrorFactory.php | 43 + .../src/AwsError/JsonRestAwsErrorFactory.php | 45 + .../src/AwsError/JsonRpcAwsErrorFactory.php | 42 + .../core/src/AwsError/XmlAwsErrorFactory.php | 54 + vendor/async-aws/core/src/Configuration.php | 266 + .../core/src/Credentials/CacheProvider.php | 48 + .../core/src/Credentials/ChainProvider.php | 84 + .../src/Credentials/ConfigurationProvider.php | 92 + .../src/Credentials/ContainerProvider.php | 80 + .../src/Credentials/CredentialProvider.php | 20 + .../core/src/Credentials/Credentials.php | 88 + .../core/src/Credentials/DateFromResult.php | 21 + .../core/src/Credentials/IniFileLoader.php | 110 + .../core/src/Credentials/IniFileProvider.php | 224 + .../core/src/Credentials/InstanceProvider.php | 158 + .../core/src/Credentials/NullProvider.php | 20 + .../core/src/Credentials/PsrCacheProvider.php | 73 + .../src/Credentials/SsoCacheFileLoader.php | 79 + .../src/Credentials/SymfonyCacheProvider.php | 71 + .../src/Credentials/WebIdentityProvider.php | 158 + .../src/EndpointDiscovery/EndpointCache.php | 126 + .../EndpointDiscovery/EndpointInterface.php | 10 + vendor/async-aws/core/src/EnvVar.php | 31 + .../core/src/Exception/Exception.php | 14 + .../src/Exception/Http/ClientException.php | 17 + .../core/src/Exception/Http/HttpException.php | 21 + .../src/Exception/Http/HttpExceptionTrait.php | 81 + .../src/Exception/Http/NetworkException.php | 17 + .../Exception/Http/RedirectionException.php | 17 + .../src/Exception/Http/ServerException.php | 17 + .../core/src/Exception/InvalidArgument.php | 9 + .../core/src/Exception/LogicException.php | 9 + .../core/src/Exception/MissingDependency.php | 16 + .../core/src/Exception/RuntimeException.php | 9 + .../core/src/Exception/UnexpectedValue.php | 9 + .../core/src/Exception/UnparsableResponse.php | 9 + .../core/src/Exception/UnsupportedRegion.php | 9 + .../src/HttpClient/AwsHttpClientFactory.php | 32 + .../core/src/HttpClient/AwsRetryStrategy.php | 73 + vendor/async-aws/core/src/Input.php | 36 + vendor/async-aws/core/src/Request.php | 215 + vendor/async-aws/core/src/RequestContext.php | 119 + vendor/async-aws/core/src/Response.php | 477 + vendor/async-aws/core/src/Result.php | 145 + vendor/async-aws/core/src/Signer/Signer.php | 19 + vendor/async-aws/core/src/Signer/SignerV4.php | 369 + .../core/src/Signer/SigningContext.php | 78 + .../core/src/Stream/CallableStream.php | 84 + .../core/src/Stream/FixedSizeStream.php | 90 + .../core/src/Stream/IterableStream.php | 70 + .../core/src/Stream/ReadOnceResultStream.php | 12 + .../core/src/Stream/RequestStream.php | 22 + .../core/src/Stream/ResourceStream.php | 105 + .../src/Stream/ResponseBodyResourceStream.php | 82 + .../core/src/Stream/ResponseBodyStream.php | 101 + .../core/src/Stream/ResultStream.php | 35 + .../core/src/Stream/RewindableStream.php | 97 + .../core/src/Stream/StreamFactory.php | 34 + .../core/src/Stream/StringStream.php | 68 + .../Sts/Exception/ExpiredTokenException.php | 13 + .../IDPCommunicationErrorException.php | 15 + .../Exception/IDPRejectedClaimException.php | 15 + .../InvalidIdentityTokenException.php | 13 + .../MalformedPolicyDocumentException.php | 12 + .../PackedPolicyTooLargeException.php | 22 + .../Sts/Exception/RegionDisabledException.php | 16 + .../core/src/Sts/Input/AssumeRoleRequest.php | 550 + .../AssumeRoleWithWebIdentityRequest.php | 320 + .../Sts/Input/GetCallerIdentityRequest.php | 58 + .../src/Sts/Result/AssumeRoleResponse.php | 110 + .../AssumeRoleWithWebIdentityResponse.php | 166 + .../Sts/Result/GetCallerIdentityResponse.php | 69 + vendor/async-aws/core/src/Sts/StsClient.php | 445 + .../src/Sts/ValueObject/AssumedRoleUser.php | 70 + .../core/src/Sts/ValueObject/Credentials.php | 96 + .../Sts/ValueObject/PolicyDescriptorType.php | 59 + .../src/Sts/ValueObject/ProvidedContext.php | 72 + .../core/src/Sts/ValueObject/Tag.php | 94 + .../src/Test/Http/SimpleMockedResponse.php | 91 + .../core/src/Test/ResultMockFactory.php | 290 + .../core/src/Test/SimpleResultStream.php | 53 + vendor/async-aws/core/src/Test/TestCase.php | 103 + vendor/async-aws/core/src/Waiter.php | 228 + vendor/async-aws/s3/CHANGELOG.md | 247 + vendor/async-aws/s3/LICENSE | 21 + vendor/async-aws/s3/README.md | 20 + vendor/async-aws/s3/composer.json | 36 + .../async-aws/s3/src/Enum/ArchiveStatus.php | 17 + .../async-aws/s3/src/Enum/BucketCannedACL.php | 21 + .../s3/src/Enum/BucketLocationConstraint.php | 69 + .../s3/src/Enum/ChecksumAlgorithm.php | 21 + vendor/async-aws/s3/src/Enum/ChecksumMode.php | 15 + vendor/async-aws/s3/src/Enum/EncodingType.php | 21 + vendor/async-aws/s3/src/Enum/Event.php | 70 + .../async-aws/s3/src/Enum/FilterRuleName.php | 17 + .../src/Enum/IntelligentTieringAccessTier.php | 17 + .../s3/src/Enum/MetadataDirective.php | 17 + .../async-aws/s3/src/Enum/ObjectCannedACL.php | 27 + .../s3/src/Enum/ObjectLockLegalHoldStatus.php | 17 + .../async-aws/s3/src/Enum/ObjectLockMode.php | 17 + .../async-aws/s3/src/Enum/ObjectOwnership.php | 33 + .../s3/src/Enum/ObjectStorageClass.php | 33 + .../s3/src/Enum/OptionalObjectAttributes.php | 15 + vendor/async-aws/s3/src/Enum/Permission.php | 23 + .../s3/src/Enum/ReplicationStatus.php | 21 + .../async-aws/s3/src/Enum/RequestCharged.php | 18 + vendor/async-aws/s3/src/Enum/RequestPayer.php | 22 + .../s3/src/Enum/ServerSideEncryption.php | 19 + vendor/async-aws/s3/src/Enum/StorageClass.php | 33 + .../s3/src/Enum/TaggingDirective.php | 17 + vendor/async-aws/s3/src/Enum/Type.php | 19 + .../BucketAlreadyExistsException.php | 13 + .../BucketAlreadyOwnedByYouException.php | 15 + .../Exception/InvalidObjectStateException.php | 50 + .../src/Exception/NoSuchBucketException.php | 12 + .../s3/src/Exception/NoSuchKeyException.php | 12 + .../src/Exception/NoSuchUploadException.php | 12 + .../ObjectNotInActiveTierErrorException.php | 12 + .../src/Input/AbortMultipartUploadRequest.php | 210 + .../Input/CompleteMultipartUploadRequest.php | 449 + .../s3/src/Input/CopyObjectRequest.php | 1267 ++ .../s3/src/Input/CreateBucketRequest.php | 337 + .../Input/CreateMultipartUploadRequest.php | 933 ++ .../s3/src/Input/DeleteBucketCorsRequest.php | 107 + .../s3/src/Input/DeleteBucketRequest.php | 107 + .../s3/src/Input/DeleteObjectRequest.php | 260 + .../src/Input/DeleteObjectTaggingRequest.php | 174 + .../s3/src/Input/DeleteObjectsRequest.php | 292 + .../s3/src/Input/GetBucketCorsRequest.php | 116 + .../src/Input/GetBucketEncryptionRequest.php | 107 + .../s3/src/Input/GetObjectAclRequest.php | 200 + .../s3/src/Input/GetObjectRequest.php | 633 + .../s3/src/Input/GetObjectTaggingRequest.php | 207 + .../s3/src/Input/HeadBucketRequest.php | 127 + .../s3/src/Input/HeadObjectRequest.php | 480 + .../s3/src/Input/ListBucketsRequest.php | 51 + .../src/Input/ListMultipartUploadsRequest.php | 329 + .../s3/src/Input/ListObjectsV2Request.php | 386 + .../s3/src/Input/ListPartsRequest.php | 347 + .../s3/src/Input/PutBucketCorsRequest.php | 223 + ...BucketNotificationConfigurationRequest.php | 170 + .../s3/src/Input/PutBucketTaggingRequest.php | 221 + .../s3/src/Input/PutObjectAclRequest.php | 497 + .../s3/src/Input/PutObjectRequest.php | 1178 ++ .../s3/src/Input/PutObjectTaggingRequest.php | 318 + .../s3/src/Input/UploadPartRequest.php | 557 + .../src/Result/AbortMultipartUploadOutput.php | 32 + .../s3/src/Result/BucketExistsWaiter.php | 49 + .../s3/src/Result/BucketNotExistsWaiter.php | 37 + .../Result/CompleteMultipartUploadOutput.php | 273 + .../s3/src/Result/CopyObjectOutput.php | 202 + .../s3/src/Result/CreateBucketOutput.php | 30 + .../Result/CreateMultipartUploadOutput.php | 251 + .../s3/src/Result/DeleteObjectOutput.php | 62 + .../src/Result/DeleteObjectTaggingOutput.php | 30 + .../s3/src/Result/DeleteObjectsOutput.php | 109 + .../s3/src/Result/GetBucketCorsOutput.php | 118 + .../src/Result/GetBucketEncryptionOutput.php | 51 + .../s3/src/Result/GetObjectAclOutput.php | 95 + .../s3/src/Result/GetObjectOutput.php | 621 + .../s3/src/Result/GetObjectTaggingOutput.php | 67 + .../s3/src/Result/HeadObjectOutput.php | 641 + .../s3/src/Result/ListBucketsOutput.php | 81 + .../src/Result/ListMultipartUploadsOutput.php | 402 + .../s3/src/Result/ListObjectsV2Output.php | 438 + .../s3/src/Result/ListPartsOutput.php | 352 + .../s3/src/Result/ObjectExistsWaiter.php | 41 + .../s3/src/Result/ObjectNotExistsWaiter.php | 37 + .../s3/src/Result/PutObjectAclOutput.php | 32 + .../s3/src/Result/PutObjectOutput.php | 259 + .../s3/src/Result/PutObjectTaggingOutput.php | 30 + .../s3/src/Result/UploadPartOutput.php | 206 + vendor/async-aws/s3/src/S3Client.php | 2651 ++++ .../async-aws/s3/src/Signer/SignerV4ForS3.php | 173 + .../src/ValueObject/AccessControlPolicy.php | 79 + .../s3/src/ValueObject/AwsObject.php | 169 + .../async-aws/s3/src/ValueObject/Bucket.php | 58 + .../s3/src/ValueObject/CORSConfiguration.php | 71 + .../async-aws/s3/src/ValueObject/CORSRule.php | 174 + .../s3/src/ValueObject/CommonPrefix.php | 43 + .../ValueObject/CompletedMultipartUpload.php | 60 + .../s3/src/ValueObject/CompletedPart.php | 157 + .../s3/src/ValueObject/CopyObjectResult.php | 132 + .../ValueObject/CreateBucketConfiguration.php | 61 + .../async-aws/s3/src/ValueObject/Delete.php | 86 + .../s3/src/ValueObject/DeletedObject.php | 88 + vendor/async-aws/s3/src/ValueObject/Error.php | 563 + .../ValueObject/EventBridgeConfiguration.php | 24 + .../s3/src/ValueObject/FilterRule.php | 82 + vendor/async-aws/s3/src/ValueObject/Grant.php | 80 + .../async-aws/s3/src/ValueObject/Grantee.php | 155 + .../s3/src/ValueObject/Initiator.php | 57 + .../LambdaFunctionConfiguration.php | 124 + .../s3/src/ValueObject/MultipartUpload.php | 140 + .../ValueObject/NotificationConfiguration.php | 129 + .../NotificationConfigurationFilter.php | 54 + .../s3/src/ValueObject/ObjectIdentifier.php | 83 + vendor/async-aws/s3/src/ValueObject/Owner.php | 79 + vendor/async-aws/s3/src/ValueObject/Part.php | 162 + .../s3/src/ValueObject/QueueConfiguration.php | 123 + .../s3/src/ValueObject/RestoreStatus.php | 72 + .../s3/src/ValueObject/S3KeyFilter.php | 56 + .../ServerSideEncryptionByDefault.php | 92 + .../ServerSideEncryptionConfiguration.php | 54 + .../ValueObject/ServerSideEncryptionRule.php | 63 + vendor/async-aws/s3/src/ValueObject/Tag.php | 77 + .../async-aws/s3/src/ValueObject/Tagging.php | 69 + .../s3/src/ValueObject/TopicConfiguration.php | 126 + vendor/autoload.php | 20 +- vendor/bin/jp.php | 120 +- vendor/bin/jp.php.bat | 5 + vendor/composer/ClassLoader.php | 208 +- vendor/composer/InstalledVersions.php | 359 + vendor/composer/autoload_classmap.php | 9 +- vendor/composer/autoload_files.php | 6 +- vendor/composer/autoload_namespaces.php | 2 +- vendor/composer/autoload_psr4.php | 14 +- vendor/composer/autoload_real.php | 60 +- vendor/composer/autoload_static.php | 73 +- vendor/composer/installed.json | 2343 ++- vendor/composer/installed.php | 257 + vendor/composer/platform_check.php | 26 + vendor/psr/cache/CHANGELOG.md | 16 + vendor/psr/cache/LICENSE.txt | 19 + vendor/psr/cache/README.md | 9 + vendor/psr/cache/composer.json | 25 + vendor/psr/cache/src/CacheException.php | 10 + vendor/psr/cache/src/CacheItemInterface.php | 105 + .../psr/cache/src/CacheItemPoolInterface.php | 138 + .../cache/src/InvalidArgumentException.php | 13 + vendor/psr/container/.gitignore | 3 + vendor/psr/container/LICENSE | 21 + vendor/psr/container/README.md | 13 + vendor/psr/container/composer.json | 22 + .../src/ContainerExceptionInterface.php | 10 + .../psr/container/src/ContainerInterface.php | 36 + .../src/NotFoundExceptionInterface.php | 10 + vendor/psr/log/LICENSE | 19 + vendor/psr/log/Psr/Log/AbstractLogger.php | 128 + .../log/Psr/Log/InvalidArgumentException.php | 7 + vendor/psr/log/Psr/Log/LogLevel.php | 18 + .../psr/log/Psr/Log/LoggerAwareInterface.php | 18 + vendor/psr/log/Psr/Log/LoggerAwareTrait.php | 26 + vendor/psr/log/Psr/Log/LoggerInterface.php | 125 + vendor/psr/log/Psr/Log/LoggerTrait.php | 142 + vendor/psr/log/Psr/Log/NullLogger.php | 30 + vendor/psr/log/Psr/Log/Test/DummyTest.php | 18 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 138 + vendor/psr/log/Psr/Log/Test/TestLogger.php | 147 + vendor/psr/log/README.md | 58 + vendor/psr/log/composer.json | 26 + .../symfony/http-client-contracts/.gitignore | 3 + .../http-client-contracts/CHANGELOG.md | 5 + .../http-client-contracts/ChunkInterface.php | 71 + .../Exception/ClientExceptionInterface.php | 21 + .../Exception/DecodingExceptionInterface.php | 21 + .../Exception/ExceptionInterface.php | 21 + .../Exception/HttpExceptionInterface.php | 24 + .../RedirectionExceptionInterface.php | 21 + .../Exception/ServerExceptionInterface.php | 21 + .../Exception/TimeoutExceptionInterface.php | 21 + .../Exception/TransportExceptionInterface.php | 21 + .../HttpClientInterface.php | 95 + vendor/symfony/http-client-contracts/LICENSE | 19 + .../symfony/http-client-contracts/README.md | 9 + .../ResponseInterface.php | 109 + .../ResponseStreamInterface.php | 26 + .../Test/Fixtures/web/index.php | 192 + .../Test/HttpClientTestCase.php | 1137 ++ .../Test/TestHttpServer.php | 46 + .../http-client-contracts/composer.json | 37 + vendor/symfony/http-client/AmpHttpClient.php | 181 + .../http-client/AsyncDecoratorTrait.php | 48 + vendor/symfony/http-client/CHANGELOG.md | 54 + .../symfony/http-client/CachingHttpClient.php | 152 + .../symfony/http-client/Chunk/DataChunk.php | 87 + .../symfony/http-client/Chunk/ErrorChunk.php | 140 + .../symfony/http-client/Chunk/FirstChunk.php | 28 + .../http-client/Chunk/InformationalChunk.php | 35 + .../symfony/http-client/Chunk/LastChunk.php | 28 + .../http-client/Chunk/ServerSentEvent.php | 79 + vendor/symfony/http-client/CurlHttpClient.php | 552 + .../DataCollector/HttpClientDataCollector.php | 176 + vendor/symfony/http-client/DecoratorTrait.php | 66 + .../DependencyInjection/HttpClientPass.php | 51 + .../http-client/EventSourceHttpClient.php | 159 + .../http-client/Exception/ClientException.php | 24 + .../Exception/EventSourceException.php | 21 + .../Exception/HttpExceptionTrait.php | 78 + .../Exception/InvalidArgumentException.php | 21 + .../http-client/Exception/JsonException.php | 23 + .../Exception/RedirectionException.php | 24 + .../http-client/Exception/ServerException.php | 24 + .../Exception/TimeoutException.php | 21 + .../Exception/TransportException.php | 21 + vendor/symfony/http-client/HttpClient.php | 79 + .../symfony/http-client/HttpClientTrait.php | 710 + vendor/symfony/http-client/HttpOptions.php | 331 + vendor/symfony/http-client/HttplugClient.php | 276 + .../symfony/http-client/Internal/AmpBody.php | 142 + .../http-client/Internal/AmpClientState.php | 217 + .../http-client/Internal/AmpListener.php | 183 + .../http-client/Internal/AmpResolver.php | 52 + .../symfony/http-client/Internal/Canary.php | 40 + .../http-client/Internal/ClientState.php | 26 + .../http-client/Internal/CurlClientState.php | 149 + .../symfony/http-client/Internal/DnsCache.php | 39 + .../http-client/Internal/HttplugWaitLoop.php | 145 + .../Internal/NativeClientState.php | 47 + .../http-client/Internal/PushedResponse.php | 41 + vendor/symfony/http-client/LICENSE | 19 + vendor/symfony/http-client/MockHttpClient.php | 124 + .../symfony/http-client/NativeHttpClient.php | 468 + .../NoPrivateNetworkHttpClient.php | 132 + vendor/symfony/http-client/Psr18Client.php | 248 + vendor/symfony/http-client/README.md | 27 + .../http-client/Response/AmpResponse.php | 460 + .../http-client/Response/AsyncContext.php | 195 + .../http-client/Response/AsyncResponse.php | 478 + .../Response/CommonResponseTrait.php | 185 + .../http-client/Response/CurlResponse.php | 473 + .../http-client/Response/HttplugPromise.php | 80 + .../http-client/Response/MockResponse.php | 343 + .../http-client/Response/NativeResponse.php | 376 + .../http-client/Response/ResponseStream.php | 54 + .../http-client/Response/StreamWrapper.php | 313 + .../Response/StreamableInterface.php | 35 + .../Response/TraceableResponse.php | 219 + .../Response/TransportResponseTrait.php | 312 + .../Retry/GenericRetryStrategy.php | 115 + .../Retry/RetryStrategyInterface.php | 36 + .../http-client/RetryableHttpClient.php | 171 + .../symfony/http-client/ScopingHttpClient.php | 131 + .../http-client/TraceableHttpClient.php | 120 + vendor/symfony/http-client/composer.json | 55 + vendor/symfony/polyfill-php73/LICENSE | 19 + vendor/symfony/polyfill-php73/Php73.php | 43 + vendor/symfony/polyfill-php73/README.md | 18 + .../Resources/stubs/JsonException.php | 16 + vendor/symfony/polyfill-php73/bootstrap.php | 31 + vendor/symfony/polyfill-php73/composer.json | 36 + vendor/symfony/polyfill-php80/LICENSE | 19 + vendor/symfony/polyfill-php80/Php80.php | 115 + vendor/symfony/polyfill-php80/PhpToken.php | 103 + vendor/symfony/polyfill-php80/README.md | 25 + .../Resources/stubs/Attribute.php | 31 + .../Resources/stubs/PhpToken.php | 16 + .../Resources/stubs/Stringable.php | 20 + .../Resources/stubs/UnhandledMatchError.php | 16 + .../Resources/stubs/ValueError.php | 16 + vendor/symfony/polyfill-php80/bootstrap.php | 42 + vendor/symfony/polyfill-php80/composer.json | 40 + vendor/symfony/service-contracts/.gitignore | 3 + .../service-contracts/Attribute/Required.php | 25 + .../Attribute/SubscribedService.php | 33 + vendor/symfony/service-contracts/CHANGELOG.md | 5 + vendor/symfony/service-contracts/LICENSE | 19 + vendor/symfony/service-contracts/README.md | 9 + .../service-contracts/ResetInterface.php | 30 + .../service-contracts/ServiceLocatorTrait.php | 128 + .../ServiceProviderInterface.php | 36 + .../ServiceSubscriberInterface.php | 53 + .../ServiceSubscriberTrait.php | 109 + .../Test/ServiceLocatorTest.php | 95 + .../symfony/service-contracts/composer.json | 42 + 380 files changed, 49041 insertions(+), 13563 deletions(-) delete mode 100644 package-lock.json create mode 100644 vendor/async-aws/core/CHANGELOG.md create mode 100644 vendor/async-aws/core/LICENSE create mode 100644 vendor/async-aws/core/README.md create mode 100644 vendor/async-aws/core/composer.json create mode 100644 vendor/async-aws/core/roave-bc-check.yaml create mode 100644 vendor/async-aws/core/src/AbstractApi.php create mode 100644 vendor/async-aws/core/src/AwsClientFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/AwsError.php create mode 100644 vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php create mode 100644 vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php create mode 100644 vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php create mode 100644 vendor/async-aws/core/src/Configuration.php create mode 100644 vendor/async-aws/core/src/Credentials/CacheProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/ChainProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/ConfigurationProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/ContainerProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/CredentialProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/Credentials.php create mode 100644 vendor/async-aws/core/src/Credentials/DateFromResult.php create mode 100644 vendor/async-aws/core/src/Credentials/IniFileLoader.php create mode 100644 vendor/async-aws/core/src/Credentials/IniFileProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/InstanceProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/NullProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/PsrCacheProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php create mode 100644 vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php create mode 100644 vendor/async-aws/core/src/Credentials/WebIdentityProvider.php create mode 100644 vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php create mode 100644 vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php create mode 100644 vendor/async-aws/core/src/EnvVar.php create mode 100644 vendor/async-aws/core/src/Exception/Exception.php create mode 100644 vendor/async-aws/core/src/Exception/Http/ClientException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/HttpException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/HttpExceptionTrait.php create mode 100644 vendor/async-aws/core/src/Exception/Http/NetworkException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/RedirectionException.php create mode 100644 vendor/async-aws/core/src/Exception/Http/ServerException.php create mode 100644 vendor/async-aws/core/src/Exception/InvalidArgument.php create mode 100644 vendor/async-aws/core/src/Exception/LogicException.php create mode 100644 vendor/async-aws/core/src/Exception/MissingDependency.php create mode 100644 vendor/async-aws/core/src/Exception/RuntimeException.php create mode 100644 vendor/async-aws/core/src/Exception/UnexpectedValue.php create mode 100644 vendor/async-aws/core/src/Exception/UnparsableResponse.php create mode 100644 vendor/async-aws/core/src/Exception/UnsupportedRegion.php create mode 100644 vendor/async-aws/core/src/HttpClient/AwsHttpClientFactory.php create mode 100644 vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php create mode 100644 vendor/async-aws/core/src/Input.php create mode 100644 vendor/async-aws/core/src/Request.php create mode 100644 vendor/async-aws/core/src/RequestContext.php create mode 100644 vendor/async-aws/core/src/Response.php create mode 100644 vendor/async-aws/core/src/Result.php create mode 100644 vendor/async-aws/core/src/Signer/Signer.php create mode 100644 vendor/async-aws/core/src/Signer/SignerV4.php create mode 100644 vendor/async-aws/core/src/Signer/SigningContext.php create mode 100644 vendor/async-aws/core/src/Stream/CallableStream.php create mode 100644 vendor/async-aws/core/src/Stream/FixedSizeStream.php create mode 100644 vendor/async-aws/core/src/Stream/IterableStream.php create mode 100644 vendor/async-aws/core/src/Stream/ReadOnceResultStream.php create mode 100644 vendor/async-aws/core/src/Stream/RequestStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResourceStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResponseBodyStream.php create mode 100644 vendor/async-aws/core/src/Stream/ResultStream.php create mode 100644 vendor/async-aws/core/src/Stream/RewindableStream.php create mode 100644 vendor/async-aws/core/src/Stream/StreamFactory.php create mode 100644 vendor/async-aws/core/src/Stream/StringStream.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/IDPCommunicationErrorException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/IDPRejectedClaimException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/InvalidIdentityTokenException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/MalformedPolicyDocumentException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/PackedPolicyTooLargeException.php create mode 100644 vendor/async-aws/core/src/Sts/Exception/RegionDisabledException.php create mode 100644 vendor/async-aws/core/src/Sts/Input/AssumeRoleRequest.php create mode 100644 vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php create mode 100644 vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php create mode 100644 vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php create mode 100644 vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php create mode 100644 vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php create mode 100644 vendor/async-aws/core/src/Sts/StsClient.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/Credentials.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php create mode 100644 vendor/async-aws/core/src/Sts/ValueObject/Tag.php create mode 100644 vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php create mode 100644 vendor/async-aws/core/src/Test/ResultMockFactory.php create mode 100644 vendor/async-aws/core/src/Test/SimpleResultStream.php create mode 100644 vendor/async-aws/core/src/Test/TestCase.php create mode 100644 vendor/async-aws/core/src/Waiter.php create mode 100644 vendor/async-aws/s3/CHANGELOG.md create mode 100644 vendor/async-aws/s3/LICENSE create mode 100644 vendor/async-aws/s3/README.md create mode 100644 vendor/async-aws/s3/composer.json create mode 100644 vendor/async-aws/s3/src/Enum/ArchiveStatus.php create mode 100644 vendor/async-aws/s3/src/Enum/BucketCannedACL.php create mode 100644 vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php create mode 100644 vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php create mode 100644 vendor/async-aws/s3/src/Enum/ChecksumMode.php create mode 100644 vendor/async-aws/s3/src/Enum/EncodingType.php create mode 100644 vendor/async-aws/s3/src/Enum/Event.php create mode 100644 vendor/async-aws/s3/src/Enum/FilterRuleName.php create mode 100644 vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php create mode 100644 vendor/async-aws/s3/src/Enum/MetadataDirective.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectCannedACL.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectLockMode.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectOwnership.php create mode 100644 vendor/async-aws/s3/src/Enum/ObjectStorageClass.php create mode 100644 vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php create mode 100644 vendor/async-aws/s3/src/Enum/Permission.php create mode 100644 vendor/async-aws/s3/src/Enum/ReplicationStatus.php create mode 100644 vendor/async-aws/s3/src/Enum/RequestCharged.php create mode 100644 vendor/async-aws/s3/src/Enum/RequestPayer.php create mode 100644 vendor/async-aws/s3/src/Enum/ServerSideEncryption.php create mode 100644 vendor/async-aws/s3/src/Enum/StorageClass.php create mode 100644 vendor/async-aws/s3/src/Enum/TaggingDirective.php create mode 100644 vendor/async-aws/s3/src/Enum/Type.php create mode 100644 vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php create mode 100644 vendor/async-aws/s3/src/Exception/BucketAlreadyOwnedByYouException.php create mode 100644 vendor/async-aws/s3/src/Exception/InvalidObjectStateException.php create mode 100644 vendor/async-aws/s3/src/Exception/NoSuchBucketException.php create mode 100644 vendor/async-aws/s3/src/Exception/NoSuchKeyException.php create mode 100644 vendor/async-aws/s3/src/Exception/NoSuchUploadException.php create mode 100644 vendor/async-aws/s3/src/Exception/ObjectNotInActiveTierErrorException.php create mode 100644 vendor/async-aws/s3/src/Input/AbortMultipartUploadRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CopyObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CreateBucketRequest.php create mode 100644 vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteBucketRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetObjectAclRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/HeadBucketRequest.php create mode 100644 vendor/async-aws/s3/src/Input/HeadObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/ListBucketsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/ListObjectsV2Request.php create mode 100644 vendor/async-aws/s3/src/Input/ListPartsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutObjectAclRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutObjectRequest.php create mode 100644 vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php create mode 100644 vendor/async-aws/s3/src/Input/UploadPartRequest.php create mode 100644 vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php create mode 100644 vendor/async-aws/s3/src/Result/BucketExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php create mode 100644 vendor/async-aws/s3/src/Result/CopyObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/CreateBucketOutput.php create mode 100644 vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php create mode 100644 vendor/async-aws/s3/src/Result/DeleteObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php create mode 100644 vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetObjectAclOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php create mode 100644 vendor/async-aws/s3/src/Result/HeadObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ListBucketsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ListObjectsV2Output.php create mode 100644 vendor/async-aws/s3/src/Result/ListPartsOutput.php create mode 100644 vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php create mode 100644 vendor/async-aws/s3/src/Result/PutObjectAclOutput.php create mode 100644 vendor/async-aws/s3/src/Result/PutObjectOutput.php create mode 100644 vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php create mode 100644 vendor/async-aws/s3/src/Result/UploadPartOutput.php create mode 100644 vendor/async-aws/s3/src/S3Client.php create mode 100644 vendor/async-aws/s3/src/Signer/SignerV4ForS3.php create mode 100644 vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php create mode 100644 vendor/async-aws/s3/src/ValueObject/AwsObject.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Bucket.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CORSRule.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CommonPrefix.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CompletedPart.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php create mode 100644 vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Delete.php create mode 100644 vendor/async-aws/s3/src/ValueObject/DeletedObject.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Error.php create mode 100644 vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/FilterRule.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Grant.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Grantee.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Initiator.php create mode 100644 vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/MultipartUpload.php create mode 100644 vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Owner.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Part.php create mode 100644 vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/RestoreStatus.php create mode 100644 vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php create mode 100644 vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Tag.php create mode 100644 vendor/async-aws/s3/src/ValueObject/Tagging.php create mode 100644 vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php create mode 100644 vendor/bin/jp.php.bat create mode 100644 vendor/composer/InstalledVersions.php create mode 100644 vendor/composer/installed.php create mode 100644 vendor/composer/platform_check.php create mode 100644 vendor/psr/cache/CHANGELOG.md create mode 100644 vendor/psr/cache/LICENSE.txt create mode 100644 vendor/psr/cache/README.md create mode 100644 vendor/psr/cache/composer.json create mode 100644 vendor/psr/cache/src/CacheException.php create mode 100644 vendor/psr/cache/src/CacheItemInterface.php create mode 100644 vendor/psr/cache/src/CacheItemPoolInterface.php create mode 100644 vendor/psr/cache/src/InvalidArgumentException.php create mode 100644 vendor/psr/container/.gitignore create mode 100644 vendor/psr/container/LICENSE create mode 100644 vendor/psr/container/README.md create mode 100644 vendor/psr/container/composer.json create mode 100644 vendor/psr/container/src/ContainerExceptionInterface.php create mode 100644 vendor/psr/container/src/ContainerInterface.php create mode 100644 vendor/psr/container/src/NotFoundExceptionInterface.php create mode 100644 vendor/psr/log/LICENSE create mode 100644 vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 vendor/psr/log/Psr/Log/Test/DummyTest.php create mode 100644 vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 vendor/psr/log/Psr/Log/Test/TestLogger.php create mode 100644 vendor/psr/log/README.md create mode 100644 vendor/psr/log/composer.json create mode 100644 vendor/symfony/http-client-contracts/.gitignore create mode 100644 vendor/symfony/http-client-contracts/CHANGELOG.md create mode 100644 vendor/symfony/http-client-contracts/ChunkInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php create mode 100644 vendor/symfony/http-client-contracts/HttpClientInterface.php create mode 100644 vendor/symfony/http-client-contracts/LICENSE create mode 100644 vendor/symfony/http-client-contracts/README.md create mode 100644 vendor/symfony/http-client-contracts/ResponseInterface.php create mode 100644 vendor/symfony/http-client-contracts/ResponseStreamInterface.php create mode 100644 vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php create mode 100644 vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php create mode 100644 vendor/symfony/http-client-contracts/Test/TestHttpServer.php create mode 100644 vendor/symfony/http-client-contracts/composer.json create mode 100644 vendor/symfony/http-client/AmpHttpClient.php create mode 100644 vendor/symfony/http-client/AsyncDecoratorTrait.php create mode 100644 vendor/symfony/http-client/CHANGELOG.md create mode 100644 vendor/symfony/http-client/CachingHttpClient.php create mode 100644 vendor/symfony/http-client/Chunk/DataChunk.php create mode 100644 vendor/symfony/http-client/Chunk/ErrorChunk.php create mode 100644 vendor/symfony/http-client/Chunk/FirstChunk.php create mode 100644 vendor/symfony/http-client/Chunk/InformationalChunk.php create mode 100644 vendor/symfony/http-client/Chunk/LastChunk.php create mode 100644 vendor/symfony/http-client/Chunk/ServerSentEvent.php create mode 100644 vendor/symfony/http-client/CurlHttpClient.php create mode 100644 vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php create mode 100644 vendor/symfony/http-client/DecoratorTrait.php create mode 100644 vendor/symfony/http-client/DependencyInjection/HttpClientPass.php create mode 100644 vendor/symfony/http-client/EventSourceHttpClient.php create mode 100644 vendor/symfony/http-client/Exception/ClientException.php create mode 100644 vendor/symfony/http-client/Exception/EventSourceException.php create mode 100644 vendor/symfony/http-client/Exception/HttpExceptionTrait.php create mode 100644 vendor/symfony/http-client/Exception/InvalidArgumentException.php create mode 100644 vendor/symfony/http-client/Exception/JsonException.php create mode 100644 vendor/symfony/http-client/Exception/RedirectionException.php create mode 100644 vendor/symfony/http-client/Exception/ServerException.php create mode 100644 vendor/symfony/http-client/Exception/TimeoutException.php create mode 100644 vendor/symfony/http-client/Exception/TransportException.php create mode 100644 vendor/symfony/http-client/HttpClient.php create mode 100644 vendor/symfony/http-client/HttpClientTrait.php create mode 100644 vendor/symfony/http-client/HttpOptions.php create mode 100644 vendor/symfony/http-client/HttplugClient.php create mode 100644 vendor/symfony/http-client/Internal/AmpBody.php create mode 100644 vendor/symfony/http-client/Internal/AmpClientState.php create mode 100644 vendor/symfony/http-client/Internal/AmpListener.php create mode 100644 vendor/symfony/http-client/Internal/AmpResolver.php create mode 100644 vendor/symfony/http-client/Internal/Canary.php create mode 100644 vendor/symfony/http-client/Internal/ClientState.php create mode 100644 vendor/symfony/http-client/Internal/CurlClientState.php create mode 100644 vendor/symfony/http-client/Internal/DnsCache.php create mode 100644 vendor/symfony/http-client/Internal/HttplugWaitLoop.php create mode 100644 vendor/symfony/http-client/Internal/NativeClientState.php create mode 100644 vendor/symfony/http-client/Internal/PushedResponse.php create mode 100644 vendor/symfony/http-client/LICENSE create mode 100644 vendor/symfony/http-client/MockHttpClient.php create mode 100644 vendor/symfony/http-client/NativeHttpClient.php create mode 100644 vendor/symfony/http-client/NoPrivateNetworkHttpClient.php create mode 100644 vendor/symfony/http-client/Psr18Client.php create mode 100644 vendor/symfony/http-client/README.md create mode 100644 vendor/symfony/http-client/Response/AmpResponse.php create mode 100644 vendor/symfony/http-client/Response/AsyncContext.php create mode 100644 vendor/symfony/http-client/Response/AsyncResponse.php create mode 100644 vendor/symfony/http-client/Response/CommonResponseTrait.php create mode 100644 vendor/symfony/http-client/Response/CurlResponse.php create mode 100644 vendor/symfony/http-client/Response/HttplugPromise.php create mode 100644 vendor/symfony/http-client/Response/MockResponse.php create mode 100644 vendor/symfony/http-client/Response/NativeResponse.php create mode 100644 vendor/symfony/http-client/Response/ResponseStream.php create mode 100644 vendor/symfony/http-client/Response/StreamWrapper.php create mode 100644 vendor/symfony/http-client/Response/StreamableInterface.php create mode 100644 vendor/symfony/http-client/Response/TraceableResponse.php create mode 100644 vendor/symfony/http-client/Response/TransportResponseTrait.php create mode 100644 vendor/symfony/http-client/Retry/GenericRetryStrategy.php create mode 100644 vendor/symfony/http-client/Retry/RetryStrategyInterface.php create mode 100644 vendor/symfony/http-client/RetryableHttpClient.php create mode 100644 vendor/symfony/http-client/ScopingHttpClient.php create mode 100644 vendor/symfony/http-client/TraceableHttpClient.php create mode 100644 vendor/symfony/http-client/composer.json create mode 100644 vendor/symfony/polyfill-php73/LICENSE create mode 100644 vendor/symfony/polyfill-php73/Php73.php create mode 100644 vendor/symfony/polyfill-php73/README.md create mode 100644 vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php create mode 100644 vendor/symfony/polyfill-php73/bootstrap.php create mode 100644 vendor/symfony/polyfill-php73/composer.json create mode 100644 vendor/symfony/polyfill-php80/LICENSE create mode 100644 vendor/symfony/polyfill-php80/Php80.php create mode 100644 vendor/symfony/polyfill-php80/PhpToken.php create mode 100644 vendor/symfony/polyfill-php80/README.md create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php create mode 100644 vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php create mode 100644 vendor/symfony/polyfill-php80/bootstrap.php create mode 100644 vendor/symfony/polyfill-php80/composer.json create mode 100644 vendor/symfony/service-contracts/.gitignore create mode 100644 vendor/symfony/service-contracts/Attribute/Required.php create mode 100644 vendor/symfony/service-contracts/Attribute/SubscribedService.php create mode 100644 vendor/symfony/service-contracts/CHANGELOG.md create mode 100644 vendor/symfony/service-contracts/LICENSE create mode 100644 vendor/symfony/service-contracts/README.md create mode 100644 vendor/symfony/service-contracts/ResetInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceLocatorTrait.php create mode 100644 vendor/symfony/service-contracts/ServiceProviderInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceSubscriberInterface.php create mode 100644 vendor/symfony/service-contracts/ServiceSubscriberTrait.php create mode 100644 vendor/symfony/service-contracts/Test/ServiceLocatorTest.php create mode 100644 vendor/symfony/service-contracts/composer.json diff --git a/composer.json b/composer.json index 17bd7f3d2..b95e7e1fd 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "yoast/phpunit-polyfills": "dev-main" }, "require": { - "aws/aws-sdk-php": "^3.235" + "aws/aws-sdk-php": "^3.235", + "async-aws/s3": "^2.0" }, "scripts": { "pre-autoload-dump": "Aws\\Script\\Composer\\Composer::removeUnusedServices" diff --git a/composer.lock b/composer.lock index 102d3f949..aef52451a 100644 --- a/composer.lock +++ b/composer.lock @@ -1,11 +1,139 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "796127396252780d637c7e6db70edfc6", + "content-hash": "14ce5f2993b144fc5b52fd63402a4b23", "packages": [ + { + "name": "async-aws/core", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/core.git", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/core/zipball/e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/http-client": "^4.4.16 || ^5.1.7 || ^6.0 || ^7.0", + "symfony/http-client-contracts": "^1.1.8 || ^2.0 || ^3.0", + "symfony/service-contracts": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "async-aws/s3": "<1.1", + "symfony/http-client": "5.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.20-dev" + } + }, + "autoload": { + "psr-4": { + "AsyncAws\\Core\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Core package to integrate with AWS. This is a lightweight AWS SDK provider by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "sdk", + "sts" + ], + "support": { + "source": "https://github.com/async-aws/core/tree/1.20.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-08-07T20:00:50+00:00" + }, + { + "name": "async-aws/s3", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/s3.git", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/s3/zipball/1486ae6592a8f870da60dfc29bfc98390c7b9092", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092", + "shasum": "" + }, + "require": { + "async-aws/core": "^1.9", + "ext-dom": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "autoload": { + "psr-4": { + "AsyncAws\\S3\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "S3 client, part of the AWS SDK provided by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "s3", + "sdk" + ], + "support": { + "source": "https://github.com/async-aws/s3/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-08-07T20:00:50+00:00" + }, { "name": "aws/aws-crt-php", "version": "v1.2.1", @@ -477,6 +605,103 @@ ], "time": "2021-06-14T00:11:39+00:00" }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "time": "2021-03-05T17:36:06+00:00" + }, { "name": "psr/http-client", "version": "1.0.2", @@ -628,6 +853,56 @@ ], "time": "2023-04-04T09:50:52+00:00" }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, { "name": "ralouphie/getallheaders", "version": "3.0.3", @@ -718,6 +993,175 @@ "homepage": "https://symfony.com", "time": "2022-01-02T09:53:40+00:00" }, + { + "name": "symfony/http-client", + "version": "v5.4.26", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/19d48ef7f38e5057ed1789a503cd3eccef039bce", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.4", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "2.4" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "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": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v5.4.26" + }, + "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": "2023-07-03T12:14:50+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "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": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.2" + }, + "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": "2022-04-12T15:48:08+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.27.0", @@ -783,6 +1227,251 @@ "shim" ], "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.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": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.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": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, + "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": "2022-05-30T19:17:29+00:00" } ], "packages-dev": [ @@ -2422,5 +3111,6 @@ "platform-dev": [], "platform-overrides": { "php": "7.3.5" - } + }, + "plugin-api-version": "2.3.0" } diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index 2cae67294..9efe9d866 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -37,19 +37,20 @@ function get_s3_client() { $secret = $fv_fp->_get_option(array('digitalocean_spaces','secret')); $key = $fv_fp->_get_option(array('digitalocean_spaces','key')); - $credentials = new Aws\Credentials\Credentials( $key, $secret ); - - return Aws\S3\S3Client::factory( array( - 'credentials' => $credentials, + return new AsyncAws\S3\S3Client( array( + 'accessKeyId' => $key, + 'accessKeySecret' => $secret, 'region' => $region, - 'version' => 'latest', 'endpoint' => $endpoint ) ); + } function get_formatted_assets_data() { - $this->include_aws_sdk(); - global $fv_fp, $s3Client; + // $this->include_aws_sdk(); + $this->include_async_aws_sdk(); + + global $fv_fp; $bucket = $fv_fp->_get_option(array('digitalocean_spaces','space')); @@ -63,13 +64,52 @@ function get_formatted_assets_data() { // instantiate the S3 client with AWS credentials $s3Client = $this->get_s3_client(); + try { - - list( $request_path, $paged, $date_format ) = $this->get_metadata( $s3Client, $bucket ); + $args = array( + 'Bucket' => $bucket, + 'Delimiter' => '/', + ); + + $date_format = get_option( 'date_format' ); + + $request_path = !empty($_POST['path']) ? str_replace( 'Home/', '', stripslashes($_POST['path']) ) : false; + + if ( $request_path ) { + $args['Prefix'] = $request_path; + } + + $paged = $s3Client->listObjectsV2($args); + + foreach ($paged->getContents() as $object) { + $path = $object->getKey(); + + $item['path'] = 'Home/' . $path; + + if( $request_path ) { + $item['name'] = str_replace( $request_path, '', $path ); + } else { + $item['name'] = $path; + } + + if( $object->getSize() ) { + $dateString = $object->getLastModified()->format('Y-m-d H:i:s'); + $timetamp = strtotime($dateString); + $item['modified'] = date($date_format, $timetamp); + $item['size'] = $object->getSize(); + $item['type'] = 'file'; + + $item['link'] = ''; + + } else { + $item['type'] = 'folder'; + $item['items'] = array(); + } + + $output['items'][] = $item; + } - list($output, $sum_up ) = $this->get_output_items( $output, $s3Client, $request_path, $paged, $date_format, $bucket ); - - } catch ( Aws\S3\Exception\S3Exception $e ) { + } catch ( Exception $e ) { //echo $e->getMessage() . "\n"; $err = $e->getMessage(); $output = array( diff --git a/models/media-browser.php b/models/media-browser.php index d7fdc4755..67c9d689f 100644 --- a/models/media-browser.php +++ b/models/media-browser.php @@ -67,6 +67,12 @@ function register() { add_action( $this->ajax_action_name, array($this, 'load_assets') ); } + function include_async_aws_sdk() { + if ( ! class_exists( 'AsyncAws\S3\S3Client' ) ) { + require_once( dirname( __FILE__ ) . "/../vendor/autoload.php" ); + } + } + function include_aws_sdk() { if ( ! class_exists( 'Aws\S3\S3Client' ) ) { require_once( dirname( __FILE__ ) . "/../vendor/autoload.php" ); diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index c910a49db..000000000 --- a/package-lock.json +++ /dev/null @@ -1,12651 +0,0 @@ -{ - "name": "fv-wordpress-flowplayer", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "fv-wordpress-flowplayer", - "version": "1.0.0", - "hasInstallScript": true, - "license": "GPL-3.0", - "devDependencies": { - "@babel/core": "^7.17.9", - "@babel/preset-env": "^7.16.11", - "gulp": "^4.0.2", - "gulp-autoprefixer": "^8.0.0", - "gulp-babel": "^8.0.0", - "gulp-clean-css": "^4.3.0", - "gulp-concat": "^2.6.1", - "gulp-rename": "^2.0.0", - "gulp-sort": "^2.0.0", - "gulp-sourcemaps": "^3.0.0", - "gulp-uglify": "^3.0.2", - "gulp-wp-pot": "^2.5.0", - "gulp-zip": "^5.1.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", - "dev": true, - "dependencies": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-babel/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - ], - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "node_modules/gulp-sourcemaps/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "dependencies": { - "glob-stream": "^6.1.0", - "vinyl-sourcemap": "^1.1.0", - "to-through": "^2.0.0", - "resolve-options": "^1.1.0", - "pumpify": "^1.3.5", - "remove-bom-buffer": "^3.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "fs-mkdirp-stream": "^1.0.0", - "object.assign": "^4.0.4", - "value-or-function": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "readable-stream": "^2.3.3", - "vinyl": "^2.0.0", - "is-valid-glob": "^1.0.0", - "through2": "^2.0.0", - "graceful-fs": "^4.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@gulp-sourcemaps/identity-map/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/chokidar/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "node_modules/glob-stream/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", - "dev": true, - "dependencies": { - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "dependencies": { - "flush-write-stream": "^1.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/each-props/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-uglify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", - "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "extend-shallow": "^3.0.2", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "isobject": "^3.0.1", - "make-error-cause": "^1.1.1", - "safe-buffer": "^5.1.2", - "through2": "^2.0.0", - "uglify-js": "^3.0.5", - "vinyl-sourcemaps-apply": "^0.2.0" - } - }, - "node_modules/unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "dependencies": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "node_modules/matched": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", - "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", - "dev": true, - "dependencies": { - "glob": "^7.1.6", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", - "dev": true, - "dependencies": { - "buffer-equal": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", - "dev": true, - "dependencies": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/matchdep/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "extraneous": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/fs-mkdirp-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/gulp-wp-pot": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/gulp-wp-pot/-/gulp-wp-pot-2.5.0.tgz", - "integrity": "sha512-3IIVEsgAaRFi4DWv5hRZcM7VEsCtGD4ZxgPL8qPdX+yrSpwD8I2+Q1cP3olXhn7KLJsnGSNuqor5sxo97H5pmQ==", - "dev": true, - "dependencies": { - "plugin-error": "^1.0.1", - "vinyl": "^2.2.1", - "wp-pot": "^1.9.6" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/remove-bom-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-uglify/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "dependencies": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/gulp-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", - "integrity": "sha512-MyTel3FXOdh1qhw1yKhpimQrAmur9q1X0ZigLmCOxouQD+BD3za9/89O+HfbgBQvvh4igEbp0/PUWO+VqGYG1g==", - "dev": true, - "dependencies": { - "through2": "^2.0.1" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/array-initial/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "dependencies": { - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==", - "dev": true, - "dependencies": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "dependencies": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/micromatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==", - "dev": true, - "dependencies": { - "sparkles": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/gulp-concat/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-sourcemaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz", - "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==", - "dev": true, - "dependencies": { - "@gulp-sourcemaps/identity-map": "^2.0.1", - "@gulp-sourcemaps/map-sources": "^1.0.0", - "acorn": "^6.4.1", - "convert-source-map": "^1.0.0", - "css": "^3.0.0", - "debug-fabulous": "^1.0.0", - "detect-newline": "^2.0.0", - "graceful-fs": "^4.0.0", - "source-map": "^0.6.0", - "strip-bom-string": "^1.0.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-clean-css": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz", - "integrity": "sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg==", - "dev": true, - "dependencies": { - "clean-css": "4.2.3", - "plugin-error": "1.0.1", - "through2": "3.0.1", - "vinyl-sourcemaps-apply": "0.2.1" - } - }, - "node_modules/gulp-uglify/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "dev": true, - "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@gulp-sourcemaps/map-sources/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "dependencies": { - "invert-kv": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "dependencies": { - "once": "^1.3.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "dependencies": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - } - }, - "node_modules/glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "dependencies": { - "sparkles": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", - "dev": true, - "dependencies": { - "sver-compat": "^1.5.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/liftoff/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/gulp-uglify/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/matchdep/node_modules/findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "dependencies": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "node_modules/php-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.1.2.tgz", - "integrity": "sha512-RRCMK/bCKYPLRhlpfMlVVVsaIesuW+X6UxRqWjm7dTAmTZk8PvD6hCmG/RVeDzse7iqYWJwLJeqEbaGLC+aHeQ==", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/plugin-error/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "dev": true, - "dependencies": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.1" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/plugin-error/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "dependencies": { - "ansi-wrap": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "dependencies": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/split-string/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/gulp-zip": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.1.0.tgz", - "integrity": "sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw==", - "dev": true, - "dependencies": { - "get-stream": "^5.2.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "vinyl": "^2.1.0", - "yazl": "^2.5.1" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "gulp": ">=4" - }, - "peerDependenciesMeta": { - "gulp": { - "optional": true - } - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/micromatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "dependencies": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/gulp-uglify/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", - "dev": true, - "dependencies": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/plugin-error/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "node_modules/which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "node_modules/@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-sourcemap/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/glob-stream/node_modules/glob-parent": { - "version": "^6.0.1", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "node_modules/fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://www.patreon.com/infusion" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/to-through/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@gulp-sourcemaps/identity-map/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "^6.0.1", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "dependencies": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "dependencies": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-rename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz", - "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/gulp-clean-css/node_modules/through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "dev": true, - "dependencies": { - "readable-stream": "2 || 3" - } - }, - "node_modules/vinyl-fs/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", - "dev": true, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", - "dev": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", - "dev": true, - "dependencies": { - "each-props": "^1.3.2", - "is-plain-object": "^5.0.0" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/nanomatch/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", - "dev": true, - "dependencies": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "dependencies": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "node_modules/gulp-autoprefixer": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-8.0.0.tgz", - "integrity": "sha512-sVR++PIaXpa81p52dmmA/jt50bw0egmylK5mjagfgOJ8uLDGaF9tHyzvetkY9Uo0gBZUS5sVqN3kX/GlUKOyog==", - "dev": true, - "dependencies": { - "autoprefixer": "^10.2.6", - "fancy-log": "^1.3.3", - "plugin-error": "^1.0.1", - "postcss": "^8.3.0", - "through2": "^4.0.2", - "vinyl-sourcemaps-apply": "^0.2.1" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "gulp": ">=4" - }, - "peerDependenciesMeta": { - "gulp": { - "optional": true - } - } - }, - "node_modules/cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true, - "optional": true - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "dev": true, - "dependencies": { - "browserslist": "^4.21.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", - "dev": true, - "dependencies": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "dependencies": { - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "semver": "^6.3.0", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "core-js-compat": "^3.25.1", - "@babel/compat-data": "^7.20.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/preset-modules": "^0.1.5", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/types": "^7.20.2", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-reserved-words": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "dependencies": { - "lcid": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "dependencies": { - "path-root-regex": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/gulp-sort/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha512-4TO2Y3HkBnis4c0dxhAgD/jprySYLACf7nwN6V0HAHDx59g12WlRpUmFy1bRHamjGUEEBrEvCq6SUpsEE2lhUg==", - "dev": true, - "dependencies": { - "make-error": "^1.2.0" - } - }, - "node_modules/path-sort": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-sort/-/path-sort-0.1.0.tgz", - "integrity": "sha512-70MSq7edKtbODYKkqXYzSMQxtYMjDgP3K6D15Fu4KUvpyBPlxDWPvv8JI9GjNDF2K5baPHFEtlg818dOmf2ifg==", - "dev": true - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/snapdragon/node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/micromatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "dependencies": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "node_modules/async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", - "dev": true, - "dependencies": { - "source-map": "^0.5.1" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/through2-filter/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-zip/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/@gulp-sourcemaps/identity-map/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", - "dev": true, - "dependencies": { - "async-done": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/fined/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", - "dev": true, - "dependencies": { - "glogg": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "dependencies": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-last/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha512-a2scActrQrDBpBbR3WUZGyGS1JEPLg5PZJdIa7/Bi3GuKAmPYDK6SFhy/NZq5R8KsKKFvtfR0fakbUCcKGCCjg==", - "dev": true, - "dependencies": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp-babel": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-8.0.0.tgz", - "integrity": "sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ==", - "dev": true, - "dependencies": { - "plugin-error": "^1.0.1", - "replace-ext": "^1.0.0", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "dependencies": { - "kind-of": "^5.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/make-iterator/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/debug-fabulous/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "dependencies": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.1" - } - }, - "node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/@gulp-sourcemaps/identity-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", - "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==", - "dev": true, - "dependencies": { - "acorn": "^6.4.1", - "normalize-path": "^3.0.0", - "postcss": "^7.0.16", - "source-map": "^0.6.0", - "through2": "^3.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/nanomatch/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "dependencies": { - "yargs": "^7.1.0", - "v8flags": "^3.2.0", - "ansi-colors": "^1.0.1", - "color-support": "^1.1.3", - "copy-props": "^2.0.1", - "replace-homedir": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "fancy-log": "^1.3.2", - "matchdep": "^2.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "isobject": "^3.0.1", - "archy": "^1.0.0", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "mute-stdout": "^1.0.0", - "array-sort": "^1.0.0", - "concat-stream": "^1.6.0", - "liftoff": "^3.1.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", - "dev": true, - "dependencies": { - "value-or-function": "^3.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/wp-pot": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/wp-pot/-/wp-pot-1.10.2.tgz", - "integrity": "sha512-NJ9+dsSilghAYMiuGdURJSbKFf9Z2mH+P6ojT8Nw1Pp8KuwvHdRTFTYK73THlYzohUEXlQGpvKkz+mJb8K1ToA==", - "dev": true, - "dependencies": { - "espree": "^9.3.1", - "matched": "^5.0.1", - "path-sort": "^0.1.0", - "php-parser": "^3.0.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.2" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz", - "integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==", - "dev": true - }, - "@babel/core": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.2.tgz", - "integrity": "sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.2", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.1", - "@babel/parser": "^7.20.2", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - } - }, - "@babel/generator": { - "version": "7.20.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz", - "integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", - "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz", - "integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", - "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", - "dev": true, - "requires": { - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" - } - }, - "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dev": true, - "requires": { - "@babel/types": "^7.20.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" - } - }, - "@babel/helpers": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz", - "integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.0" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz", - "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==", - "dev": true - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" - } - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", - "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", - "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.1" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz", - "integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", - "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.19.1", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", - "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", - "dev": true, - "requires": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", - "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", - "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-simple-access": "^7.19.4" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", - "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.19.1" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz", - "integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.20.2" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", - "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.9" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" - } - }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/runtime": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz", - "integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.10" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@babel/traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz", - "integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.1", - "@babel/types": "^7.20.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz", - "integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@gulp-sourcemaps/identity-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", - "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==", - "dev": true, - "requires": { - "acorn": "^6.4.1", - "normalize-path": "^3.0.0", - "postcss": "^7.0.16", - "source-map": "^0.6.0", - "through2": "^3.0.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==", - "dev": true, - "requires": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - } - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", - "dev": true, - "requires": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", - "dev": true, - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.3" - } - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001431", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz", - "integrity": "sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^6.0.1", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "dependencies": { - "glob-parent": { - "version": "^6.0.1", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - } - } - }, - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true - }, - "copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", - "dev": true, - "requires": { - "each-props": "^1.3.2", - "is-plain-object": "^5.0.0" - } - }, - "core-js-compat": { - "version": "3.26.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", - "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", - "dev": true, - "requires": { - "browserslist": "^4.21.4" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "requires": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true - } - } - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^6.0.1", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "glob-parent": { - "version": "^6.0.1", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - } - }, - "gulp-autoprefixer": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-8.0.0.tgz", - "integrity": "sha512-sVR++PIaXpa81p52dmmA/jt50bw0egmylK5mjagfgOJ8uLDGaF9tHyzvetkY9Uo0gBZUS5sVqN3kX/GlUKOyog==", - "dev": true, - "requires": { - "autoprefixer": "^10.2.6", - "fancy-log": "^1.3.3", - "plugin-error": "^1.0.1", - "postcss": "^8.3.0", - "through2": "^4.0.2", - "vinyl-sourcemaps-apply": "^0.2.1" - } - }, - "gulp-babel": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-8.0.0.tgz", - "integrity": "sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ==", - "dev": true, - "requires": { - "plugin-error": "^1.0.1", - "replace-ext": "^1.0.0", - "through2": "^2.0.0", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-clean-css": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz", - "integrity": "sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg==", - "dev": true, - "requires": { - "clean-css": "4.2.3", - "plugin-error": "1.0.1", - "through2": "3.0.1", - "vinyl-sourcemaps-apply": "0.2.1" - }, - "dependencies": { - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "dev": true, - "requires": { - "readable-stream": "2 || 3" - } - } - } - }, - "gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha512-a2scActrQrDBpBbR3WUZGyGS1JEPLg5PZJdIa7/Bi3GuKAmPYDK6SFhy/NZq5R8KsKKFvtfR0fakbUCcKGCCjg==", - "dev": true, - "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-rename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-2.0.0.tgz", - "integrity": "sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ==", - "dev": true - }, - "gulp-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", - "integrity": "sha512-MyTel3FXOdh1qhw1yKhpimQrAmur9q1X0ZigLmCOxouQD+BD3za9/89O+HfbgBQvvh4igEbp0/PUWO+VqGYG1g==", - "dev": true, - "requires": { - "through2": "^2.0.1" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-sourcemaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz", - "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==", - "dev": true, - "requires": { - "@gulp-sourcemaps/identity-map": "^2.0.1", - "@gulp-sourcemaps/map-sources": "^1.0.0", - "acorn": "^6.4.1", - "convert-source-map": "^1.0.0", - "css": "^3.0.0", - "debug-fabulous": "^1.0.0", - "detect-newline": "^2.0.0", - "graceful-fs": "^4.0.0", - "source-map": "^0.6.0", - "strip-bom-string": "^1.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-uglify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", - "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "extend-shallow": "^3.0.2", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "isobject": "^3.0.1", - "make-error-cause": "^1.1.1", - "safe-buffer": "^5.1.2", - "through2": "^2.0.0", - "uglify-js": "^3.0.5", - "vinyl-sourcemaps-apply": "^0.2.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-wp-pot": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/gulp-wp-pot/-/gulp-wp-pot-2.5.0.tgz", - "integrity": "sha512-3IIVEsgAaRFi4DWv5hRZcM7VEsCtGD4ZxgPL8qPdX+yrSpwD8I2+Q1cP3olXhn7KLJsnGSNuqor5sxo97H5pmQ==", - "dev": true, - "requires": { - "plugin-error": "^1.0.1", - "vinyl": "^2.2.1", - "wp-pot": "^1.9.6" - } - }, - "gulp-zip": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.1.0.tgz", - "integrity": "sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw==", - "dev": true, - "requires": { - "get-stream": "^5.2.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "vinyl": "^2.1.0", - "yazl": "^2.5.1" - }, - "dependencies": { - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha512-+F4GzLjwHNNDEAJW2DC1xXfEoPkRDmUdJ7CBYw4MpqtDwOnqdImJl7GWlpqx+Wko6//J8uKTnIe4wZSv7yCqmw==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha512-4TO2Y3HkBnis4c0dxhAgD/jprySYLACf7nwN6V0HAHDx59g12WlRpUmFy1bRHamjGUEEBrEvCq6SUpsEE2lhUg==", - "dev": true, - "requires": { - "make-error": "^1.2.0" - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "matched": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/matched/-/matched-5.0.1.tgz", - "integrity": "sha512-E1fhSTPRyhAlNaNvGXAgZQlq1hL0bgYMTk/6bktVlIhzUnX/SZs7296ACdVeNJE8xFNGSuvd9IpI7vSnmcqLvw==", - "dev": true, - "requires": { - "glob": "^7.1.6", - "picomatch": "^2.2.1" - } - }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true, - "optional": true - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - } - } - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true - }, - "path-sort": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-sort/-/path-sort-0.1.0.tgz", - "integrity": "sha512-70MSq7edKtbODYKkqXYzSMQxtYMjDgP3K6D15Fu4KUvpyBPlxDWPvv8JI9GjNDF2K5baPHFEtlg818dOmf2ifg==", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "php-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/php-parser/-/php-parser-3.1.2.tgz", - "integrity": "sha512-RRCMK/bCKYPLRhlpfMlVVVsaIesuW+X6UxRqWjm7dTAmTZk8PvD6hCmG/RVeDzse7iqYWJwLJeqEbaGLC+aHeQ==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true - }, - "postcss": { - "version": "8.4.19", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", - "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", - "dev": true, - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "regexpu-core": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", - "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", - "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - } - }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", - "dev": true - }, - "regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true - } - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true - }, - "source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - } - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "dev": true - }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true - }, - "undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", - "dev": true - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", - "dev": true - }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", - "dev": true, - "requires": { - "source-map": "^0.5.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "wp-pot": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/wp-pot/-/wp-pot-1.10.2.tgz", - "integrity": "sha512-NJ9+dsSilghAYMiuGdURJSbKFf9Z2mH+P6ojT8Nw1Pp8KuwvHdRTFTYK73THlYzohUEXlQGpvKkz+mJb8K1ToA==", - "dev": true, - "requires": { - "espree": "^9.3.1", - "matched": "^5.0.1", - "path-sort": "^0.1.0", - "php-parser": "^3.0.3" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.1" - } - }, - "yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - }, - "yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3" - } - } - } -} \ No newline at end of file diff --git a/vendor/async-aws/core/CHANGELOG.md b/vendor/async-aws/core/CHANGELOG.md new file mode 100644 index 000000000..ccf1ee19a --- /dev/null +++ b/vendor/async-aws/core/CHANGELOG.md @@ -0,0 +1,433 @@ +# Change Log + +## 1.20.0 + +### Added + +- Support for LocationService +- Support for hostPrefix in requests +- AWS api-change: API updates for the AWS Security Token Service +- Support for SSO credentials +- Avoid overriding the exception message with the raw message + +### Changed + +- Improve parameter type and return type in phpdoc + +## 1.19.0 + +### Added + +- Support for Symfony 7 +- Support for Athena +- Support for MediaConvert +- Support for IMDS v2 authentication +- Support for using endpoint discovery with parameters passed in the query string or the path + +### Fixed + +- Fix potential malformed URI in discovered endpoints + +## 1.18.1 + +### Changed + +- AWS enhancement: Documentation updates. +- Fix deprecation by adding return type on reset methods + +## 1.18.0 + +### Added + +- Support for Scheduler + +## 1.17.0 + +### Added + +- Support for Iot Data + +## 1.16.0 + +### Added + +- Support for endpoint discovery +- Support for Iot Core + +## 1.15.0 + +### Added + +- Support for CodeBuild +- Support for CodeCommit +- Support for TimestreamQuery +- Support for TimestreamWrite +- AWS enhancement: Documentation updates. +- Reverted the automated decoration of the injected HttpClient +- Added an AwsHttpClientFactory to help people creating retryable clients +- Add 403 errors in the list of potential retryiable operations + +### Changed + +- Set default value to `false` for the `sendChunkedBody` option. + +## 1.14.0 + +### Added + +- Make the injected HttpClient decorated by our `RetryableHttpClient` +- Support for KMS + +### Fixed + +- Issue with symfony http-client when posting empty payload + +## 1.13.0 + +### Added + +- AWS api-change: Added `us-iso-west-1` region +- AWS api-change: Used regional endpoint for `us` regions +- AWS enhancement: Documentation updates. +- Support for AppSync +- Support for XRay + +## 1.12.0 + +### Added + +- Support for Firehose +- Support for ElastiCache +- Support for CloudWatchClient +- Support for psr/log 2.0 and 3.0 + +## 1.11.0 + +### Added + +- Support for StepFunctions +- Support for Kinesis +- Support for SecretsManager +- Support for Symfony contracts v3 +- AWS enhancement: Documentation updates for AWS Security Token Service. + +### Fixed + +- Wrap the HttpClient's decoding exception in UnparsableResponse. + +## 1.10.0 + +### Added + +- AWS enhancement: STS now supports assume role with Web Identity using JWT token length upto 20000 characters +- AWS api-change: This release adds the SourceIdentity parameter that can be set when assuming a role. +- Support for Symfony 6 + +## 1.9.2 + +### Fixed + +- Support for psr/cache v2 and v3 +- Fix forming signature with multiple spaces + +## 1.9.1 + +### Fixed + +- Make sure mocked results have a response with `Response::$bodyDownloaded = true`. + +## 1.9.0 + +### Added + +- Changed case of object's properties to camelCase. +- Added documentation in class headers. +- Removed `final` from `ClientException` and `ServerException`. +- Make Responses thrown Business Exception when AwsErrorCode <-> Exception class mapping provided through RequestContext. +- Added domain exceptions. +- Improved Aws Error parsing by using specialized AwsErrorFactory. + +### Fixed + +- Exception thrown twice by waiters. + +## 1.8.0 + +### Added + +- Added option `sendChunkedBody` dedicated to S3. + +## 1.7.2 + +- Make sure we can get credentials even if the cache storage fails +- Clear `realpath` cache to make sure we get the latest credentials token + +## 1.7.1 + +### Fixed + +- Fix for an edge case where aws config file could be a directory +- Fix when AWS profile name is only digits + +## 1.7.0 + +### Added + +- A `AwsRetryStrategy` to define what HTTP request we retry +- Support for Elastic Container Registry (ECR) in `AwsClientFactory` +- Read "region" from ini files. +- Support for hard coded `roleArn` in `ConfigurationProvider` +- Added exception `AsyncAws\Core\Exception\UnexpectedValue` and `AsyncAws\Core\Exception\UnparsableResponse` + +### Fixed + +- Merge configuration if a profile is spread out over multiple files. Ie if `[profile company]` is defined in both `~/.aws/config` and `~/.aws/credentials`. +- All exceptions thrown must extend `AsyncAws\Core\Exception\Exception` + +## 1.6.0 + +### Added + +- Support for Rekognition in `AwsClientFactory` + +## 1.5.0 + +### Added + +- Support for `debug` configuration option to log HTTP requests and responses +- Use Symfony `RetryableHttpClient` when available. + +### Fixed + +- Allow signing request with non-standard region when using custom endpoint? +- Fix unresolved Env Variable in some php configuration + +## 1.4.2 + +### Fixed + +- Fixed logic in `AbstractApi::getSigner()` when passing `@region` to an API operation + +## 1.4.1 + +### Fixed + +- Make sure passing `@region` to an API operation has effect. +- Check that both AWS access id and secret exists before using them. + +## 1.4.0 + +### Added + +- Allow to pass additional content to `ResultMockFactory::createFailing()` + +## 1.3.0 + +### Added + +- Support for PHP 8 +- Added second parameter `$preferredChunkSize` to `StreamFactory::create()` +- Support for CloudFront in `AwsClientFactory` +- Support for RdsDataService in `AwsClientFactory` + +### Fixed + +- Allows non-AWS regions when using custom endpoints + +### Changed + +- Add more context to error logs +- Log level for 404 responses changed to "info". + +## 1.2.0 + +### Added + +- Support for EventBridge in `AwsClientFactory` +- Support for IAM in `AwsClientFactory` +- Add a `PsrCacheProvider` and `SymfonyCacheProvider` to persists crendentials in a cache pool +- Add a `Credential::adjustExpireDate` method for adjusting the time according to the time difference with AWS clock +- Support for global and regional endpoints +- Add a `Configuration::optionExists` to allow third parties to check if an option is available (needed by libraries supporting several versions of core) + +### Deprecation + +- Clients extending `AbstractApi` should override `getEndpointMetata`. The method will be abstract in 2.0 +- Custom endpoints should not contain `%region%` and `%service` placeholder. They won't be replaced anymore in 2.0 +- Protected methods `getServiceCode`, `getSignatureVersion` and `getSignatureScopeName` of AbstractApi are deprecated and will be removed in 2.0 + +### Fixed + +- Fix signing of requests with a header containing a date (like `expires` in `S3`). +- Fix thread safety regarding env vars by using `$_SERVER` instead of `getenv()`. + +## 1.1.0 + +### Added + +- Support for ECS Credentials Provider +- Support for Cognito Identity Provider client in `AwsClientFactory` +- Support for Cloud Watch Log client in `AwsClientFactory` + +### Fixed + +- Fixed invalid chunking of request with large body for most clients but S3. This version removed the invalid code from SignerV4 to make sure requests are not chunked. +- Use camelCase for all getter methods. + +## 1.0.0 + +### Added + +- Support for CodeDeploy client in `AwsClientFactory` + +### Fixed + +- Handle Aws Error type in JsonRest error responses + +## 0.5.4 + +### Added + +- Logging on HTTP exceptions. + +## 0.5.3 + +### Added + +- Support for SSM client in `AwsClientFactory` +- Support for Waiters in `ResultMockFactory` + +## 0.5.2 + +### Fixed + +- Add support for `Content-Type: application/x-amz-json-1.1` in test case. + +## 0.5.1 + +### Added + +- Add `Configuration::isDefault` methods. + +### Fixed + +- Allow mocking of Results classes named "*Result" + +## 0.5.0 + +### Added + +- Add support for multiregion via `@region` input parameter. +- DynamoDB support. +- `ResultMockFactory` was updated with `createFailing()` and support for pagination. +- `AbstractApi::presign()`. +- `Result::wait()` for multiplexing downloads. +- Interface `AsyncAws\Core\Input`. +- `AsyncAws\Core\Stream\ResponseBodyResourceStream` and `AsyncAws\Core\Stream\ResponseBodyStream`. +- Internal `AsyncAws\Core\Response` to encapsulate the HTTP client. +- Internal `AsyncAws\Core\RequestContext`. +- Internal `AsyncAws\Core\Stream\RewindableStream`. + +### Removed + +- The input's `validate()` function was merged with the `request()` function. +- `Configuration::isDefault()`. +- Protected property `AbstractApi::$logger`. +- `AsyncAws\Core\StreamableBody` in favor of `AsyncAws\Core\Stream\ResponseBodyStream`. + +### Changed + +- Exceptions will contain more information from the HTTP response. +- Moved STS value objects to a dedicated namespace. +- The `AsyncAws\Core\Sts\Input\*` and `AsyncAws\Core\Sts\ValueObject*` classes are marked final. +- Using `DateTimeImmutable` instead of `DateTimeInterface`. +- Protected properties `AbstractApi::$httpClient`, `AbstractApi::$configuration` and `AbstractApi::$credentialProvider` are now private. +- `AbstractApi::getResponse()` has new signature. New optional second argument `?RequestContext $context = null` and the return type is `AsyncAws\Core\Response`. +- The `CredentialProvider`s and `Configuration` are now `final`. +- Renamed `AsyncAws\Core\Stream\Stream` to `AsyncAws\Core\Stream\RequestStream`. +- Renamed `AsyncAws\Core\StreamableBodyInterface` to `AsyncAws\Core\Stream\ResultStream`. +- The `ResultStream::getChunks()` now returns a iterable of string. + +### Fixed + +- Bugfix in `WebIdentityProvider` + +## 0.4.0 + +### Added + +- Test class `AsyncAws\Core\Test\SimpleStreamableBody` + +### Changed + +- Moved `AsyncAws\Core\Signer\Request` to `AsyncAws\Core\Request`. +- Added constructor argument to `AsyncAws\Core\Request::__construct()` to support query parameters. +- Renamed `AsyncAws\Core\Request::getUrl()` to `AsyncAws\Core\Request::getEndpoint()` +- Class `AsyncAws\Core\Stream\StreamFactory` is not internal anymore. +- Removed `requestBody()`, `requestHeaders()`, `requestQuery()` and `requestUri()` input classes. They are replaced with `request()`. + +### Removed + +- Public `AbstractApi::request()` was removed. +- Protected function `AbstractApi::getEndpoint()` was made private. + +### Fixed + +- Fix Instance Provider Role fetching + +## 0.3.3 + +### Added + +- Added a `ResultMockFactory` to helps creating tests + +### Fixed + +- Http method is replaced by PUT in REST calls + +## 0.3.2 + +### Fixed + +- `Configuration` don't mix anymore attributes injected by php array and env variables. + +## 0.3.1 + +### Added + +- `AbstractApi::getConfiguration()` + +### Fixed + +- Make sure `Configuration::create(['foo'=>null])` is using the default value of "foo". + +## 0.3.0 + +### Added + +- Requests can now be streamed +- Streamable request accepts iterable alongside string, callable, resource +- Support for getting credentials from Web Identity or OpenID Connect Federation. (`WebIdentityProvider`) + +### Changed + +- Rename namespace `Signers` into `Signer`. + +## 0.2.0 + +### Added + +- Class `AsyncAws\Core\Credentials\NullProvider` +- Methods `AwsClient::cloudFormation()`, `AwsClient::lambda()`, `AwsClient::sns()` +- Protected methods `Result::registerPrefetch()` and `Result::unregisterPrefetch()` +- Timeout parameter to `InstanceProvider::__construct()` + +### Changed + +- Removed `AwsClient` and replaced it with `AwsClientFactory` +- Class `AsyncAws\Core\Signer\Request` is marked as internal +- Make sure behavior of calling `Result::resolve()` is consistent + +## 0.1.0 + +First version diff --git a/vendor/async-aws/core/LICENSE b/vendor/async-aws/core/LICENSE new file mode 100644 index 000000000..191fcfb40 --- /dev/null +++ b/vendor/async-aws/core/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Jérémy Derussé, Tobias Nyholm + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/async-aws/core/README.md b/vendor/async-aws/core/README.md new file mode 100644 index 000000000..f1188d7bf --- /dev/null +++ b/vendor/async-aws/core/README.md @@ -0,0 +1,21 @@ +# AsyncAws Core + +![](https://github.com/async-aws/core/workflows/Tests/badge.svg?branch=master) +![](https://github.com/async-aws/core/workflows/BC%20Check/badge.svg?branch=master) + +The repository contains shared classes between all AWS services. It also contains +the STS client to handle authentication. + +## Install + +```cli +composer require async-aws/core +``` + +## Documentation + +See https://async-aws.com for documentation. + +## Contribute + +Contributions are welcome and appreciated. Please read https://async-aws.com/contribute/ diff --git a/vendor/async-aws/core/composer.json b/vendor/async-aws/core/composer.json new file mode 100644 index 000000000..dbc0851c5 --- /dev/null +++ b/vendor/async-aws/core/composer.json @@ -0,0 +1,44 @@ +{ + "name": "async-aws/core", + "description": "Core package to integrate with AWS. This is a lightweight AWS SDK provider by AsyncAws.", + "license": "MIT", + "type": "library", + "keywords": [ + "aws", + "amazon", + "sdk", + "async-aws", + "sts" + ], + "require": { + "php": "^7.2.5 || ^8.0", + "ext-SimpleXML": "*", + "ext-hash": "*", + "ext-json": "*", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/http-client": "^4.4.16 || ^5.1.7 || ^6.0 || ^7.0", + "symfony/http-client-contracts": "^1.1.8 || ^2.0 || ^3.0", + "symfony/service-contracts": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "async-aws/s3": "<1.1", + "symfony/http-client": "5.2.0" + }, + "autoload": { + "psr-4": { + "AsyncAws\\Core\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "AsyncAws\\Core\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.20-dev" + } + } +} diff --git a/vendor/async-aws/core/roave-bc-check.yaml b/vendor/async-aws/core/roave-bc-check.yaml new file mode 100644 index 000000000..2fbae213d --- /dev/null +++ b/vendor/async-aws/core/roave-bc-check.yaml @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - '#ReflectionClass "PHPUnit\\Framework\\TestCase" could not be found in the located source#' diff --git a/vendor/async-aws/core/src/AbstractApi.php b/vendor/async-aws/core/src/AbstractApi.php new file mode 100644 index 000000000..ad48a6912 --- /dev/null +++ b/vendor/async-aws/core/src/AbstractApi.php @@ -0,0 +1,358 @@ + + * @author Jérémy Derussé + */ +abstract class AbstractApi +{ + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * @var Configuration + */ + private $configuration; + + /** + * @var CredentialProvider + */ + private $credentialProvider; + + /** + * @var array + */ + private $signers; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var AwsErrorFactoryInterface + */ + private $awsErrorFactory; + + /** + * @var EndpointCache + */ + private $endpointCache; + + /** + * @param Configuration|array $configuration + */ + public function __construct($configuration = [], ?CredentialProvider $credentialProvider = null, ?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null) + { + if (\is_array($configuration)) { + $configuration = Configuration::create($configuration); + } elseif (!$configuration instanceof Configuration) { + throw new InvalidArgument(sprintf('First argument to "%s::__construct()" must be an array or an instance of "%s"', static::class, Configuration::class)); + } + + $this->logger = $logger ?? new NullLogger(); + $this->awsErrorFactory = $this->getAwsErrorFactory(); + $this->endpointCache = new EndpointCache(); + if (!isset($httpClient)) { + $httpClient = HttpClient::create(); + if (class_exists(RetryableHttpClient::class)) { + /** @psalm-suppress MissingDependency */ + $httpClient = new RetryableHttpClient( + $httpClient, + new AwsRetryStrategy(AwsRetryStrategy::DEFAULT_RETRY_STATUS_CODES, 1000, 2.0, 0, 0.1, $this->awsErrorFactory), + 3, + $this->logger + ); + } + } + $this->httpClient = $httpClient; + $this->configuration = $configuration; + $this->credentialProvider = $credentialProvider ?? new CacheProvider(ChainProvider::createDefaultChain($this->httpClient, $this->logger)); + } + + final public function getConfiguration(): Configuration + { + return $this->configuration; + } + + final public function presign(Input $input, ?\DateTimeImmutable $expires = null): string + { + $request = $input->request(); + $request->setEndpoint($this->getEndpoint($request->getUri(), $request->getQuery(), $input->getRegion())); + + if (null !== $credentials = $this->credentialProvider->getCredentials($this->configuration)) { + $this->getSigner($input->getRegion())->presign($request, $credentials, new RequestContext(['expirationDate' => $expires])); + } + + return $request->getEndpoint(); + } + + /** + * @deprecated + */ + protected function getServiceCode(): string + { + throw new LogicException(sprintf('The method "%s" should not be called. The Client "%s" must implement the "%s" method.', __FUNCTION__, \get_class($this), 'getEndpointMetadata')); + } + + /** + * @deprecated + */ + protected function getSignatureVersion(): string + { + throw new LogicException(sprintf('The method "%s" should not be called. The Client "%s" must implement the "%s" method.', __FUNCTION__, \get_class($this), 'getEndpointMetadata')); + } + + /** + * @deprecated + */ + protected function getSignatureScopeName(): string + { + throw new LogicException(sprintf('The method "%s" should not be called. The Client "%s" must implement the "%s" method.', __FUNCTION__, \get_class($this), 'getEndpointMetadata')); + } + + final protected function getResponse(Request $request, ?RequestContext $context = null): Response + { + $request->setEndpoint($this->getDiscoveredEndpoint($request->getUri(), $request->getQuery(), $context ? $context->getRegion() : null, $context ? $context->usesEndpointDiscovery() : false, $context ? $context->requiresEndpointDiscovery() : false)); + + if (null !== $credentials = $this->credentialProvider->getCredentials($this->configuration)) { + $this->getSigner($context ? $context->getRegion() : null)->sign($request, $credentials, $context ?? new RequestContext()); + } + + $length = $request->getBody()->length(); + if (null !== $length && !$request->hasHeader('content-length')) { + $request->setHeader('content-length', (string) $length); + } + + // Some servers (like testing Docker Images) does not support `Transfer-Encoding: chunked` requests. + // The body is converted into string to prevent curl using `Transfer-Encoding: chunked` unless it really has to. + if (($requestBody = $request->getBody()) instanceof StringStream) { + $requestBody = $requestBody->stringify(); + } + + $response = $this->httpClient->request( + $request->getMethod(), + $request->getEndpoint(), + [ + 'headers' => $request->getHeaders(), + ] + (0 === $length ? [] : ['body' => $requestBody]) + ); + + if ($debug = filter_var($this->configuration->get('debug'), \FILTER_VALIDATE_BOOLEAN)) { + $this->logger->debug('AsyncAws HTTP request sent: {method} {endpoint}', [ + 'method' => $request->getMethod(), + 'endpoint' => $request->getEndpoint(), + 'headers' => json_encode($request->getHeaders()), + 'body' => 0 === $length ? null : $requestBody, + ]); + } + + return new Response($response, $this->httpClient, $this->logger, $this->awsErrorFactory, $this->endpointCache, $request, $debug, $context ? $context->getExceptionMapping() : []); + } + + /** + * @return array + */ + protected function getSignerFactories(): array + { + return [ + 'v4' => static function (string $service, string $region) { + return new SignerV4($service, $region); + }, + ]; + } + + protected function getAwsErrorFactory(): AwsErrorFactoryInterface + { + return new ChainAwsErrorFactory(); + } + + /** + * Returns the AWS endpoint metadata for the given region. + * When user did not provide a region, the client have to either return a global endpoint or fallback to + * the Configuration::DEFAULT_REGION constant. + * + * This implementation is a BC layer for client that does not require core:^1.2. + * + * @param ?string $region region provided by the user (without fallback to a default region) + * + * @return array{endpoint: string, signRegion: string, signService: string, signVersions: string[]} + */ + protected function getEndpointMetadata(?string $region): array + { + /** @psalm-suppress TooManyArguments */ + trigger_deprecation('async-aws/core', '1.2', 'Extending "%s"" without overriding "%s" is deprecated. This method will be abstract in version 2.0.', __CLASS__, __FUNCTION__); + + /** @var string $endpoint */ + $endpoint = $this->configuration->get('endpoint'); + /** @var string $region */ + $region = $region ?? $this->configuration->get('region'); + + return [ + 'endpoint' => strtr($endpoint, [ + '%region%' => $region, + '%service%' => $this->getServiceCode(), + ]), + 'signRegion' => $region, + 'signService' => $this->getSignatureScopeName(), + 'signVersions' => [$this->getSignatureVersion()], + ]; + } + + /** + * Build the endpoint full uri. + * + * @param string $uri or path + * @param array $query parameters that should go in the query string + * @param ?string $region region provided by the user in the `@region` parameter of the Input + */ + protected function getEndpoint(string $uri, array $query, ?string $region): string + { + $region = $region ?? ($this->configuration->isDefault('region') ? null : $this->configuration->get('region')); + if (!$this->configuration->isDefault('endpoint')) { + /** @var string $endpoint */ + $endpoint = $this->configuration->get('endpoint'); + } else { + $metadata = $this->getEndpointMetadata($region); + $endpoint = $metadata['endpoint']; + } + + if (false !== strpos($endpoint, '%region%') || false !== strpos($endpoint, '%service%')) { + /** @psalm-suppress TooManyArguments */ + trigger_deprecation('async-aws/core', '1.2', 'providing an endpoint with placeholder is deprecated and will be ignored in version 2.0. Provide full endpoint instead.'); + + $endpoint = strtr($endpoint, [ + '%region%' => $region ?? $this->configuration->get('region'), + '%service%' => $this->getServiceCode(), // if people provides a custom endpoint 'http://%service%.localhost/ + ]); + } + + $endpoint .= $uri; + if ([] === $query) { + return $endpoint; + } + + return $endpoint . (false === strpos($endpoint, '?') ? '?' : '&') . http_build_query($query, '', '&', \PHP_QUERY_RFC3986); + } + + /** + * @return EndpointInterface[] + */ + protected function discoverEndpoints(?string $region): array + { + throw new LogicException(sprintf('The Client "%s" must implement the "%s" method.', \get_class($this), 'discoverEndpoints')); + } + + /** + * @param array $query + * + * @return string + */ + private function getDiscoveredEndpoint(string $uri, array $query, ?string $region, bool $usesEndpointDiscovery, bool $requiresEndpointDiscovery) + { + if (!$this->configuration->isDefault('endpoint')) { + return $this->getEndpoint($uri, $query, $region); + } + + $usesEndpointDiscovery = $requiresEndpointDiscovery || ($usesEndpointDiscovery && filter_var($this->configuration->get(Configuration::OPTION_ENDPOINT_DISCOVERY_ENABLED), \FILTER_VALIDATE_BOOLEAN)); + if (!$usesEndpointDiscovery) { + return $this->getEndpoint($uri, $query, $region); + } + + // 1. use an active endpoints + if (null === $endpoint = $this->endpointCache->getActiveEndpoint($region)) { + $previous = null; + + try { + // 2. call API to fetch new endpoints + $endpoints = $this->discoverEndpoints($region); + $this->endpointCache->addEndpoints($region, $endpoints); + + // 3. use active endpoints that has just been injected + $endpoint = $this->endpointCache->getActiveEndpoint($region); + } catch (\Exception $previous) { + } + + // 4. if endpoint is still null, fallback to expired endpoint + if (null === $endpoint && null === $endpoint = $this->endpointCache->getExpiredEndpoint($region)) { + if ($requiresEndpointDiscovery) { + throw new RuntimeException(sprintf('The Client "%s" failed to fetch the endpoint.', \get_class($this)), 0, $previous); + } + + return $this->getEndpoint($uri, $query, $region); + } + } + + $endpoint .= $uri; + if (empty($query)) { + return $endpoint; + } + + return $endpoint . (false === strpos($endpoint, '?') ? '?' : '&') . http_build_query($query); + } + + /** + * @param ?string $region region provided by the user in the `@region` parameter of the Input + */ + private function getSigner(?string $region): Signer + { + /** @var string $region */ + $region = $region ?? ($this->configuration->isDefault('region') ? null : $this->configuration->get('region')); + if (!isset($this->signers[$region])) { + $factories = $this->getSignerFactories(); + $factory = null; + if ($this->configuration->isDefault('endpoint') || $this->configuration->isDefault('region')) { + $metadata = $this->getEndpointMetadata($region); + } else { + // Allow non-aws region with custom endpoint + $metadata = $this->getEndpointMetadata(Configuration::DEFAULT_REGION); + $metadata['signRegion'] = $region; + } + + foreach ($metadata['signVersions'] as $signatureVersion) { + if (isset($factories[$signatureVersion])) { + $factory = $factories[$signatureVersion]; + + break; + } + } + + if (null === $factory) { + throw new InvalidArgument(sprintf('None of the signatures "%s" is implemented.', implode(', ', $metadata['signVersions']))); + } + + $this->signers[$region] = $factory($metadata['signService'], $metadata['signRegion']); + } + + /** @psalm-suppress PossiblyNullArrayOffset */ + return $this->signers[$region]; + } +} diff --git a/vendor/async-aws/core/src/AwsClientFactory.php b/vendor/async-aws/core/src/AwsClientFactory.php new file mode 100644 index 000000000..5ff2b0981 --- /dev/null +++ b/vendor/async-aws/core/src/AwsClientFactory.php @@ -0,0 +1,631 @@ + + */ +class AwsClientFactory +{ + /** + * @var array + */ + private $serviceCache; + + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * @var Configuration + */ + private $configuration; + + /** + * @var CredentialProvider + */ + private $credentialProvider; + + /** + * @var LoggerInterface|null + */ + private $logger; + + /** + * @param Configuration|array $configuration + */ + public function __construct($configuration = [], ?CredentialProvider $credentialProvider = null, ?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null) + { + if (\is_array($configuration)) { + $configuration = Configuration::create($configuration); + } elseif (!$configuration instanceof Configuration) { + throw new InvalidArgument(sprintf('Second argument to "%s::__construct()" must be an array or an instance of "%s"', __CLASS__, Configuration::class)); + } + + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->logger = $logger ?? new NullLogger(); + $this->configuration = $configuration; + $this->credentialProvider = $credentialProvider ?? new CacheProvider(ChainProvider::createDefaultChain($this->httpClient, $this->logger)); + } + + public function appSync(): AppSyncClient + { + if (!class_exists(AppSyncClient::class)) { + throw MissingDependency::create('async-aws/app-sync', 'AppSync'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new AppSyncClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudFormation(): CloudFormationClient + { + if (!class_exists(CloudFormationClient::class)) { + throw MissingDependency::create('async-aws/cloud-formation', 'CloudFormation'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudFormationClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudFront(): CloudFrontClient + { + if (!class_exists(CloudFrontClient::class)) { + throw MissingDependency::create('async-aws/cloud-front', 'CloudFront'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudFrontClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudWatch(): CloudWatchClient + { + if (!class_exists(CloudWatchClient::class)) { + throw MissingDependency::create('async-aws/cloud-watch', 'CloudWatch'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudWatchClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cloudWatchLogs(): CloudWatchLogsClient + { + if (!class_exists(CloudWatchLogsClient::class)) { + throw MissingDependency::create('async-aws/cloud-watch-logs', 'CloudWatchLogs'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CloudWatchLogsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function codeBuild(): CodeBuildClient + { + if (!class_exists(CodeBuildClient::class)) { + throw MissingDependency::create('async-aws/code-build', 'CodeBuild'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CodeBuildClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function codeCommit(): CodeCommitClient + { + if (!class_exists(CodeCommitClient::class)) { + throw MissingDependency::create('async-aws/code-commit', 'CodeCommit'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CodeCommitClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function codeDeploy(): CodeDeployClient + { + if (!class_exists(CodeDeployClient::class)) { + throw MissingDependency::create('async-aws/code-deploy', 'CodeDeploy'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CodeDeployClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function comprehend(): ComprehendClient + { + if (!class_exists(ComprehendClient::class)) { + throw MissingDependency::create('async-aws/comprehend', 'ComprehendClient'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new ComprehendClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function dynamoDb(): DynamoDbClient + { + if (!class_exists(DynamoDbClient::class)) { + throw MissingDependency::create('async-aws/dynamo-db', 'DynamoDb'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new DynamoDbClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function ecr(): EcrClient + { + if (!class_exists(EcrClient::class)) { + throw MissingDependency::create('async-aws/ecr', 'ECR'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new EcrClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function elastiCache(): ElastiCacheClient + { + if (!class_exists(ElastiCacheClient::class)) { + throw MissingDependency::create('async-aws/elasti-cache', 'ElastiCache'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new ElastiCacheClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function eventBridge(): EventBridgeClient + { + if (!class_exists(EventBridgeClient::class)) { + throw MissingDependency::create('async-aws/event-bridge', 'EventBridge'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new EventBridgeClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function firehose(): FirehoseClient + { + if (!class_exists(FirehoseClient::class)) { + throw MissingDependency::create('async-aws/firehose', 'Firehose'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new FirehoseClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function iam(): IamClient + { + if (!class_exists(IamClient::class)) { + throw MissingDependency::create('async-aws/iam', 'IAM'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new IamClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function iot(): IotClient + { + if (!class_exists(IotClient::class)) { + throw MissingDependency::create('async-aws/iot', 'Iot'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new IotClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function iotData(): IotDataClient + { + if (!class_exists(IotDataClient::class)) { + throw MissingDependency::create('async-aws/iot-data', 'IotData'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new IotDataClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function kinesis(): KinesisClient + { + if (!class_exists(KinesisClient::class)) { + throw MissingDependency::create('aws/kinesis', 'Kinesis'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new KinesisClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function kms(): KmsClient + { + if (!class_exists(KmsClient::class)) { + throw MissingDependency::create('aws/kms', 'Kms'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new KmsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function lambda(): LambdaClient + { + if (!class_exists(LambdaClient::class)) { + throw MissingDependency::create('async-aws/lambda', 'Lambda'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new LambdaClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function locationService(): LocationServiceClient + { + if (!class_exists(LocationServiceClient::class)) { + throw MissingDependency::create('async-aws/location-service', 'LocationService'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new LocationServiceClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function mediaConvert(): MediaConvertClient + { + if (!class_exists(MediaConvertClient::class)) { + throw MissingDependency::create('async-aws/media-convert', 'MediaConvert'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new MediaConvertClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function rdsDataService(): RdsDataServiceClient + { + if (!class_exists(RdsDataServiceClient::class)) { + throw MissingDependency::create('async-aws/rds-data-service', 'RdsDataService'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new RdsDataServiceClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function rekognition(): RekognitionClient + { + if (!class_exists(RekognitionClient::class)) { + throw MissingDependency::create('aws/rekognition', 'Rekognition'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new RekognitionClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function route53(): Route53Client + { + if (!class_exists(Route53Client::class)) { + throw MissingDependency::create('aws/route53', 'Route53'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new Route53Client($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function s3(): S3Client + { + if (!class_exists(S3Client::class)) { + throw MissingDependency::create('async-aws/s3', 'S3'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new S3Client($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function scheduler(): SchedulerClient + { + if (!class_exists(SchedulerClient::class)) { + throw MissingDependency::create('async-aws/scheduler', 'Scheduler'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SchedulerClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function secretsManager(): SecretsManagerClient + { + if (!class_exists(SecretsManagerClient::class)) { + throw MissingDependency::create('async-aws/secret-manager', 'SecretsManager'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SecretsManagerClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function ses(): SesClient + { + if (!class_exists(SesClient::class)) { + throw MissingDependency::create('async-aws/ses', 'SES'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SesClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sns(): SnsClient + { + if (!class_exists(SnsClient::class)) { + throw MissingDependency::create('async-aws/sns', 'SNS'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SnsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sqs(): SqsClient + { + if (!class_exists(SqsClient::class)) { + throw MissingDependency::create('async-aws/sqs', 'SQS'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SqsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function ssm(): SsmClient + { + if (!class_exists(SsmClient::class)) { + throw MissingDependency::create('async-aws/ssm', 'SSM'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SsmClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sso(): SsoClient + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new SsoClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function sts(): StsClient + { + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new StsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function stepFunctions(): StepFunctionsClient + { + if (!class_exists(StepFunctionsClient::class)) { + throw MissingDependency::create('async-aws/step-functions', 'StepFunctions'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new StepFunctionsClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function timestreamQuery(): TimestreamQueryClient + { + if (!class_exists(TimestreamQueryClient::class)) { + throw MissingDependency::create('async-aws/timestream-query', 'TimestreamQuery'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new TimestreamQueryClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function timestreamWrite(): TimestreamWriteClient + { + if (!class_exists(TimestreamWriteClient::class)) { + throw MissingDependency::create('async-aws/timestream-write', 'TimestreamWrite'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new TimestreamWriteClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function translate(): TranslateClient + { + if (!class_exists(TranslateClient::class)) { + throw MissingDependency::create('async-aws/translate', 'Translate'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new TranslateClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function xRay(): XRayClient + { + if (!class_exists(XRayClient::class)) { + throw MissingDependency::create('async-aws/x-ray', 'XRay'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new XRayClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function cognitoIdentityProvider(): CognitoIdentityProviderClient + { + if (!class_exists(CognitoIdentityProviderClient::class)) { + throw MissingDependency::create('aws/cognito-identity-provider', 'CognitoIdentityProvider'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new CognitoIdentityProviderClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } + + public function athena(): AthenaClient + { + if (!class_exists(AthenaClient::class)) { + throw MissingDependency::create('async-aws/athena', 'Athena'); + } + + if (!isset($this->serviceCache[__METHOD__])) { + $this->serviceCache[__METHOD__] = new AthenaClient($this->configuration, $this->credentialProvider, $this->httpClient, $this->logger); + } + + return $this->serviceCache[__METHOD__]; + } +} diff --git a/vendor/async-aws/core/src/AwsError/AwsError.php b/vendor/async-aws/core/src/AwsError/AwsError.php new file mode 100644 index 000000000..126735473 --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/AwsError.php @@ -0,0 +1,54 @@ +code = $code; + $this->message = $message; + $this->type = $type; + $this->detail = $detail; + } + + public function getCode(): ?string + { + return $this->code; + } + + public function getMessage(): ?string + { + return $this->message; + } + + public function getType(): ?string + { + return $this->type; + } + + public function getDetail(): ?string + { + return $this->detail; + } +} diff --git a/vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php new file mode 100644 index 000000000..51782845d --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryFromResponseTrait.php @@ -0,0 +1,16 @@ +getContent(false); + $headers = $response->getHeaders(false); + + return $this->createFromContent($content, $headers); + } +} diff --git a/vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php new file mode 100644 index 000000000..d3e6c4536 --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/AwsErrorFactoryInterface.php @@ -0,0 +1,15 @@ +> $headers + */ + public function createFromContent(string $content, array $headers): AwsError; +} diff --git a/vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php new file mode 100644 index 000000000..75080c9eb --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/ChainAwsErrorFactory.php @@ -0,0 +1,43 @@ +factories = $factories ?? [ + new JsonRestAwsErrorFactory(), + new JsonRpcAwsErrorFactory(), + new XmlAwsErrorFactory(), + ]; + } + + public function createFromContent(string $content, array $headers): AwsError + { + $e = null; + foreach ($this->factories as $factory) { + try { + return $factory->createFromContent($content, $headers); + } catch (UnparsableResponse $e) { + } + } + + throw new UnparsableResponse('Failed to parse AWS error: ' . $content, 0, $e); + } +} diff --git a/vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php new file mode 100644 index 000000000..1af77d9b7 --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/JsonRestAwsErrorFactory.php @@ -0,0 +1,45 @@ + $body + * @param array> $headers + */ + private static function parseJson(array $body, array $headers): AwsError + { + $code = null; + $type = $body['type'] ?? $body['Type'] ?? null; + if ($type) { + $type = strtolower($type); + } + $message = $body['message'] ?? $body['Message'] ?? null; + if (isset($headers['x-amzn-errortype'][0])) { + $code = explode(':', $headers['x-amzn-errortype'][0], 2)[0]; + } + + if (null !== $code) { + return new AwsError($code, $message, $type, null); + } + + throw new UnexpectedValue('JSON does not contains AWS Error'); + } +} diff --git a/vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php new file mode 100644 index 000000000..bf774be4d --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/JsonRpcAwsErrorFactory.php @@ -0,0 +1,42 @@ + $body + * @param array> $headers + */ + private static function parseJson(array $body, array $headers): AwsError + { + $code = null; + $message = $body['message'] ?? $body['Message'] ?? null; + if (isset($body['__type'])) { + $parts = explode('#', $body['__type'], 2); + $code = $parts[1] ?? $parts[0]; + } + + if (null !== $code || null !== $message) { + return new AwsError($code, $message, null, null); + } + + throw new UnexpectedValue('JSON does not contains AWS Error'); + } +} diff --git a/vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php b/vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php new file mode 100644 index 000000000..6a152f92f --- /dev/null +++ b/vendor/async-aws/core/src/AwsError/XmlAwsErrorFactory.php @@ -0,0 +1,54 @@ +Error->count()) { + return new AwsError( + $xml->Error->Code->__toString(), + $xml->Error->Message->__toString(), + $xml->Error->Type->__toString(), + $xml->Error->Detail->__toString() + ); + } + + if (1 === $xml->Code->count() && 1 === $xml->Message->count()) { + return new AwsError( + $xml->Code->__toString(), + $xml->Message->__toString(), + null, + null + ); + } + + throw new UnexpectedValue('XML does not contains AWS Error'); + } +} diff --git a/vendor/async-aws/core/src/Configuration.php b/vendor/async-aws/core/src/Configuration.php new file mode 100644 index 000000000..66f7530a4 --- /dev/null +++ b/vendor/async-aws/core/src/Configuration.php @@ -0,0 +1,266 @@ + + * @author Jérémy Derussé + */ +final class Configuration +{ + public const DEFAULT_REGION = 'us-east-1'; + + public const OPTION_REGION = 'region'; + public const OPTION_DEBUG = 'debug'; + public const OPTION_PROFILE = 'profile'; + public const OPTION_ACCESS_KEY_ID = 'accessKeyId'; + public const OPTION_SECRET_ACCESS_KEY = 'accessKeySecret'; + public const OPTION_SESSION_TOKEN = 'sessionToken'; + public const OPTION_SHARED_CREDENTIALS_FILE = 'sharedCredentialsFile'; + public const OPTION_SHARED_CONFIG_FILE = 'sharedConfigFile'; + public const OPTION_ENDPOINT = 'endpoint'; + public const OPTION_ROLE_ARN = 'roleArn'; + public const OPTION_WEB_IDENTITY_TOKEN_FILE = 'webIdentityTokenFile'; + public const OPTION_ROLE_SESSION_NAME = 'roleSessionName'; + public const OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI = 'containerCredentialsRelativeUri'; + public const OPTION_ENDPOINT_DISCOVERY_ENABLED = 'endpointDiscoveryEnabled'; + + // S3 specific option + public const OPTION_PATH_STYLE_ENDPOINT = 'pathStyleEndpoint'; + public const OPTION_SEND_CHUNKED_BODY = 'sendChunkedBody'; + + private const AVAILABLE_OPTIONS = [ + self::OPTION_REGION => true, + self::OPTION_DEBUG => true, + self::OPTION_PROFILE => true, + self::OPTION_ACCESS_KEY_ID => true, + self::OPTION_SECRET_ACCESS_KEY => true, + self::OPTION_SESSION_TOKEN => true, + self::OPTION_SHARED_CREDENTIALS_FILE => true, + self::OPTION_SHARED_CONFIG_FILE => true, + self::OPTION_ENDPOINT => true, + self::OPTION_ROLE_ARN => true, + self::OPTION_WEB_IDENTITY_TOKEN_FILE => true, + self::OPTION_ROLE_SESSION_NAME => true, + self::OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI => true, + self::OPTION_ENDPOINT_DISCOVERY_ENABLED => true, + self::OPTION_PATH_STYLE_ENDPOINT => true, + self::OPTION_SEND_CHUNKED_BODY => true, + ]; + + // Put fallback options into groups to avoid mixing of provided config and environment variables + private const FALLBACK_OPTIONS = [ + [self::OPTION_REGION => ['AWS_REGION', 'AWS_DEFAULT_REGION']], + [self::OPTION_PROFILE => ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']], + [ + self::OPTION_ACCESS_KEY_ID => ['AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY'], + self::OPTION_SECRET_ACCESS_KEY => ['AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_KEY'], + self::OPTION_SESSION_TOKEN => 'AWS_SESSION_TOKEN', + ], + [self::OPTION_SHARED_CREDENTIALS_FILE => 'AWS_SHARED_CREDENTIALS_FILE'], + [self::OPTION_SHARED_CONFIG_FILE => 'AWS_CONFIG_FILE'], + [ + self::OPTION_ROLE_ARN => 'AWS_ROLE_ARN', + self::OPTION_WEB_IDENTITY_TOKEN_FILE => 'AWS_WEB_IDENTITY_TOKEN_FILE', + self::OPTION_ROLE_SESSION_NAME => 'AWS_ROLE_SESSION_NAME', + ], + [self::OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI => 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'], + [self::OPTION_ENDPOINT_DISCOVERY_ENABLED => ['AWS_ENDPOINT_DISCOVERY_ENABLED', 'AWS_ENABLE_ENDPOINT_DISCOVERY']], + ]; + + private const DEFAULT_OPTIONS = [ + self::OPTION_REGION => self::DEFAULT_REGION, + self::OPTION_DEBUG => 'false', + self::OPTION_PROFILE => 'default', + self::OPTION_SHARED_CREDENTIALS_FILE => '~/.aws/credentials', + self::OPTION_SHARED_CONFIG_FILE => '~/.aws/config', + // https://docs.aws.amazon.com/general/latest/gr/rande.html + self::OPTION_ENDPOINT => 'https://%service%.%region%.amazonaws.com', + self::OPTION_PATH_STYLE_ENDPOINT => 'false', + self::OPTION_SEND_CHUNKED_BODY => 'false', + self::OPTION_ENDPOINT_DISCOVERY_ENABLED => 'false', + ]; + + /** + * @var array + */ + private $data = []; + + /** + * @var array + */ + private $userData = []; + + /** + * @param array $options + */ + public static function create(array $options): self + { + if (0 < \count($invalidOptions = array_diff_key($options, self::AVAILABLE_OPTIONS))) { + throw new InvalidArgument(sprintf('Invalid option(s) "%s" passed to "%s::%s". ', implode('", "', array_keys($invalidOptions)), __CLASS__, __METHOD__)); + } + + // Force each option to be string or null + $options = array_map(static function ($value) { + return null !== $value ? (string) $value : $value; + }, $options); + + $configuration = new self(); + $options = self::parseEnvironmentVariables($options); + self::populateConfiguration($configuration, $options); + $iniOptions = self::parseIniFiles($configuration); + self::populateConfiguration($configuration, $iniOptions); + + return $configuration; + } + + public static function optionExists(string $optionName): bool + { + return isset(self::AVAILABLE_OPTIONS[$optionName]); + } + + /** + * @param self::OPTION_* $name + * + * @psalm-return ( + * $name is + * self::OPTION_REGION + * |self::OPTION_DEBUG + * |self::OPTION_PROFILE + * |self::OPTION_SHARED_CREDENTIALS_FILE + * |self::OPTION_SHARED_CONFIG_FILE + * |self::OPTION_ENDPOINT + * |self::OPTION_PATH_STYLE_ENDPOINT + * |self::OPTION_SEND_CHUNKED_BODY + * ? string + * : ?string + * ) + */ + public function get(string $name): ?string + { + if (!isset(self::AVAILABLE_OPTIONS[$name])) { + throw new InvalidArgument(sprintf('Invalid option "%s" passed to "%s::%s". ', $name, __CLASS__, __METHOD__)); + } + + return $this->data[$name] ?? null; + } + + /** + * @param self::OPTION_* $name + */ + public function has(string $name): bool + { + if (!isset(self::AVAILABLE_OPTIONS[$name])) { + throw new InvalidArgument(sprintf('Invalid option "%s" passed to "%s::%s". ', $name, __CLASS__, __METHOD__)); + } + + return isset($this->data[$name]); + } + + /** + * @param self::OPTION_* $name + */ + public function isDefault(string $name): bool + { + if (!isset(self::AVAILABLE_OPTIONS[$name])) { + throw new InvalidArgument(sprintf('Invalid option "%s" passed to "%s::%s". ', $name, __CLASS__, __METHOD__)); + } + + return empty($this->userData[$name]); + } + + /** + * @param array $options + * + * @return array + */ + private static function parseEnvironmentVariables(array $options): array + { + foreach (self::FALLBACK_OPTIONS as $fallbackGroup) { + // prevent mixing env variables with config keys + foreach ($fallbackGroup as $option => $envVariableNames) { + if (isset($options[$option])) { + continue 2; + } + } + + foreach ($fallbackGroup as $option => $envVariableNames) { + // Read environment files + $envVariableNames = (array) $envVariableNames; + foreach ($envVariableNames as $envVariableName) { + if (null !== $envVariableValue = EnvVar::get($envVariableName)) { + $options[$option] = $envVariableValue; + + break; + } + } + } + } + + return $options; + } + + /** + * Look for "region" in the configured ini files. + * + * @return array + */ + private static function parseIniFiles(Configuration $configuration): array + { + $options = []; + if (!$configuration->isDefault(self::OPTION_REGION)) { + return $options; + } + + $profilesData = (new IniFileLoader())->loadProfiles([ + $configuration->get(self::OPTION_SHARED_CREDENTIALS_FILE), + $configuration->get(self::OPTION_SHARED_CONFIG_FILE), + ]); + + if (empty($profilesData)) { + return $options; + } + + /** @var string $profile */ + $profile = $configuration->get(Configuration::OPTION_PROFILE); + if (isset($profilesData[$profile]['region'])) { + $options[self::OPTION_REGION] = $profilesData[$profile]['region']; + } + + return $options; + } + + /** + * Add array options to the configuration object. + * + * @param array $options + */ + private static function populateConfiguration(Configuration $configuration, array $options): void + { + foreach ($options as $key => $value) { + if (null !== $value) { + $configuration->userData[$key] = true; + } + } + + // If we have not applied default before + if (empty($configuration->data)) { + foreach (self::DEFAULT_OPTIONS as $optionTrigger => $defaultValue) { + if (isset($options[$optionTrigger])) { + continue; + } + + $options[$optionTrigger] = $defaultValue; + } + } + + $configuration->data = array_merge($configuration->data, $options); + } +} diff --git a/vendor/async-aws/core/src/Credentials/CacheProvider.php b/vendor/async-aws/core/src/Credentials/CacheProvider.php new file mode 100644 index 000000000..428e62e47 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/CacheProvider.php @@ -0,0 +1,48 @@ + + */ +final class CacheProvider implements CredentialProvider, ResetInterface +{ + /** + * @var array + */ + private $cache = []; + + /** + * @var CredentialProvider + */ + private $decorated; + + public function __construct(CredentialProvider $decorated) + { + $this->decorated = $decorated; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $key = spl_object_hash($configuration); + if (!\array_key_exists($key, $this->cache) || (null !== $this->cache[$key] && $this->cache[$key]->isExpired())) { + $this->cache[$key] = $this->decorated->getCredentials($configuration); + } + + return $this->cache[$key]; + } + + public function reset(): void + { + $this->cache = []; + } +} diff --git a/vendor/async-aws/core/src/Credentials/ChainProvider.php b/vendor/async-aws/core/src/Credentials/ChainProvider.php new file mode 100644 index 000000000..abc46f032 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/ChainProvider.php @@ -0,0 +1,84 @@ + + */ +final class ChainProvider implements CredentialProvider, ResetInterface +{ + /** + * @var iterable + */ + private $providers; + + /** + * @var array + */ + private $lastSuccessfulProvider = []; + + /** + * @param iterable $providers + */ + public function __construct(iterable $providers) + { + $this->providers = $providers; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $key = spl_object_hash($configuration); + if (\array_key_exists($key, $this->lastSuccessfulProvider)) { + if (null === $provider = $this->lastSuccessfulProvider[$key]) { + return null; + } + + return $provider->getCredentials($configuration); + } + + foreach ($this->providers as $provider) { + if (null !== $credentials = $provider->getCredentials($configuration)) { + $this->lastSuccessfulProvider[$key] = $provider; + + return $credentials; + } + } + + $this->lastSuccessfulProvider[$key] = null; + + return null; + } + + public function reset(): void + { + $this->lastSuccessfulProvider = []; + } + + public static function createDefaultChain(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null): CredentialProvider + { + $httpClient = $httpClient ?? HttpClient::create(); + $logger = $logger ?? new NullLogger(); + + return new ChainProvider([ + new ConfigurationProvider(), + new WebIdentityProvider($logger, null, $httpClient), + new IniFileProvider($logger, null, $httpClient), + new ContainerProvider($httpClient, $logger), + new InstanceProvider($httpClient, $logger), + ]); + } +} diff --git a/vendor/async-aws/core/src/Credentials/ConfigurationProvider.php b/vendor/async-aws/core/src/Credentials/ConfigurationProvider.php new file mode 100644 index 000000000..3dca53444 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/ConfigurationProvider.php @@ -0,0 +1,92 @@ + + */ +final class ConfigurationProvider implements CredentialProvider +{ + use DateFromResult; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface|null + */ + private $httpClient; + + public function __construct(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null) + { + $this->logger = $logger ?? new NullLogger(); + $this->httpClient = $httpClient; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $accessKeyId = $configuration->get(Configuration::OPTION_ACCESS_KEY_ID); + $secretAccessKeyId = $configuration->get(Configuration::OPTION_SECRET_ACCESS_KEY); + + if (null === $accessKeyId || null === $secretAccessKeyId) { + return null; + } + + $credentials = new Credentials( + $accessKeyId, + $secretAccessKeyId, + $configuration->get(Configuration::OPTION_SESSION_TOKEN) + ); + + $roleArn = $configuration->get(Configuration::OPTION_ROLE_ARN); + if (null !== $roleArn) { + $region = $configuration->get(Configuration::OPTION_REGION); + $roleSessionName = $configuration->get(Configuration::OPTION_ROLE_SESSION_NAME); + + return $this->getCredentialsFromRole($credentials, $region, $roleArn, $roleSessionName); + } + + /** @psalm-suppress PossiblyNullArgument */ + return $credentials; + } + + private function getCredentialsFromRole(Credentials $credentials, string $region, string $roleArn, ?string $roleSessionName = null): ?Credentials + { + $roleSessionName = $roleSessionName ?? uniqid('async-aws-', true); + $stsClient = new StsClient(['region' => $region], $credentials, $this->httpClient); + $result = $stsClient->assumeRole([ + 'RoleArn' => $roleArn, + 'RoleSessionName' => $roleSessionName, + ]); + + try { + if (null === $credentials = $result->getCredentials()) { + throw new RuntimeException('The AsumeRole response does not contains credentials'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from assumed role: {exception}".', ['exception' => $e]); + + return null; + } + + return new Credentials( + $credentials->getAccessKeyId(), + $credentials->getSecretAccessKey(), + $credentials->getSessionToken(), + Credentials::adjustExpireDate($credentials->getExpiration(), $this->getDateFromResult($result)) + ); + } +} diff --git a/vendor/async-aws/core/src/Credentials/ContainerProvider.php b/vendor/async-aws/core/src/Credentials/ContainerProvider.php new file mode 100644 index 000000000..6b31e545a --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/ContainerProvider.php @@ -0,0 +1,80 @@ +logger = $logger ?? new NullLogger(); + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->timeout = $timeout; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $relativeUri = $configuration->get(Configuration::OPTION_CONTAINER_CREDENTIALS_RELATIVE_URI); + // introduces an early exit if the env variable is not set. + if (empty($relativeUri)) { + return null; + } + + // fetch credentials from ecs endpoint + try { + $response = $this->httpClient->request('GET', self::ENDPOINT . $relativeUri, ['timeout' => $this->timeout]); + $result = $response->toArray(); + } catch (DecodingExceptionInterface $e) { + $this->logger->info('Failed to decode Credentials.', ['exception' => $e]); + + return null; + } catch (TransportExceptionInterface|HttpExceptionInterface $e) { + $this->logger->info('Failed to fetch Profile from Instance Metadata.', ['exception' => $e]); + + return null; + } + + if (null !== $date = $response->getHeaders(false)['date'][0] ?? null) { + $date = new \DateTimeImmutable($date); + } + + return new Credentials( + $result['AccessKeyId'], + $result['SecretAccessKey'], + $result['Token'], + Credentials::adjustExpireDate(new \DateTimeImmutable($result['Expiration']), $date) + ); + } +} diff --git a/vendor/async-aws/core/src/Credentials/CredentialProvider.php b/vendor/async-aws/core/src/Credentials/CredentialProvider.php new file mode 100644 index 000000000..a160fbd4a --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/CredentialProvider.php @@ -0,0 +1,20 @@ + + */ +interface CredentialProvider +{ + /** + * Return a Credential when possible. Return null otherwise. + */ + public function getCredentials(Configuration $configuration): ?Credentials; +} diff --git a/vendor/async-aws/core/src/Credentials/Credentials.php b/vendor/async-aws/core/src/Credentials/Credentials.php new file mode 100644 index 000000000..acd2a8052 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/Credentials.php @@ -0,0 +1,88 @@ + + */ +final class Credentials implements CredentialProvider +{ + private const EXPIRATION_DRIFT = 30; + + /** + * @var string + */ + private $accessKeyId; + + /** + * @var string + */ + private $secretKey; + + /** + * @var string|null + */ + private $sessionToken; + + /** + * @var \DateTimeImmutable|null + */ + private $expireDate; + + public function __construct( + string $accessKeyId, + string $secretKey, + ?string $sessionToken = null, + ?\DateTimeImmutable $expireDate = null + ) { + $this->accessKeyId = $accessKeyId; + $this->secretKey = $secretKey; + $this->sessionToken = $sessionToken; + $this->expireDate = $expireDate; + } + + public function getAccessKeyId(): string + { + return $this->accessKeyId; + } + + public function getSecretKey(): string + { + return $this->secretKey; + } + + public function getSessionToken(): ?string + { + return $this->sessionToken; + } + + public function getExpireDate(): ?\DateTimeImmutable + { + return $this->expireDate; + } + + public function isExpired(): bool + { + return null !== $this->expireDate && new \DateTimeImmutable() >= $this->expireDate; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + return $this->isExpired() ? null : $this; + } + + public static function adjustExpireDate(\DateTimeImmutable $expireDate, ?\DateTimeImmutable $reference = null): \DateTimeImmutable + { + if (null !== $reference) { + $expireDate = (new \DateTimeImmutable())->add($reference->diff($expireDate)); + } + + return $expireDate->sub(new \DateInterval(sprintf('PT%dS', self::EXPIRATION_DRIFT))); + } +} diff --git a/vendor/async-aws/core/src/Credentials/DateFromResult.php b/vendor/async-aws/core/src/Credentials/DateFromResult.php new file mode 100644 index 000000000..513ba13b0 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/DateFromResult.php @@ -0,0 +1,21 @@ +info()['response']; + if (null !== $date = $response->getHeaders(false)['date'][0] ?? null) { + return new \DateTimeImmutable($date); + } + + return null; + } +} diff --git a/vendor/async-aws/core/src/Credentials/IniFileLoader.php b/vendor/async-aws/core/src/Credentials/IniFileLoader.php new file mode 100644 index 000000000..df45ed73b --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/IniFileLoader.php @@ -0,0 +1,110 @@ + + */ +final class IniFileLoader +{ + public const KEY_REGION = 'region'; + public const KEY_ACCESS_KEY_ID = 'aws_access_key_id'; + public const KEY_SECRET_ACCESS_KEY = 'aws_secret_access_key'; + public const KEY_SESSION_TOKEN = 'aws_session_token'; + public const KEY_ROLE_ARN = 'role_arn'; + public const KEY_ROLE_SESSION_NAME = 'role_session_name'; + public const KEY_SOURCE_PROFILE = 'source_profile'; + public const KEY_WEB_IDENTITY_TOKEN_FILE = 'web_identity_token_file'; + public const KEY_SSO_START_URL = 'sso_start_url'; + public const KEY_SSO_REGION = 'sso_region'; + public const KEY_SSO_ACCOUNT_ID = 'sso_account_id'; + public const KEY_SSO_ROLE_NAME = 'sso_role_name'; + + /** + * @var LoggerInterface + */ + private $logger; + + public function __construct(?LoggerInterface $logger = null) + { + $this->logger = $logger ?? new NullLogger(); + } + + /** + * @param string[] $filepaths + * + * @return array> + */ + public function loadProfiles(array $filepaths): array + { + $profilesData = []; + $homeDir = null; + foreach ($filepaths as $filepath) { + if ('' === $filepath) { + continue; + } + if ('~' === $filepath[0]) { + $homeDir = $homeDir ?? $this->getHomeDir(); + $filepath = $homeDir . substr($filepath, 1); + } + if (!is_readable($filepath) || !is_file($filepath)) { + continue; + } + + foreach ($this->parseIniFile($filepath) as $name => $profile) { + $name = preg_replace('/^profile /', '', (string) $name); + if (!isset($profilesData[$name])) { + $profilesData[$name] = array_map('trim', $profile); + } else { + foreach ($profile as $k => $v) { + if (!isset($profilesData[$name][$k])) { + $profilesData[$name][$k] = trim($v); + } + } + } + } + } + + return $profilesData; + } + + private function getHomeDir(): string + { + // On Linux/Unix-like systems, use the HOME environment variable + if (null !== $homeDir = EnvVar::get('HOME')) { + return $homeDir; + } + + // Get the HOMEDRIVE and HOMEPATH values for Windows hosts + $homeDrive = EnvVar::get('HOMEDRIVE'); + $homePath = EnvVar::get('HOMEPATH'); + + return ($homeDrive && $homePath) ? $homeDrive . $homePath : '/'; + } + + /** + * @return array + */ + private function parseIniFile(string $filepath): array + { + if (false === $data = parse_ini_string( + preg_replace('/^#/m', ';', file_get_contents($filepath)), + true, + \INI_SCANNER_RAW + )) { + $this->logger->warning('The ini file {path} is invalid.', ['path' => $filepath]); + + return []; + } + + return $data; + } +} diff --git a/vendor/async-aws/core/src/Credentials/IniFileProvider.php b/vendor/async-aws/core/src/Credentials/IniFileProvider.php new file mode 100644 index 000000000..c8476c49d --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/IniFileProvider.php @@ -0,0 +1,224 @@ + + */ +final class IniFileProvider implements CredentialProvider +{ + use DateFromResult; + + /** + * @var IniFileLoader + */ + private $iniFileLoader; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface|null + */ + private $httpClient; + + public function __construct(?LoggerInterface $logger = null, ?IniFileLoader $iniFileLoader = null, ?HttpClientInterface $httpClient = null) + { + $this->logger = $logger ?? new NullLogger(); + $this->iniFileLoader = $iniFileLoader ?? new IniFileLoader($this->logger); + $this->httpClient = $httpClient; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $profilesData = $this->iniFileLoader->loadProfiles([ + $configuration->get(Configuration::OPTION_SHARED_CREDENTIALS_FILE), + $configuration->get(Configuration::OPTION_SHARED_CONFIG_FILE), + ]); + if (empty($profilesData)) { + return null; + } + + /** @var string $profile */ + $profile = $configuration->get(Configuration::OPTION_PROFILE); + + return $this->getCredentialsFromProfile($profilesData, $profile); + } + + /** + * @param array> $profilesData + * @param array $circularCollector + */ + private function getCredentialsFromProfile(array $profilesData, string $profile, array $circularCollector = []): ?Credentials + { + if (isset($circularCollector[$profile])) { + $this->logger->warning('Circular reference detected when loading "{profile}". Already loaded {previous_profiles}', ['profile' => $profile, 'previous_profiles' => array_keys($circularCollector)]); + + return null; + } + $circularCollector[$profile] = true; + + if (!isset($profilesData[$profile])) { + $this->logger->warning('Profile "{profile}" not found.', ['profile' => $profile]); + + return null; + } + + $profileData = $profilesData[$profile]; + if (isset($profileData[IniFileLoader::KEY_ACCESS_KEY_ID], $profileData[IniFileLoader::KEY_SECRET_ACCESS_KEY])) { + return new Credentials( + $profileData[IniFileLoader::KEY_ACCESS_KEY_ID], + $profileData[IniFileLoader::KEY_SECRET_ACCESS_KEY], + $profileData[IniFileLoader::KEY_SESSION_TOKEN] ?? null + ); + } + + if (isset($profileData[IniFileLoader::KEY_ROLE_ARN])) { + return $this->getCredentialsFromRole($profilesData, $profileData, $profile, $circularCollector); + } + + if (isset($profileData[IniFileLoader::KEY_SSO_START_URL])) { + if (class_exists(SsoClient::class)) { + return $this->getCredentialsFromLegacySso($profileData, $profile); + } + + $this->logger->warning('The profile "{profile}" contains SSO (legacy) config but the "async-aws/sso" package is not installed. Try running "composer require async-aws/sso".', ['profile' => $profile]); + + return null; + } + + $this->logger->info('No credentials found for profile "{profile}".', ['profile' => $profile]); + + return null; + } + + /** + * @param array> $profilesData + * @param array $profileData + * @param array $circularCollector + */ + private function getCredentialsFromRole(array $profilesData, array $profileData, string $profile, array $circularCollector = []): ?Credentials + { + $roleArn = (string) ($profileData[IniFileLoader::KEY_ROLE_ARN] ?? ''); + $roleSessionName = (string) ($profileData[IniFileLoader::KEY_ROLE_SESSION_NAME] ?? uniqid('async-aws-', true)); + if (null === $sourceProfileName = $profileData[IniFileLoader::KEY_SOURCE_PROFILE] ?? null) { + $this->logger->warning('The source profile is not defined in Role "{profile}".', ['profile' => $profile]); + + return null; + } + + $sourceCredentials = $this->getCredentialsFromProfile($profilesData, $sourceProfileName, $circularCollector); + if (null === $sourceCredentials) { + $this->logger->warning('The source profile "{profile}" does not contains valid credentials.', ['profile' => $profile]); + + return null; + } + + $stsClient = new StsClient( + isset($profilesData[$sourceProfileName][IniFileLoader::KEY_REGION]) ? ['region' => $profilesData[$sourceProfileName][IniFileLoader::KEY_REGION]] : [], + $sourceCredentials, + $this->httpClient + ); + $result = $stsClient->assumeRole([ + 'RoleArn' => $roleArn, + 'RoleSessionName' => $roleSessionName, + ]); + + try { + if (null === $credentials = $result->getCredentials()) { + throw new RuntimeException('The AssumeRole response does not contains credentials'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from assumed role in profile "{profile}: {exception}".', ['profile' => $profile, 'exception' => $e]); + + return null; + } + + return new Credentials( + $credentials->getAccessKeyId(), + $credentials->getSecretAccessKey(), + $credentials->getSessionToken(), + Credentials::adjustExpireDate($credentials->getExpiration(), $this->getDateFromResult($result)) + ); + } + + /** + * @param array $profileData + */ + private function getCredentialsFromLegacySso(array $profileData, string $profile): ?Credentials + { + if (!isset( + $profileData[IniFileLoader::KEY_SSO_START_URL], + $profileData[IniFileLoader::KEY_SSO_REGION], + $profileData[IniFileLoader::KEY_SSO_ACCOUNT_ID], + $profileData[IniFileLoader::KEY_SSO_ROLE_NAME] + )) { + $this->logger->warning('Profile "{profile}" does not contains required legacy SSO config.', ['profile' => $profile]); + + return null; + } + + $ssoCacheFileLoader = new SsoCacheFileLoader($this->logger); + $tokenData = $ssoCacheFileLoader->loadSsoCacheFile($profileData[IniFileLoader::KEY_SSO_START_URL]); + + if ([] === $tokenData) { + return null; + } + + $ssoClient = new SsoClient( + ['region' => $profileData[IniFileLoader::KEY_SSO_REGION]], + new NullProvider(), // no credentials required as we provide an access token via the role credentials request + $this->httpClient + ); + $result = $ssoClient->getRoleCredentials([ + 'accessToken' => $tokenData[SsoCacheFileLoader::KEY_ACCESS_TOKEN], + 'accountId' => $profileData[IniFileLoader::KEY_SSO_ACCOUNT_ID], + 'roleName' => $profileData[IniFileLoader::KEY_SSO_ROLE_NAME], + ]); + + try { + if (null === $credentials = $result->getRoleCredentials()) { + throw new RuntimeException('The RoleCredentials response does not contains credentials'); + } + if (null === $accessKeyId = $credentials->getAccessKeyId()) { + throw new RuntimeException('The RoleCredentials response does not contain an accessKeyId'); + } + if (null === $secretAccessKey = $credentials->getSecretAccessKey()) { + throw new RuntimeException('The RoleCredentials response does not contain a secretAccessKey'); + } + if (null === $sessionToken = $credentials->getSessionToken()) { + throw new RuntimeException('The RoleCredentials response does not contain a sessionToken'); + } + if (null === $expiration = $credentials->getExpiration()) { + throw new RuntimeException('The RoleCredentials response does not contain an expiration'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from role credentials in profile "{profile}: {exception}".', ['profile' => $profile, 'exception' => $e]); + + return null; + } + + return new Credentials( + $accessKeyId, + $secretAccessKey, + $sessionToken, + (new \DateTimeImmutable())->setTimestamp($expiration) + ); + } +} diff --git a/vendor/async-aws/core/src/Credentials/InstanceProvider.php b/vendor/async-aws/core/src/Credentials/InstanceProvider.php new file mode 100644 index 000000000..033e8c8e5 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/InstanceProvider.php @@ -0,0 +1,158 @@ + + */ +final class InstanceProvider implements CredentialProvider +{ + private const TOKEN_ENDPOINT = 'http://169.254.169.254/latest/api/token'; + private const METADATA_ENDPOINT = 'http://169.254.169.254/latest/meta-data/iam/security-credentials'; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * @var float + */ + private $timeout; + + /** + * @var int + */ + private $tokenTtl; + + public function __construct(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null, float $timeout = 1.0, int $tokenTtl = 21600) + { + $this->logger = $logger ?? new NullLogger(); + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->timeout = $timeout; + $this->tokenTtl = $tokenTtl; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $token = $this->getToken(); + $headers = []; + + if (null !== $token) { + $headers = ['X-aws-ec2-metadata-token' => $token]; + } + + try { + // Fetch current Profile + $response = $this->httpClient->request('GET', self::METADATA_ENDPOINT, [ + 'timeout' => $this->timeout, + 'headers' => $headers, + ]); + $profile = $response->getContent(); + + // Fetch credentials from profile + $response = $this->httpClient->request('GET', self::METADATA_ENDPOINT . '/' . $profile, [ + 'timeout' => $this->timeout, + 'headers' => $headers, + ]); + $result = $this->toArray($response); + + if ('Success' !== $result['Code']) { + $this->logger->info('Unexpected instance profile.', ['response_code' => $result['Code']]); + + return null; + } + } catch (DecodingExceptionInterface $e) { + $this->logger->info('Failed to decode Credentials.', ['exception' => $e]); + + return null; + } catch (TransportExceptionInterface|HttpExceptionInterface $e) { + $this->logger->info('Failed to fetch Profile from Instance Metadata.', ['exception' => $e]); + + return null; + } + + if (null !== $date = $response->getHeaders(false)['date'][0] ?? null) { + $date = new \DateTimeImmutable($date); + } + + return new Credentials( + $result['AccessKeyId'], + $result['SecretAccessKey'], + $result['Token'], + Credentials::adjustExpireDate(new \DateTimeImmutable($result['Expiration']), $date) + ); + } + + /** + * Copy of Symfony\Component\HttpClient\Response::toArray without assertion on Content-Type header. + * + * @return array + */ + private function toArray(ResponseInterface $response): array + { + if ('' === $content = $response->getContent(true)) { + throw new TransportException('Response body is empty.'); + } + + try { + $content = json_decode($content, true, 512, \JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0)); + } catch (\JsonException $e) { + /** @psalm-suppress all */ + throw new JsonException(sprintf('%s for "%s".', $e->getMessage(), $response->getInfo('url')), $e->getCode()); + } + + if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error()) { + /** @psalm-suppress InvalidArgument */ + throw new JsonException(sprintf('%s for "%s".', json_last_error_msg(), $response->getInfo('url')), json_last_error()); + } + + if (!\is_array($content)) { + /** @psalm-suppress InvalidArgument */ + throw new JsonException(sprintf('JSON content was expected to decode to an array, %s returned for "%s".', \gettype($content), $response->getInfo('url'))); + } + + return $content; + } + + private function getToken(): ?string + { + try { + $response = $this->httpClient->request('PUT', self::TOKEN_ENDPOINT, + [ + 'timeout' => $this->timeout, + 'headers' => ['X-aws-ec2-metadata-token-ttl-seconds' => $this->tokenTtl], + ] + ); + + return $response->getContent(); + } catch (TransportExceptionInterface|HttpExceptionInterface $e) { + $this->logger->info('Failed to fetch metadata token for IMDSv2, fallback to IMDSv1.', ['exception' => $e]); + + return null; + } + } +} diff --git a/vendor/async-aws/core/src/Credentials/NullProvider.php b/vendor/async-aws/core/src/Credentials/NullProvider.php new file mode 100644 index 000000000..b6399216e --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/NullProvider.php @@ -0,0 +1,20 @@ + + */ +final class NullProvider implements CredentialProvider +{ + public function getCredentials(Configuration $configuration): ?Credentials + { + return null; + } +} diff --git a/vendor/async-aws/core/src/Credentials/PsrCacheProvider.php b/vendor/async-aws/core/src/Credentials/PsrCacheProvider.php new file mode 100644 index 000000000..7dd0a0421 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/PsrCacheProvider.php @@ -0,0 +1,73 @@ + + */ +final class PsrCacheProvider implements CredentialProvider +{ + /** + * @var CacheItemPoolInterface + */ + private $cache; + + /** + * @var CredentialProvider + */ + private $decorated; + + /** + * @var LoggerInterface|null + */ + private $logger; + + public function __construct(CredentialProvider $decorated, CacheItemPoolInterface $cache, ?LoggerInterface $logger = null) + { + $this->decorated = $decorated; + $this->cache = $cache; + $this->logger = $logger; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + try { + return $this->getFromCache($configuration); + } catch (CacheException $e) { + if (null !== $this->logger) { + $this->logger->error('Failed to get AWS credentials from cache.', ['exception' => $e]); + } + + return $this->decorated->getCredentials($configuration); + } + } + + /** + * @throws CacheException + */ + private function getFromCache(Configuration $configuration): ?Credentials + { + $item = $this->cache->getItem('AsyncAws.Credentials.' . sha1(serialize([$configuration, \get_class($this->decorated)]))); + if (!$item->isHit()) { + $item->set($credential = $this->decorated->getCredentials($configuration)); + + if (null !== $credential && null !== $exp = $credential->getExpireDate()) { + $item->expiresAt($exp); + $this->cache->save($item); + } + } + + return $item->get(); + } +} diff --git a/vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php b/vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php new file mode 100644 index 000000000..756476835 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/SsoCacheFileLoader.php @@ -0,0 +1,79 @@ +logger = $logger ?? new NullLogger(); + } + + /** + * @return array + */ + public function loadSsoCacheFile(string $ssoStartUrl): array + { + $filepath = sprintf('%s/.aws/sso/cache/%s.json', $this->getHomeDir(), sha1($ssoStartUrl)); + + if (false === ($contents = @file_get_contents($filepath))) { + $this->logger->warning('The sso cache file {path} is not readable.', ['path' => $filepath]); + + return []; + } + + $tokenData = json_decode($contents, true); + if (!isset($tokenData[self::KEY_ACCESS_TOKEN], $tokenData[self::KEY_EXPIRES_AT])) { + $this->logger->warning('Token file at {path} must contain an accessToken and an expiresAt.', ['path' => $filepath]); + + return []; + } + + try { + $expiration = (new \DateTimeImmutable($tokenData[self::KEY_EXPIRES_AT])); + } catch (\Exception $e) { + $this->logger->warning('Cached SSO credentials returned an invalid expiresAt value.'); + + return []; + } + + if ($expiration < new \DateTimeImmutable()) { + $this->logger->warning('Cached SSO credentials returned an invalid expiresAt value.'); + + return []; + } + + return $tokenData; + } + + private function getHomeDir(): string + { + // On Linux/Unix-like systems, use the HOME environment variable + if (null !== $homeDir = EnvVar::get('HOME')) { + return $homeDir; + } + + // Get the HOMEDRIVE and HOMEPATH values for Windows hosts + $homeDrive = EnvVar::get('HOMEDRIVE'); + $homePath = EnvVar::get('HOMEPATH'); + + return ($homeDrive && $homePath) ? $homeDrive . $homePath : '/'; + } +} diff --git a/vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php b/vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php new file mode 100644 index 000000000..e3bfe25c3 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/SymfonyCacheProvider.php @@ -0,0 +1,71 @@ + + */ +final class SymfonyCacheProvider implements CredentialProvider +{ + /** + * @var CacheInterface + */ + private $cache; + + /** + * @var CredentialProvider + */ + private $decorated; + + /** + * @var LoggerInterface|null + */ + private $logger; + + public function __construct(CredentialProvider $decorated, CacheInterface $cache, ?LoggerInterface $logger = null) + { + $this->decorated = $decorated; + $this->cache = $cache; + $this->logger = $logger; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $provider = $this->decorated; + $closure = \Closure::fromCallable(static function (ItemInterface $item) use ($configuration, $provider) { + $credential = $provider->getCredentials($configuration); + + if (null !== $credential && null !== $exp = $credential->getExpireDate()) { + $item->expiresAt($exp); + } else { + $item->expiresAfter(0); + } + + return $credential; + }); + + try { + return $this->cache->get('AsyncAws.Credentials.' . sha1(serialize([$configuration, \get_class($this->decorated)])), $closure); + } catch (CacheException $e) { + if (null !== $this->logger) { + $this->logger->error('Failed to get AWS credentials from cache.', ['exception' => $e]); + } + + return $provider->getCredentials($configuration); + } + } +} diff --git a/vendor/async-aws/core/src/Credentials/WebIdentityProvider.php b/vendor/async-aws/core/src/Credentials/WebIdentityProvider.php new file mode 100644 index 000000000..f05485e66 --- /dev/null +++ b/vendor/async-aws/core/src/Credentials/WebIdentityProvider.php @@ -0,0 +1,158 @@ + + */ +final class WebIdentityProvider implements CredentialProvider +{ + use DateFromResult; + + /** + * @var IniFileLoader + */ + private $iniFileLoader; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var HttpClientInterface|null + */ + private $httpClient; + + public function __construct(?LoggerInterface $logger = null, ?IniFileLoader $iniFileLoader = null, ?HttpClientInterface $httpClient = null) + { + $this->logger = $logger ?? new NullLogger(); + $this->iniFileLoader = $iniFileLoader ?? new IniFileLoader($this->logger); + $this->httpClient = $httpClient; + } + + public function getCredentials(Configuration $configuration): ?Credentials + { + $roleArn = $configuration->get(Configuration::OPTION_ROLE_ARN); + $tokenFile = $configuration->get(Configuration::OPTION_WEB_IDENTITY_TOKEN_FILE); + + if ($tokenFile && $roleArn) { + return $this->getCredentialsFromRole( + $roleArn, + $tokenFile, + $configuration->get(Configuration::OPTION_ROLE_SESSION_NAME), + $configuration->get(Configuration::OPTION_REGION) + ); + } + + $profilesData = $this->iniFileLoader->loadProfiles([ + $configuration->get(Configuration::OPTION_SHARED_CREDENTIALS_FILE), + $configuration->get(Configuration::OPTION_SHARED_CONFIG_FILE), + ]); + if (empty($profilesData)) { + return null; + } + + /** @var string $profile */ + $profile = $configuration->get(Configuration::OPTION_PROFILE); + if (!isset($profilesData[$profile])) { + $this->logger->warning('Profile "{profile}" not found.', ['profile' => $profile]); + + return null; + } + + $profileData = $profilesData[$profile]; + $roleArn = $profileData[IniFileLoader::KEY_ROLE_ARN] ?? null; + $tokenFile = $profileData[IniFileLoader::KEY_WEB_IDENTITY_TOKEN_FILE] ?? null; + + if (null !== $roleArn && null !== $tokenFile) { + return $this->getCredentialsFromRole( + $roleArn, + $tokenFile, + $profileData[IniFileLoader::KEY_ROLE_SESSION_NAME] ?? null, + $profileData[IniFileLoader::KEY_REGION] ?? $configuration->get(Configuration::OPTION_REGION) + ); + } + + return null; + } + + private function getCredentialsFromRole(string $roleArn, string $tokenFile, ?string $sessionName, ?string $region): ?Credentials + { + $sessionName = $sessionName ?? uniqid('async-aws-', true); + if (!preg_match("/^\w\:|^\/|^\\\/", $tokenFile)) { + $this->logger->warning('WebIdentityTokenFile "{tokenFile}" must be an absolute path.', ['tokenFile' => $tokenFile]); + } + + try { + $token = $this->getTokenFileContent($tokenFile); + } catch (\Exception $e) { + $this->logger->warning('"Error reading WebIdentityTokenFile "{tokenFile}.', ['tokenFile' => $tokenFile, 'exception' => $e]); + + return null; + } + + $stsClient = new StsClient(['region' => $region], new NullProvider(), $this->httpClient); + $result = $stsClient->assumeRoleWithWebIdentity([ + 'RoleArn' => $roleArn, + 'RoleSessionName' => $sessionName, + 'WebIdentityToken' => $token, + ]); + + try { + if (null === $credentials = $result->getCredentials()) { + throw new RuntimeException('The AssumeRoleWithWebIdentity response does not contains credentials'); + } + } catch (\Exception $e) { + $this->logger->warning('Failed to get credentials from assumed role: {exception}".', ['exception' => $e]); + + return null; + } + + return new Credentials( + $credentials->getAccessKeyId(), + $credentials->getSecretAccessKey(), + $credentials->getSessionToken(), + Credentials::adjustExpireDate($credentials->getExpiration(), $this->getDateFromResult($result)) + ); + } + + /** + * @see https://github.com/async-aws/aws/issues/900 + * @see https://github.com/aws/aws-sdk-php/issues/2014 + * @see https://github.com/aws/aws-sdk-php/pull/2043 + */ + private function getTokenFileContent(string $tokenFile): string + { + $token = @file_get_contents($tokenFile); + + if (false !== $token) { + return $token; + } + + $tokenDir = \dirname($tokenFile); + $tokenLink = readlink($tokenFile); + clearstatcache(true, $tokenDir . \DIRECTORY_SEPARATOR . $tokenLink); + clearstatcache(true, $tokenDir . \DIRECTORY_SEPARATOR . \dirname($tokenLink)); + clearstatcache(true, $tokenFile); + + if (false === $token = file_get_contents($tokenFile)) { + throw new RuntimeException('Failed to read data'); + } + + return $token; + } +} diff --git a/vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php b/vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php new file mode 100644 index 000000000..e659e4900 --- /dev/null +++ b/vendor/async-aws/core/src/EndpointDiscovery/EndpointCache.php @@ -0,0 +1,126 @@ + + * + * @internal + */ +class EndpointCache +{ + /** + * @var array> + */ + private $endpoints = []; + + /** + * @var array> + */ + private $expired = []; + + /** + * @param EndpointInterface[] $endpoints + */ + public function addEndpoints(?string $region, array $endpoints): void + { + $now = time(); + + if (null === $region) { + $region = ''; + } + if (!isset($this->endpoints[$region])) { + $this->endpoints[$region] = []; + } + + foreach ($endpoints as $endpoint) { + $this->endpoints[$region][$this->sanitizeEndpoint($endpoint->getAddress())] = $now + ($endpoint->getCachePeriodInMinutes() * 60); + } + arsort($this->endpoints[$region]); + } + + public function removeEndpoint(string $endpoint): void + { + $endpoint = $this->sanitizeEndpoint($endpoint); + foreach ($this->endpoints as &$endpoints) { + unset($endpoints[$endpoint]); + } + unset($endpoints); + foreach ($this->expired as &$endpoints) { + unset($endpoints[$endpoint]); + } + + unset($endpoints); + } + + public function getActiveEndpoint(?string $region): ?string + { + if (null === $region) { + $region = ''; + } + $now = time(); + + foreach ($this->endpoints[$region] ?? [] as $endpoint => $expiresAt) { + if ($expiresAt < $now) { + $this->expired[$region] = \array_slice($this->expired[$region] ?? [], -100); // keep only the last 100 items + unset($this->endpoints[$region][$endpoint]); + $this->expired[$region][$endpoint] = $expiresAt; + + continue; + } + + return $endpoint; + } + + return null; + } + + public function getExpiredEndpoint(?string $region): ?string + { + if (null === $region) { + $region = ''; + } + if (empty($this->expired[$region])) { + return null; + } + + return array_key_last($this->expired[$region]); + } + + private function sanitizeEndpoint(string $address): string + { + $parsed = parse_url($address); + + // parse_url() will correctly parse full URIs with schemes + if (isset($parsed['host'])) { + return rtrim(sprintf( + '%s://%s/%s', + $parsed['scheme'] ?? 'https', + $parsed['host'], + ltrim($parsed['path'] ?? '/', '/') + ), '/'); + } + + // parse_url() will put host & path in 'path' if scheme is not provided + if (isset($parsed['path'])) { + $split = explode('/', $parsed['path'], 2); + $parsed['host'] = $split[0]; + if (isset($split[1])) { + $parsed['path'] = $split[1]; + } else { + $parsed['path'] = ''; + } + + return rtrim(sprintf( + '%s://%s/%s', + $parsed['scheme'] ?? 'https', + $parsed['host'], + ltrim($parsed['path'], '/') + ), '/'); + } + + throw new LogicException(sprintf('The supplied endpoint "%s" is invalid.', $address)); + } +} diff --git a/vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php b/vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php new file mode 100644 index 000000000..d46e2f340 --- /dev/null +++ b/vendor/async-aws/core/src/EndpointDiscovery/EndpointInterface.php @@ -0,0 +1,10 @@ + + * + * @internal + */ +final class EnvVar +{ + public static function get(string $name): ?string + { + if (isset($_ENV[$name])) { + // variable_order = *E*GPCS + return (string) $_ENV[$name]; + } elseif (isset($_SERVER[$name]) && !\is_array($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + // fastcgi_param, env var, ... + return (string) $_SERVER[$name]; + } elseif (false === $env = getenv($name)) { + // getenv not thread safe + return null; + } + + return $env; + } +} diff --git a/vendor/async-aws/core/src/Exception/Exception.php b/vendor/async-aws/core/src/Exception/Exception.php new file mode 100644 index 000000000..87b8074e9 --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Exception.php @@ -0,0 +1,14 @@ + + */ +interface Exception extends \Throwable +{ +} diff --git a/vendor/async-aws/core/src/Exception/Http/ClientException.php b/vendor/async-aws/core/src/Exception/Http/ClientException.php new file mode 100644 index 000000000..5ffbe0227 --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/ClientException.php @@ -0,0 +1,17 @@ + + */ +class ClientException extends \RuntimeException implements ClientExceptionInterface, HttpException +{ + use HttpExceptionTrait; +} diff --git a/vendor/async-aws/core/src/Exception/Http/HttpException.php b/vendor/async-aws/core/src/Exception/Http/HttpException.php new file mode 100644 index 000000000..cc5f6e64f --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/HttpException.php @@ -0,0 +1,21 @@ + + * @author Tobias Nyholm + * @author Jérémy Derussé + * + * @internal + */ +trait HttpExceptionTrait +{ + /** + * @var ResponseInterface + */ + private $response; + + /** + * @var ?AwsError + */ + private $awsError; + + public function __construct(ResponseInterface $response, ?AwsError $awsError = null) + { + $this->response = $response; + /** @var int $code */ + $code = $response->getInfo('http_code'); + /** @var string $url */ + $url = $response->getInfo('url'); + + $message = sprintf('HTTP %d returned for "%s".', $code, $url); + if (null !== $this->awsError = $awsError) { + $message .= <<awsError->getCode()} +Message: {$this->awsError->getMessage()} +Type: {$this->awsError->getType()} +Detail: {$this->awsError->getDetail()} + +TEXT; + } + + parent::__construct($message, $code); + + $this->populateResult($response); + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } + + public function getAwsCode(): ?string + { + return $this->awsError ? $this->awsError->getCode() : null; + } + + public function getAwsType(): ?string + { + return $this->awsError ? $this->awsError->getType() : null; + } + + public function getAwsMessage(): ?string + { + return $this->awsError ? $this->awsError->getMessage() : null; + } + + public function getAwsDetail(): ?string + { + return $this->awsError ? $this->awsError->getDetail() : null; + } + + protected function populateResult(ResponseInterface $response): void + { + } +} diff --git a/vendor/async-aws/core/src/Exception/Http/NetworkException.php b/vendor/async-aws/core/src/Exception/Http/NetworkException.php new file mode 100644 index 000000000..9c893ddde --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/NetworkException.php @@ -0,0 +1,17 @@ + + */ +class NetworkException extends \RuntimeException implements Exception, TransportExceptionInterface +{ +} diff --git a/vendor/async-aws/core/src/Exception/Http/RedirectionException.php b/vendor/async-aws/core/src/Exception/Http/RedirectionException.php new file mode 100644 index 000000000..c1443b98c --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/RedirectionException.php @@ -0,0 +1,17 @@ + + */ +final class RedirectionException extends \RuntimeException implements HttpException, RedirectionExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/async-aws/core/src/Exception/Http/ServerException.php b/vendor/async-aws/core/src/Exception/Http/ServerException.php new file mode 100644 index 000000000..baf6560f8 --- /dev/null +++ b/vendor/async-aws/core/src/Exception/Http/ServerException.php @@ -0,0 +1,17 @@ + + */ +class ServerException extends \RuntimeException implements HttpException, ServerExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/async-aws/core/src/Exception/InvalidArgument.php b/vendor/async-aws/core/src/Exception/InvalidArgument.php new file mode 100644 index 000000000..46604d57a --- /dev/null +++ b/vendor/async-aws/core/src/Exception/InvalidArgument.php @@ -0,0 +1,9 @@ + + */ +class AwsHttpClientFactory +{ + public static function createRetryableClient(?HttpClientInterface $httpClient = null, ?LoggerInterface $logger = null): HttpClientInterface + { + if (null === $httpClient) { + $httpClient = HttpClient::create(); + } + if (class_exists(RetryableHttpClient::class)) { + /** @psalm-suppress MissingDependency */ + $httpClient = new RetryableHttpClient( + $httpClient, + new AwsRetryStrategy(), + 3, + $logger + ); + } + + return $httpClient; + } +} diff --git a/vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php b/vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php new file mode 100644 index 000000000..d779f6f80 --- /dev/null +++ b/vendor/async-aws/core/src/HttpClient/AwsRetryStrategy.php @@ -0,0 +1,73 @@ + + */ +class AwsRetryStrategy extends GenericRetryStrategy +{ + // Override Symfony default options for a better integration of AWS servers. + public const DEFAULT_RETRY_STATUS_CODES = [0, 423, 425, 429, 500, 502, 503, 504, 507, 510]; + + /** + * @var AwsErrorFactoryInterface + */ + private $awsErrorFactory; + + /** + * @param array $statusCodes + */ + public function __construct(array $statusCodes = self::DEFAULT_RETRY_STATUS_CODES, int $delayMs = 1000, float $multiplier = 2.0, int $maxDelayMs = 0, float $jitter = 0.1, ?AwsErrorFactoryInterface $awsErrorFactory = null) + { + parent::__construct($statusCodes, $delayMs, $multiplier, $maxDelayMs, $jitter); + $this->awsErrorFactory = $awsErrorFactory ?? new ChainAwsErrorFactory(); + } + + public function shouldRetry(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): ?bool + { + if (parent::shouldRetry($context, $responseContent, $exception)) { + return true; + } + + if (!\in_array($context->getStatusCode(), [400, 403], true)) { + return false; + } + + if (null === $responseContent) { + return null; // null mean no decision taken and need to be called again with the body + } + + try { + $error = $this->awsErrorFactory->createFromContent($responseContent, $context->getHeaders()); + } catch (UnparsableResponse $e) { + return false; + } + + return \in_array($error->getCode(), [ + 'RequestLimitExceeded', + 'Throttling', + 'ThrottlingException', + 'ThrottledException', + 'LimitExceededException', + 'PriorRequestNotComplete', + 'ProvisionedThroughputExceededException', + 'RequestThrottled', + 'SlowDown', + 'BandwidthLimitExceeded', + 'RequestThrottledException', + 'RetryableThrottlingException', + 'TooManyRequestsException', + 'IDPCommunicationError', + 'EC2ThrottledException', + 'TransactionInProgressException', + ], true); + } +} diff --git a/vendor/async-aws/core/src/Input.php b/vendor/async-aws/core/src/Input.php new file mode 100644 index 000000000..2c360d94e --- /dev/null +++ b/vendor/async-aws/core/src/Input.php @@ -0,0 +1,36 @@ + + */ +abstract class Input +{ + /** + * @var string|null + */ + public $region; + + /** + * @param array{'@region'?: ?string,...} $input + */ + protected function __construct(array $input) + { + $this->region = $input['@region'] ?? null; + } + + public function setRegion(?string $region): void + { + $this->region = $region; + } + + public function getRegion(): ?string + { + return $this->region; + } + + abstract public function request(): Request; +} diff --git a/vendor/async-aws/core/src/Request.php b/vendor/async-aws/core/src/Request.php new file mode 100644 index 000000000..52eac4dde --- /dev/null +++ b/vendor/async-aws/core/src/Request.php @@ -0,0 +1,215 @@ + + */ +final class Request +{ + /** + * @var string + */ + private $method; + + /** + * @var string + */ + private $uri; + + /** + * @var array + */ + private $headers; + + /** + * @var RequestStream + */ + private $body; + + /** + * @var string|null + */ + private $queryString; + + /** + * @var array + */ + private $query; + + /** + * @var string + */ + private $endpoint; + + /** + * @var string + */ + private $hostPrefix; + + /** + * @var array{scheme: string, host: string, port: int|null}|null + */ + private $parsed; + + /** + * @param array $query + * @param array $headers + */ + public function __construct(string $method, string $uri, array $query, array $headers, RequestStream $body, string $hostPrefix = '') + { + $this->method = $method; + $this->uri = $uri; + $this->headers = []; + foreach ($headers as $key => $value) { + $this->headers[strtolower($key)] = (string) $value; + } + $this->body = $body; + $this->query = $query; + $this->hostPrefix = $hostPrefix; + $this->endpoint = ''; + } + + public function getMethod(): string + { + return $this->method; + } + + public function setMethod(string $method): void + { + $this->method = $method; + } + + public function getUri(): string + { + return $this->uri; + } + + public function hasHeader(string $name): bool + { + return \array_key_exists(strtolower($name), $this->headers); + } + + public function setHeader(string $name, string $value): void + { + $this->headers[strtolower($name)] = $value; + } + + /** + * @return array + */ + public function getHeaders(): array + { + return $this->headers; + } + + public function getHeader(string $name): ?string + { + return $this->headers[strtolower($name)] ?? null; + } + + public function removeHeader(string $name): void + { + unset($this->headers[strtolower($name)]); + } + + public function getBody(): RequestStream + { + return $this->body; + } + + public function setBody(RequestStream $body): void + { + $this->body = $body; + } + + public function hasQueryAttribute(string $name): bool + { + return \array_key_exists($name, $this->query); + } + + public function removeQueryAttribute(string $name): void + { + unset($this->query[$name]); + $this->queryString = null; + $this->endpoint = ''; + } + + public function setQueryAttribute(string $name, string $value): void + { + $this->query[$name] = $value; + $this->queryString = null; + $this->endpoint = ''; + } + + public function getQueryAttribute(string $name): ?string + { + return $this->query[$name] ?? null; + } + + /** + * @return array + */ + public function getQuery(): array + { + return $this->query; + } + + public function getHostPrefix(): string + { + return $this->hostPrefix; + } + + public function setHostPrefix(string $hostPrefix): void + { + $this->hostPrefix = $hostPrefix; + $this->endpoint = ''; + } + + public function getEndpoint(): string + { + if (empty($this->endpoint)) { + if (null === $this->parsed) { + throw new LogicException('Request::$endpoint must be set before using it.'); + } + + $this->endpoint = $this->parsed['scheme'] . '://' . $this->hostPrefix . $this->parsed['host'] . (isset($this->parsed['port']) ? ':' . $this->parsed['port'] : '') . $this->uri . ($this->query ? (false === strpos($this->uri, '?') ? '?' : '&') . $this->getQueryString() : ''); + } + + return $this->endpoint; + } + + public function setEndpoint(string $endpoint): void + { + if (null !== $this->parsed) { + throw new LogicException('Request::$endpoint cannot be changed after it has a value.'); + } + + $parsed = parse_url($endpoint); + + if (false === $parsed || !isset($parsed['scheme'], $parsed['host'])) { + throw new InvalidArgument(sprintf('The endpoint "%s" is invalid.', $endpoint)); + } + + $this->parsed = ['scheme' => $parsed['scheme'], 'host' => $parsed['host'], 'port' => $parsed['port'] ?? null]; + + $this->queryString = $parsed['query'] ?? ''; + parse_str($parsed['query'] ?? '', $this->query); + $this->uri = $parsed['path'] ?? '/'; + } + + private function getQueryString(): string + { + if (null === $this->queryString) { + $this->queryString = http_build_query($this->query, '', '&', \PHP_QUERY_RFC3986); + } + + return $this->queryString; + } +} diff --git a/vendor/async-aws/core/src/RequestContext.php b/vendor/async-aws/core/src/RequestContext.php new file mode 100644 index 000000000..9d5226eb9 --- /dev/null +++ b/vendor/async-aws/core/src/RequestContext.php @@ -0,0 +1,119 @@ + + */ +final class RequestContext +{ + public const AVAILABLE_OPTIONS = [ + 'region' => true, + 'operation' => true, + 'expirationDate' => true, + 'currentDate' => true, + 'exceptionMapping' => true, + 'usesEndpointDiscovery' => true, + 'requiresEndpointDiscovery' => true, + ]; + + /** + * @var string|null + */ + private $operation; + + /** + * @var bool + */ + private $usesEndpointDiscovery = false; + + /** + * @var bool + */ + private $requiresEndpointDiscovery = false; + + /** + * @var string|null + */ + private $region; + + /** + * @var \DateTimeImmutable|null + */ + private $expirationDate; + + /** + * @var \DateTimeImmutable|null + */ + private $currentDate; + + /** + * @var array> + */ + private $exceptionMapping = []; + + /** + * @param array{ + * operation?: null|string, + * region?: null|string, + * expirationDate?: null|\DateTimeImmutable, + * currentDate?: null|\DateTimeImmutable, + * exceptionMapping?: array>, + * usesEndpointDiscovery?: bool, + * requiresEndpointDiscovery?: bool, + * } $options + */ + public function __construct(array $options = []) + { + if (0 < \count($invalidOptions = array_diff_key($options, self::AVAILABLE_OPTIONS))) { + throw new InvalidArgument(sprintf('Invalid option(s) "%s" passed to "%s". ', implode('", "', array_keys($invalidOptions)), __METHOD__)); + } + + foreach ($options as $property => $value) { + $this->$property = $value; + } + } + + public function getOperation(): ?string + { + return $this->operation; + } + + public function getRegion(): ?string + { + return $this->region; + } + + public function getExpirationDate(): ?\DateTimeImmutable + { + return $this->expirationDate; + } + + public function getCurrentDate(): ?\DateTimeImmutable + { + return $this->currentDate; + } + + /** + * @return array> + */ + public function getExceptionMapping(): array + { + return $this->exceptionMapping; + } + + public function usesEndpointDiscovery(): bool + { + return $this->usesEndpointDiscovery; + } + + public function requiresEndpointDiscovery(): bool + { + return $this->requiresEndpointDiscovery; + } +} diff --git a/vendor/async-aws/core/src/Response.php b/vendor/async-aws/core/src/Response.php new file mode 100644 index 000000000..b58ade040 --- /dev/null +++ b/vendor/async-aws/core/src/Response.php @@ -0,0 +1,477 @@ + + */ +final class Response +{ + /** + * @var ResponseInterface + */ + private $httpResponse; + + /** + * @var HttpClientInterface + */ + private $httpClient; + + /** + * A Result can be resolved many times. This variable contains the last resolve result. + * Null means that the result has never been resolved. Array contains material to create an exception. + * + * @var bool|HttpException|NetworkException|(callable(): (HttpException|NetworkException))|null + */ + private $resolveResult; + + /** + * A flag that indicated that the body have been downloaded. + * + * @var bool + */ + private $bodyDownloaded = false; + + /** + * A flag that indicated that the body started being downloaded. + * + * @var bool + */ + private $streamStarted = false; + + /** + * A flag that indicated that an exception has been thrown to the user. + * + * @var bool + */ + private $didThrow = false; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var AwsErrorFactoryInterface + */ + private $awsErrorFactory; + + /** + * @var ?EndpointCache + */ + private $endpointCache; + + /** + * @var ?Request + */ + private $request; + + /** + * @var bool + */ + private $debug; + + /** + * @var array> + */ + private $exceptionMapping; + + /** + * @param array> $exceptionMapping + */ + public function __construct(ResponseInterface $response, HttpClientInterface $httpClient, LoggerInterface $logger, ?AwsErrorFactoryInterface $awsErrorFactory = null, ?EndpointCache $endpointCache = null, ?Request $request = null, bool $debug = false, array $exceptionMapping = []) + { + $this->httpResponse = $response; + $this->httpClient = $httpClient; + $this->logger = $logger; + $this->awsErrorFactory = $awsErrorFactory ?? new ChainAwsErrorFactory(); + $this->endpointCache = $endpointCache; + $this->request = $request; + $this->debug = $debug; + $this->exceptionMapping = $exceptionMapping; + } + + public function __destruct() + { + if (null === $this->resolveResult || !$this->didThrow) { + $this->resolve(); + } + } + + /** + * Make sure the actual request is executed. + * + * @param float|null $timeout Duration in seconds before aborting. When null wait + * until the end of execution. Using 0 means non-blocking + * + * @return bool whether the request is executed or not + * + * @throws NetworkException + * @throws HttpException + */ + public function resolve(?float $timeout = null): bool + { + if (null !== $this->resolveResult) { + return $this->getResolveStatus(); + } + + try { + if (null === $timeout) { + $this->httpResponse->getStatusCode(); + } else { + foreach ($this->httpClient->stream($this->httpResponse, $timeout) as $chunk) { + if ($chunk->isTimeout()) { + return false; + } + if ($chunk->isFirst()) { + break; + } + } + } + + $this->defineResolveStatus(); + } catch (TransportExceptionInterface $e) { + $this->resolveResult = new NetworkException('Could not contact remote server.', 0, $e); + } + + if (true === $this->debug) { + $httpStatusCode = $this->httpResponse->getInfo('http_code'); + if (0 === $httpStatusCode) { + // Network exception + $this->logger->debug('AsyncAws HTTP request could not be sent due network issues'); + } else { + $this->logger->debug('AsyncAws HTTP response received with status code {status_code}', [ + 'status_code' => $httpStatusCode, + 'headers' => json_encode($this->httpResponse->getHeaders(false)), + 'body' => $this->httpResponse->getContent(false), + ]); + $this->bodyDownloaded = true; + } + } + + return $this->getResolveStatus(); + } + + /** + * Make sure all provided requests are executed. + * + * @param self[] $responses + * @param float|null $timeout Duration in seconds before aborting. When null wait + * until the end of execution. Using 0 means non-blocking + * @param bool $downloadBody Wait until receiving the entire response body or only the first bytes + * + * @return iterable + * + * @throws NetworkException + * @throws HttpException + */ + final public static function wait(iterable $responses, ?float $timeout = null, bool $downloadBody = false): iterable + { + /** @var self[] $responseMap */ + $responseMap = []; + $indexMap = []; + $httpResponses = []; + $httpClient = null; + foreach ($responses as $index => $response) { + if (null !== $response->resolveResult && (true !== $response->resolveResult || !$downloadBody || $response->bodyDownloaded)) { + yield $index => $response; + + continue; + } + + if (null === $httpClient) { + $httpClient = $response->httpClient; + } elseif ($httpClient !== $response->httpClient) { + throw new LogicException('Unable to wait for the given results, they all have to be created with the same HttpClient'); + } + $httpResponses[] = $response->httpResponse; + $indexMap[$hash = spl_object_id($response->httpResponse)] = $index; + $responseMap[$hash] = $response; + } + + // no response provided (or all responses already resolved) + if (empty($httpResponses)) { + return; + } + + if (null === $httpClient) { + throw new InvalidArgument('At least one response should have contain an Http Client'); + } + + foreach ($httpClient->stream($httpResponses, $timeout) as $httpResponse => $chunk) { + $hash = spl_object_id($httpResponse); + $response = $responseMap[$hash] ?? null; + // Check if null, just in case symfony yield an unexpected response. + if (null === $response) { + continue; + } + + // index could be null if already yield + $index = $indexMap[$hash] ?? null; + + try { + if ($chunk->isTimeout()) { + // Receiving a timeout mean all responses are inactive. + break; + } + } catch (TransportExceptionInterface $e) { + // Exception is stored as an array, because storing an instance of \Exception will create a circular + // reference and prevent `__destruct` being called. + $response->resolveResult = new NetworkException('Could not contact remote server.', 0, $e); + + if (null !== $index) { + unset($indexMap[$hash]); + yield $index => $response; + if (empty($indexMap)) { + // early exit if all statusCode are known. We don't have to wait for all responses + return; + } + } + } + + if (!$response->streamStarted && '' !== $chunk->getContent()) { + $response->streamStarted = true; + } + + if ($chunk->isLast()) { + $response->bodyDownloaded = true; + if (null !== $index && $downloadBody) { + unset($indexMap[$hash]); + yield $index => $response; + } + } + if ($chunk->isFirst()) { + $response->defineResolveStatus(); + if (null !== $index && !$downloadBody) { + unset($indexMap[$hash]); + yield $index => $response; + } + } + + if (empty($indexMap)) { + // early exit if all statusCode are known. We don't have to wait for all responses + return; + } + } + } + + /** + * Returns info on the current request. + * + * @return array{ + * resolved: bool, + * body_downloaded: bool, + * response: \Symfony\Contracts\HttpClient\ResponseInterface, + * status: int, + * } + */ + public function info(): array + { + return [ + 'resolved' => null !== $this->resolveResult, + 'body_downloaded' => $this->bodyDownloaded, + 'response' => $this->httpResponse, + 'status' => (int) $this->httpResponse->getInfo('http_code'), + ]; + } + + public function cancel(): void + { + $this->httpResponse->cancel(); + $this->resolveResult = false; + } + + /** + * @return array> + * + * @throws NetworkException + * @throws HttpException + */ + public function getHeaders(): array + { + $this->resolve(); + + return $this->httpResponse->getHeaders(false); + } + + /** + * @throws NetworkException + * @throws HttpException + */ + public function getContent(): string + { + $this->resolve(); + + try { + return $this->httpResponse->getContent(false); + } finally { + $this->bodyDownloaded = true; + } + } + + /** + * @return array + * + * @throws NetworkException + * @throws UnparsableResponse + * @throws HttpException + */ + public function toArray(): array + { + $this->resolve(); + + try { + return $this->httpResponse->toArray(false); + } catch (DecodingExceptionInterface $e) { + throw new UnparsableResponse('Could not parse response as array', 0, $e); + } finally { + $this->bodyDownloaded = true; + } + } + + public function getStatusCode(): int + { + return $this->httpResponse->getStatusCode(); + } + + /** + * @throws NetworkException + * @throws HttpException + */ + public function toStream(): ResultStream + { + $this->resolve(); + + if (\is_callable([$this->httpResponse, 'toStream'])) { + return new ResponseBodyResourceStream($this->httpResponse->toStream()); + } + + if ($this->streamStarted) { + throw new RuntimeException('Can not create a ResultStream because the body started being downloaded. The body was started to be downloaded in Response::wait()'); + } + + try { + return new ResponseBodyStream($this->httpClient->stream($this->httpResponse)); + } finally { + $this->bodyDownloaded = true; + } + } + + /** + * In PHP < 7.4, a reference to the arguments is present in the stackTrace of the exception. + * This creates a Circular reference: Response -> resolveResult -> Exception -> stackTrace -> Response. + * This mean, that calling `unset($response)` does not call the `__destruct` method and does not throw the + * remaining exception present in `resolveResult`. The `__destruct` method will be called once the garbage collector + * will detect the loop. + * That's why this method does not creates exception here, but creates closure instead that will be resolved right + * before throwing the exception. + */ + private function defineResolveStatus(): void + { + try { + $statusCode = $this->httpResponse->getStatusCode(); + } catch (TransportExceptionInterface $e) { + $this->resolveResult = static function () use ($e): NetworkException { + return new NetworkException('Could not contact remote server.', 0, $e); + }; + + return; + } + + if (300 <= $statusCode) { + try { + $awsError = $this->awsErrorFactory->createFromResponse($this->httpResponse); + if ($this->request && $this->endpointCache && (400 === $statusCode || 'InvalidEndpointException' === $awsError->getCode())) { + $this->endpointCache->removeEndpoint($this->request->getEndpoint()); + } + } catch (UnparsableResponse $e) { + $awsError = null; + } + + if ((null !== $awsCode = ($awsError ? $awsError->getCode() : null)) && isset($this->exceptionMapping[$awsCode])) { + $exceptionClass = $this->exceptionMapping[$awsCode]; + } elseif (500 <= $statusCode) { + $exceptionClass = ServerException::class; + } elseif (400 <= $statusCode) { + $exceptionClass = ClientException::class; + } else { + $exceptionClass = RedirectionException::class; + } + + $httpResponse = $this->httpResponse; + $this->resolveResult = static function () use ($exceptionClass, $httpResponse, $awsError): HttpException { + return new $exceptionClass($httpResponse, $awsError); + }; + + return; + } + + $this->resolveResult = true; + } + + private function getResolveStatus(): bool + { + if (\is_bool($this->resolveResult)) { + return $this->resolveResult; + } + + if (\is_callable($this->resolveResult)) { + $this->resolveResult = ($this->resolveResult)(); + } + + $code = null; + $message = null; + $context = ['exception' => $this->resolveResult]; + if ($this->resolveResult instanceof HttpException) { + /** @var int $code */ + $code = $this->httpResponse->getInfo('http_code'); + /** @var string $url */ + $url = $this->httpResponse->getInfo('url'); + $context['aws_code'] = $this->resolveResult->getAwsCode(); + $context['aws_message'] = $this->resolveResult->getAwsMessage(); + $context['aws_type'] = $this->resolveResult->getAwsType(); + $context['aws_detail'] = $this->resolveResult->getAwsDetail(); + $message = sprintf('HTTP %d returned for "%s".', $code, $url); + } + + if ($this->resolveResult instanceof Exception) { + $this->logger->log( + 404 === $code ? LogLevel::INFO : LogLevel::ERROR, + $message ?? $this->resolveResult->getMessage(), + $context + ); + $this->didThrow = true; + + throw $this->resolveResult; + } + + throw new RuntimeException('Unexpected resolve state'); + } +} diff --git a/vendor/async-aws/core/src/Result.php b/vendor/async-aws/core/src/Result.php new file mode 100644 index 000000000..fb57737b3 --- /dev/null +++ b/vendor/async-aws/core/src/Result.php @@ -0,0 +1,145 @@ +response = $response; + $this->awsClient = $awsClient; + $this->input = $request; + } + + public function __destruct() + { + while (!empty($this->prefetchResults)) { + array_shift($this->prefetchResults)->cancel(); + } + } + + /** + * Make sure the actual request is executed. + * + * @param float|null $timeout Duration in seconds before aborting. When null wait until the end of execution. + * + * @return bool whether the request is executed or not + * + * @throws NetworkException + * @throws HttpException + */ + final public function resolve(?float $timeout = null): bool + { + return $this->response->resolve($timeout); + } + + /** + * Make sure all provided requests are executed. + * This only work if the http responses are produced by the same HTTP client. + * See https://symfony.com/doc/current/components/http_client.html#multiplexing-responses. + * + * @param self[] $results + * @param float|null $timeout Duration in seconds before aborting. When null wait + * until the end of execution. Using 0 means non-blocking + * @param bool $downloadBody Wait until receiving the entire response body or only the first bytes + * + * @return iterable + * + * @throws NetworkException + * @throws HttpException + */ + final public static function wait(iterable $results, ?float $timeout = null, bool $downloadBody = false): iterable + { + $resultMap = []; + $responses = []; + foreach ($results as $index => $result) { + $responses[$index] = $result->response; + $resultMap[$index] = $result; + } + + foreach (Response::wait($responses, $timeout, $downloadBody) as $index => $response) { + yield $index => $resultMap[$index]; + } + } + + /** + * Returns info on the current request. + * + * @return array{ + * resolved: bool, + * body_downloaded: bool, + * response: \Symfony\Contracts\HttpClient\ResponseInterface, + * status: int, + * } + */ + final public function info(): array + { + return $this->response->info(); + } + + final public function cancel(): void + { + $this->response->cancel(); + } + + final protected function registerPrefetch(self $result): void + { + $this->prefetchResults[spl_object_id($result)] = $result; + } + + final protected function unregisterPrefetch(self $result): void + { + unset($this->prefetchResults[spl_object_id($result)]); + } + + final protected function initialize(): void + { + if ($this->initialized) { + return; + } + + $this->resolve(); + $this->initialized = true; + $this->populateResult($this->response); + } + + protected function populateResult(Response $response): void + { + } +} diff --git a/vendor/async-aws/core/src/Signer/Signer.php b/vendor/async-aws/core/src/Signer/Signer.php new file mode 100644 index 000000000..7ce4ed5d2 --- /dev/null +++ b/vendor/async-aws/core/src/Signer/Signer.php @@ -0,0 +1,19 @@ + + */ +interface Signer +{ + public function sign(Request $request, Credentials $credentials, RequestContext $context): void; + + public function presign(Request $request, Credentials $credentials, RequestContext $context): void; +} diff --git a/vendor/async-aws/core/src/Signer/SignerV4.php b/vendor/async-aws/core/src/Signer/SignerV4.php new file mode 100644 index 000000000..a407df599 --- /dev/null +++ b/vendor/async-aws/core/src/Signer/SignerV4.php @@ -0,0 +1,369 @@ + + */ +class SignerV4 implements Signer +{ + private const ALGORITHM_REQUEST = 'AWS4-HMAC-SHA256'; + + private const BLACKLIST_HEADERS = [ + 'cache-control' => true, + 'content-type' => true, + 'content-length' => true, + 'expect' => true, + 'max-forwards' => true, + 'pragma' => true, + 'range' => true, + 'te' => true, + 'if-match' => true, + 'if-none-match' => true, + 'if-modified-since' => true, + 'if-unmodified-since' => true, + 'if-range' => true, + 'accept' => true, + 'authorization' => true, + 'proxy-authorization' => true, + 'from' => true, + 'referer' => true, + 'user-agent' => true, + 'x-amzn-trace-id' => true, + 'aws-sdk-invocation-id' => true, + 'aws-sdk-retry' => true, + ]; + + /** + * @var string + */ + private $scopeName; + + /** + * @var string + */ + private $region; + + public function __construct(string $scopeName, string $region) + { + $this->scopeName = $scopeName; + $this->region = $region; + } + + public function presign(Request $request, Credentials $credentials, RequestContext $context): void + { + $now = $context->getCurrentDate() ?? new \DateTimeImmutable(); + + // Signer date have to be UTC https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html + $now = $now->setTimezone(new \DateTimeZone('UTC')); + $expires = $context->getExpirationDate() ?? $now->add(new \DateInterval('PT1H')); + + $this->handleSignature($request, $credentials, $now, $expires, true); + } + + public function sign(Request $request, Credentials $credentials, RequestContext $context): void + { + $now = $context->getCurrentDate() ?? new \DateTimeImmutable(); + + // Signer date have to be UTC https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html + $now = $now->setTimezone(new \DateTimeZone('UTC')); + + $this->handleSignature($request, $credentials, $now, $now, false); + } + + protected function buildBodyDigest(Request $request, bool $isPresign): string + { + if ($request->hasHeader('x-amz-content-sha256')) { + /** @var string $hash */ + $hash = $request->getHeader('x-amz-content-sha256'); + } else { + $body = $request->getBody(); + if ($body instanceof ReadOnceResultStream) { + $request->setBody($body = RewindableStream::create($body)); + } + + $hash = $request->getBody()->hash(); + } + + if ('UNSIGNED-PAYLOAD' === $hash) { + $request->setHeader('x-amz-content-sha256', $hash); + } + + return $hash; + } + + protected function convertBodyToStream(SigningContext $context): void + { + $request = $context->getRequest(); + $request->setBody(StringStream::create($request->getBody())); + } + + protected function buildCanonicalPath(Request $request): string + { + $doubleEncoded = rawurlencode(ltrim($request->getUri(), '/')); + + return '/' . str_replace('%2F', '/', $doubleEncoded); + } + + private function handleSignature(Request $request, Credentials $credentials, \DateTimeImmutable $now, \DateTimeImmutable $expires, bool $isPresign): void + { + $this->removePresign($request); + $this->sanitizeHostForHeader($request); + $this->assignAmzQueryValues($request, $credentials, $isPresign); + + $this->buildTime($request, $now, $expires, $isPresign); + $credentialScope = $this->buildCredentialString($request, $credentials, $now, $isPresign); + $context = new SigningContext( + $request, + $now, + implode('/', $credentialScope), + $this->buildSigningKey($credentials, $credentialScope) + ); + if ($isPresign) { + // Should be called before `buildBodyDigest` because this method may alter the body + $this->convertBodyToQuery($request); + } else { + $this->convertBodyToStream($context); + } + + $bodyDigest = $this->buildBodyDigest($request, $isPresign); + + if ($isPresign) { + // Should be called after `buildBodyDigest` because this method may remove the header `x-amz-content-sha256` + $this->convertHeaderToQuery($request); + } + + $canonicalHeaders = $this->buildCanonicalHeaders($request, $isPresign); + $canonicalRequest = $this->buildCanonicalRequest($request, $canonicalHeaders, $bodyDigest); + $stringToSign = $this->buildStringToSign($context->getNow(), $context->getCredentialString(), $canonicalRequest); + $context->setSignature($signature = $this->buildSignature($stringToSign, $context->getSigningKey())); + + if ($isPresign) { + $request->setQueryAttribute('X-Amz-Signature', $signature); + } else { + $request->setHeader('authorization', sprintf( + '%s Credential=%s/%s, SignedHeaders=%s, Signature=%s', + self::ALGORITHM_REQUEST, + $credentials->getAccessKeyId(), + implode('/', $credentialScope), + implode(';', array_keys($canonicalHeaders)), + $signature + )); + } + } + + private function removePresign(Request $request): void + { + $request->removeQueryAttribute('X-Amz-Algorithm'); + $request->removeQueryAttribute('X-Amz-Signature'); + $request->removeQueryAttribute('X-Amz-Security-Token'); + $request->removeQueryAttribute('X-Amz-Date'); + $request->removeQueryAttribute('X-Amz-Expires'); + $request->removeQueryAttribute('X-Amz-Credential'); + $request->removeQueryAttribute('X-Amz-SignedHeaders'); + } + + private function sanitizeHostForHeader(Request $request): void + { + if (false === $parsedUrl = parse_url($request->getEndpoint())) { + throw new InvalidArgument(sprintf('The endpoint "%s" is invalid.', $request->getEndpoint())); + } + + if (!isset($parsedUrl['host'])) { + return; + } + + $host = $parsedUrl['host']; + if (isset($parsedUrl['port'])) { + $host .= ':' . $parsedUrl['port']; + } + + $request->setHeader('host', $host); + } + + private function assignAmzQueryValues(Request $request, Credentials $credentials, bool $isPresign): void + { + if ($isPresign) { + $request->setQueryAttribute('X-Amz-Algorithm', self::ALGORITHM_REQUEST); + if (null !== $sessionToken = $credentials->getSessionToken()) { + $request->setQueryAttribute('X-Amz-Security-Token', $sessionToken); + } + + return; + } + + if (null !== $sessionToken = $credentials->getSessionToken()) { + $request->setHeader('x-amz-security-token', $sessionToken); + } + } + + private function buildTime(Request $request, \DateTimeImmutable $now, \DateTimeImmutable $expires, bool $isPresign): void + { + if ($isPresign) { + $duration = $expires->getTimestamp() - $now->getTimestamp(); + if ($duration > 604800) { + throw new InvalidArgument('The expiration date of presigned URL must be less than one week'); + } + if ($duration < 0) { + throw new InvalidArgument('The expiration date of presigned URL must be in the future'); + } + + $request->setQueryAttribute('X-Amz-Date', $now->format('Ymd\THis\Z')); + $request->setQueryAttribute('X-Amz-Expires', (string) $duration); + } else { + $request->setHeader('X-Amz-Date', $now->format('Ymd\THis\Z')); + } + } + + /** + * @return string[] + */ + private function buildCredentialString(Request $request, Credentials $credentials, \DateTimeImmutable $now, bool $isPresign): array + { + $credentialScope = [$now->format('Ymd'), $this->region, $this->scopeName, 'aws4_request']; + + if ($isPresign) { + $request->setQueryAttribute('X-Amz-Credential', $credentials->getAccessKeyId() . '/' . implode('/', $credentialScope)); + } + + return $credentialScope; + } + + private function convertHeaderToQuery(Request $request): void + { + foreach ($request->getHeaders() as $name => $value) { + if ('x-amz' === substr($name, 0, 5)) { + $request->setQueryAttribute($name, $value); + } + + if (isset(self::BLACKLIST_HEADERS[$name])) { + $request->removeHeader($name); + } + } + $request->removeHeader('x-amz-content-sha256'); + } + + private function convertBodyToQuery(Request $request): void + { + if ('POST' !== $request->getMethod()) { + return; + } + + $request->setMethod('GET'); + if ('application/x-www-form-urlencoded' === $request->getHeader('Content-Type')) { + parse_str($request->getBody()->stringify(), $params); + foreach ($params as $name => $value) { + $request->setQueryAttribute($name, $value); + } + } + + $request->removeHeader('content-type'); + $request->removeHeader('content-length'); + $request->setBody(StringStream::create('')); + } + + /** + * @return array + */ + private function buildCanonicalHeaders(Request $request, bool $isPresign): array + { + // Case-insensitively aggregate all of the headers. + $canonicalHeaders = []; + foreach ($request->getHeaders() as $key => $value) { + $key = strtolower($key); + if (isset(self::BLACKLIST_HEADERS[$key])) { + continue; + } + + $canonicalHeaders[$key] = $key . ':' . preg_replace('/\s+/', ' ', $value); + } + ksort($canonicalHeaders); + + if ($isPresign) { + $request->setQueryAttribute('X-Amz-SignedHeaders', implode(';', array_keys($canonicalHeaders))); + } + + return $canonicalHeaders; + } + + /** + * @param array $canonicalHeaders + */ + private function buildCanonicalRequest(Request $request, array $canonicalHeaders, string $bodyDigest): string + { + return implode("\n", [ + $request->getMethod(), + $this->buildCanonicalPath($request), + $this->buildCanonicalQuery($request), + implode("\n", array_values($canonicalHeaders)), + '', // empty line after headers + implode(';', array_keys($canonicalHeaders)), + $bodyDigest, + ]); + } + + private function buildCanonicalQuery(Request $request): string + { + $query = $request->getQuery(); + + unset($query['X-Amz-Signature']); + if (!$query) { + return ''; + } + + ksort($query); + $encodedQuery = []; + foreach ($query as $key => $values) { + if (!\is_array($values)) { + $encodedQuery[] = rawurlencode($key) . '=' . rawurlencode($values); + + continue; + } + + sort($values); + foreach ($values as $value) { + $encodedQuery[] = rawurlencode($key) . '=' . rawurlencode($value); + } + } + + return implode('&', $encodedQuery); + } + + private function buildStringToSign(\DateTimeImmutable $now, string $credentialString, string $canonicalRequest): string + { + return implode("\n", [ + self::ALGORITHM_REQUEST, + $now->format('Ymd\THis\Z'), + $credentialString, + hash('sha256', $canonicalRequest), + ]); + } + + /** + * @param string[] $credentialScope + */ + private function buildSigningKey(Credentials $credentials, array $credentialScope): string + { + $signingKey = 'AWS4' . $credentials->getSecretKey(); + foreach ($credentialScope as $scopePart) { + $signingKey = hash_hmac('sha256', $scopePart, $signingKey, true); + } + + return $signingKey; + } + + private function buildSignature(string $stringToSign, string $signingKey): string + { + return hash_hmac('sha256', $stringToSign, $signingKey); + } +} diff --git a/vendor/async-aws/core/src/Signer/SigningContext.php b/vendor/async-aws/core/src/Signer/SigningContext.php new file mode 100644 index 000000000..f012806b1 --- /dev/null +++ b/vendor/async-aws/core/src/Signer/SigningContext.php @@ -0,0 +1,78 @@ + + */ +final class SigningContext +{ + /** + * @var Request + */ + private $request; + + /** + * @var \DateTimeImmutable + */ + private $now; + + /** + * @var string + */ + private $credentialString; + + /** + * @var string + */ + private $signingKey; + + /** + * @var string + */ + private $signature = ''; + + public function __construct( + Request $request, + \DateTimeImmutable $now, + string $credentialString, + string $signingKey + ) { + $this->request = $request; + $this->now = $now; + $this->credentialString = $credentialString; + $this->signingKey = $signingKey; + } + + public function getRequest(): Request + { + return $this->request; + } + + public function getNow(): \DateTimeImmutable + { + return $this->now; + } + + public function getCredentialString(): string + { + return $this->credentialString; + } + + public function getSigningKey(): string + { + return $this->signingKey; + } + + public function getSignature(): string + { + return $this->signature; + } + + public function setSignature(string $signature): void + { + $this->signature = $signature; + } +} diff --git a/vendor/async-aws/core/src/Stream/CallableStream.php b/vendor/async-aws/core/src/Stream/CallableStream.php new file mode 100644 index 000000000..76111e9c0 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/CallableStream.php @@ -0,0 +1,84 @@ + + * + * @internal + */ +final class CallableStream implements ReadOnceResultStream, RequestStream +{ + /** + * @var callable(int): string + */ + private $content; + + /** + * @var int + */ + private $chunkSize; + + /** + * @param callable(int): string $content + */ + private function __construct(callable $content, int $chunkSize = 64 * 1024) + { + $this->content = $content; + $this->chunkSize = $chunkSize; + } + + /** + * @param self|callable(int): string $content + */ + public static function create($content, int $chunkSize = 64 * 1024): CallableStream + { + if ($content instanceof self) { + return $content; + } + if (\is_callable($content)) { + return new self($content, $chunkSize); + } + + throw new InvalidArgument(sprintf('Expect content to be a "callable". "%s" given.', \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): ?int + { + return null; + } + + public function stringify(): string + { + return implode('', iterator_to_array($this)); + } + + public function getIterator(): \Traversable + { + while (true) { + if (!\is_string($data = ($this->content)($this->chunkSize))) { + throw new InvalidArgument(sprintf('The return value of content callback must be a string, %s returned.', \is_object($data) ? \get_class($data) : \gettype($data))); + } + if ('' === $data) { + break; + } + + yield $data; + } + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + $ctx = hash_init($algo); + foreach ($this as $chunk) { + hash_update($ctx, $chunk); + } + + return hash_final($ctx, $raw); + } +} diff --git a/vendor/async-aws/core/src/Stream/FixedSizeStream.php b/vendor/async-aws/core/src/Stream/FixedSizeStream.php new file mode 100644 index 000000000..a0021c039 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/FixedSizeStream.php @@ -0,0 +1,90 @@ + + */ +final class FixedSizeStream implements RequestStream +{ + /** + * @var RequestStream + */ + private $content; + + /** + * @var int + */ + private $chunkSize; + + private function __construct(RequestStream $content, int $chunkSize = 64 * 1024) + { + $this->content = $content; + $this->chunkSize = $chunkSize; + } + + public static function create(RequestStream $content, int $chunkSize = 64 * 1024): FixedSizeStream + { + if ($content instanceof self) { + if ($content->chunkSize === $chunkSize) { + return $content; + } + + return new self($content->content, $chunkSize); + } + + return new self($content, $chunkSize); + } + + public function length(): ?int + { + return $this->content->length(); + } + + public function stringify(): string + { + return $this->content->stringify(); + } + + public function getIterator(): \Traversable + { + // This algorithm do not use string concatenation nor substr, to reuse the same ZVAL et reduce memory footprint. + $chunk = ''; + foreach ($this->content as $buffer) { + if (!\is_string($buffer)) { + throw new InvalidArgument(sprintf('The return value of content callback must be a string, %s returned.', \is_object($buffer) ? \get_class($buffer) : \gettype($buffer))); + } + + $chunk .= $nextBytes = substr($buffer, 0, $this->chunkSize - \strlen($chunk)); + $bufferPosition = \strlen($nextBytes); + + if (\strlen($chunk) < $this->chunkSize) { + // The chunk does not have yet the expected size. Let's fetching new data + continue; + } + + yield $chunk; + while (\strlen($buffer) - $bufferPosition >= $this->chunkSize) { + // The buffer is bigger than the expected size. Let's flushing it. + yield substr($buffer, $bufferPosition, $this->chunkSize); + $bufferPosition += $this->chunkSize; + } + + // Here we can substr the buffer because the remaining size is smaller that chunkSize + $chunk = substr($buffer, $bufferPosition); + } + + if ('' !== $chunk) { + yield $chunk; + } + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + return $this->content->hash($algo, $raw); + } +} diff --git a/vendor/async-aws/core/src/Stream/IterableStream.php b/vendor/async-aws/core/src/Stream/IterableStream.php new file mode 100644 index 000000000..f77407506 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/IterableStream.php @@ -0,0 +1,70 @@ + + */ +final class IterableStream implements ReadOnceResultStream, RequestStream +{ + /** + * @var iterable + */ + private $content; + + /** + * @param iterable $content + */ + private function __construct(iterable $content) + { + $this->content = $content; + } + + /** + * @param self|iterable $content + */ + public static function create($content): IterableStream + { + if ($content instanceof self) { + return $content; + } + if (is_iterable($content)) { + return new self($content); + } + + throw new InvalidArgument(sprintf('Expect content to be an iterable. "%s" given.', \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): ?int + { + return null; + } + + public function stringify(): string + { + if ($this->content instanceof \Traversable) { + return implode('', iterator_to_array($this->content)); + } + + return implode('', iterator_to_array((function () {yield from $this->content; })())); + } + + public function getIterator(): \Traversable + { + yield from $this->content; + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + $ctx = hash_init($algo); + foreach ($this->content as $chunk) { + hash_update($ctx, $chunk); + } + + return hash_final($ctx, $raw); + } +} diff --git a/vendor/async-aws/core/src/Stream/ReadOnceResultStream.php b/vendor/async-aws/core/src/Stream/ReadOnceResultStream.php new file mode 100644 index 000000000..b1fa03ac0 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ReadOnceResultStream.php @@ -0,0 +1,12 @@ + + * + * @extends \IteratorAggregate + */ +interface RequestStream extends \IteratorAggregate +{ + /** + * Length in bytes. + */ + public function length(): ?int; + + public function stringify(): string; + + public function hash(string $algo = 'sha256', bool $raw = false): string; +} diff --git a/vendor/async-aws/core/src/Stream/ResourceStream.php b/vendor/async-aws/core/src/Stream/ResourceStream.php new file mode 100644 index 000000000..0e863e4f7 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResourceStream.php @@ -0,0 +1,105 @@ + + * + * @internal + */ +final class ResourceStream implements RequestStream +{ + /** + * @var resource + */ + private $content; + + /** + * @var int + */ + private $chunkSize; + + /** + * @param resource $content + */ + private function __construct($content, int $chunkSize = 64 * 1024) + { + $this->content = $content; + $this->chunkSize = $chunkSize; + } + + /** + * @param self|resource $content + */ + public static function create($content, int $chunkSize = 64 * 1024): ResourceStream + { + if ($content instanceof self) { + return $content; + } + if (\is_resource($content)) { + if (!stream_get_meta_data($content)['seekable']) { + throw new InvalidArgument(sprintf('The give body is not seekable.')); + } + + return new self($content, $chunkSize); + } + + throw new InvalidArgument(sprintf('Expect content to be a "resource". "%s" given.', \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): ?int + { + return fstat($this->content)['size'] ?? null; + } + + public function stringify(): string + { + if (-1 === fseek($this->content, 0)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + return stream_get_contents($this->content); + } + + public function getIterator(): \Traversable + { + if (-1 === fseek($this->content, 0)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + while (!feof($this->content)) { + yield fread($this->content, $this->chunkSize); + } + } + + /** + * @return resource + */ + public function getResource() + { + return $this->content; + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + $pos = ftell($this->content); + + if ($pos > 0 && -1 === fseek($this->content, 0)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + $ctx = hash_init($algo); + hash_update_stream($ctx, $this->content); + $out = hash_final($ctx, $raw); + + if (-1 === fseek($this->content, $pos)) { + throw new InvalidArgument('Unable to seek the content.'); + } + + return $out; + } +} diff --git a/vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php b/vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php new file mode 100644 index 000000000..00ce21a2d --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResponseBodyResourceStream.php @@ -0,0 +1,82 @@ + + */ +class ResponseBodyResourceStream implements ResultStream +{ + /** + * @var resource + */ + private $resource; + + /** + * @param resource $resource + */ + public function __construct($resource) + { + $this->resource = $resource; + } + + public function __toString(): string + { + return $this->getContentAsString(); + } + + /** + * {@inheritdoc} + */ + public function getChunks(): iterable + { + $pos = ftell($this->resource); + if (0 !== $pos && !rewind($this->resource)) { + throw new RuntimeException('The stream is not rewindable'); + } + + try { + while (!feof($this->resource)) { + yield fread($this->resource, 64 * 1024); + } + } finally { + fseek($this->resource, $pos); + } + } + + /** + * {@inheritdoc} + */ + public function getContentAsString(): string + { + $pos = ftell($this->resource); + + try { + if (!rewind($this->resource)) { + throw new RuntimeException('Failed to rewind the stream'); + } + + return stream_get_contents($this->resource); + } finally { + fseek($this->resource, $pos); + } + } + + /** + * {@inheritdoc} + */ + public function getContentAsResource() + { + if (!rewind($this->resource)) { + throw new RuntimeException('Failed to rewind the stream'); + } + + return $this->resource; + } +} diff --git a/vendor/async-aws/core/src/Stream/ResponseBodyStream.php b/vendor/async-aws/core/src/Stream/ResponseBodyStream.php new file mode 100644 index 000000000..138c56570 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResponseBodyStream.php @@ -0,0 +1,101 @@ + + * @author Jérémy Derussé + */ +class ResponseBodyStream implements ResultStream +{ + /** + * @var ResponseStreamInterface + */ + private $responseStream; + + /** + * @var ResponseBodyResourceStream|null + */ + private $fallback; + + /** + * @var bool + */ + private $partialRead = false; + + public function __construct(ResponseStreamInterface $responseStream) + { + $this->responseStream = $responseStream; + } + + public function __toString(): string + { + return $this->getContentAsString(); + } + + /** + * {@inheritdoc} + */ + public function getChunks(): iterable + { + if (null !== $this->fallback) { + yield from $this->fallback->getChunks(); + + return; + } + if ($this->partialRead) { + throw new LogicException(sprintf('You can not call "%s". Another process doesn\'t reading "getChunks" till the end.', __METHOD__)); + } + + $resource = fopen('php://temp', 'rb+'); + foreach ($this->responseStream as $chunk) { + $this->partialRead = true; + $chunkContent = $chunk->getContent(); + fwrite($resource, $chunkContent); + yield $chunkContent; + } + + $this->fallback = new ResponseBodyResourceStream($resource); + $this->partialRead = false; + } + + /** + * {@inheritdoc} + */ + public function getContentAsString(): string + { + if (null === $this->fallback) { + // Use getChunks() to read stream content to $this->fallback + foreach ($this->getChunks() as $chunk) { + } + \assert(null !== $this->fallback); + } + + return $this->fallback->getContentAsString(); + } + + /** + * {@inheritdoc} + */ + public function getContentAsResource() + { + if (null === $this->fallback) { + // Use getChunks() to read stream content to $this->fallback + foreach ($this->getChunks() as $chunk) { + } + \assert(null !== $this->fallback); + } + + return $this->fallback->getContentAsResource(); + } +} diff --git a/vendor/async-aws/core/src/Stream/ResultStream.php b/vendor/async-aws/core/src/Stream/ResultStream.php new file mode 100644 index 000000000..754662375 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/ResultStream.php @@ -0,0 +1,35 @@ +getBody()->getChunks() as $chunk) { + * fwrite($fileHandler, $chunk); + * } + * + * @return iterable + */ + public function getChunks(): iterable; + + /** + * Download content into a temporary resource and return a string. + */ + public function getContentAsString(): string; + + /** + * Download content into a resource and then return that resource. + * + * @return resource + */ + public function getContentAsResource(); +} diff --git a/vendor/async-aws/core/src/Stream/RewindableStream.php b/vendor/async-aws/core/src/Stream/RewindableStream.php new file mode 100644 index 000000000..44f015dcd --- /dev/null +++ b/vendor/async-aws/core/src/Stream/RewindableStream.php @@ -0,0 +1,97 @@ + + */ +final class RewindableStream implements RequestStream +{ + /** + * @var RequestStream + */ + private $content; + + /** + * @var RequestStream|null + */ + private $fallback; + + private function __construct(RequestStream $content) + { + $this->content = $content; + } + + public static function create(RequestStream $content): RewindableStream + { + if ($content instanceof self) { + return $content; + } + + return new self($content); + } + + public function length(): ?int + { + if (null !== $this->fallback) { + return $this->fallback->length(); + } + + return $this->content->length(); + } + + public function stringify(): string + { + if (null !== $this->fallback) { + return $this->fallback->stringify(); + } + + return implode('', iterator_to_array($this)); + } + + public function getIterator(): \Traversable + { + if (null !== $this->fallback) { + yield from $this->fallback; + + return; + } + + $resource = fopen('php://temp', 'r+b'); + $this->fallback = ResourceStream::create($resource); + + foreach ($this->content as $chunk) { + fwrite($resource, $chunk); + yield $chunk; + } + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + if (null !== $this->fallback) { + return $this->fallback->hash($algo, $raw); + } + + $ctx = hash_init($algo); + foreach ($this as $chunk) { + hash_update($ctx, $chunk); + } + + return hash_final($ctx, $raw); + } + + public function read(): void + { + // Use getIterator() to read stream content to $this->fallback + foreach ($this as $chunk) { + } + } +} diff --git a/vendor/async-aws/core/src/Stream/StreamFactory.php b/vendor/async-aws/core/src/Stream/StreamFactory.php new file mode 100644 index 000000000..658a7f33e --- /dev/null +++ b/vendor/async-aws/core/src/Stream/StreamFactory.php @@ -0,0 +1,34 @@ + + */ +class StreamFactory +{ + /** + * @param string|resource|(callable(int): string)|iterable|null $content + */ + public static function create($content, int $preferredChunkSize = 64 * 1024): RequestStream + { + if (null === $content || \is_string($content)) { + return StringStream::create($content ?? ''); + } + if (\is_callable($content)) { + return CallableStream::create($content, $preferredChunkSize); + } + if (is_iterable($content)) { + return IterableStream::create($content); + } + if (\is_resource($content)) { + return ResourceStream::create($content, $preferredChunkSize); + } + + throw new InvalidArgument(sprintf('Unexpected content type "%s".', \is_object($content) ? \get_class($content) : \gettype($content))); + } +} diff --git a/vendor/async-aws/core/src/Stream/StringStream.php b/vendor/async-aws/core/src/Stream/StringStream.php new file mode 100644 index 000000000..550fd63b1 --- /dev/null +++ b/vendor/async-aws/core/src/Stream/StringStream.php @@ -0,0 +1,68 @@ + + * + * @internal + */ +final class StringStream implements RequestStream +{ + /** + * @var string + */ + private $content; + + /** + * @var int|null + */ + private $lengthCache; + + private function __construct(string $content) + { + $this->content = $content; + } + + /** + * @param RequestStream|string $content + */ + public static function create($content): StringStream + { + if ($content instanceof self) { + return $content; + } + if ($content instanceof RequestStream) { + return new self($content->stringify()); + } + if (\is_string($content)) { + return new self($content); + } + + throw new InvalidArgument(sprintf('Expect content to be a "%s" or as "string". "%s" given.', RequestStream::class, \is_object($content) ? \get_class($content) : \gettype($content))); + } + + public function length(): int + { + return $this->lengthCache ?? $this->lengthCache = \strlen($this->content); + } + + public function stringify(): string + { + return $this->content; + } + + public function getIterator(): \Traversable + { + yield $this->content; + } + + public function hash(string $algo = 'sha256', bool $raw = false): string + { + return hash($algo, $this->content, $raw); + } +} diff --git a/vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php b/vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php new file mode 100644 index 000000000..ccbd4dd0b --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Exception/ExpiredTokenException.php @@ -0,0 +1,13 @@ + An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * Passing policies to this operation returns new temporary credentials. The resulting session's permissions are the + * intersection of the role's identity-based policy and the session policies. You can use the role's temporary + * credentials in subsequent Amazon Web Services API calls to access resources in the account that owns the role. You + * cannot use session policies to grant more permissions than those allowed by the identity-based policy of the role + * that is being assumed. For more information, see Session Policies [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var PolicyDescriptorType[]|null + */ + private $policyArns; + + /** + * An IAM policy in JSON format that you want to use as an inline session policy. + * + * This parameter is optional. Passing policies to this operation returns new temporary credentials. The resulting + * session's permissions are the intersection of the role's identity-based policy and the session policies. You can use + * the role's temporary credentials in subsequent Amazon Web Services API calls to access resources in the account that + * owns the role. You cannot use session policies to grant more permissions than those allowed by the identity-based + * policy of the role that is being assumed. For more information, see Session Policies [^1] in the *IAM User Guide*. + * + * The plaintext that you use for both inline and managed session policies can't exceed 2,048 characters. The JSON + * policy characters can be any ASCII character from the space character to the end of the valid character list (\u0020 + * through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage return (\u000D) characters. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var string|null + */ + private $policy; + + /** + * The duration, in seconds, of the role session. The value specified can range from 900 seconds (15 minutes) up to the + * maximum session duration set for the role. The maximum session duration setting can have a value from 1 hour to 12 + * hours. If you specify a value higher than this setting or the administrator setting (whichever is lower), the + * operation fails. For example, if you specify a session duration of 12 hours, but your administrator set the maximum + * session duration to 6 hours, your operation fails. + * + * Role chaining limits your Amazon Web Services CLI or Amazon Web Services API role session to a maximum of one hour. + * When you use the `AssumeRole` API operation to assume a role, you can specify the duration of your role session with + * the `DurationSeconds` parameter. You can specify a parameter value of up to 43200 seconds (12 hours), depending on + * the maximum session duration setting for your role. However, if you assume a role using role chaining and provide a + * `DurationSeconds` parameter value greater than one hour, the operation fails. To learn how to view the maximum value + * for your role, see View the Maximum Session Duration Setting for a Role [^1] in the *IAM User Guide*. + * + * By default, the value is set to `3600` seconds. + * + * > The `DurationSeconds` parameter is separate from the duration of a console session that you might request using the + * > returned credentials. The request to the federation endpoint for a console sign-in token takes a `SessionDuration` + * > parameter that specifies the maximum length of the console session. For more information, see Creating a URL that + * > Enables Federated Users to Access the Amazon Web Services Management Console [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html + * + * @var int|null + */ + private $durationSeconds; + + /** + * A list of session tags that you want to pass. Each session tag consists of a key name and an associated value. For + * more information about session tags, see Tagging Amazon Web Services STS Sessions [^1] in the *IAM User Guide*. + * + * This parameter is optional. You can pass up to 50 session tags. The plaintext session tag keys can’t exceed 128 + * characters, and the values can’t exceed 256 characters. For these and additional limits, see IAM and STS Character + * Limits [^2] in the *IAM User Guide*. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * You can pass a session tag with the same key as a tag that is already attached to the role. When you do, session tags + * override a role tag with the same key. + * + * Tag key–value pairs are not case sensitive, but case is preserved. This means that you cannot have separate + * `Department` and `department` tag keys. Assume that the role has the `Department`=`Marketing` tag and you pass the + * `department`=`engineering` session tag. `Department` and `department` are not saved as separate tags, and the session + * tag passed in the request takes precedence over the role tag. + * + * Additionally, if you used temporary credentials to perform this operation, the new session inherits any transitive + * session tags from the calling session. If you pass a session tag with the same key as an inherited tag, the operation + * fails. To view the inherited tags for a session, see the CloudTrail logs. For more information, see Viewing Session + * Tags in CloudTrail [^3] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length + * [^3]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_ctlogs + * + * @var Tag[]|null + */ + private $tags; + + /** + * A list of keys for session tags that you want to set as transitive. If you set a tag key as transitive, the + * corresponding key and value passes to subsequent sessions in a role chain. For more information, see Chaining Roles + * with Session Tags [^1] in the *IAM User Guide*. + * + * This parameter is optional. When you set session tags as transitive, the session policy and session tags packed + * binary limit is not affected. + * + * If you choose not to specify a transitive tag key, then no tags are passed from this session to any subsequent + * sessions. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining + * + * @var string[]|null + */ + private $transitiveTagKeys; + + /** + * A unique identifier that might be required when you assume a role in another account. If the administrator of the + * account to which the role belongs provided you with an external ID, then provide that value in the `ExternalId` + * parameter. This value can be any string, such as a passphrase or account number. A cross-account role is usually set + * up to trust everyone in an account. Therefore, the administrator of the trusting account might send an external ID to + * the administrator of the trusted account. That way, only someone with the ID can assume the role, rather than + * everyone in the account. For more information about the external ID, see How to Use an External ID When Granting + * Access to Your Amazon Web Services Resources to a Third Party [^1] in the *IAM User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@:/- + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html + * + * @var string|null + */ + private $externalId; + + /** + * The identification number of the MFA device that is associated with the user who is making the `AssumeRole` call. + * Specify this value if the trust policy of the role being assumed includes a condition that requires MFA + * authentication. The value is either the serial number for a hardware device (such as `GAHT12345678`) or an Amazon + * Resource Name (ARN) for a virtual device (such as `arn:aws:iam::123456789012:mfa/user`). + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@- + * + * @var string|null + */ + private $serialNumber; + + /** + * The value provided by the MFA device, if the trust policy of the role being assumed requires MFA. (In other words, if + * the policy includes a condition that tests for MFA). If the role being assumed requires MFA and if the `TokenCode` + * value is missing or expired, the `AssumeRole` call returns an "access denied" error. + * + * The format for this parameter, as described by its regex pattern, is a sequence of six numeric digits. + * + * @var string|null + */ + private $tokenCode; + + /** + * The source identity specified by the principal that is calling the `AssumeRole` operation. + * + * You can require users to specify a source identity when they assume a role. You do this by using the + * `sts:SourceIdentity` condition key in a role trust policy. You can use source identity information in CloudTrail logs + * to determine who took actions with a role. You can use the `aws:SourceIdentity` condition key to further control + * access to Amazon Web Services resources based on the value of source identity. For more information about using + * source identity, see Monitor and control actions taken with assumed roles [^1] in the *IAM User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@-. You cannot use + * a value that begins with the text `aws:`. This prefix is reserved for Amazon Web Services internal use. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html + * + * @var string|null + */ + private $sourceIdentity; + + /** + * Reserved for future use. + * + * @var ProvidedContext[]|null + */ + private $providedContexts; + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * Tags?: array, + * TransitiveTagKeys?: string[], + * ExternalId?: string, + * SerialNumber?: string, + * TokenCode?: string, + * SourceIdentity?: string, + * ProvidedContexts?: array, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->roleArn = $input['RoleArn'] ?? null; + $this->roleSessionName = $input['RoleSessionName'] ?? null; + $this->policyArns = isset($input['PolicyArns']) ? array_map([PolicyDescriptorType::class, 'create'], $input['PolicyArns']) : null; + $this->policy = $input['Policy'] ?? null; + $this->durationSeconds = $input['DurationSeconds'] ?? null; + $this->tags = isset($input['Tags']) ? array_map([Tag::class, 'create'], $input['Tags']) : null; + $this->transitiveTagKeys = $input['TransitiveTagKeys'] ?? null; + $this->externalId = $input['ExternalId'] ?? null; + $this->serialNumber = $input['SerialNumber'] ?? null; + $this->tokenCode = $input['TokenCode'] ?? null; + $this->sourceIdentity = $input['SourceIdentity'] ?? null; + $this->providedContexts = isset($input['ProvidedContexts']) ? array_map([ProvidedContext::class, 'create'], $input['ProvidedContexts']) : null; + parent::__construct($input); + } + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * Tags?: array, + * TransitiveTagKeys?: string[], + * ExternalId?: string, + * SerialNumber?: string, + * TokenCode?: string, + * SourceIdentity?: string, + * ProvidedContexts?: array, + * '@region'?: string|null, + * }|AssumeRoleRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDurationSeconds(): ?int + { + return $this->durationSeconds; + } + + public function getExternalId(): ?string + { + return $this->externalId; + } + + public function getPolicy(): ?string + { + return $this->policy; + } + + /** + * @return PolicyDescriptorType[] + */ + public function getPolicyArns(): array + { + return $this->policyArns ?? []; + } + + /** + * @return ProvidedContext[] + */ + public function getProvidedContexts(): array + { + return $this->providedContexts ?? []; + } + + public function getRoleArn(): ?string + { + return $this->roleArn; + } + + public function getRoleSessionName(): ?string + { + return $this->roleSessionName; + } + + public function getSerialNumber(): ?string + { + return $this->serialNumber; + } + + public function getSourceIdentity(): ?string + { + return $this->sourceIdentity; + } + + /** + * @return Tag[] + */ + public function getTags(): array + { + return $this->tags ?? []; + } + + public function getTokenCode(): ?string + { + return $this->tokenCode; + } + + /** + * @return string[] + */ + public function getTransitiveTagKeys(): array + { + return $this->transitiveTagKeys ?? []; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/x-www-form-urlencoded']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = http_build_query(['Action' => 'AssumeRole', 'Version' => '2011-06-15'] + $this->requestBody(), '', '&', \PHP_QUERY_RFC1738); + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setDurationSeconds(?int $value): self + { + $this->durationSeconds = $value; + + return $this; + } + + public function setExternalId(?string $value): self + { + $this->externalId = $value; + + return $this; + } + + public function setPolicy(?string $value): self + { + $this->policy = $value; + + return $this; + } + + /** + * @param PolicyDescriptorType[] $value + */ + public function setPolicyArns(array $value): self + { + $this->policyArns = $value; + + return $this; + } + + /** + * @param ProvidedContext[] $value + */ + public function setProvidedContexts(array $value): self + { + $this->providedContexts = $value; + + return $this; + } + + public function setRoleArn(?string $value): self + { + $this->roleArn = $value; + + return $this; + } + + public function setRoleSessionName(?string $value): self + { + $this->roleSessionName = $value; + + return $this; + } + + public function setSerialNumber(?string $value): self + { + $this->serialNumber = $value; + + return $this; + } + + public function setSourceIdentity(?string $value): self + { + $this->sourceIdentity = $value; + + return $this; + } + + /** + * @param Tag[] $value + */ + public function setTags(array $value): self + { + $this->tags = $value; + + return $this; + } + + public function setTokenCode(?string $value): self + { + $this->tokenCode = $value; + + return $this; + } + + /** + * @param string[] $value + */ + public function setTransitiveTagKeys(array $value): self + { + $this->transitiveTagKeys = $value; + + return $this; + } + + private function requestBody(): array + { + $payload = []; + if (null === $v = $this->roleArn) { + throw new InvalidArgument(sprintf('Missing parameter "RoleArn" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleArn'] = $v; + if (null === $v = $this->roleSessionName) { + throw new InvalidArgument(sprintf('Missing parameter "RoleSessionName" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleSessionName'] = $v; + if (null !== $v = $this->policyArns) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["PolicyArns.member.$index.$bodyKey"] = $bodyValue; + } + } + } + if (null !== $v = $this->policy) { + $payload['Policy'] = $v; + } + if (null !== $v = $this->durationSeconds) { + $payload['DurationSeconds'] = $v; + } + if (null !== $v = $this->tags) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["Tags.member.$index.$bodyKey"] = $bodyValue; + } + } + } + if (null !== $v = $this->transitiveTagKeys) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + $payload["TransitiveTagKeys.member.$index"] = $mapValue; + } + } + if (null !== $v = $this->externalId) { + $payload['ExternalId'] = $v; + } + if (null !== $v = $this->serialNumber) { + $payload['SerialNumber'] = $v; + } + if (null !== $v = $this->tokenCode) { + $payload['TokenCode'] = $v; + } + if (null !== $v = $this->sourceIdentity) { + $payload['SourceIdentity'] = $v; + } + if (null !== $v = $this->providedContexts) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["ProvidedContexts.member.$index.$bodyKey"] = $bodyValue; + } + } + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php b/vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php new file mode 100644 index 000000000..c2eeb101b --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Input/AssumeRoleWithWebIdentityRequest.php @@ -0,0 +1,320 @@ + An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * Passing policies to this operation returns new temporary credentials. The resulting session's permissions are the + * intersection of the role's identity-based policy and the session policies. You can use the role's temporary + * credentials in subsequent Amazon Web Services API calls to access resources in the account that owns the role. You + * cannot use session policies to grant more permissions than those allowed by the identity-based policy of the role + * that is being assumed. For more information, see Session Policies [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var PolicyDescriptorType[]|null + */ + private $policyArns; + + /** + * An IAM policy in JSON format that you want to use as an inline session policy. + * + * This parameter is optional. Passing policies to this operation returns new temporary credentials. The resulting + * session's permissions are the intersection of the role's identity-based policy and the session policies. You can use + * the role's temporary credentials in subsequent Amazon Web Services API calls to access resources in the account that + * owns the role. You cannot use session policies to grant more permissions than those allowed by the identity-based + * policy of the role that is being assumed. For more information, see Session Policies [^1] in the *IAM User Guide*. + * + * The plaintext that you use for both inline and managed session policies can't exceed 2,048 characters. The JSON + * policy characters can be any ASCII character from the space character to the end of the valid character list (\u0020 + * through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage return (\u000D) characters. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * + * @var string|null + */ + private $policy; + + /** + * The duration, in seconds, of the role session. The value can range from 900 seconds (15 minutes) up to the maximum + * session duration setting for the role. This setting can have a value from 1 hour to 12 hours. If you specify a value + * higher than this setting, the operation fails. For example, if you specify a session duration of 12 hours, but your + * administrator set the maximum session duration to 6 hours, your operation fails. To learn how to view the maximum + * value for your role, see View the Maximum Session Duration Setting for a Role [^1] in the *IAM User Guide*. + * + * By default, the value is set to `3600` seconds. + * + * > The `DurationSeconds` parameter is separate from the duration of a console session that you might request using the + * > returned credentials. The request to the federation endpoint for a console sign-in token takes a `SessionDuration` + * > parameter that specifies the maximum length of the console session. For more information, see Creating a URL that + * > Enables Federated Users to Access the Amazon Web Services Management Console [^2] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session + * [^2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html + * + * @var int|null + */ + private $durationSeconds; + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * WebIdentityToken?: string, + * ProviderId?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->roleArn = $input['RoleArn'] ?? null; + $this->roleSessionName = $input['RoleSessionName'] ?? null; + $this->webIdentityToken = $input['WebIdentityToken'] ?? null; + $this->providerId = $input['ProviderId'] ?? null; + $this->policyArns = isset($input['PolicyArns']) ? array_map([PolicyDescriptorType::class, 'create'], $input['PolicyArns']) : null; + $this->policy = $input['Policy'] ?? null; + $this->durationSeconds = $input['DurationSeconds'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * RoleArn?: string, + * RoleSessionName?: string, + * WebIdentityToken?: string, + * ProviderId?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * '@region'?: string|null, + * }|AssumeRoleWithWebIdentityRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDurationSeconds(): ?int + { + return $this->durationSeconds; + } + + public function getPolicy(): ?string + { + return $this->policy; + } + + /** + * @return PolicyDescriptorType[] + */ + public function getPolicyArns(): array + { + return $this->policyArns ?? []; + } + + public function getProviderId(): ?string + { + return $this->providerId; + } + + public function getRoleArn(): ?string + { + return $this->roleArn; + } + + public function getRoleSessionName(): ?string + { + return $this->roleSessionName; + } + + public function getWebIdentityToken(): ?string + { + return $this->webIdentityToken; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/x-www-form-urlencoded']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = http_build_query(['Action' => 'AssumeRoleWithWebIdentity', 'Version' => '2011-06-15'] + $this->requestBody(), '', '&', \PHP_QUERY_RFC1738); + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setDurationSeconds(?int $value): self + { + $this->durationSeconds = $value; + + return $this; + } + + public function setPolicy(?string $value): self + { + $this->policy = $value; + + return $this; + } + + /** + * @param PolicyDescriptorType[] $value + */ + public function setPolicyArns(array $value): self + { + $this->policyArns = $value; + + return $this; + } + + public function setProviderId(?string $value): self + { + $this->providerId = $value; + + return $this; + } + + public function setRoleArn(?string $value): self + { + $this->roleArn = $value; + + return $this; + } + + public function setRoleSessionName(?string $value): self + { + $this->roleSessionName = $value; + + return $this; + } + + public function setWebIdentityToken(?string $value): self + { + $this->webIdentityToken = $value; + + return $this; + } + + private function requestBody(): array + { + $payload = []; + if (null === $v = $this->roleArn) { + throw new InvalidArgument(sprintf('Missing parameter "RoleArn" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleArn'] = $v; + if (null === $v = $this->roleSessionName) { + throw new InvalidArgument(sprintf('Missing parameter "RoleSessionName" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['RoleSessionName'] = $v; + if (null === $v = $this->webIdentityToken) { + throw new InvalidArgument(sprintf('Missing parameter "WebIdentityToken" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['WebIdentityToken'] = $v; + if (null !== $v = $this->providerId) { + $payload['ProviderId'] = $v; + } + if (null !== $v = $this->policyArns) { + $index = 0; + foreach ($v as $mapValue) { + ++$index; + foreach ($mapValue->requestBody() as $bodyKey => $bodyValue) { + $payload["PolicyArns.member.$index.$bodyKey"] = $bodyValue; + } + } + } + if (null !== $v = $this->policy) { + $payload['Policy'] = $v; + } + if (null !== $v = $this->durationSeconds) { + $payload['DurationSeconds'] = $v; + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php b/vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php new file mode 100644 index 000000000..88b804afc --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Input/GetCallerIdentityRequest.php @@ -0,0 +1,58 @@ + 'application/x-www-form-urlencoded']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = http_build_query(['Action' => 'GetCallerIdentity', 'Version' => '2011-06-15'] + $this->requestBody(), '', '&', \PHP_QUERY_RFC1738); + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + private function requestBody(): array + { + $payload = []; + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php b/vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php new file mode 100644 index 000000000..cb4ac1cd2 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Result/AssumeRoleResponse.php @@ -0,0 +1,110 @@ + The size of the security token that STS API operations return is not fixed. We strongly recommend that you make no + * > assumptions about the maximum size. + * + * @var Credentials|null + */ + private $credentials; + + /** + * The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers that you can use to refer to the + * resulting temporary security credentials. For example, you can reference these credentials as a principal in a + * resource-based policy by using the ARN or assumed role ID. The ARN and ID include the `RoleSessionName` that you + * specified when you called `AssumeRole`. + * + * @var AssumedRoleUser|null + */ + private $assumedRoleUser; + + /** + * A percentage value that indicates the packed size of the session policies and session tags combined passed in the + * request. The request fails if the packed size is greater than 100 percent, which means the policies and tags exceeded + * the allowed space. + * + * @var int|null + */ + private $packedPolicySize; + + /** + * The source identity specified by the principal that is calling the `AssumeRole` operation. + * + * You can require users to specify a source identity when they assume a role. You do this by using the + * `sts:SourceIdentity` condition key in a role trust policy. You can use source identity information in CloudTrail logs + * to determine who took actions with a role. You can use the `aws:SourceIdentity` condition key to further control + * access to Amazon Web Services resources based on the value of source identity. For more information about using + * source identity, see Monitor and control actions taken with assumed roles [^1] in the *IAM User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@- + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html + * + * @var string|null + */ + private $sourceIdentity; + + public function getAssumedRoleUser(): ?AssumedRoleUser + { + $this->initialize(); + + return $this->assumedRoleUser; + } + + public function getCredentials(): ?Credentials + { + $this->initialize(); + + return $this->credentials; + } + + public function getPackedPolicySize(): ?int + { + $this->initialize(); + + return $this->packedPolicySize; + } + + public function getSourceIdentity(): ?string + { + $this->initialize(); + + return $this->sourceIdentity; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $data = $data->AssumeRoleResult; + + $this->credentials = !$data->Credentials ? null : new Credentials([ + 'AccessKeyId' => (string) $data->Credentials->AccessKeyId, + 'SecretAccessKey' => (string) $data->Credentials->SecretAccessKey, + 'SessionToken' => (string) $data->Credentials->SessionToken, + 'Expiration' => new \DateTimeImmutable((string) $data->Credentials->Expiration), + ]); + $this->assumedRoleUser = !$data->AssumedRoleUser ? null : new AssumedRoleUser([ + 'AssumedRoleId' => (string) $data->AssumedRoleUser->AssumedRoleId, + 'Arn' => (string) $data->AssumedRoleUser->Arn, + ]); + $this->packedPolicySize = ($v = $data->PackedPolicySize) ? (int) (string) $v : null; + $this->sourceIdentity = ($v = $data->SourceIdentity) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php b/vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php new file mode 100644 index 000000000..6eb109477 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Result/AssumeRoleWithWebIdentityResponse.php @@ -0,0 +1,166 @@ + The size of the security token that STS API operations return is not fixed. We strongly recommend that you make no + * > assumptions about the maximum size. + * + * @var Credentials|null + */ + private $credentials; + + /** + * The unique user identifier that is returned by the identity provider. This identifier is associated with the + * `WebIdentityToken` that was submitted with the `AssumeRoleWithWebIdentity` call. The identifier is typically unique + * to the user and the application that acquired the `WebIdentityToken` (pairwise identifier). For OpenID Connect ID + * tokens, this field contains the value returned by the identity provider as the token's `sub` (Subject) claim. + * + * @var string|null + */ + private $subjectFromWebIdentityToken; + + /** + * The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers that you can use to refer to the + * resulting temporary security credentials. For example, you can reference these credentials as a principal in a + * resource-based policy by using the ARN or assumed role ID. The ARN and ID include the `RoleSessionName` that you + * specified when you called `AssumeRole`. + * + * @var AssumedRoleUser|null + */ + private $assumedRoleUser; + + /** + * A percentage value that indicates the packed size of the session policies and session tags combined passed in the + * request. The request fails if the packed size is greater than 100 percent, which means the policies and tags exceeded + * the allowed space. + * + * @var int|null + */ + private $packedPolicySize; + + /** + * The issuing authority of the web identity token presented. For OpenID Connect ID tokens, this contains the value of + * the `iss` field. For OAuth 2.0 access tokens, this contains the value of the `ProviderId` parameter that was passed + * in the `AssumeRoleWithWebIdentity` request. + * + * @var string|null + */ + private $provider; + + /** + * The intended audience (also known as client ID) of the web identity token. This is traditionally the client + * identifier issued to the application that requested the web identity token. + * + * @var string|null + */ + private $audience; + + /** + * The value of the source identity that is returned in the JSON web token (JWT) from the identity provider. + * + * You can require users to set a source identity value when they assume a role. You do this by using the + * `sts:SourceIdentity` condition key in a role trust policy. That way, actions that are taken with the role are + * associated with that user. After the source identity is set, the value cannot be changed. It is present in the + * request for all actions that are taken by the role and persists across chained role [^1] sessions. You can configure + * your identity provider to use an attribute associated with your users, like user name or email, as the source + * identity when calling `AssumeRoleWithWebIdentity`. You do this by adding a claim to the JSON web token. To learn more + * about OIDC tokens and claims, see Using Tokens with User Pools [^2] in the *Amazon Cognito Developer Guide*. For more + * information about using source identity, see Monitor and control actions taken with assumed roles [^3] in the *IAM + * User Guide*. + * + * The regex used to validate this parameter is a string of characters consisting of upper- and lower-case alphanumeric + * characters with no spaces. You can also include underscores or any of the following characters: =,.@- + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts#iam-term-role-chaining + * [^2]: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html + * [^3]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html + * + * @var string|null + */ + private $sourceIdentity; + + public function getAssumedRoleUser(): ?AssumedRoleUser + { + $this->initialize(); + + return $this->assumedRoleUser; + } + + public function getAudience(): ?string + { + $this->initialize(); + + return $this->audience; + } + + public function getCredentials(): ?Credentials + { + $this->initialize(); + + return $this->credentials; + } + + public function getPackedPolicySize(): ?int + { + $this->initialize(); + + return $this->packedPolicySize; + } + + public function getProvider(): ?string + { + $this->initialize(); + + return $this->provider; + } + + public function getSourceIdentity(): ?string + { + $this->initialize(); + + return $this->sourceIdentity; + } + + public function getSubjectFromWebIdentityToken(): ?string + { + $this->initialize(); + + return $this->subjectFromWebIdentityToken; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $data = $data->AssumeRoleWithWebIdentityResult; + + $this->credentials = !$data->Credentials ? null : new Credentials([ + 'AccessKeyId' => (string) $data->Credentials->AccessKeyId, + 'SecretAccessKey' => (string) $data->Credentials->SecretAccessKey, + 'SessionToken' => (string) $data->Credentials->SessionToken, + 'Expiration' => new \DateTimeImmutable((string) $data->Credentials->Expiration), + ]); + $this->subjectFromWebIdentityToken = ($v = $data->SubjectFromWebIdentityToken) ? (string) $v : null; + $this->assumedRoleUser = !$data->AssumedRoleUser ? null : new AssumedRoleUser([ + 'AssumedRoleId' => (string) $data->AssumedRoleUser->AssumedRoleId, + 'Arn' => (string) $data->AssumedRoleUser->Arn, + ]); + $this->packedPolicySize = ($v = $data->PackedPolicySize) ? (int) (string) $v : null; + $this->provider = ($v = $data->Provider) ? (string) $v : null; + $this->audience = ($v = $data->Audience) ? (string) $v : null; + $this->sourceIdentity = ($v = $data->SourceIdentity) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php b/vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php new file mode 100644 index 000000000..1be671113 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/Result/GetCallerIdentityResponse.php @@ -0,0 +1,69 @@ +initialize(); + + return $this->account; + } + + public function getArn(): ?string + { + $this->initialize(); + + return $this->arn; + } + + public function getUserId(): ?string + { + $this->initialize(); + + return $this->userId; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $data = $data->GetCallerIdentityResult; + + $this->userId = ($v = $data->UserId) ? (string) $v : null; + $this->account = ($v = $data->Account) ? (string) $v : null; + $this->arn = ($v = $data->Arn) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/core/src/Sts/StsClient.php b/vendor/async-aws/core/src/Sts/StsClient.php new file mode 100644 index 000000000..42304e21c --- /dev/null +++ b/vendor/async-aws/core/src/Sts/StsClient.php @@ -0,0 +1,445 @@ +, + * Policy?: string, + * DurationSeconds?: int, + * Tags?: array, + * TransitiveTagKeys?: string[], + * ExternalId?: string, + * SerialNumber?: string, + * TokenCode?: string, + * SourceIdentity?: string, + * ProvidedContexts?: array, + * '@region'?: string|null, + * }|AssumeRoleRequest $input + * + * @throws MalformedPolicyDocumentException + * @throws PackedPolicyTooLargeException + * @throws RegionDisabledException + * @throws ExpiredTokenException + */ + public function assumeRole($input): AssumeRoleResponse + { + $input = AssumeRoleRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'AssumeRole', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'MalformedPolicyDocument' => MalformedPolicyDocumentException::class, + 'PackedPolicyTooLarge' => PackedPolicyTooLargeException::class, + 'RegionDisabledException' => RegionDisabledException::class, + 'ExpiredTokenException' => ExpiredTokenException::class, + ]])); + + return new AssumeRoleResponse($response); + } + + /** + * Returns a set of temporary security credentials for users who have been authenticated in a mobile or web application + * with a web identity provider. Example providers include the OAuth 2.0 providers Login with Amazon and Facebook, or + * any OpenID Connect-compatible identity provider such as Google or Amazon Cognito federated identities [^1]. + * + * > For mobile applications, we recommend that you use Amazon Cognito. You can use Amazon Cognito with the Amazon Web + * > Services SDK for iOS Developer Guide [^2] and the Amazon Web Services SDK for Android Developer Guide [^3] to + * > uniquely identify a user. You can also supply the user with a consistent identity throughout the lifetime of an + * > application. + * > + * > To learn more about Amazon Cognito, see Amazon Cognito identity pools [^4] in *Amazon Cognito Developer Guide*. + * + * Calling `AssumeRoleWithWebIdentity` does not require the use of Amazon Web Services security credentials. Therefore, + * you can distribute an application (for example, on mobile devices) that requests temporary security credentials + * without including long-term Amazon Web Services credentials in the application. You also don't need to deploy + * server-based proxy services that use long-term Amazon Web Services credentials. Instead, the identity of the caller + * is validated by using a token from the web identity provider. For a comparison of `AssumeRoleWithWebIdentity` with + * the other API operations that produce temporary credentials, see Requesting Temporary Security Credentials [^5] and + * Comparing the Amazon Web Services STS API operations [^6] in the *IAM User Guide*. + * + * The temporary security credentials returned by this API consist of an access key ID, a secret access key, and a + * security token. Applications can use these temporary security credentials to sign calls to Amazon Web Services + * service API operations. + * + * **Session Duration** + * + * By default, the temporary security credentials created by `AssumeRoleWithWebIdentity` last for one hour. However, you + * can use the optional `DurationSeconds` parameter to specify the duration of your session. You can provide a value + * from 900 seconds (15 minutes) up to the maximum session duration setting for the role. This setting can have a value + * from 1 hour to 12 hours. To learn how to view the maximum value for your role, see View the Maximum Session Duration + * Setting for a Role [^7] in the *IAM User Guide*. The maximum session duration limit applies when you use the + * `AssumeRole*` API operations or the `assume-role*` CLI commands. However the limit does not apply when you use those + * operations to create a console URL. For more information, see Using IAM Roles [^8] in the *IAM User Guide*. + * + * **Permissions** + * + * The temporary security credentials created by `AssumeRoleWithWebIdentity` can be used to make API calls to any Amazon + * Web Services service with the following exception: you cannot call the STS `GetFederationToken` or `GetSessionToken` + * API operations. + * + * (Optional) You can pass inline or managed session policies [^9] to this operation. You can pass a single JSON policy + * document to use as an inline session policy. You can also specify up to 10 managed policy Amazon Resource Names + * (ARNs) to use as managed session policies. The plaintext that you use for both inline and managed session policies + * can't exceed 2,048 characters. Passing policies to this operation returns new temporary credentials. The resulting + * session's permissions are the intersection of the role's identity-based policy and the session policies. You can use + * the role's temporary credentials in subsequent Amazon Web Services API calls to access resources in the account that + * owns the role. You cannot use session policies to grant more permissions than those allowed by the identity-based + * policy of the role that is being assumed. For more information, see Session Policies [^10] in the *IAM User Guide*. + * + * **Tags** + * + * (Optional) You can configure your IdP to pass attributes into your web identity token as session tags. Each session + * tag consists of a key name and an associated value. For more information about session tags, see Passing Session Tags + * in STS [^11] in the *IAM User Guide*. + * + * You can pass up to 50 session tags. The plaintext session tag keys can’t exceed 128 characters and the values + * can’t exceed 256 characters. For these and additional limits, see IAM and STS Character Limits [^12] in the *IAM + * User Guide*. + * + * > An Amazon Web Services conversion compresses the passed inline session policy, managed policy ARNs, and session + * > tags into a packed binary format that has a separate limit. Your request can fail for this limit even if your + * > plaintext meets the other requirements. The `PackedPolicySize` response element indicates by percentage how close + * > the policies and tags for your request are to the upper size limit. + * + * You can pass a session tag with the same key as a tag that is attached to the role. When you do, the session tag + * overrides the role tag with the same key. + * + * An administrator must grant you the permissions necessary to pass session tags. The administrator can also create + * granular permissions to allow you to pass only specific session tags. For more information, see Tutorial: Using Tags + * for Attribute-Based Access Control [^13] in the *IAM User Guide*. + * + * You can set the session tags as transitive. Transitive tags persist during role chaining. For more information, see + * Chaining Roles with Session Tags [^14] in the *IAM User Guide*. + * + * **Identities** + * + * Before your application can call `AssumeRoleWithWebIdentity`, you must have an identity token from a supported + * identity provider and create a role that the application can assume. The role that your application assumes must + * trust the identity provider that is associated with the identity token. In other words, the identity provider must be + * specified in the role's trust policy. + * + * ! Calling `AssumeRoleWithWebIdentity` can result in an entry in your CloudTrail logs. The entry includes the Subject + * ! [^15] of the provided web identity token. We recommend that you avoid using any personally identifiable information + * ! (PII) in this field. For example, you could instead use a GUID or a pairwise identifier, as suggested in the OIDC + * ! specification [^16]. + * + * For more information about how to use web identity federation and the `AssumeRoleWithWebIdentity` API, see the + * following resources: + * + * - Using Web Identity Federation API Operations for Mobile Apps [^17] and Federation Through a Web-based Identity + * Provider [^18]. + * - Web Identity Federation Playground [^19]. Walk through the process of authenticating through Login with Amazon, + * Facebook, or Google, getting temporary security credentials, and then using those credentials to make a request to + * Amazon Web Services. + * - Amazon Web Services SDK for iOS Developer Guide [^20] and Amazon Web Services SDK for Android Developer Guide + * [^21]. These toolkits contain sample apps that show how to invoke the identity providers. The toolkits then show + * how to use the information from these providers to get and use temporary security credentials. + * - Web Identity Federation with Mobile Applications [^22]. This article discusses web identity federation and shows an + * example of how to use web identity federation to get access to content in Amazon S3. + * + * [^1]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html + * [^2]: http://aws.amazon.com/sdkforios/ + * [^3]: http://aws.amazon.com/sdkforandroid/ + * [^4]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html + * [^5]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html + * [^6]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison + * [^7]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session + * [^8]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html + * [^9]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * [^10]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session + * [^11]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html + * [^12]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length + * [^13]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html + * [^14]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining + * [^15]: http://openid.net/specs/openid-connect-core-1_0.html#Claims + * [^16]: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes + * [^17]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html + * [^18]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity + * [^19]: https://aws.amazon.com/blogs/aws/the-aws-web-identity-federation-playground/ + * [^20]: http://aws.amazon.com/sdkforios/ + * [^21]: http://aws.amazon.com/sdkforandroid/ + * [^22]: http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications + * + * @see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sts-2011-06-15.html#assumerolewithwebidentity + * + * @param array{ + * RoleArn: string, + * RoleSessionName: string, + * WebIdentityToken: string, + * ProviderId?: string, + * PolicyArns?: array, + * Policy?: string, + * DurationSeconds?: int, + * '@region'?: string|null, + * }|AssumeRoleWithWebIdentityRequest $input + * + * @throws MalformedPolicyDocumentException + * @throws PackedPolicyTooLargeException + * @throws IDPRejectedClaimException + * @throws IDPCommunicationErrorException + * @throws InvalidIdentityTokenException + * @throws ExpiredTokenException + * @throws RegionDisabledException + */ + public function assumeRoleWithWebIdentity($input): AssumeRoleWithWebIdentityResponse + { + $input = AssumeRoleWithWebIdentityRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'AssumeRoleWithWebIdentity', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'MalformedPolicyDocument' => MalformedPolicyDocumentException::class, + 'PackedPolicyTooLarge' => PackedPolicyTooLargeException::class, + 'IDPRejectedClaim' => IDPRejectedClaimException::class, + 'IDPCommunicationError' => IDPCommunicationErrorException::class, + 'InvalidIdentityToken' => InvalidIdentityTokenException::class, + 'ExpiredTokenException' => ExpiredTokenException::class, + 'RegionDisabledException' => RegionDisabledException::class, + ]])); + + return new AssumeRoleWithWebIdentityResponse($response); + } + + /** + * Returns details about the IAM user or role whose credentials are used to call the operation. + * + * > No permissions are required to perform this operation. If an administrator attaches a policy to your identity that + * > explicitly denies access to the `sts:GetCallerIdentity` action, you can still perform this operation. Permissions + * > are not required because the same information is returned when access is denied. To view an example response, see I + * > Am Not Authorized to Perform: iam:DeleteVirtualMFADevice [^1] in the *IAM User Guide*. + * + * [^1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_access-denied-delete-mfa + * + * @see https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sts-2011-06-15.html#getcalleridentity + * + * @param array{ + * '@region'?: string|null, + * }|GetCallerIdentityRequest $input + */ + public function getCallerIdentity($input = []): GetCallerIdentityResponse + { + $input = GetCallerIdentityRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetCallerIdentity', 'region' => $input->getRegion()])); + + return new GetCallerIdentityResponse($response); + } + + protected function getAwsErrorFactory(): AwsErrorFactoryInterface + { + return new XmlAwsErrorFactory(); + } + + protected function getEndpointMetadata(?string $region): array + { + if (null === $region) { + return [ + 'endpoint' => 'https://sts.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + } + + switch ($region) { + case 'cn-north-1': + case 'cn-northwest-1': + return [ + 'endpoint' => "https://sts.$region.amazonaws.com.cn", + 'signRegion' => $region, + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-east-1-fips': + return [ + 'endpoint' => 'https://sts-fips.us-east-1.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-east-2-fips': + return [ + 'endpoint' => 'https://sts-fips.us-east-2.amazonaws.com', + 'signRegion' => 'us-east-2', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-west-1-fips': + return [ + 'endpoint' => 'https://sts-fips.us-west-1.amazonaws.com', + 'signRegion' => 'us-west-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-west-2-fips': + return [ + 'endpoint' => 'https://sts-fips.us-west-2.amazonaws.com', + 'signRegion' => 'us-west-2', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-gov-east-1-fips': + return [ + 'endpoint' => 'https://sts.us-gov-east-1.amazonaws.com', + 'signRegion' => 'us-gov-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-gov-west-1-fips': + return [ + 'endpoint' => 'https://sts.us-gov-west-1.amazonaws.com', + 'signRegion' => 'us-gov-west-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-iso-east-1': + case 'us-iso-west-1': + return [ + 'endpoint' => "https://sts.$region.c2s.ic.gov", + 'signRegion' => $region, + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + case 'us-isob-east-1': + return [ + 'endpoint' => 'https://sts.us-isob-east-1.sc2s.sgov.gov', + 'signRegion' => 'us-isob-east-1', + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + } + + return [ + 'endpoint' => "https://sts.$region.amazonaws.com", + 'signRegion' => $region, + 'signService' => 'sts', + 'signVersions' => ['v4'], + ]; + } + + protected function getServiceCode(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 'sts'; + } + + protected function getSignatureScopeName(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 'sts'; + } + + protected function getSignatureVersion(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 'v4'; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php b/vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php new file mode 100644 index 000000000..e543d9990 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/AssumedRoleUser.php @@ -0,0 +1,70 @@ +assumedRoleId = $input['AssumedRoleId'] ?? $this->throwException(new InvalidArgument('Missing required field "AssumedRoleId".')); + $this->arn = $input['Arn'] ?? $this->throwException(new InvalidArgument('Missing required field "Arn".')); + } + + /** + * @param array{ + * AssumedRoleId: string, + * Arn: string, + * }|AssumedRoleUser $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getArn(): string + { + return $this->arn; + } + + public function getAssumedRoleId(): string + { + return $this->assumedRoleId; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/Credentials.php b/vendor/async-aws/core/src/Sts/ValueObject/Credentials.php new file mode 100644 index 000000000..93cabc9fe --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/Credentials.php @@ -0,0 +1,96 @@ +accessKeyId = $input['AccessKeyId'] ?? $this->throwException(new InvalidArgument('Missing required field "AccessKeyId".')); + $this->secretAccessKey = $input['SecretAccessKey'] ?? $this->throwException(new InvalidArgument('Missing required field "SecretAccessKey".')); + $this->sessionToken = $input['SessionToken'] ?? $this->throwException(new InvalidArgument('Missing required field "SessionToken".')); + $this->expiration = $input['Expiration'] ?? $this->throwException(new InvalidArgument('Missing required field "Expiration".')); + } + + /** + * @param array{ + * AccessKeyId: string, + * SecretAccessKey: string, + * SessionToken: string, + * Expiration: \DateTimeImmutable, + * }|Credentials $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getAccessKeyId(): string + { + return $this->accessKeyId; + } + + public function getExpiration(): \DateTimeImmutable + { + return $this->expiration; + } + + public function getSecretAccessKey(): string + { + return $this->secretAccessKey; + } + + public function getSessionToken(): string + { + return $this->sessionToken; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php b/vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php new file mode 100644 index 000000000..434ea3462 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/PolicyDescriptorType.php @@ -0,0 +1,59 @@ +arn = $input['arn'] ?? null; + } + + /** + * @param array{ + * arn?: null|string, + * }|PolicyDescriptorType $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getArn(): ?string + { + return $this->arn; + } + + /** + * @internal + */ + public function requestBody(): array + { + $payload = []; + if (null !== $v = $this->arn) { + $payload['arn'] = $v; + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php b/vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php new file mode 100644 index 000000000..950e3eb49 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/ProvidedContext.php @@ -0,0 +1,72 @@ +providerArn = $input['ProviderArn'] ?? null; + $this->contextAssertion = $input['ContextAssertion'] ?? null; + } + + /** + * @param array{ + * ProviderArn?: null|string, + * ContextAssertion?: null|string, + * }|ProvidedContext $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getContextAssertion(): ?string + { + return $this->contextAssertion; + } + + public function getProviderArn(): ?string + { + return $this->providerArn; + } + + /** + * @internal + */ + public function requestBody(): array + { + $payload = []; + if (null !== $v = $this->providerArn) { + $payload['ProviderArn'] = $v; + } + if (null !== $v = $this->contextAssertion) { + $payload['ContextAssertion'] = $v; + } + + return $payload; + } +} diff --git a/vendor/async-aws/core/src/Sts/ValueObject/Tag.php b/vendor/async-aws/core/src/Sts/ValueObject/Tag.php new file mode 100644 index 000000000..3ac064b40 --- /dev/null +++ b/vendor/async-aws/core/src/Sts/ValueObject/Tag.php @@ -0,0 +1,94 @@ +key = $input['Key'] ?? $this->throwException(new InvalidArgument('Missing required field "Key".')); + $this->value = $input['Value'] ?? $this->throwException(new InvalidArgument('Missing required field "Value".')); + } + + /** + * @param array{ + * Key: string, + * Value: string, + * }|Tag $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): string + { + return $this->key; + } + + public function getValue(): string + { + return $this->value; + } + + /** + * @internal + */ + public function requestBody(): array + { + $payload = []; + $v = $this->key; + $payload['Key'] = $v; + $v = $this->value; + $payload['Value'] = $v; + + return $payload; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php b/vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php new file mode 100644 index 000000000..161122ede --- /dev/null +++ b/vendor/async-aws/core/src/Test/Http/SimpleMockedResponse.php @@ -0,0 +1,91 @@ +> + */ + private $headers = []; + + /** + * @var string + */ + private $content = ''; + + /** + * @var int + */ + private $statusCode; + + /** + * @param array> $headers ['name'=>'value'] OR ['name'=>['value']] + */ + public function __construct(string $content = '', array $headers = [], int $statusCode = 200) + { + $this->content = $content; + $this->statusCode = $statusCode; + $this->headers = []; + foreach ($headers as $name => $value) { + if (!\is_array($value)) { + $value = [$value]; + } + $this->headers[$name] = $value; + } + + parent::__construct($content, [ + 'response_headers' => $this->getFlatHeaders(), + 'http_code' => $statusCode, + ]); + } + + public function getStatusCode(): int + { + return $this->statusCode; + } + + public function getHeaders(bool $throw = true): array + { + return $this->headers; + } + + public function getContent(bool $throw = true): string + { + return $this->content; + } + + /** + * @return array + */ + public function toArray(bool $throw = true): array + { + return json_decode($this->getContent($throw), true); + } + + public function cancel(): void + { + throw new LogicException('Not implemented'); + } + + /** + * @return list + */ + private function getFlatHeaders() + { + $flat = []; + foreach ($this->headers as $name => $value) { + $flat[] = sprintf('%s: %s', $name, implode(';', $value)); + } + + return $flat; + } +} diff --git a/vendor/async-aws/core/src/Test/ResultMockFactory.php b/vendor/async-aws/core/src/Test/ResultMockFactory.php new file mode 100644 index 000000000..564f83906 --- /dev/null +++ b/vendor/async-aws/core/src/Test/ResultMockFactory.php @@ -0,0 +1,290 @@ + + */ +class ResultMockFactory +{ + /** + * Instantiate a Result class that throws exception. + * + * + * ResultMockFactory::createFailing(SendEmailResponse::class, 400, 'invalid value'); + * + * + * @template T of Result + * + * @param class-string $class + * @param array $additionalContent + * + * @return T + */ + public static function createFailing( + string $class, + int $code, + ?string $message = null, + array $additionalContent = [] + ) { + if (Result::class !== $class) { + $parent = get_parent_class($class); + if (false === $parent || Result::class !== $parent) { + throw new LogicException(sprintf('The "%s::%s" can only be used for classes that extend "%s"', __CLASS__, __METHOD__, Result::class)); + } + } + + $httpResponse = new SimpleMockedResponse(json_encode(array_merge(['message' => $message], $additionalContent)), ['content-type' => 'application/json'], $code); + $client = new MockHttpClient($httpResponse); + $response = new Response($client->request('POST', 'http://localhost'), $client, new NullLogger()); + + /** @psalm-var \ReflectionClass $reflectionClass */ + $reflectionClass = new \ReflectionClass($class); + + return $reflectionClass->newInstance($response); + } + + /** + * Instantiate a Result class with some data. + * + * + * ResultMockFactory::create(SendEmailResponse::class, ['MessageId'=>'foo123']); + * + * + * @template T of Result + * + * @param class-string $class + * @param array $data + * + * @return T + */ + public static function create(string $class, array $data = []) + { + if (Result::class !== $class) { + $parent = get_parent_class($class); + if (false === $parent || Result::class !== $parent) { + throw new LogicException(sprintf('The "%s::%s" can only be used for classes that extend "%s"', __CLASS__, __METHOD__, Result::class)); + } + } + + $response = self::getResponseObject(); + + // Make sure the Result is initialized + $reflectionClass = new \ReflectionClass(Result::class); + $initializedProperty = $reflectionClass->getProperty('initialized'); + $initializedProperty->setAccessible(true); + + /** @psalm-var \ReflectionClass $reflectionClass */ + $reflectionClass = new \ReflectionClass($class); + $object = $reflectionClass->newInstance($response); + if (Result::class !== $class) { + self::addPropertiesOnResult($reflectionClass, $object, $class); + } + + $initializedProperty->setValue($object, true); + foreach ($data as $propertyName => $propertyValue) { + if ($reflectionClass->hasProperty($propertyName)) { + $property = $reflectionClass->getProperty($propertyName); + } elseif ($reflectionClass->hasProperty(lcfirst($propertyName))) { + // backward compatibility with `UpperCamelCase` naming (fast) + $property = $reflectionClass->getProperty(lcfirst($propertyName)); + } else { + // compatibility with new `wordWithABREV` naming (slow) + $lowerPropertyName = strtolower($propertyName); + $property = null; + foreach ($reflectionClass->getProperties() as $prop) { + if (strtolower($prop->getName()) === $lowerPropertyName) { + $property = $prop; + + break; + } + } + if (null === $property) { + // let bubble the original exception + $property = $reflectionClass->getProperty($propertyName); + } + } + $property->setAccessible(true); + $property->setValue($object, $propertyValue); + } + + self::addUndefinedProperties($reflectionClass, $object, $data); + + return $object; + } + + /** + * Instantiate a Waiter class with a final state. + * + * @template T of Waiter + * + * @psalm-param class-string $class + * + * @return T + */ + public static function waiter(string $class, string $finalState) + { + if (Waiter::class !== $class) { + $parent = get_parent_class($class); + if (false === $parent || Waiter::class !== $parent) { + throw new LogicException(sprintf('The "%s::%s" can only be used for classes that extend "%s"', __CLASS__, __METHOD__, Waiter::class)); + } + } + + if (Waiter::STATE_SUCCESS !== $finalState && Waiter::STATE_FAILURE !== $finalState) { + throw new LogicException(sprintf('The state passed to "%s::%s" must be "%s" or "%s".', __CLASS__, __METHOD__, Waiter::STATE_SUCCESS, Waiter::STATE_FAILURE)); + } + + $response = self::getResponseObject(); + + $reflectionClass = new \ReflectionClass(Waiter::class); + $propertyResponse = $reflectionClass->getProperty('response'); + $propertyResponse->setAccessible(true); + + $propertyState = $reflectionClass->getProperty('finalState'); + $propertyState->setAccessible(true); + + /** @psalm-var \ReflectionClass $reflectionClass */ + $reflectionClass = new \ReflectionClass($class); + $result = $reflectionClass->newInstanceWithoutConstructor(); + $propertyResponse->setValue($result, $response); + $propertyState->setValue($result, $finalState); + + return $result; + } + + /** + * Try to add some values to the properties not defined in $data. + * + * @param \ReflectionClass $reflectionClass + * @param array $data + * + * @throws \ReflectionException + */ + private static function addUndefinedProperties(\ReflectionClass $reflectionClass, object $object, array $data): void + { + foreach ($reflectionClass->getProperties(\ReflectionProperty::IS_PRIVATE) as $property) { + if (\array_key_exists($property->getName(), $data) || \array_key_exists(ucfirst($property->getName()), $data)) { + continue; + } + + if (!$reflectionClass->hasMethod('get' . $property->getName())) { + continue; + } + + $getter = $reflectionClass->getMethod('get' . $property->getName()); + if (!$getter->hasReturnType() || (!($type = $getter->getReturnType()) instanceof \ReflectionNamedType) || $type->allowsNull()) { + continue; + } + + switch ($type->getName()) { + case 'int': + $propertyValue = 0; + + break; + case 'string': + $propertyValue = ''; + + break; + case 'bool': + $propertyValue = false; + + break; + case 'float': + $propertyValue = 0.0; + + break; + case 'array': + $propertyValue = []; + + break; + default: + $propertyValue = null; + + break; + } + + if (null !== $propertyValue) { + $property->setAccessible(true); + $property->setValue($object, $propertyValue); + } + } + } + + /** + * Set input and aws client to handle pagination. + * + * @param \ReflectionClass $reflectionClass + */ + private static function addPropertiesOnResult(\ReflectionClass $reflectionClass, object $object, string $class): void + { + if (false === $pos = strrpos($class, '\\')) { + throw new LogicException(sprintf('Expected class "%s" to have a backslash. ', $class)); + } + + $className = substr($class, $pos + 1); + if ('Output' === substr($className, -6)) { + $classNameWithoutSuffix = substr($className, 0, -6); + } elseif ('Response' === substr($className, -8)) { + $classNameWithoutSuffix = substr($className, 0, -8); + } elseif ('Result' === substr($className, -6)) { + $classNameWithoutSuffix = substr($className, 0, -6); + } else { + throw new LogicException(sprintf('Unknown class suffix: "%s"', $className)); + } + + if (false === $pos = strrpos($class, '\\', -2 - \strlen($className))) { + throw new LogicException(sprintf('Expected class "%s" to have more than one backslash. ', $class)); + } + + $baseNamespace = substr($class, 0, $pos); + if (false === $pos = strrpos($baseNamespace, '\\')) { + throw new LogicException(sprintf('Expected base namespace "%s" to have a backslash. ', $baseNamespace)); + } + + $awsClientClass = $baseNamespace . substr($baseNamespace, $pos) . 'Client'; + $inputClass = $baseNamespace . '\\Input\\' . $classNameWithoutSuffix . 'Request'; + + if (class_exists($awsClientClass)) { + $awsClientMock = (new \ReflectionClass($awsClientClass))->newInstanceWithoutConstructor(); + $property = $reflectionClass->getProperty('awsClient'); + $property->setAccessible(true); + $property->setValue($object, $awsClientMock); + } + + if (class_exists($inputClass)) { + $inputMock = (new \ReflectionClass($inputClass))->newInstanceWithoutConstructor(); + $property = $reflectionClass->getProperty('input'); + $property->setAccessible(true); + $property->setValue($object, $inputMock); + } + } + + private static function getResponseObject(): Response + { + $reflectionClass = new \ReflectionClass(Response::class); + $response = $reflectionClass->newInstanceWithoutConstructor(); + + $property = $reflectionClass->getProperty('resolveResult'); + $property->setAccessible(true); + $property->setValue($response, true); + + $property = $reflectionClass->getProperty('bodyDownloaded'); + $property->setAccessible(true); + $property->setValue($response, true); + + return $response; + } +} diff --git a/vendor/async-aws/core/src/Test/SimpleResultStream.php b/vendor/async-aws/core/src/Test/SimpleResultStream.php new file mode 100644 index 000000000..402b96737 --- /dev/null +++ b/vendor/async-aws/core/src/Test/SimpleResultStream.php @@ -0,0 +1,53 @@ + + */ +class SimpleResultStream implements ResultStream +{ + /** + * @var string + */ + private $data; + + public function __construct(string $data) + { + $this->data = $data; + } + + public function getChunks(): iterable + { + yield $this->data; + } + + public function getContentAsString(): string + { + return $this->data; + } + + public function getContentAsResource() + { + $resource = fopen('php://temp', 'rw+'); + + try { + fwrite($resource, $this->data); + + // Rewind + fseek($resource, 0, \SEEK_SET); + + return $resource; + } catch (\Throwable $e) { + fclose($resource); + + throw $e; + } + } +} diff --git a/vendor/async-aws/core/src/Test/TestCase.php b/vendor/async-aws/core/src/Test/TestCase.php new file mode 100644 index 000000000..645c20bfe --- /dev/null +++ b/vendor/async-aws/core/src/Test/TestCase.php @@ -0,0 +1,103 @@ +getMethod()); + + $actualUrl = $actual->getUri(); + if ($actual->getQuery()) { + $actualUrl .= false !== strpos($actual->getUri(), '?') ? '&' : '?'; + $actualUrl .= http_build_query($actual->getQuery(), '', '&', \PHP_QUERY_RFC3986); + } + self::assertUrlEqualsUrl($url, $actualUrl); + + $expectedHeaders = []; + foreach ($headers as $header) { + $parts = explode(':', trim($header), 2); + $key = $parts[0]; + $value = $parts[1] ?? ''; + $expectedHeaders[strtolower($key)] = trim($value); + } + self::assertEqualsIgnoringCase($expectedHeaders, $actual->getHeaders(), $message); + + switch ($expectedHeaders['content-type'] ?? null) { + case 'application/x-www-form-urlencoded': + self::assertHttpFormEqualsHttpForm(trim($body), $actual->getBody()->stringify(), $message); + + break; + case 'application/json': + case 'application/x-amz-json-1.0': + case 'application/x-amz-json-1.1': + if ('' === trim($body)) { + self::assertSame($body, $actual->getBody()->stringify()); + } else { + self::assertJsonStringEqualsJsonString(trim($body), $actual->getBody()->stringify(), $message); + } + + break; + case 'application/xml': + if ('' === trim($body)) { + self::assertSame($body, $actual->getBody()->stringify()); + } else { + self::assertXmlStringEqualsXmlString(trim($body), $actual->getBody()->stringify(), $message); + } + + break; + default: + self::assertSame(trim($body), $actual->getBody()->stringify()); + + break; + } + } +} diff --git a/vendor/async-aws/core/src/Waiter.php b/vendor/async-aws/core/src/Waiter.php new file mode 100644 index 000000000..387abf7e6 --- /dev/null +++ b/vendor/async-aws/core/src/Waiter.php @@ -0,0 +1,228 @@ +response = $response; + $this->awsClient = $awsClient; + $this->input = $request; + } + + public function __destruct() + { + if (!$this->resolved) { + $this->resolve(); + } + } + + final public function isSuccess(): bool + { + return self::STATE_SUCCESS === $this->getState(); + } + + final public function isFailure(): bool + { + return self::STATE_FAILURE === $this->getState(); + } + + final public function isPending(): bool + { + return self::STATE_PENDING === $this->getState(); + } + + final public function getState(): string + { + if (null !== $this->finalState) { + return $this->finalState; + } + + if ($this->needRefresh) { + $this->stealResponse($this->refreshState()); + } + + try { + $this->response->resolve(); + $exception = null; + } catch (HttpException $exception) { + // use $exception later + } finally { + $this->resolved = true; + $this->needRefresh = true; + } + + $state = $this->extractState($this->response, $exception); + + switch ($state) { + case self::STATE_SUCCESS: + case self::STATE_FAILURE: + $this->finalState = $state; + + break; + case self::STATE_PENDING: + break; + default: + throw new LogicException(sprintf('Unexpected state "%s" from Waiter "%s".', $state, __CLASS__)); + } + + return $state; + } + + /** + * Make sure the actual request is executed. + * + * @param float|null $timeout Duration in seconds before aborting. When null wait until the end of execution. + * + * @return bool false on timeout. True if the response has returned with as status code. + * + * @throws NetworkException + */ + final public function resolve(?float $timeout = null): bool + { + try { + return $this->response->resolve($timeout); + } catch (HttpException $exception) { + return true; + } finally { + $this->resolved = true; + } + } + + /** + * Returns info on the current request. + * + * @return array{ + * resolved: bool, + * body_downloaded: bool, + * response: \Symfony\Contracts\HttpClient\ResponseInterface, + * status: int, + * } + */ + final public function info(): array + { + return $this->response->info(); + } + + final public function cancel(): void + { + $this->response->cancel(); + $this->needRefresh = true; + $this->resolved = true; + } + + /** + * Wait until the state is success. + * Stopped when the state become Failure or the defined timeout is reached. + * + * @param float $timeout Duration in seconds before aborting + * @param float $delay Duration in seconds between each check + * + * @return bool true if a final state was reached + */ + final public function wait(?float $timeout = null, ?float $delay = null): bool + { + if (null !== $this->finalState) { + return true; + } + + $timeout = $timeout ?? static::WAIT_TIMEOUT; + $delay = $delay ?? static::WAIT_DELAY; + + $start = microtime(true); + while (true) { + if ($this->needRefresh) { + $this->stealResponse($this->refreshState()); + } + + // If request times out + if (!$this->resolve($timeout - (microtime(true) - $start))) { + break; + } + + $this->getState(); + // If we reached a final state + if ($this->finalState) { + return true; + } + + // If the timeout will expire during our sleep, then exit early. + if ($delay > $timeout - (microtime(true) - $start)) { + break; + } + + usleep((int) ceil($delay * 1000000)); + } + + return false; + } + + protected function extractState(Response $response, ?HttpException $exception): string + { + return self::STATE_PENDING; + } + + protected function refreshState(): Waiter + { + return $this; + } + + private function stealResponse(self $waiter): void + { + $this->response = $waiter->response; + $this->resolved = $waiter->resolved; + $waiter->resolved = true; + $this->needRefresh = false; + } +} diff --git a/vendor/async-aws/s3/CHANGELOG.md b/vendor/async-aws/s3/CHANGELOG.md new file mode 100644 index 000000000..1ba736a56 --- /dev/null +++ b/vendor/async-aws/s3/CHANGELOG.md @@ -0,0 +1,247 @@ +# Change Log + +## 2.0.0 + +### BC-BREAK + +- The type for `\AsyncAws\S3\Input\PutObjectRequest::getContentLength` and `\AsyncAws\S3\Input\PutObjectRequest::setContentLength` uses `int` instead of `string` to reflect the AWS type. +- The type for `\AsyncAws\S3\Input\UploadPartRequest::getContentLength` and `\AsyncAws\S3\Input\UploadPartRequest::setContentLength` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\Result\GetObjectOutput::getContentLength` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\Result\HeadObjectOutput::getContentLength` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\ValueObject\AwsObject::getSize` uses `int` instead of `string` to reflect the AWS type. +- The return type for `\AsyncAws\S3\ValueObject\Part::getSize` uses `int` instead of `string` to reflect the AWS type. + +### Added + +- AWS api-change: The S3 LISTObjects, ListObjectsV2 and ListObjectVersions API now supports a new optional header x-amz-optional-object-attributes. If header contains RestoreStatus as the value, then S3 will include Glacier restore status i.e. isRestoreInProgress and RestoreExpiryDate in List response. +- AWS api-change: Added `ap-south-2` and `eu-south-2` bucket location constraints. +- AWS api-change: Add support for the `il-central-1` region +- Use int as the PHP representation of long fields in generated code + +### Changed + +- Improve parameter type and return type in phpdoc + +## 1.14.0 + +### Added + +- AWS api-change: Added `ap-southeast-4` region. +- AWS enhancement: Documentation updates. +- AWS api-change: Provides support for "Snow" Storage class. +- AWS api-change: Integrate double encryption feature to SDKs. +- AWS api-change: This release adds SDK support for request-payer request header and request-charged response header in the "GetBucketAccelerateConfiguration", "ListMultipartUploads", "ListObjects", "ListObjectsV2" and "ListObjectVersions" S3 APIs. + +## 1.13.0 + +### Added + +- Added `me-central-1`, `ap-southeast-3`, `eu-central-2`, `eu-south-2` and `ap-south-2` regions + +## 1.12.0 + +### Fixed + +- Format datetime with `RFC7231` to provide a workaround for unsupported `RFC822` format. +- Broken path to host when operation's URL contains a query string. + +### Changed + +- Set default value to `false` for the `sendChunkedBody` option. + +## 1.11.0 + +### Added + +- AWS api-change: Added `ap-southeast-3` region. +- AWS enhancement: Documentation updates. +- AWS feature: Adds support for flexible checksums +- AWS api-change: This release adds support for new integrity checking capabilities in Amazon S3. You can choose from four supported checksum algorithms for data integrity checking on your upload and download requests. In addition, AWS SDK can automatically calculate a checksum as it streams data into S3 + +## 1.10.0 + +### Added + +- AWS api-change: used unique endpoint for `accesspoint-*` regions +- AWS api-change: Rework regions configuration. +- AWS api-change: Introduce Amazon S3 Glacier Instant Retrieval storage class and a new setting in S3 Object Ownership to disable ACLs for bucket and the objects in it. +- AWS api-change: Amazon S3 Event Notifications adds Amazon EventBridge as a destination and supports additional event types. The PutBucketNotificationConfiguration API can now skip validation of Amazon SQS, Amazon SNS and AWS Lambda destinations. +- AWS api-change: Introduce two new Filters to S3 Lifecycle configurations - ObjectSizeGreaterThan and ObjectSizeLessThan. Introduce a new way to trigger actions on noncurrent versions by providing the number of newer noncurrent versions along with noncurrent days. + +## 1.9.2 + +### Added + +- AWS enhancement: Documentation updates for Amazon S3 +- Fixed camelCased of Dom classes + +## 1.9.1 + +### Fixed + +- Fix issue when a request to upload a file is retried +- camelCased methods with paginator and waiter +- AWS enhancement: Documentation updates for Amazon S3 + +## 1.9.0 + +### Added + +- AWS api-change: Adding ID element to the CORSRule schema +- AWS api-change: Adding many more regions + +### Changed + +- AWS api-change: Reword docblocks +- AWS enhancement: Amazon S3 Documentation updates +- AWS api-change: Improve documentation +- AWS enhancement: Documentation updates for Amazon S3 + +### Fixed + +- Wrong custom encoding on chunked stream + +## 1.8.0 + +### Added + +- Changed case of object's properties to camelCase. +- Added documentation in class headers. +- Added `PutBucketCors`, `DeleteBucketCors` and `GetBucketCors` methods. +- Added domain exceptions + +## 1.7.0 + +### Added + +- AWS api-change: S3 adds support for multiple-destination replication, option to sync replica modifications; S3 Bucket Keys to reduce cost of S3 SSE with AWS KMS +- AWS api-change: Format GetObject's Expires header to be an http-date instead of iso8601 +- Added support for `sendChunkedBody` option to enable/disabled chunked body. + +## 1.6.0 + +### Added + +- Added `S3Client::putBucketNotificationConfiguration()` +- AWS api-change: S3 Intelligent-Tiering adds support for Archive and Deep Archive Access tiers + +### Changed + +- Removed deprecation warning on Content-MD5 headers. + +### Fixed + +- Make sure we throw exception from async-aws/core + +## 1.5.1 + +### Fixed + +- Fixed endpoint issue when a bucket name started with a number. +- Improve StorageClass documentation. + +## 1.5.0 + +### Added + +- AWS api-change: Amazon S3 on Outposts expands object storage to on-premises AWS Outposts environments, enabling you to store and retrieve objects using S3 APIs and features. + +## 1.4.0 + +### Added + +- AWS api-change: Bucket owner verification feature added. This feature introduces the x-amz-expected-bucket-owner and x-amz-source-expected-bucket-owner headers. + +## 1.3.0 + +### Added + +- Support for PHP 8 +- Added `S3Client::deleteBucket()` + +### Fixed + +- Fixed an issue in Metadata not beeing sent to AWS in `PutObject`, `CopyObject` and `CreateMultipartUpload` +- Internal AWS prefix were added to Metadata's name in `GetObject` and `HeadObject`. + +### Deprecated by AWS + +- `PutObjectAclRequest::getContentMD5()` +- `PutObjectAclRequest::setContentMD5()` + +## 1.2.0 + +### Added + +- Changed from "path style" endpoints (https://amazon.com/bucket) to "host style" endpoints (https://bucket.amazon.com). To keep the old behavior, use `s3PathStyleEndpoint: true` configuration option. + +### Fixed + +- Fixed issue when Bucket or Object's Key contained a special char like `#` + +### Deprecation + +- Protected methods `getServiceCode`, `getSignatureVersion` and `getSignatureScopeName` of `S3Client` are deprecated and will be removed in 2.0 + +## 1.1.0 + +### Added + +- Backported split request behavior in `SignerV4ForS3` + +### Fixed + +- Add return typehint for `listMultipartUploads`, `listObjectsV2` and `listParts` + +## 1.0.0 + +### Added + +- Support for async-aws/core 1.0. + +## 0.4.0 + +### Added + +- Support for presign +- Multipart upload +- Waiters: `S3Client::bucketExists()` and `S3Client::objectExists()` +- The `AsyncAws\S3\Enum\*`, `AsyncAws\S3\Input\*` and `AsyncAws\S3\ValueObject*` classes are marked final. + +### Changed + +- Moved value objects to a dedicated namespace. +- Results' `populateResult()` has only one argument. It takes a `AsyncAws\Core\Response`. +- Using `DateTimeImmutable` instead of `DateTimeInterface` + +### Removed + +- Dependency on `symfony/http-client-contracts` +- All `validate()` methods on the inputs. They are merged with `request()`. + +## 0.3.0 + +### Added + +- Enums; `BucketCannedACL`, `BucketLocationConstraint`, `EncodingType`, `MetadataDirective`, `ObjectCannedACL`, `ObjectLockLegalHoldStatus` + `ObjectLockMode`, `ObjectStorageClass`, `Permission`, `ReplicationStatus`, `RequestCharged`, `RequestPayer`, `ServerSideEncryption` + `StorageClass`, `TaggingDirective`, `Type` + +### Changed + +- Removed `requestBody()`, `requestHeaders()`, `requestQuery()` and `requestUri()` input classes. They are replaced with `request()`. +- Using async-aws/core: 0.4.0 + +### Fixed + +- Dont generate a request body when no body is needed. + +## 0.2.0 + +### Changed + +- Using async-aws/core: 0.3.0 + +## 0.1.0 + +First version diff --git a/vendor/async-aws/s3/LICENSE b/vendor/async-aws/s3/LICENSE new file mode 100644 index 000000000..191fcfb40 --- /dev/null +++ b/vendor/async-aws/s3/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Jérémy Derussé, Tobias Nyholm + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/async-aws/s3/README.md b/vendor/async-aws/s3/README.md new file mode 100644 index 000000000..b7071b41b --- /dev/null +++ b/vendor/async-aws/s3/README.md @@ -0,0 +1,20 @@ +# AsyncAws S3 Client + +![](https://github.com/async-aws/s3/workflows/Tests/badge.svg?branch=master) +![](https://github.com/async-aws/s3/workflows/BC%20Check/badge.svg?branch=master) + +An API client for S3. + +## Install + +```cli +composer require async-aws/s3 +``` + +## Documentation + +See https://async-aws.com/clients/s3.html for documentation. + +## Contribute + +Contributions are welcome and appreciated. Please read https://async-aws.com/contribute/ diff --git a/vendor/async-aws/s3/composer.json b/vendor/async-aws/s3/composer.json new file mode 100644 index 000000000..b12a7e1fb --- /dev/null +++ b/vendor/async-aws/s3/composer.json @@ -0,0 +1,36 @@ +{ + "name": "async-aws/s3", + "description": "S3 client, part of the AWS SDK provided by AsyncAws.", + "license": "MIT", + "type": "library", + "keywords": [ + "aws", + "amazon", + "sdk", + "async-aws", + "s3" + ], + "require": { + "php": "^7.2.5 || ^8.0", + "ext-SimpleXML": "*", + "ext-dom": "*", + "ext-filter": "*", + "ext-hash": "*", + "async-aws/core": "^1.9" + }, + "autoload": { + "psr-4": { + "AsyncAws\\S3\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "AsyncAws\\S3\\Tests\\": "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + } +} diff --git a/vendor/async-aws/s3/src/Enum/ArchiveStatus.php b/vendor/async-aws/s3/src/Enum/ArchiveStatus.php new file mode 100644 index 000000000..2b57ceaf6 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ArchiveStatus.php @@ -0,0 +1,17 @@ + true, + self::DEEP_ARCHIVE_ACCESS => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/BucketCannedACL.php b/vendor/async-aws/s3/src/Enum/BucketCannedACL.php new file mode 100644 index 000000000..e923df03f --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/BucketCannedACL.php @@ -0,0 +1,21 @@ + true, + self::PRIVATE => true, + self::PUBLIC_READ => true, + self::PUBLIC_READ_WRITE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php b/vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php new file mode 100644 index 000000000..cdd40e4a5 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/BucketLocationConstraint.php @@ -0,0 +1,69 @@ + true, + self::AP_EAST_1 => true, + self::AP_NORTHEAST_1 => true, + self::AP_NORTHEAST_2 => true, + self::AP_NORTHEAST_3 => true, + self::AP_SOUTHEAST_1 => true, + self::AP_SOUTHEAST_2 => true, + self::AP_SOUTHEAST_3 => true, + self::AP_SOUTH_1 => true, + self::AP_SOUTH_2 => true, + self::CA_CENTRAL_1 => true, + self::CN_NORTHWEST_1 => true, + self::CN_NORTH_1 => true, + self::EU => true, + self::EU_CENTRAL_1 => true, + self::EU_NORTH_1 => true, + self::EU_SOUTH_1 => true, + self::EU_SOUTH_2 => true, + self::EU_WEST_1 => true, + self::EU_WEST_2 => true, + self::EU_WEST_3 => true, + self::ME_SOUTH_1 => true, + self::SA_EAST_1 => true, + self::US_EAST_2 => true, + self::US_GOV_EAST_1 => true, + self::US_GOV_WEST_1 => true, + self::US_WEST_1 => true, + self::US_WEST_2 => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php b/vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php new file mode 100644 index 000000000..a2eb4adb6 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ChecksumAlgorithm.php @@ -0,0 +1,21 @@ + true, + self::CRC32C => true, + self::SHA1 => true, + self::SHA256 => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ChecksumMode.php b/vendor/async-aws/s3/src/Enum/ChecksumMode.php new file mode 100644 index 000000000..307467f1c --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ChecksumMode.php @@ -0,0 +1,15 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/EncodingType.php b/vendor/async-aws/s3/src/Enum/EncodingType.php new file mode 100644 index 000000000..f6816062b --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/EncodingType.php @@ -0,0 +1,21 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/Event.php b/vendor/async-aws/s3/src/Enum/Event.php new file mode 100644 index 000000000..b52aaba14 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/Event.php @@ -0,0 +1,70 @@ + true, + self::S3_LIFECYCLE_EXPIRATION_ALL => true, + self::S3_LIFECYCLE_EXPIRATION_DELETE => true, + self::S3_LIFECYCLE_EXPIRATION_DELETE_MARKER_CREATED => true, + self::S3_LIFECYCLE_TRANSITION => true, + self::S3_OBJECT_ACL_PUT => true, + self::S3_OBJECT_CREATED_ALL => true, + self::S3_OBJECT_CREATED_COMPLETE_MULTIPART_UPLOAD => true, + self::S3_OBJECT_CREATED_COPY => true, + self::S3_OBJECT_CREATED_POST => true, + self::S3_OBJECT_CREATED_PUT => true, + self::S3_OBJECT_REMOVED_ALL => true, + self::S3_OBJECT_REMOVED_DELETE => true, + self::S3_OBJECT_REMOVED_DELETE_MARKER_CREATED => true, + self::S3_OBJECT_RESTORE_ALL => true, + self::S3_OBJECT_RESTORE_COMPLETED => true, + self::S3_OBJECT_RESTORE_DELETE => true, + self::S3_OBJECT_RESTORE_POST => true, + self::S3_OBJECT_TAGGING_ALL => true, + self::S3_OBJECT_TAGGING_DELETE => true, + self::S3_OBJECT_TAGGING_PUT => true, + self::S3_REDUCED_REDUNDANCY_LOST_OBJECT => true, + self::S3_REPLICATION_ALL => true, + self::S3_REPLICATION_OPERATION_FAILED_REPLICATION => true, + self::S3_REPLICATION_OPERATION_MISSED_THRESHOLD => true, + self::S3_REPLICATION_OPERATION_NOT_TRACKED => true, + self::S3_REPLICATION_OPERATION_REPLICATED_AFTER_THRESHOLD => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/FilterRuleName.php b/vendor/async-aws/s3/src/Enum/FilterRuleName.php new file mode 100644 index 000000000..1628c7f69 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/FilterRuleName.php @@ -0,0 +1,17 @@ + true, + self::SUFFIX => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php b/vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php new file mode 100644 index 000000000..1b62f24ed --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/IntelligentTieringAccessTier.php @@ -0,0 +1,17 @@ + true, + self::DEEP_ARCHIVE_ACCESS => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/MetadataDirective.php b/vendor/async-aws/s3/src/Enum/MetadataDirective.php new file mode 100644 index 000000000..173e492b7 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/MetadataDirective.php @@ -0,0 +1,17 @@ + true, + self::REPLACE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectCannedACL.php b/vendor/async-aws/s3/src/Enum/ObjectCannedACL.php new file mode 100644 index 000000000..6f5ab1608 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectCannedACL.php @@ -0,0 +1,27 @@ + true, + self::AWS_EXEC_READ => true, + self::BUCKET_OWNER_FULL_CONTROL => true, + self::BUCKET_OWNER_READ => true, + self::PRIVATE => true, + self::PUBLIC_READ => true, + self::PUBLIC_READ_WRITE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php b/vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php new file mode 100644 index 000000000..959b1949e --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectLockLegalHoldStatus.php @@ -0,0 +1,17 @@ + true, + self::ON => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectLockMode.php b/vendor/async-aws/s3/src/Enum/ObjectLockMode.php new file mode 100644 index 000000000..568d9e1af --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectLockMode.php @@ -0,0 +1,17 @@ + true, + self::GOVERNANCE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectOwnership.php b/vendor/async-aws/s3/src/Enum/ObjectOwnership.php new file mode 100644 index 000000000..9158c4d1b --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectOwnership.php @@ -0,0 +1,33 @@ + true, + self::BUCKET_OWNER_PREFERRED => true, + self::OBJECT_WRITER => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ObjectStorageClass.php b/vendor/async-aws/s3/src/Enum/ObjectStorageClass.php new file mode 100644 index 000000000..e41e12d2a --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ObjectStorageClass.php @@ -0,0 +1,33 @@ + true, + self::GLACIER => true, + self::GLACIER_IR => true, + self::INTELLIGENT_TIERING => true, + self::ONEZONE_IA => true, + self::OUTPOSTS => true, + self::REDUCED_REDUNDANCY => true, + self::SNOW => true, + self::STANDARD => true, + self::STANDARD_IA => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php b/vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php new file mode 100644 index 000000000..3477c8bf3 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/OptionalObjectAttributes.php @@ -0,0 +1,15 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/Permission.php b/vendor/async-aws/s3/src/Enum/Permission.php new file mode 100644 index 000000000..1a2f918c6 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/Permission.php @@ -0,0 +1,23 @@ + true, + self::READ => true, + self::READ_ACP => true, + self::WRITE => true, + self::WRITE_ACP => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ReplicationStatus.php b/vendor/async-aws/s3/src/Enum/ReplicationStatus.php new file mode 100644 index 000000000..753c8268d --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ReplicationStatus.php @@ -0,0 +1,21 @@ + true, + self::FAILED => true, + self::PENDING => true, + self::REPLICA => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/RequestCharged.php b/vendor/async-aws/s3/src/Enum/RequestCharged.php new file mode 100644 index 000000000..e0e4afb90 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/RequestCharged.php @@ -0,0 +1,18 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/RequestPayer.php b/vendor/async-aws/s3/src/Enum/RequestPayer.php new file mode 100644 index 000000000..ff8ce7675 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/RequestPayer.php @@ -0,0 +1,22 @@ + true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/ServerSideEncryption.php b/vendor/async-aws/s3/src/Enum/ServerSideEncryption.php new file mode 100644 index 000000000..12dd2429b --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/ServerSideEncryption.php @@ -0,0 +1,19 @@ + true, + self::AWS_KMS => true, + self::AWS_KMS_DSSE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/StorageClass.php b/vendor/async-aws/s3/src/Enum/StorageClass.php new file mode 100644 index 000000000..5df870dda --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/StorageClass.php @@ -0,0 +1,33 @@ + true, + self::GLACIER => true, + self::GLACIER_IR => true, + self::INTELLIGENT_TIERING => true, + self::ONEZONE_IA => true, + self::OUTPOSTS => true, + self::REDUCED_REDUNDANCY => true, + self::SNOW => true, + self::STANDARD => true, + self::STANDARD_IA => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/TaggingDirective.php b/vendor/async-aws/s3/src/Enum/TaggingDirective.php new file mode 100644 index 000000000..c908c78ed --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/TaggingDirective.php @@ -0,0 +1,17 @@ + true, + self::REPLACE => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Enum/Type.php b/vendor/async-aws/s3/src/Enum/Type.php new file mode 100644 index 000000000..b07830451 --- /dev/null +++ b/vendor/async-aws/s3/src/Enum/Type.php @@ -0,0 +1,19 @@ + true, + self::CANONICAL_USER => true, + self::GROUP => true, + ][$value]); + } +} diff --git a/vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php b/vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php new file mode 100644 index 000000000..a72e63145 --- /dev/null +++ b/vendor/async-aws/s3/src/Exception/BucketAlreadyExistsException.php @@ -0,0 +1,13 @@ +accessTier; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + protected function populateResult(ResponseInterface $response): void + { + $data = new \SimpleXMLElement($response->getContent(false)); + if (0 < $data->Error->count()) { + $data = $data->Error; + } + $this->storageClass = ($v = $data->StorageClass) ? (string) $v : null; + $this->accessTier = ($v = $data->AccessTier) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/s3/src/Exception/NoSuchBucketException.php b/vendor/async-aws/s3/src/Exception/NoSuchBucketException.php new file mode 100644 index 000000000..5dc50a07b --- /dev/null +++ b/vendor/async-aws/s3/src/Exception/NoSuchBucketException.php @@ -0,0 +1,12 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->uploadId = $input['UploadId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * UploadId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|AbortMultipartUploadRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php b/vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php new file mode 100644 index 000000000..670281245 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CompleteMultipartUploadRequest.php @@ -0,0 +1,449 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->multipartUpload = isset($input['MultipartUpload']) ? CompletedMultipartUpload::create($input['MultipartUpload']) : null; + $this->uploadId = $input['UploadId'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * MultipartUpload?: CompletedMultipartUpload|array, + * UploadId?: string, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|CompleteMultipartUploadRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMultipartUpload(): ?CompletedMultipartUpload + { + return $this->multipartUpload; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->checksumCrc32) { + $headers['x-amz-checksum-crc32'] = $this->checksumCrc32; + } + if (null !== $this->checksumCrc32C) { + $headers['x-amz-checksum-crc32c'] = $this->checksumCrc32C; + } + if (null !== $this->checksumSha1) { + $headers['x-amz-checksum-sha1'] = $this->checksumSha1; + } + if (null !== $this->checksumSha256) { + $headers['x-amz-checksum-sha256'] = $this->checksumSha256; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + + // Prepare query + $query = []; + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setChecksumCrc32(?string $value): self + { + $this->checksumCrc32 = $value; + + return $this; + } + + public function setChecksumCrc32C(?string $value): self + { + $this->checksumCrc32C = $value; + + return $this; + } + + public function setChecksumSha1(?string $value): self + { + $this->checksumSha1 = $value; + + return $this; + } + + public function setChecksumSha256(?string $value): self + { + $this->checksumSha256 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setMultipartUpload(?CompletedMultipartUpload $value): self + { + $this->multipartUpload = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null !== $v = $this->multipartUpload) { + $node->appendChild($child = $document->createElement('CompleteMultipartUpload')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/Input/CopyObjectRequest.php b/vendor/async-aws/s3/src/Input/CopyObjectRequest.php new file mode 100644 index 000000000..579d2325b --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CopyObjectRequest.php @@ -0,0 +1,1267 @@ +::accesspoint//object/`. For + * example, to copy the object `reports/january.pdf` through access point `my-access-point` owned by account + * `123456789012` in Region `us-west-2`, use the URL encoding of + * `arn:aws:s3:us-west-2:123456789012:accesspoint/my-access-point/object/reports/january.pdf`. The value must be URL + * encoded. + * + * > Amazon S3 supports copy operations using access points only when the source and destination buckets are in the + * > same Amazon Web Services Region. + * + * Alternatively, for objects accessed through Amazon S3 on Outposts, specify the ARN of the object as accessed in the + * format `arn:aws:s3-outposts:::outpost//object/`. For + * example, to copy the object `reports/january.pdf` through outpost `my-outpost` owned by account `123456789012` in + * Region `us-west-2`, use the URL encoding of + * `arn:aws:s3-outposts:us-west-2:123456789012:outpost/my-outpost/object/reports/january.pdf`. The value must be + * URL-encoded. + * + * To copy a specific version of an object, append `?versionId=` to the value (for example, + * `awsexamplebucket/reports/january.pdf?versionId=QUpfdndhfd8438MNFDN93jdnJFkdmqnh893`). If you don't specify a version + * ID, Amazon S3 copies the latest version of the source object. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-points.html + * + * @required + * + * @var string|null + */ + private $copySource; + + /** + * Copies the object if its entity tag (ETag) matches the specified tag. + * + * @var string|null + */ + private $copySourceIfMatch; + + /** + * Copies the object if it has been modified since the specified time. + * + * @var \DateTimeImmutable|null + */ + private $copySourceIfModifiedSince; + + /** + * Copies the object if its entity tag (ETag) is different than the specified ETag. + * + * @var string|null + */ + private $copySourceIfNoneMatch; + + /** + * Copies the object if it hasn't been modified since the specified time. + * + * @var \DateTimeImmutable|null + */ + private $copySourceIfUnmodifiedSince; + + /** + * The date and time at which the object is no longer cacheable. + * + * @var \DateTimeImmutable|null + */ + private $expires; + + /** + * Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantFullControl; + + /** + * Allows grantee to read the object data and its metadata. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantRead; + + /** + * Allows grantee to read the object ACL. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantReadAcp; + + /** + * Allows grantee to write the ACL for the applicable object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantWriteAcp; + + /** + * The key of the destination object. + * + * @required + * + * @var string|null + */ + private $key; + + /** + * A map of metadata to store with the object in S3. + * + * @var array|null + */ + private $metadata; + + /** + * Specifies whether the metadata is copied from the source object or replaced with metadata provided in the request. + * + * @var MetadataDirective::*|null + */ + private $metadataDirective; + + /** + * Specifies whether the object tag-set are copied from the source object or replaced with tag-set provided in the + * request. + * + * @var TaggingDirective::*|null + */ + private $taggingDirective; + + /** + * The server-side encryption algorithm used when storing this object in Amazon S3 (for example, `AES256`, `aws:kms`, + * `aws:kms:dsse`). + * + * @var ServerSideEncryption::*|null + */ + private $serverSideEncryption; + + /** + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^1] in + * the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * If the bucket is configured as a website, redirects requests for this object to another object in the same bucket or + * to an external URL. Amazon S3 stores the value of this header in the object metadata. This value is unique to each + * object and is not copied when using the `x-amz-metadata-directive` header. Instead, you may opt to provide this + * header in combination with the directive. + * + * @var string|null + */ + private $websiteRedirectLocation; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * Specifies the KMS key ID to use for object encryption. All GET and PUT requests for an object protected by KMS will + * fail if they're not made via SSL or using SigV4. For information about configuring any of the officially supported + * Amazon Web Services SDKs and Amazon Web Services CLI, see Specifying the Signature Version in Request Authentication + * [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Specifies the Amazon Web Services KMS Encryption Context to use for object encryption. The value of this header is a + * base64-encoded UTF-8 string holding JSON with the encryption context key-value pairs. + * + * @var string|null + */ + private $sseKmsEncryptionContext; + + /** + * Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption with server-side encryption using Key + * Management Service (KMS) keys (SSE-KMS). Setting this header to `true` causes Amazon S3 to use an S3 Bucket Key for + * object encryption with SSE-KMS. + * + * Specifying this header with a COPY action doesn’t affect bucket-level settings for S3 Bucket Key. + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * Specifies the algorithm to use when decrypting the source object (for example, AES256). + * + * @var string|null + */ + private $copySourceSseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use to decrypt the source object. The encryption key + * provided in this header must be one that was used when the source object was created. + * + * @var string|null + */ + private $copySourceSseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $copySourceSseCustomerKeyMd5; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The tag-set for the object destination object this value must be used in conjunction with the `TaggingDirective`. The + * tag-set must be encoded as URL Query parameters. + * + * @var string|null + */ + private $tagging; + + /** + * The Object Lock mode that you want to apply to the copied object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when you want the copied object's Object Lock to expire. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether you want to apply a legal hold to the copied object. + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + /** + * The account ID of the expected destination bucket owner. If the destination bucket is owned by a different account, + * the request fails with the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * The account ID of the expected source bucket owner. If the source bucket is owned by a different account, the request + * fails with the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedSourceBucketOwner; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * CopySource?: string, + * CopySourceIfMatch?: string, + * CopySourceIfModifiedSince?: \DateTimeImmutable|string, + * CopySourceIfNoneMatch?: string, + * CopySourceIfUnmodifiedSince?: \DateTimeImmutable|string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * MetadataDirective?: MetadataDirective::*, + * TaggingDirective?: TaggingDirective::*, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * CopySourceSSECustomerAlgorithm?: string, + * CopySourceSSECustomerKey?: string, + * CopySourceSSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ExpectedSourceBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->cacheControl = $input['CacheControl'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->contentDisposition = $input['ContentDisposition'] ?? null; + $this->contentEncoding = $input['ContentEncoding'] ?? null; + $this->contentLanguage = $input['ContentLanguage'] ?? null; + $this->contentType = $input['ContentType'] ?? null; + $this->copySource = $input['CopySource'] ?? null; + $this->copySourceIfMatch = $input['CopySourceIfMatch'] ?? null; + $this->copySourceIfModifiedSince = !isset($input['CopySourceIfModifiedSince']) ? null : ($input['CopySourceIfModifiedSince'] instanceof \DateTimeImmutable ? $input['CopySourceIfModifiedSince'] : new \DateTimeImmutable($input['CopySourceIfModifiedSince'])); + $this->copySourceIfNoneMatch = $input['CopySourceIfNoneMatch'] ?? null; + $this->copySourceIfUnmodifiedSince = !isset($input['CopySourceIfUnmodifiedSince']) ? null : ($input['CopySourceIfUnmodifiedSince'] instanceof \DateTimeImmutable ? $input['CopySourceIfUnmodifiedSince'] : new \DateTimeImmutable($input['CopySourceIfUnmodifiedSince'])); + $this->expires = !isset($input['Expires']) ? null : ($input['Expires'] instanceof \DateTimeImmutable ? $input['Expires'] : new \DateTimeImmutable($input['Expires'])); + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->metadata = $input['Metadata'] ?? null; + $this->metadataDirective = $input['MetadataDirective'] ?? null; + $this->taggingDirective = $input['TaggingDirective'] ?? null; + $this->serverSideEncryption = $input['ServerSideEncryption'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->websiteRedirectLocation = $input['WebsiteRedirectLocation'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->sseKmsKeyId = $input['SSEKMSKeyId'] ?? null; + $this->sseKmsEncryptionContext = $input['SSEKMSEncryptionContext'] ?? null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + $this->copySourceSseCustomerAlgorithm = $input['CopySourceSSECustomerAlgorithm'] ?? null; + $this->copySourceSseCustomerKey = $input['CopySourceSSECustomerKey'] ?? null; + $this->copySourceSseCustomerKeyMd5 = $input['CopySourceSSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->tagging = $input['Tagging'] ?? null; + $this->objectLockMode = $input['ObjectLockMode'] ?? null; + $this->objectLockRetainUntilDate = !isset($input['ObjectLockRetainUntilDate']) ? null : ($input['ObjectLockRetainUntilDate'] instanceof \DateTimeImmutable ? $input['ObjectLockRetainUntilDate'] : new \DateTimeImmutable($input['ObjectLockRetainUntilDate'])); + $this->objectLockLegalHoldStatus = $input['ObjectLockLegalHoldStatus'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->expectedSourceBucketOwner = $input['ExpectedSourceBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * CopySource?: string, + * CopySourceIfMatch?: string, + * CopySourceIfModifiedSince?: \DateTimeImmutable|string, + * CopySourceIfNoneMatch?: string, + * CopySourceIfUnmodifiedSince?: \DateTimeImmutable|string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * MetadataDirective?: MetadataDirective::*, + * TaggingDirective?: TaggingDirective::*, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * CopySourceSSECustomerAlgorithm?: string, + * CopySourceSSECustomerKey?: string, + * CopySourceSSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ExpectedSourceBucketOwner?: string, + * '@region'?: string|null, + * }|CopyObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + return $this->cacheControl; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentDisposition(): ?string + { + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + return $this->contentLanguage; + } + + public function getContentType(): ?string + { + return $this->contentType; + } + + public function getCopySource(): ?string + { + return $this->copySource; + } + + public function getCopySourceIfMatch(): ?string + { + return $this->copySourceIfMatch; + } + + public function getCopySourceIfModifiedSince(): ?\DateTimeImmutable + { + return $this->copySourceIfModifiedSince; + } + + public function getCopySourceIfNoneMatch(): ?string + { + return $this->copySourceIfNoneMatch; + } + + public function getCopySourceIfUnmodifiedSince(): ?\DateTimeImmutable + { + return $this->copySourceIfUnmodifiedSince; + } + + public function getCopySourceSseCustomerAlgorithm(): ?string + { + return $this->copySourceSseCustomerAlgorithm; + } + + public function getCopySourceSseCustomerKey(): ?string + { + return $this->copySourceSseCustomerKey; + } + + public function getCopySourceSseCustomerKeyMd5(): ?string + { + return $this->copySourceSseCustomerKeyMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getExpectedSourceBucketOwner(): ?string + { + return $this->expectedSourceBucketOwner; + } + + public function getExpires(): ?\DateTimeImmutable + { + return $this->expires; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata ?? []; + } + + /** + * @return MetadataDirective::*|null + */ + public function getMetadataDirective(): ?string + { + return $this->metadataDirective; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + return $this->objectLockRetainUntilDate; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getTagging(): ?string + { + return $this->tagging; + } + + /** + * @return TaggingDirective::*|null + */ + public function getTaggingDirective(): ?string + { + return $this->taggingDirective; + } + + public function getWebsiteRedirectLocation(): ?string + { + return $this->websiteRedirectLocation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->cacheControl) { + $headers['Cache-Control'] = $this->cacheControl; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->contentDisposition) { + $headers['Content-Disposition'] = $this->contentDisposition; + } + if (null !== $this->contentEncoding) { + $headers['Content-Encoding'] = $this->contentEncoding; + } + if (null !== $this->contentLanguage) { + $headers['Content-Language'] = $this->contentLanguage; + } + if (null !== $this->contentType) { + $headers['Content-Type'] = $this->contentType; + } + if (null === $v = $this->copySource) { + throw new InvalidArgument(sprintf('Missing parameter "CopySource" for "%s". The value cannot be null.', __CLASS__)); + } + $headers['x-amz-copy-source'] = $v; + if (null !== $this->copySourceIfMatch) { + $headers['x-amz-copy-source-if-match'] = $this->copySourceIfMatch; + } + if (null !== $this->copySourceIfModifiedSince) { + $headers['x-amz-copy-source-if-modified-since'] = $this->copySourceIfModifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->copySourceIfNoneMatch) { + $headers['x-amz-copy-source-if-none-match'] = $this->copySourceIfNoneMatch; + } + if (null !== $this->copySourceIfUnmodifiedSince) { + $headers['x-amz-copy-source-if-unmodified-since'] = $this->copySourceIfUnmodifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->expires) { + $headers['Expires'] = $this->expires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->metadataDirective) { + if (!MetadataDirective::exists($this->metadataDirective)) { + throw new InvalidArgument(sprintf('Invalid parameter "MetadataDirective" for "%s". The value "%s" is not a valid "MetadataDirective".', __CLASS__, $this->metadataDirective)); + } + $headers['x-amz-metadata-directive'] = $this->metadataDirective; + } + if (null !== $this->taggingDirective) { + if (!TaggingDirective::exists($this->taggingDirective)) { + throw new InvalidArgument(sprintf('Invalid parameter "TaggingDirective" for "%s". The value "%s" is not a valid "TaggingDirective".', __CLASS__, $this->taggingDirective)); + } + $headers['x-amz-tagging-directive'] = $this->taggingDirective; + } + if (null !== $this->serverSideEncryption) { + if (!ServerSideEncryption::exists($this->serverSideEncryption)) { + throw new InvalidArgument(sprintf('Invalid parameter "ServerSideEncryption" for "%s". The value "%s" is not a valid "ServerSideEncryption".', __CLASS__, $this->serverSideEncryption)); + } + $headers['x-amz-server-side-encryption'] = $this->serverSideEncryption; + } + if (null !== $this->storageClass) { + if (!StorageClass::exists($this->storageClass)) { + throw new InvalidArgument(sprintf('Invalid parameter "StorageClass" for "%s". The value "%s" is not a valid "StorageClass".', __CLASS__, $this->storageClass)); + } + $headers['x-amz-storage-class'] = $this->storageClass; + } + if (null !== $this->websiteRedirectLocation) { + $headers['x-amz-website-redirect-location'] = $this->websiteRedirectLocation; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->sseKmsKeyId) { + $headers['x-amz-server-side-encryption-aws-kms-key-id'] = $this->sseKmsKeyId; + } + if (null !== $this->sseKmsEncryptionContext) { + $headers['x-amz-server-side-encryption-context'] = $this->sseKmsEncryptionContext; + } + if (null !== $this->bucketKeyEnabled) { + $headers['x-amz-server-side-encryption-bucket-key-enabled'] = $this->bucketKeyEnabled ? 'true' : 'false'; + } + if (null !== $this->copySourceSseCustomerAlgorithm) { + $headers['x-amz-copy-source-server-side-encryption-customer-algorithm'] = $this->copySourceSseCustomerAlgorithm; + } + if (null !== $this->copySourceSseCustomerKey) { + $headers['x-amz-copy-source-server-side-encryption-customer-key'] = $this->copySourceSseCustomerKey; + } + if (null !== $this->copySourceSseCustomerKeyMd5) { + $headers['x-amz-copy-source-server-side-encryption-customer-key-MD5'] = $this->copySourceSseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->tagging) { + $headers['x-amz-tagging'] = $this->tagging; + } + if (null !== $this->objectLockMode) { + if (!ObjectLockMode::exists($this->objectLockMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockMode" for "%s". The value "%s" is not a valid "ObjectLockMode".', __CLASS__, $this->objectLockMode)); + } + $headers['x-amz-object-lock-mode'] = $this->objectLockMode; + } + if (null !== $this->objectLockRetainUntilDate) { + $headers['x-amz-object-lock-retain-until-date'] = $this->objectLockRetainUntilDate->format(\DateTimeInterface::ISO8601); + } + if (null !== $this->objectLockLegalHoldStatus) { + if (!ObjectLockLegalHoldStatus::exists($this->objectLockLegalHoldStatus)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockLegalHoldStatus" for "%s". The value "%s" is not a valid "ObjectLockLegalHoldStatus".', __CLASS__, $this->objectLockLegalHoldStatus)); + } + $headers['x-amz-object-lock-legal-hold'] = $this->objectLockLegalHoldStatus; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->expectedSourceBucketOwner) { + $headers['x-amz-source-expected-bucket-owner'] = $this->expectedSourceBucketOwner; + } + if (null !== $this->metadata) { + foreach ($this->metadata as $key => $value) { + $headers["x-amz-meta-$key"] = $value; + } + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBucketKeyEnabled(?bool $value): self + { + $this->bucketKeyEnabled = $value; + + return $this; + } + + public function setCacheControl(?string $value): self + { + $this->cacheControl = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentDisposition(?string $value): self + { + $this->contentDisposition = $value; + + return $this; + } + + public function setContentEncoding(?string $value): self + { + $this->contentEncoding = $value; + + return $this; + } + + public function setContentLanguage(?string $value): self + { + $this->contentLanguage = $value; + + return $this; + } + + public function setContentType(?string $value): self + { + $this->contentType = $value; + + return $this; + } + + public function setCopySource(?string $value): self + { + $this->copySource = $value; + + return $this; + } + + public function setCopySourceIfMatch(?string $value): self + { + $this->copySourceIfMatch = $value; + + return $this; + } + + public function setCopySourceIfModifiedSince(?\DateTimeImmutable $value): self + { + $this->copySourceIfModifiedSince = $value; + + return $this; + } + + public function setCopySourceIfNoneMatch(?string $value): self + { + $this->copySourceIfNoneMatch = $value; + + return $this; + } + + public function setCopySourceIfUnmodifiedSince(?\DateTimeImmutable $value): self + { + $this->copySourceIfUnmodifiedSince = $value; + + return $this; + } + + public function setCopySourceSseCustomerAlgorithm(?string $value): self + { + $this->copySourceSseCustomerAlgorithm = $value; + + return $this; + } + + public function setCopySourceSseCustomerKey(?string $value): self + { + $this->copySourceSseCustomerKey = $value; + + return $this; + } + + public function setCopySourceSseCustomerKeyMd5(?string $value): self + { + $this->copySourceSseCustomerKeyMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setExpectedSourceBucketOwner(?string $value): self + { + $this->expectedSourceBucketOwner = $value; + + return $this; + } + + public function setExpires(?\DateTimeImmutable $value): self + { + $this->expires = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param array $value + */ + public function setMetadata(array $value): self + { + $this->metadata = $value; + + return $this; + } + + /** + * @param MetadataDirective::*|null $value + */ + public function setMetadataDirective(?string $value): self + { + $this->metadataDirective = $value; + + return $this; + } + + /** + * @param ObjectLockLegalHoldStatus::*|null $value + */ + public function setObjectLockLegalHoldStatus(?string $value): self + { + $this->objectLockLegalHoldStatus = $value; + + return $this; + } + + /** + * @param ObjectLockMode::*|null $value + */ + public function setObjectLockMode(?string $value): self + { + $this->objectLockMode = $value; + + return $this; + } + + public function setObjectLockRetainUntilDate(?\DateTimeImmutable $value): self + { + $this->objectLockRetainUntilDate = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + /** + * @param ServerSideEncryption::*|null $value + */ + public function setServerSideEncryption(?string $value): self + { + $this->serverSideEncryption = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setSseKmsEncryptionContext(?string $value): self + { + $this->sseKmsEncryptionContext = $value; + + return $this; + } + + public function setSseKmsKeyId(?string $value): self + { + $this->sseKmsKeyId = $value; + + return $this; + } + + /** + * @param StorageClass::*|null $value + */ + public function setStorageClass(?string $value): self + { + $this->storageClass = $value; + + return $this; + } + + public function setTagging(?string $value): self + { + $this->tagging = $value; + + return $this; + } + + /** + * @param TaggingDirective::*|null $value + */ + public function setTaggingDirective(?string $value): self + { + $this->taggingDirective = $value; + + return $this; + } + + public function setWebsiteRedirectLocation(?string $value): self + { + $this->websiteRedirectLocation = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/CreateBucketRequest.php b/vendor/async-aws/s3/src/Input/CreateBucketRequest.php new file mode 100644 index 000000000..74862f720 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CreateBucketRequest.php @@ -0,0 +1,337 @@ +acl = $input['ACL'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->createBucketConfiguration = isset($input['CreateBucketConfiguration']) ? CreateBucketConfiguration::create($input['CreateBucketConfiguration']) : null; + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWrite = $input['GrantWrite'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->objectLockEnabledForBucket = $input['ObjectLockEnabledForBucket'] ?? null; + $this->objectOwnership = $input['ObjectOwnership'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: BucketCannedACL::*, + * Bucket?: string, + * CreateBucketConfiguration?: CreateBucketConfiguration|array, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * ObjectLockEnabledForBucket?: bool, + * ObjectOwnership?: ObjectOwnership::*, + * '@region'?: string|null, + * }|CreateBucketRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return BucketCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getCreateBucketConfiguration(): ?CreateBucketConfiguration + { + return $this->createBucketConfiguration; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWrite(): ?string + { + return $this->grantWrite; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getObjectLockEnabledForBucket(): ?bool + { + return $this->objectLockEnabledForBucket; + } + + /** + * @return ObjectOwnership::*|null + */ + public function getObjectOwnership(): ?string + { + return $this->objectOwnership; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!BucketCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "BucketCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWrite) { + $headers['x-amz-grant-write'] = $this->grantWrite; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->objectLockEnabledForBucket) { + $headers['x-amz-bucket-object-lock-enabled'] = $this->objectLockEnabledForBucket ? 'true' : 'false'; + } + if (null !== $this->objectOwnership) { + if (!ObjectOwnership::exists($this->objectOwnership)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectOwnership" for "%s". The value "%s" is not a valid "ObjectOwnership".', __CLASS__, $this->objectOwnership)); + } + $headers['x-amz-object-ownership'] = $this->objectOwnership; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']); + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param BucketCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setCreateBucketConfiguration(?CreateBucketConfiguration $value): self + { + $this->createBucketConfiguration = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWrite(?string $value): self + { + $this->grantWrite = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setObjectLockEnabledForBucket(?bool $value): self + { + $this->objectLockEnabledForBucket = $value; + + return $this; + } + + /** + * @param ObjectOwnership::*|null $value + */ + public function setObjectOwnership(?string $value): self + { + $this->objectOwnership = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null !== $v = $this->createBucketConfiguration) { + $node->appendChild($child = $document->createElement('CreateBucketConfiguration')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php b/vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php new file mode 100644 index 000000000..7c4d369e4 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/CreateMultipartUploadRequest.php @@ -0,0 +1,933 @@ +|null + */ + private $metadata; + + /** + * The server-side encryption algorithm used when storing this object in Amazon S3 (for example, `AES256`, `aws:kms`). + * + * @var ServerSideEncryption::*|null + */ + private $serverSideEncryption; + + /** + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^1] in + * the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * If the bucket is configured as a website, redirects requests for this object to another object in the same bucket or + * to an external URL. Amazon S3 stores the value of this header in the object metadata. + * + * @var string|null + */ + private $websiteRedirectLocation; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * Specifies the ID of the symmetric encryption customer managed key to use for object encryption. All GET and PUT + * requests for an object protected by KMS will fail if they're not made via SSL or using SigV4. For information about + * configuring any of the officially supported Amazon Web Services SDKs and Amazon Web Services CLI, see Specifying the + * Signature Version in Request Authentication [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingAWSSDK.html#specify-signature-version + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Specifies the Amazon Web Services KMS Encryption Context to use for object encryption. The value of this header is a + * base64-encoded UTF-8 string holding JSON with the encryption context key-value pairs. + * + * @var string|null + */ + private $sseKmsEncryptionContext; + + /** + * Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption with server-side encryption using Key + * Management Service (KMS) keys (SSE-KMS). Setting this header to `true` causes Amazon S3 to use an S3 Bucket Key for + * object encryption with SSE-KMS. + * + * Specifying this header with an object action doesn’t affect bucket-level settings for S3 Bucket Key. + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The tag-set for the object. The tag-set must be encoded as URL Query parameters. + * + * @var string|null + */ + private $tagging; + + /** + * Specifies the Object Lock mode that you want to apply to the uploaded object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * Specifies the date and time when you want the Object Lock to expire. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether you want to apply a legal hold to the uploaded object. + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * Indicates the algorithm you want Amazon S3 to use to create the checksum for the object. For more information, see + * Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->cacheControl = $input['CacheControl'] ?? null; + $this->contentDisposition = $input['ContentDisposition'] ?? null; + $this->contentEncoding = $input['ContentEncoding'] ?? null; + $this->contentLanguage = $input['ContentLanguage'] ?? null; + $this->contentType = $input['ContentType'] ?? null; + $this->expires = !isset($input['Expires']) ? null : ($input['Expires'] instanceof \DateTimeImmutable ? $input['Expires'] : new \DateTimeImmutable($input['Expires'])); + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->metadata = $input['Metadata'] ?? null; + $this->serverSideEncryption = $input['ServerSideEncryption'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->websiteRedirectLocation = $input['WebsiteRedirectLocation'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->sseKmsKeyId = $input['SSEKMSKeyId'] ?? null; + $this->sseKmsEncryptionContext = $input['SSEKMSEncryptionContext'] ?? null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->tagging = $input['Tagging'] ?? null; + $this->objectLockMode = $input['ObjectLockMode'] ?? null; + $this->objectLockRetainUntilDate = !isset($input['ObjectLockRetainUntilDate']) ? null : ($input['ObjectLockRetainUntilDate'] instanceof \DateTimeImmutable ? $input['ObjectLockRetainUntilDate'] : new \DateTimeImmutable($input['ObjectLockRetainUntilDate'])); + $this->objectLockLegalHoldStatus = $input['ObjectLockLegalHoldStatus'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|CreateMultipartUploadRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + return $this->cacheControl; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentDisposition(): ?string + { + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + return $this->contentLanguage; + } + + public function getContentType(): ?string + { + return $this->contentType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getExpires(): ?\DateTimeImmutable + { + return $this->expires; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata ?? []; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + return $this->objectLockRetainUntilDate; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getTagging(): ?string + { + return $this->tagging; + } + + public function getWebsiteRedirectLocation(): ?string + { + return $this->websiteRedirectLocation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->cacheControl) { + $headers['Cache-Control'] = $this->cacheControl; + } + if (null !== $this->contentDisposition) { + $headers['Content-Disposition'] = $this->contentDisposition; + } + if (null !== $this->contentEncoding) { + $headers['Content-Encoding'] = $this->contentEncoding; + } + if (null !== $this->contentLanguage) { + $headers['Content-Language'] = $this->contentLanguage; + } + if (null !== $this->contentType) { + $headers['Content-Type'] = $this->contentType; + } + if (null !== $this->expires) { + $headers['Expires'] = $this->expires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->serverSideEncryption) { + if (!ServerSideEncryption::exists($this->serverSideEncryption)) { + throw new InvalidArgument(sprintf('Invalid parameter "ServerSideEncryption" for "%s". The value "%s" is not a valid "ServerSideEncryption".', __CLASS__, $this->serverSideEncryption)); + } + $headers['x-amz-server-side-encryption'] = $this->serverSideEncryption; + } + if (null !== $this->storageClass) { + if (!StorageClass::exists($this->storageClass)) { + throw new InvalidArgument(sprintf('Invalid parameter "StorageClass" for "%s". The value "%s" is not a valid "StorageClass".', __CLASS__, $this->storageClass)); + } + $headers['x-amz-storage-class'] = $this->storageClass; + } + if (null !== $this->websiteRedirectLocation) { + $headers['x-amz-website-redirect-location'] = $this->websiteRedirectLocation; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->sseKmsKeyId) { + $headers['x-amz-server-side-encryption-aws-kms-key-id'] = $this->sseKmsKeyId; + } + if (null !== $this->sseKmsEncryptionContext) { + $headers['x-amz-server-side-encryption-context'] = $this->sseKmsEncryptionContext; + } + if (null !== $this->bucketKeyEnabled) { + $headers['x-amz-server-side-encryption-bucket-key-enabled'] = $this->bucketKeyEnabled ? 'true' : 'false'; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->tagging) { + $headers['x-amz-tagging'] = $this->tagging; + } + if (null !== $this->objectLockMode) { + if (!ObjectLockMode::exists($this->objectLockMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockMode" for "%s". The value "%s" is not a valid "ObjectLockMode".', __CLASS__, $this->objectLockMode)); + } + $headers['x-amz-object-lock-mode'] = $this->objectLockMode; + } + if (null !== $this->objectLockRetainUntilDate) { + $headers['x-amz-object-lock-retain-until-date'] = $this->objectLockRetainUntilDate->format(\DateTimeInterface::ISO8601); + } + if (null !== $this->objectLockLegalHoldStatus) { + if (!ObjectLockLegalHoldStatus::exists($this->objectLockLegalHoldStatus)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockLegalHoldStatus" for "%s". The value "%s" is not a valid "ObjectLockLegalHoldStatus".', __CLASS__, $this->objectLockLegalHoldStatus)); + } + $headers['x-amz-object-lock-legal-hold'] = $this->objectLockLegalHoldStatus; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->metadata) { + foreach ($this->metadata as $key => $value) { + $headers["x-amz-meta-$key"] = $value; + } + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?uploads'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBucketKeyEnabled(?bool $value): self + { + $this->bucketKeyEnabled = $value; + + return $this; + } + + public function setCacheControl(?string $value): self + { + $this->cacheControl = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentDisposition(?string $value): self + { + $this->contentDisposition = $value; + + return $this; + } + + public function setContentEncoding(?string $value): self + { + $this->contentEncoding = $value; + + return $this; + } + + public function setContentLanguage(?string $value): self + { + $this->contentLanguage = $value; + + return $this; + } + + public function setContentType(?string $value): self + { + $this->contentType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setExpires(?\DateTimeImmutable $value): self + { + $this->expires = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param array $value + */ + public function setMetadata(array $value): self + { + $this->metadata = $value; + + return $this; + } + + /** + * @param ObjectLockLegalHoldStatus::*|null $value + */ + public function setObjectLockLegalHoldStatus(?string $value): self + { + $this->objectLockLegalHoldStatus = $value; + + return $this; + } + + /** + * @param ObjectLockMode::*|null $value + */ + public function setObjectLockMode(?string $value): self + { + $this->objectLockMode = $value; + + return $this; + } + + public function setObjectLockRetainUntilDate(?\DateTimeImmutable $value): self + { + $this->objectLockRetainUntilDate = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + /** + * @param ServerSideEncryption::*|null $value + */ + public function setServerSideEncryption(?string $value): self + { + $this->serverSideEncryption = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setSseKmsEncryptionContext(?string $value): self + { + $this->sseKmsEncryptionContext = $value; + + return $this; + } + + public function setSseKmsKeyId(?string $value): self + { + $this->sseKmsKeyId = $value; + + return $this; + } + + /** + * @param StorageClass::*|null $value + */ + public function setStorageClass(?string $value): self + { + $this->storageClass = $value; + + return $this; + } + + public function setTagging(?string $value): self + { + $this->tagging = $value; + + return $this; + } + + public function setWebsiteRedirectLocation(?string $value): self + { + $this->websiteRedirectLocation = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php b/vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php new file mode 100644 index 000000000..a039a743b --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteBucketCorsRequest.php @@ -0,0 +1,107 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketCorsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?cors'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteBucketRequest.php b/vendor/async-aws/s3/src/Input/DeleteBucketRequest.php new file mode 100644 index 000000000..ee2371db7 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteBucketRequest.php @@ -0,0 +1,107 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteObjectRequest.php b/vendor/async-aws/s3/src/Input/DeleteObjectRequest.php new file mode 100644 index 000000000..3ded441ff --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteObjectRequest.php @@ -0,0 +1,260 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->mfa = $input['MFA'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->bypassGovernanceRetention = $input['BypassGovernanceRetention'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * MFA?: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBypassGovernanceRetention(): ?bool + { + return $this->bypassGovernanceRetention; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMfa(): ?string + { + return $this->mfa; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->mfa) { + $headers['x-amz-mfa'] = $this->mfa; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->bypassGovernanceRetention) { + $headers['x-amz-bypass-governance-retention'] = $this->bypassGovernanceRetention ? 'true' : 'false'; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBypassGovernanceRetention(?bool $value): self + { + $this->bypassGovernanceRetention = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setMfa(?string $value): self + { + $this->mfa = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php b/vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php new file mode 100644 index 000000000..06c73ab7d --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteObjectTaggingRequest.php @@ -0,0 +1,174 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?tagging'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('DELETE', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php b/vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php new file mode 100644 index 000000000..2f7a115e6 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/DeleteObjectsRequest.php @@ -0,0 +1,292 @@ +bucket = $input['Bucket'] ?? null; + $this->delete = isset($input['Delete']) ? Delete::create($input['Delete']) : null; + $this->mfa = $input['MFA'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->bypassGovernanceRetention = $input['BypassGovernanceRetention'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Delete?: Delete|array, + * MFA?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|DeleteObjectsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBypassGovernanceRetention(): ?bool + { + return $this->bypassGovernanceRetention; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getDelete(): ?Delete + { + return $this->delete; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getMfa(): ?string + { + return $this->mfa; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->mfa) { + $headers['x-amz-mfa'] = $this->mfa; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->bypassGovernanceRetention) { + $headers['x-amz-bypass-governance-retention'] = $this->bypassGovernanceRetention ? 'true' : 'false'; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?delete'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBypassGovernanceRetention(?bool $value): self + { + $this->bypassGovernanceRetention = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setDelete(?Delete $value): self + { + $this->delete = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setMfa(?string $value): self + { + $this->mfa = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->delete) { + throw new InvalidArgument(sprintf('Missing parameter "Delete" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('Delete')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php b/vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php new file mode 100644 index 000000000..67a6e4c2e --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetBucketCorsRequest.php @@ -0,0 +1,116 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketCorsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?cors'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php b/vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php new file mode 100644 index 000000000..82254c4ec --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetBucketEncryptionRequest.php @@ -0,0 +1,107 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketEncryptionRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?encryption'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetObjectAclRequest.php b/vendor/async-aws/s3/src/Input/GetObjectAclRequest.php new file mode 100644 index 000000000..97e06432e --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetObjectAclRequest.php @@ -0,0 +1,200 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetObjectAclRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?acl'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetObjectRequest.php b/vendor/async-aws/s3/src/Input/GetObjectRequest.php new file mode 100644 index 000000000..f4f5185c6 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetObjectRequest.php @@ -0,0 +1,633 @@ + Amazon S3 doesn't support retrieving multiple ranges of data per `GET` request. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#name-range + * + * @var string|null + */ + private $range; + + /** + * Sets the `Cache-Control` header of the response. + * + * @var string|null + */ + private $responseCacheControl; + + /** + * Sets the `Content-Disposition` header of the response. + * + * @var string|null + */ + private $responseContentDisposition; + + /** + * Sets the `Content-Encoding` header of the response. + * + * @var string|null + */ + private $responseContentEncoding; + + /** + * Sets the `Content-Language` header of the response. + * + * @var string|null + */ + private $responseContentLanguage; + + /** + * Sets the `Content-Type` header of the response. + * + * @var string|null + */ + private $responseContentType; + + /** + * Sets the `Expires` header of the response. + * + * @var \DateTimeImmutable|null + */ + private $responseExpires; + + /** + * VersionId used to reference a specific version of the object. + * + * @var string|null + */ + private $versionId; + + /** + * Specifies the algorithm to use to when decrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 used to encrypt the data. This value is used to decrypt + * the object when recovering it and must match the one used when storing the data. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * Part number of the object being read. This is a positive integer between 1 and 10,000. Effectively performs a + * 'ranged' GET request for the part specified. Useful for downloading just a part of an object. + * + * @var int|null + */ + private $partNumber; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * To retrieve the checksum, this mode must be enabled. + * + * @var ChecksumMode::*|null + */ + private $checksumMode; + + /** + * @param array{ + * Bucket?: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key?: string, + * Range?: string, + * ResponseCacheControl?: string, + * ResponseContentDisposition?: string, + * ResponseContentEncoding?: string, + * ResponseContentLanguage?: string, + * ResponseContentType?: string, + * ResponseExpires?: \DateTimeImmutable|string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->bucket = $input['Bucket'] ?? null; + $this->ifMatch = $input['IfMatch'] ?? null; + $this->ifModifiedSince = !isset($input['IfModifiedSince']) ? null : ($input['IfModifiedSince'] instanceof \DateTimeImmutable ? $input['IfModifiedSince'] : new \DateTimeImmutable($input['IfModifiedSince'])); + $this->ifNoneMatch = $input['IfNoneMatch'] ?? null; + $this->ifUnmodifiedSince = !isset($input['IfUnmodifiedSince']) ? null : ($input['IfUnmodifiedSince'] instanceof \DateTimeImmutable ? $input['IfUnmodifiedSince'] : new \DateTimeImmutable($input['IfUnmodifiedSince'])); + $this->key = $input['Key'] ?? null; + $this->range = $input['Range'] ?? null; + $this->responseCacheControl = $input['ResponseCacheControl'] ?? null; + $this->responseContentDisposition = $input['ResponseContentDisposition'] ?? null; + $this->responseContentEncoding = $input['ResponseContentEncoding'] ?? null; + $this->responseContentLanguage = $input['ResponseContentLanguage'] ?? null; + $this->responseContentType = $input['ResponseContentType'] ?? null; + $this->responseExpires = !isset($input['ResponseExpires']) ? null : ($input['ResponseExpires'] instanceof \DateTimeImmutable ? $input['ResponseExpires'] : new \DateTimeImmutable($input['ResponseExpires'])); + $this->versionId = $input['VersionId'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumMode = $input['ChecksumMode'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key?: string, + * Range?: string, + * ResponseCacheControl?: string, + * ResponseContentDisposition?: string, + * ResponseContentEncoding?: string, + * ResponseContentLanguage?: string, + * ResponseContentType?: string, + * ResponseExpires?: \DateTimeImmutable|string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|GetObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumMode::*|null + */ + public function getChecksumMode(): ?string + { + return $this->checksumMode; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getIfMatch(): ?string + { + return $this->ifMatch; + } + + public function getIfModifiedSince(): ?\DateTimeImmutable + { + return $this->ifModifiedSince; + } + + public function getIfNoneMatch(): ?string + { + return $this->ifNoneMatch; + } + + public function getIfUnmodifiedSince(): ?\DateTimeImmutable + { + return $this->ifUnmodifiedSince; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + public function getRange(): ?string + { + return $this->range; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getResponseCacheControl(): ?string + { + return $this->responseCacheControl; + } + + public function getResponseContentDisposition(): ?string + { + return $this->responseContentDisposition; + } + + public function getResponseContentEncoding(): ?string + { + return $this->responseContentEncoding; + } + + public function getResponseContentLanguage(): ?string + { + return $this->responseContentLanguage; + } + + public function getResponseContentType(): ?string + { + return $this->responseContentType; + } + + public function getResponseExpires(): ?\DateTimeImmutable + { + return $this->responseExpires; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->ifMatch) { + $headers['If-Match'] = $this->ifMatch; + } + if (null !== $this->ifModifiedSince) { + $headers['If-Modified-Since'] = $this->ifModifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->ifNoneMatch) { + $headers['If-None-Match'] = $this->ifNoneMatch; + } + if (null !== $this->ifUnmodifiedSince) { + $headers['If-Unmodified-Since'] = $this->ifUnmodifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->range) { + $headers['Range'] = $this->range; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumMode) { + if (!ChecksumMode::exists($this->checksumMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumMode" for "%s". The value "%s" is not a valid "ChecksumMode".', __CLASS__, $this->checksumMode)); + } + $headers['x-amz-checksum-mode'] = $this->checksumMode; + } + + // Prepare query + $query = []; + if (null !== $this->responseCacheControl) { + $query['response-cache-control'] = $this->responseCacheControl; + } + if (null !== $this->responseContentDisposition) { + $query['response-content-disposition'] = $this->responseContentDisposition; + } + if (null !== $this->responseContentEncoding) { + $query['response-content-encoding'] = $this->responseContentEncoding; + } + if (null !== $this->responseContentLanguage) { + $query['response-content-language'] = $this->responseContentLanguage; + } + if (null !== $this->responseContentType) { + $query['response-content-type'] = $this->responseContentType; + } + if (null !== $this->responseExpires) { + $query['response-expires'] = $this->responseExpires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + if (null !== $this->partNumber) { + $query['partNumber'] = (string) $this->partNumber; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumMode::*|null $value + */ + public function setChecksumMode(?string $value): self + { + $this->checksumMode = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setIfMatch(?string $value): self + { + $this->ifMatch = $value; + + return $this; + } + + public function setIfModifiedSince(?\DateTimeImmutable $value): self + { + $this->ifModifiedSince = $value; + + return $this; + } + + public function setIfNoneMatch(?string $value): self + { + $this->ifNoneMatch = $value; + + return $this; + } + + public function setIfUnmodifiedSince(?\DateTimeImmutable $value): self + { + $this->ifUnmodifiedSince = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setPartNumber(?int $value): self + { + $this->partNumber = $value; + + return $this; + } + + public function setRange(?string $value): self + { + $this->range = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setResponseCacheControl(?string $value): self + { + $this->responseCacheControl = $value; + + return $this; + } + + public function setResponseContentDisposition(?string $value): self + { + $this->responseContentDisposition = $value; + + return $this; + } + + public function setResponseContentEncoding(?string $value): self + { + $this->responseContentEncoding = $value; + + return $this; + } + + public function setResponseContentLanguage(?string $value): self + { + $this->responseContentLanguage = $value; + + return $this; + } + + public function setResponseContentType(?string $value): self + { + $this->responseContentType = $value; + + return $this; + } + + public function setResponseExpires(?\DateTimeImmutable $value): self + { + $this->responseExpires = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php b/vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php new file mode 100644 index 000000000..8d049b9d3 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/GetObjectTaggingRequest.php @@ -0,0 +1,207 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|GetObjectTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?tagging'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/HeadBucketRequest.php b/vendor/async-aws/s3/src/Input/HeadBucketRequest.php new file mode 100644 index 000000000..9e0482853 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/HeadBucketRequest.php @@ -0,0 +1,127 @@ +bucket = $input['Bucket'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|HeadBucketRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('HEAD', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/HeadObjectRequest.php b/vendor/async-aws/s3/src/Input/HeadObjectRequest.php new file mode 100644 index 000000000..ee4055e67 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/HeadObjectRequest.php @@ -0,0 +1,480 @@ +bucket = $input['Bucket'] ?? null; + $this->ifMatch = $input['IfMatch'] ?? null; + $this->ifModifiedSince = !isset($input['IfModifiedSince']) ? null : ($input['IfModifiedSince'] instanceof \DateTimeImmutable ? $input['IfModifiedSince'] : new \DateTimeImmutable($input['IfModifiedSince'])); + $this->ifNoneMatch = $input['IfNoneMatch'] ?? null; + $this->ifUnmodifiedSince = !isset($input['IfUnmodifiedSince']) ? null : ($input['IfUnmodifiedSince'] instanceof \DateTimeImmutable ? $input['IfUnmodifiedSince'] : new \DateTimeImmutable($input['IfUnmodifiedSince'])); + $this->key = $input['Key'] ?? null; + $this->range = $input['Range'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->checksumMode = $input['ChecksumMode'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key?: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumMode::*|null + */ + public function getChecksumMode(): ?string + { + return $this->checksumMode; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getIfMatch(): ?string + { + return $this->ifMatch; + } + + public function getIfModifiedSince(): ?\DateTimeImmutable + { + return $this->ifModifiedSince; + } + + public function getIfNoneMatch(): ?string + { + return $this->ifNoneMatch; + } + + public function getIfUnmodifiedSince(): ?\DateTimeImmutable + { + return $this->ifUnmodifiedSince; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + public function getRange(): ?string + { + return $this->range; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->ifMatch) { + $headers['If-Match'] = $this->ifMatch; + } + if (null !== $this->ifModifiedSince) { + $headers['If-Modified-Since'] = $this->ifModifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->ifNoneMatch) { + $headers['If-None-Match'] = $this->ifNoneMatch; + } + if (null !== $this->ifUnmodifiedSince) { + $headers['If-Unmodified-Since'] = $this->ifUnmodifiedSince->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->range) { + $headers['Range'] = $this->range; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->checksumMode) { + if (!ChecksumMode::exists($this->checksumMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumMode" for "%s". The value "%s" is not a valid "ChecksumMode".', __CLASS__, $this->checksumMode)); + } + $headers['x-amz-checksum-mode'] = $this->checksumMode; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + if (null !== $this->partNumber) { + $query['partNumber'] = (string) $this->partNumber; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('HEAD', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumMode::*|null $value + */ + public function setChecksumMode(?string $value): self + { + $this->checksumMode = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setIfMatch(?string $value): self + { + $this->ifMatch = $value; + + return $this; + } + + public function setIfModifiedSince(?\DateTimeImmutable $value): self + { + $this->ifModifiedSince = $value; + + return $this; + } + + public function setIfNoneMatch(?string $value): self + { + $this->ifNoneMatch = $value; + + return $this; + } + + public function setIfUnmodifiedSince(?\DateTimeImmutable $value): self + { + $this->ifUnmodifiedSince = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setPartNumber(?int $value): self + { + $this->partNumber = $value; + + return $this; + } + + public function setRange(?string $value): self + { + $this->range = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/ListBucketsRequest.php b/vendor/async-aws/s3/src/Input/ListBucketsRequest.php new file mode 100644 index 000000000..43ae23b87 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListBucketsRequest.php @@ -0,0 +1,51 @@ + 'application/xml']; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } +} diff --git a/vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php b/vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php new file mode 100644 index 000000000..a1e0c7c48 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListMultipartUploadsRequest.php @@ -0,0 +1,329 @@ +bucket = $input['Bucket'] ?? null; + $this->delimiter = $input['Delimiter'] ?? null; + $this->encodingType = $input['EncodingType'] ?? null; + $this->keyMarker = $input['KeyMarker'] ?? null; + $this->maxUploads = $input['MaxUploads'] ?? null; + $this->prefix = $input['Prefix'] ?? null; + $this->uploadIdMarker = $input['UploadIdMarker'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * KeyMarker?: string, + * MaxUploads?: int, + * Prefix?: string, + * UploadIdMarker?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|ListMultipartUploadsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getDelimiter(): ?string + { + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + return $this->encodingType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKeyMarker(): ?string + { + return $this->keyMarker; + } + + public function getMaxUploads(): ?int + { + return $this->maxUploads; + } + + public function getPrefix(): ?string + { + return $this->prefix; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getUploadIdMarker(): ?string + { + return $this->uploadIdMarker; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + + // Prepare query + $query = []; + if (null !== $this->delimiter) { + $query['delimiter'] = $this->delimiter; + } + if (null !== $this->encodingType) { + if (!EncodingType::exists($this->encodingType)) { + throw new InvalidArgument(sprintf('Invalid parameter "EncodingType" for "%s". The value "%s" is not a valid "EncodingType".', __CLASS__, $this->encodingType)); + } + $query['encoding-type'] = $this->encodingType; + } + if (null !== $this->keyMarker) { + $query['key-marker'] = $this->keyMarker; + } + if (null !== $this->maxUploads) { + $query['max-uploads'] = (string) $this->maxUploads; + } + if (null !== $this->prefix) { + $query['prefix'] = $this->prefix; + } + if (null !== $this->uploadIdMarker) { + $query['upload-id-marker'] = $this->uploadIdMarker; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?uploads'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setDelimiter(?string $value): self + { + $this->delimiter = $value; + + return $this; + } + + /** + * @param EncodingType::*|null $value + */ + public function setEncodingType(?string $value): self + { + $this->encodingType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKeyMarker(?string $value): self + { + $this->keyMarker = $value; + + return $this; + } + + public function setMaxUploads(?int $value): self + { + $this->maxUploads = $value; + + return $this; + } + + public function setPrefix(?string $value): self + { + $this->prefix = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setUploadIdMarker(?string $value): self + { + $this->uploadIdMarker = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/ListObjectsV2Request.php b/vendor/async-aws/s3/src/Input/ListObjectsV2Request.php new file mode 100644 index 000000000..6c84410bb --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListObjectsV2Request.php @@ -0,0 +1,386 @@ +|null + */ + private $optionalObjectAttributes; + + /** + * @param array{ + * Bucket?: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * MaxKeys?: int, + * Prefix?: string, + * ContinuationToken?: string, + * FetchOwner?: bool, + * StartAfter?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * OptionalObjectAttributes?: array, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->bucket = $input['Bucket'] ?? null; + $this->delimiter = $input['Delimiter'] ?? null; + $this->encodingType = $input['EncodingType'] ?? null; + $this->maxKeys = $input['MaxKeys'] ?? null; + $this->prefix = $input['Prefix'] ?? null; + $this->continuationToken = $input['ContinuationToken'] ?? null; + $this->fetchOwner = $input['FetchOwner'] ?? null; + $this->startAfter = $input['StartAfter'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->optionalObjectAttributes = $input['OptionalObjectAttributes'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * MaxKeys?: int, + * Prefix?: string, + * ContinuationToken?: string, + * FetchOwner?: bool, + * StartAfter?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * OptionalObjectAttributes?: array, + * '@region'?: string|null, + * }|ListObjectsV2Request $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getContinuationToken(): ?string + { + return $this->continuationToken; + } + + public function getDelimiter(): ?string + { + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + return $this->encodingType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getFetchOwner(): ?bool + { + return $this->fetchOwner; + } + + public function getMaxKeys(): ?int + { + return $this->maxKeys; + } + + /** + * @return list + */ + public function getOptionalObjectAttributes(): array + { + return $this->optionalObjectAttributes ?? []; + } + + public function getPrefix(): ?string + { + return $this->prefix; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getStartAfter(): ?string + { + return $this->startAfter; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->optionalObjectAttributes) { + $items = []; + foreach ($this->optionalObjectAttributes as $value) { + if (!OptionalObjectAttributes::exists($value)) { + throw new InvalidArgument(sprintf('Invalid parameter "OptionalObjectAttributes" for "%s". The value "%s" is not a valid "OptionalObjectAttributes".', __CLASS__, $value)); + } + $items[] = $value; + } + $headers['x-amz-optional-object-attributes'] = implode(',', $items); + } + + // Prepare query + $query = []; + if (null !== $this->delimiter) { + $query['delimiter'] = $this->delimiter; + } + if (null !== $this->encodingType) { + if (!EncodingType::exists($this->encodingType)) { + throw new InvalidArgument(sprintf('Invalid parameter "EncodingType" for "%s". The value "%s" is not a valid "EncodingType".', __CLASS__, $this->encodingType)); + } + $query['encoding-type'] = $this->encodingType; + } + if (null !== $this->maxKeys) { + $query['max-keys'] = (string) $this->maxKeys; + } + if (null !== $this->prefix) { + $query['prefix'] = $this->prefix; + } + if (null !== $this->continuationToken) { + $query['continuation-token'] = $this->continuationToken; + } + if (null !== $this->fetchOwner) { + $query['fetch-owner'] = $this->fetchOwner ? 'true' : 'false'; + } + if (null !== $this->startAfter) { + $query['start-after'] = $this->startAfter; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?list-type=2'; + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setContinuationToken(?string $value): self + { + $this->continuationToken = $value; + + return $this; + } + + public function setDelimiter(?string $value): self + { + $this->delimiter = $value; + + return $this; + } + + /** + * @param EncodingType::*|null $value + */ + public function setEncodingType(?string $value): self + { + $this->encodingType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setFetchOwner(?bool $value): self + { + $this->fetchOwner = $value; + + return $this; + } + + public function setMaxKeys(?int $value): self + { + $this->maxKeys = $value; + + return $this; + } + + /** + * @param list $value + */ + public function setOptionalObjectAttributes(array $value): self + { + $this->optionalObjectAttributes = $value; + + return $this; + } + + public function setPrefix(?string $value): self + { + $this->prefix = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setStartAfter(?string $value): self + { + $this->startAfter = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/ListPartsRequest.php b/vendor/async-aws/s3/src/Input/ListPartsRequest.php new file mode 100644 index 000000000..a1ed7e19f --- /dev/null +++ b/vendor/async-aws/s3/src/Input/ListPartsRequest.php @@ -0,0 +1,347 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->maxParts = $input['MaxParts'] ?? null; + $this->partNumberMarker = $input['PartNumberMarker'] ?? null; + $this->uploadId = $input['UploadId'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * MaxParts?: int, + * PartNumberMarker?: int, + * UploadId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|ListPartsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMaxParts(): ?int + { + return $this->maxParts; + } + + public function getPartNumberMarker(): ?int + { + return $this->partNumberMarker; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + + // Prepare query + $query = []; + if (null !== $this->maxParts) { + $query['max-parts'] = (string) $this->maxParts; + } + if (null !== $this->partNumberMarker) { + $query['part-number-marker'] = (string) $this->partNumberMarker; + } + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = ''; + + // Return the Request + return new Request('GET', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setMaxParts(?int $value): self + { + $this->maxParts = $value; + + return $this; + } + + public function setPartNumberMarker(?int $value): self + { + $this->partNumberMarker = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php b/vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php new file mode 100644 index 000000000..38f97b891 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutBucketCorsRequest.php @@ -0,0 +1,223 @@ +bucket = $input['Bucket'] ?? null; + $this->corsConfiguration = isset($input['CORSConfiguration']) ? CORSConfiguration::create($input['CORSConfiguration']) : null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * CORSConfiguration?: CORSConfiguration|array, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketCorsRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getCorsConfiguration(): ?CORSConfiguration + { + return $this->corsConfiguration; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?cors'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setCorsConfiguration(?CORSConfiguration $value): self + { + $this->corsConfiguration = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->corsConfiguration) { + throw new InvalidArgument(sprintf('Missing parameter "CORSConfiguration" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('CORSConfiguration')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php b/vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php new file mode 100644 index 000000000..0e56aba11 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutBucketNotificationConfigurationRequest.php @@ -0,0 +1,170 @@ +bucket = $input['Bucket'] ?? null; + $this->notificationConfiguration = isset($input['NotificationConfiguration']) ? NotificationConfiguration::create($input['NotificationConfiguration']) : null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->skipDestinationValidation = $input['SkipDestinationValidation'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * NotificationConfiguration?: NotificationConfiguration|array, + * ExpectedBucketOwner?: string, + * SkipDestinationValidation?: bool, + * '@region'?: string|null, + * }|PutBucketNotificationConfigurationRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getNotificationConfiguration(): ?NotificationConfiguration + { + return $this->notificationConfiguration; + } + + public function getSkipDestinationValidation(): ?bool + { + return $this->skipDestinationValidation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->skipDestinationValidation) { + $headers['x-amz-skip-destination-validation'] = $this->skipDestinationValidation ? 'true' : 'false'; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?notification'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setNotificationConfiguration(?NotificationConfiguration $value): self + { + $this->notificationConfiguration = $value; + + return $this; + } + + public function setSkipDestinationValidation(?bool $value): self + { + $this->skipDestinationValidation = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->notificationConfiguration) { + throw new InvalidArgument(sprintf('Missing parameter "NotificationConfiguration" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('NotificationConfiguration')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php b/vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php new file mode 100644 index 000000000..23ce581ef --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutBucketTaggingRequest.php @@ -0,0 +1,221 @@ +bucket = $input['Bucket'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->tagging = isset($input['Tagging']) ? Tagging::create($input['Tagging']) : null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging?: Tagging|array, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getTagging(): ?Tagging + { + return $this->tagging; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '?tagging'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setTagging(?Tagging $value): self + { + $this->tagging = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->tagging) { + throw new InvalidArgument(sprintf('Missing parameter "Tagging" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('Tagging')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/PutObjectAclRequest.php b/vendor/async-aws/s3/src/Input/PutObjectAclRequest.php new file mode 100644 index 000000000..d9022f361 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutObjectAclRequest.php @@ -0,0 +1,497 @@ + [^1]. + * + * For requests made using the Amazon Web Services Command Line Interface (CLI) or Amazon Web Services SDKs, this field + * is calculated automatically. + * + * [^1]: http://www.ietf.org/rfc/rfc1864.txt + * + * @var string|null + */ + private $contentMd5; + + /** + * Indicates the algorithm used to create the checksum for the object when using the SDK. This header will not provide + * any additional functionality if not using the SDK. When sending this header, there must be a corresponding + * `x-amz-checksum` or `x-amz-trailer` header sent. Otherwise, Amazon S3 fails the request with the HTTP status code + * `400 Bad Request`. For more information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * If you provide an individual checksum, Amazon S3 ignores any provided `ChecksumAlgorithm` parameter. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * Allows grantee the read, write, read ACP, and write ACP permissions on the bucket. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantFullControl; + + /** + * Allows grantee to list the objects in the bucket. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantRead; + + /** + * Allows grantee to read the bucket ACL. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantReadAcp; + + /** + * Allows grantee to create new objects in the bucket. + * + * For the bucket and object owners of existing objects, also allows deletions and overwrites of those objects. + * + * @var string|null + */ + private $grantWrite; + + /** + * Allows grantee to write the ACL for the applicable bucket. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantWriteAcp; + + /** + * Key for which the PUT action was initiated. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @required + * + * @var string|null + */ + private $key; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * VersionId used to reference a specific version of the object. + * + * @var string|null + */ + private $versionId; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * AccessControlPolicy?: AccessControlPolicy|array, + * Bucket?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * Key?: string, + * RequestPayer?: RequestPayer::*, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->accessControlPolicy = isset($input['AccessControlPolicy']) ? AccessControlPolicy::create($input['AccessControlPolicy']) : null; + $this->bucket = $input['Bucket'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWrite = $input['GrantWrite'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * AccessControlPolicy?: AccessControlPolicy|array, + * Bucket?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * Key?: string, + * RequestPayer?: RequestPayer::*, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectAclRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getAccessControlPolicy(): ?AccessControlPolicy + { + return $this->accessControlPolicy; + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWrite(): ?string + { + return $this->grantWrite; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWrite) { + $headers['x-amz-grant-write'] = $this->grantWrite; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?acl'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setAccessControlPolicy(?AccessControlPolicy $value): self + { + $this->accessControlPolicy = $value; + + return $this; + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWrite(?string $value): self + { + $this->grantWrite = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null !== $v = $this->accessControlPolicy) { + $node->appendChild($child = $document->createElement('AccessControlPolicy')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/Input/PutObjectRequest.php b/vendor/async-aws/s3/src/Input/PutObjectRequest.php new file mode 100644 index 000000000..b500f7755 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutObjectRequest.php @@ -0,0 +1,1178 @@ +|null + */ + private $body; + + /** + * The bucket name to which the PUT action was initiated. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @required + * + * @var string|null + */ + private $bucket; + + /** + * Can be used to specify caching behavior along the request/reply chain. For more information, see + * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 [^1]. + * + * [^1]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 + * + * @var string|null + */ + private $cacheControl; + + /** + * Specifies presentational information for the object. For more information, see + * https://www.rfc-editor.org/rfc/rfc6266#section-4 [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc6266#section-4 + * + * @var string|null + */ + private $contentDisposition; + + /** + * Specifies what content encodings have been applied to the object and thus what decoding mechanisms must be applied to + * obtain the media-type referenced by the Content-Type header field. For more information, see + * https://www.rfc-editor.org/rfc/rfc9110.html#field.content-encoding [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#field.content-encoding + * + * @var string|null + */ + private $contentEncoding; + + /** + * The language the content is in. + * + * @var string|null + */ + private $contentLanguage; + + /** + * Size of the body in bytes. This parameter is useful when the size of the body cannot be determined automatically. For + * more information, see https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#name-content-length + * + * @var int|null + */ + private $contentLength; + + /** + * The base64-encoded 128-bit MD5 digest of the message (without the headers) according to RFC 1864. This header can be + * used as a message integrity check to verify that the data is the same data that was originally sent. Although it is + * optional, we recommend using the Content-MD5 mechanism as an end-to-end integrity check. For more information about + * REST request authentication, see REST Authentication [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html + * + * @var string|null + */ + private $contentMd5; + + /** + * A standard MIME type describing the format of the contents. For more information, see + * https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc9110.html#name-content-type + * + * @var string|null + */ + private $contentType; + + /** + * Indicates the algorithm used to create the checksum for the object when using the SDK. This header will not provide + * any additional functionality if not using the SDK. When sending this header, there must be a corresponding + * `x-amz-checksum` or `x-amz-trailer` header sent. Otherwise, Amazon S3 fails the request with the HTTP status code + * `400 Bad Request`. For more information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * If you provide an individual checksum, Amazon S3 ignores any provided `ChecksumAlgorithm` parameter. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32 checksum of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32C checksum of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32C; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 160-bit SHA-1 digest of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha1; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 256-bit SHA-256 digest of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha256; + + /** + * The date and time at which the object is no longer cacheable. For more information, see + * https://www.rfc-editor.org/rfc/rfc7234#section-5.3 [^1]. + * + * [^1]: https://www.rfc-editor.org/rfc/rfc7234#section-5.3 + * + * @var \DateTimeImmutable|null + */ + private $expires; + + /** + * Gives the grantee READ, READ_ACP, and WRITE_ACP permissions on the object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantFullControl; + + /** + * Allows grantee to read the object data and its metadata. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantRead; + + /** + * Allows grantee to read the object ACL. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantReadAcp; + + /** + * Allows grantee to write the ACL for the applicable object. + * + * This action is not supported by Amazon S3 on Outposts. + * + * @var string|null + */ + private $grantWriteAcp; + + /** + * Object key for which the PUT action was initiated. + * + * @required + * + * @var string|null + */ + private $key; + + /** + * A map of metadata to store with the object in S3. + * + * @var array|null + */ + private $metadata; + + /** + * The server-side encryption algorithm used when storing this object in Amazon S3 (for example, `AES256`, `aws:kms`, + * `aws:kms:dsse`). + * + * @var ServerSideEncryption::*|null + */ + private $serverSideEncryption; + + /** + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^1] in + * the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * If the bucket is configured as a website, redirects requests for this object to another object in the same bucket or + * to an external URL. Amazon S3 stores the value of this header in the object metadata. For information about object + * metadata, see Object Key and Metadata [^1]. + * + * In the following example, the request header sets the redirect to an object (anotherPage.html) in the same bucket: + * + * `x-amz-website-redirect-location: /anotherPage.html` + * + * In the following example, the request header sets the object redirect to another website: + * + * `x-amz-website-redirect-location: http://www.example.com/` + * + * For more information about website hosting in Amazon S3, see Hosting Websites on Amazon S3 [^2] and How to Configure + * Website Page Redirects [^3]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html + * + * @var string|null + */ + private $websiteRedirectLocation; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm` header. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * If `x-amz-server-side-encryption` has a valid value of `aws:kms` or `aws:kms:dsse`, this header specifies the ID of + * the Key Management Service (KMS) symmetric encryption customer managed key that was used for the object. If you + * specify `x-amz-server-side-encryption:aws:kms` or `x-amz-server-side-encryption:aws:kms:dsse`, but do not provide` + * x-amz-server-side-encryption-aws-kms-key-id`, Amazon S3 uses the Amazon Web Services managed key (`aws/s3`) to + * protect the data. If the KMS key does not exist in the same account that's issuing the command, you must use the full + * ARN and not just the ID. + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Specifies the Amazon Web Services KMS Encryption Context to use for object encryption. The value of this header is a + * base64-encoded UTF-8 string holding JSON with the encryption context key-value pairs. This value is stored as object + * metadata and automatically gets passed on to Amazon Web Services KMS for future `GetObject` or `CopyObject` + * operations on this object. + * + * @var string|null + */ + private $sseKmsEncryptionContext; + + /** + * Specifies whether Amazon S3 should use an S3 Bucket Key for object encryption with server-side encryption using Key + * Management Service (KMS) keys (SSE-KMS). Setting this header to `true` causes Amazon S3 to use an S3 Bucket Key for + * object encryption with SSE-KMS. + * + * Specifying this header with a PUT action doesn’t affect bucket-level settings for S3 Bucket Key. + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The tag-set for the object. The tag-set must be encoded as URL Query parameters. (For example, "Key1=Value1"). + * + * @var string|null + */ + private $tagging; + + /** + * The Object Lock mode that you want to apply to this object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when you want this object's Object Lock to expire. Must be formatted as a timestamp parameter. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether a legal hold will be applied to this object. For more information about S3 Object Lock, see Object + * Lock [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ContentType?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->acl = $input['ACL'] ?? null; + $this->body = $input['Body'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->cacheControl = $input['CacheControl'] ?? null; + $this->contentDisposition = $input['ContentDisposition'] ?? null; + $this->contentEncoding = $input['ContentEncoding'] ?? null; + $this->contentLanguage = $input['ContentLanguage'] ?? null; + $this->contentLength = $input['ContentLength'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->contentType = $input['ContentType'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->expires = !isset($input['Expires']) ? null : ($input['Expires'] instanceof \DateTimeImmutable ? $input['Expires'] : new \DateTimeImmutable($input['Expires'])); + $this->grantFullControl = $input['GrantFullControl'] ?? null; + $this->grantRead = $input['GrantRead'] ?? null; + $this->grantReadAcp = $input['GrantReadACP'] ?? null; + $this->grantWriteAcp = $input['GrantWriteACP'] ?? null; + $this->key = $input['Key'] ?? null; + $this->metadata = $input['Metadata'] ?? null; + $this->serverSideEncryption = $input['ServerSideEncryption'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->websiteRedirectLocation = $input['WebsiteRedirectLocation'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->sseKmsKeyId = $input['SSEKMSKeyId'] ?? null; + $this->sseKmsEncryptionContext = $input['SSEKMSEncryptionContext'] ?? null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->tagging = $input['Tagging'] ?? null; + $this->objectLockMode = $input['ObjectLockMode'] ?? null; + $this->objectLockRetainUntilDate = !isset($input['ObjectLockRetainUntilDate']) ? null : ($input['ObjectLockRetainUntilDate'] instanceof \DateTimeImmutable ? $input['ObjectLockRetainUntilDate'] : new \DateTimeImmutable($input['ObjectLockRetainUntilDate'])); + $this->objectLockLegalHoldStatus = $input['ObjectLockLegalHoldStatus'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * ACL?: ObjectCannedACL::*, + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ContentType?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key?: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectCannedACL::*|null + */ + public function getAcl(): ?string + { + return $this->acl; + } + + /** + * @return string|resource|(callable(int): string)|iterable|null + */ + public function getBody() + { + return $this->body; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + return $this->cacheControl; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getContentDisposition(): ?string + { + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + return $this->contentLanguage; + } + + public function getContentLength(): ?int + { + return $this->contentLength; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getContentType(): ?string + { + return $this->contentType; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getExpires(): ?\DateTimeImmutable + { + return $this->expires; + } + + public function getGrantFullControl(): ?string + { + return $this->grantFullControl; + } + + public function getGrantRead(): ?string + { + return $this->grantRead; + } + + public function getGrantReadAcp(): ?string + { + return $this->grantReadAcp; + } + + public function getGrantWriteAcp(): ?string + { + return $this->grantWriteAcp; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return array + */ + public function getMetadata(): array + { + return $this->metadata ?? []; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + return $this->objectLockRetainUntilDate; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getTagging(): ?string + { + return $this->tagging; + } + + public function getWebsiteRedirectLocation(): ?string + { + return $this->websiteRedirectLocation; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = []; + if (null !== $this->acl) { + if (!ObjectCannedACL::exists($this->acl)) { + throw new InvalidArgument(sprintf('Invalid parameter "ACL" for "%s". The value "%s" is not a valid "ObjectCannedACL".', __CLASS__, $this->acl)); + } + $headers['x-amz-acl'] = $this->acl; + } + if (null !== $this->cacheControl) { + $headers['Cache-Control'] = $this->cacheControl; + } + if (null !== $this->contentDisposition) { + $headers['Content-Disposition'] = $this->contentDisposition; + } + if (null !== $this->contentEncoding) { + $headers['Content-Encoding'] = $this->contentEncoding; + } + if (null !== $this->contentLanguage) { + $headers['Content-Language'] = $this->contentLanguage; + } + if (null !== $this->contentLength) { + $headers['Content-Length'] = (string) $this->contentLength; + } + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->contentType) { + $headers['Content-Type'] = $this->contentType; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->checksumCrc32) { + $headers['x-amz-checksum-crc32'] = $this->checksumCrc32; + } + if (null !== $this->checksumCrc32C) { + $headers['x-amz-checksum-crc32c'] = $this->checksumCrc32C; + } + if (null !== $this->checksumSha1) { + $headers['x-amz-checksum-sha1'] = $this->checksumSha1; + } + if (null !== $this->checksumSha256) { + $headers['x-amz-checksum-sha256'] = $this->checksumSha256; + } + if (null !== $this->expires) { + $headers['Expires'] = $this->expires->setTimezone(new \DateTimeZone('GMT'))->format(\DateTimeInterface::RFC7231); + } + if (null !== $this->grantFullControl) { + $headers['x-amz-grant-full-control'] = $this->grantFullControl; + } + if (null !== $this->grantRead) { + $headers['x-amz-grant-read'] = $this->grantRead; + } + if (null !== $this->grantReadAcp) { + $headers['x-amz-grant-read-acp'] = $this->grantReadAcp; + } + if (null !== $this->grantWriteAcp) { + $headers['x-amz-grant-write-acp'] = $this->grantWriteAcp; + } + if (null !== $this->serverSideEncryption) { + if (!ServerSideEncryption::exists($this->serverSideEncryption)) { + throw new InvalidArgument(sprintf('Invalid parameter "ServerSideEncryption" for "%s". The value "%s" is not a valid "ServerSideEncryption".', __CLASS__, $this->serverSideEncryption)); + } + $headers['x-amz-server-side-encryption'] = $this->serverSideEncryption; + } + if (null !== $this->storageClass) { + if (!StorageClass::exists($this->storageClass)) { + throw new InvalidArgument(sprintf('Invalid parameter "StorageClass" for "%s". The value "%s" is not a valid "StorageClass".', __CLASS__, $this->storageClass)); + } + $headers['x-amz-storage-class'] = $this->storageClass; + } + if (null !== $this->websiteRedirectLocation) { + $headers['x-amz-website-redirect-location'] = $this->websiteRedirectLocation; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->sseKmsKeyId) { + $headers['x-amz-server-side-encryption-aws-kms-key-id'] = $this->sseKmsKeyId; + } + if (null !== $this->sseKmsEncryptionContext) { + $headers['x-amz-server-side-encryption-context'] = $this->sseKmsEncryptionContext; + } + if (null !== $this->bucketKeyEnabled) { + $headers['x-amz-server-side-encryption-bucket-key-enabled'] = $this->bucketKeyEnabled ? 'true' : 'false'; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->tagging) { + $headers['x-amz-tagging'] = $this->tagging; + } + if (null !== $this->objectLockMode) { + if (!ObjectLockMode::exists($this->objectLockMode)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockMode" for "%s". The value "%s" is not a valid "ObjectLockMode".', __CLASS__, $this->objectLockMode)); + } + $headers['x-amz-object-lock-mode'] = $this->objectLockMode; + } + if (null !== $this->objectLockRetainUntilDate) { + $headers['x-amz-object-lock-retain-until-date'] = $this->objectLockRetainUntilDate->format(\DateTimeInterface::ISO8601); + } + if (null !== $this->objectLockLegalHoldStatus) { + if (!ObjectLockLegalHoldStatus::exists($this->objectLockLegalHoldStatus)) { + throw new InvalidArgument(sprintf('Invalid parameter "ObjectLockLegalHoldStatus" for "%s". The value "%s" is not a valid "ObjectLockLegalHoldStatus".', __CLASS__, $this->objectLockLegalHoldStatus)); + } + $headers['x-amz-object-lock-legal-hold'] = $this->objectLockLegalHoldStatus; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->metadata) { + foreach ($this->metadata as $key => $value) { + $headers["x-amz-meta-$key"] = $value; + } + } + + // Prepare query + $query = []; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = $this->body ?? ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param ObjectCannedACL::*|null $value + */ + public function setAcl(?string $value): self + { + $this->acl = $value; + + return $this; + } + + /** + * @param string|resource|(callable(int): string)|iterable|null $value + */ + public function setBody($value): self + { + $this->body = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + public function setBucketKeyEnabled(?bool $value): self + { + $this->bucketKeyEnabled = $value; + + return $this; + } + + public function setCacheControl(?string $value): self + { + $this->cacheControl = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setChecksumCrc32(?string $value): self + { + $this->checksumCrc32 = $value; + + return $this; + } + + public function setChecksumCrc32C(?string $value): self + { + $this->checksumCrc32C = $value; + + return $this; + } + + public function setChecksumSha1(?string $value): self + { + $this->checksumSha1 = $value; + + return $this; + } + + public function setChecksumSha256(?string $value): self + { + $this->checksumSha256 = $value; + + return $this; + } + + public function setContentDisposition(?string $value): self + { + $this->contentDisposition = $value; + + return $this; + } + + public function setContentEncoding(?string $value): self + { + $this->contentEncoding = $value; + + return $this; + } + + public function setContentLanguage(?string $value): self + { + $this->contentLanguage = $value; + + return $this; + } + + public function setContentLength(?int $value): self + { + $this->contentLength = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setContentType(?string $value): self + { + $this->contentType = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setExpires(?\DateTimeImmutable $value): self + { + $this->expires = $value; + + return $this; + } + + public function setGrantFullControl(?string $value): self + { + $this->grantFullControl = $value; + + return $this; + } + + public function setGrantRead(?string $value): self + { + $this->grantRead = $value; + + return $this; + } + + public function setGrantReadAcp(?string $value): self + { + $this->grantReadAcp = $value; + + return $this; + } + + public function setGrantWriteAcp(?string $value): self + { + $this->grantWriteAcp = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param array $value + */ + public function setMetadata(array $value): self + { + $this->metadata = $value; + + return $this; + } + + /** + * @param ObjectLockLegalHoldStatus::*|null $value + */ + public function setObjectLockLegalHoldStatus(?string $value): self + { + $this->objectLockLegalHoldStatus = $value; + + return $this; + } + + /** + * @param ObjectLockMode::*|null $value + */ + public function setObjectLockMode(?string $value): self + { + $this->objectLockMode = $value; + + return $this; + } + + public function setObjectLockRetainUntilDate(?\DateTimeImmutable $value): self + { + $this->objectLockRetainUntilDate = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + /** + * @param ServerSideEncryption::*|null $value + */ + public function setServerSideEncryption(?string $value): self + { + $this->serverSideEncryption = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setSseKmsEncryptionContext(?string $value): self + { + $this->sseKmsEncryptionContext = $value; + + return $this; + } + + public function setSseKmsKeyId(?string $value): self + { + $this->sseKmsKeyId = $value; + + return $this; + } + + /** + * @param StorageClass::*|null $value + */ + public function setStorageClass(?string $value): self + { + $this->storageClass = $value; + + return $this; + } + + public function setTagging(?string $value): self + { + $this->tagging = $value; + + return $this; + } + + public function setWebsiteRedirectLocation(?string $value): self + { + $this->websiteRedirectLocation = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php b/vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php new file mode 100644 index 000000000..ee14771a4 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/PutObjectTaggingRequest.php @@ -0,0 +1,318 @@ +bucket = $input['Bucket'] ?? null; + $this->key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->tagging = isset($input['Tagging']) ? Tagging::create($input['Tagging']) : null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Bucket?: string, + * Key?: string, + * VersionId?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging?: Tagging|array, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|PutObjectTaggingRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getTagging(): ?Tagging + { + return $this->tagging; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = ['content-type' => 'application/xml']; + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + + // Prepare query + $query = []; + if (null !== $this->versionId) { + $query['versionId'] = $this->versionId; + } + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])) . '?tagging'; + + // Prepare Body + + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = false; + $this->requestBody($document, $document); + $body = $document->hasChildNodes() ? $document->saveXML() : ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setTagging(?Tagging $value): self + { + $this->tagging = $value; + + return $this; + } + + public function setVersionId(?string $value): self + { + $this->versionId = $value; + + return $this; + } + + private function requestBody(\DOMNode $node, \DOMDocument $document): void + { + if (null === $v = $this->tagging) { + throw new InvalidArgument(sprintf('Missing parameter "Tagging" for "%s". The value cannot be null.', __CLASS__)); + } + + $node->appendChild($child = $document->createElement('Tagging')); + $child->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/'); + $v->requestBody($child, $document); + } +} diff --git a/vendor/async-aws/s3/src/Input/UploadPartRequest.php b/vendor/async-aws/s3/src/Input/UploadPartRequest.php new file mode 100644 index 000000000..7527d2181 --- /dev/null +++ b/vendor/async-aws/s3/src/Input/UploadPartRequest.php @@ -0,0 +1,557 @@ +|null + */ + private $body; + + /** + * The name of the bucket to which the multipart upload was initiated. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @required + * + * @var string|null + */ + private $bucket; + + /** + * Size of the body in bytes. This parameter is useful when the size of the body cannot be determined automatically. + * + * @var int|null + */ + private $contentLength; + + /** + * The base64-encoded 128-bit MD5 digest of the part data. This parameter is auto-populated when using the command from + * the CLI. This parameter is required if object lock parameters are specified. + * + * @var string|null + */ + private $contentMd5; + + /** + * Indicates the algorithm used to create the checksum for the object when using the SDK. This header will not provide + * any additional functionality if not using the SDK. When sending this header, there must be a corresponding + * `x-amz-checksum` or `x-amz-trailer` header sent. Otherwise, Amazon S3 fails the request with the HTTP status code + * `400 Bad Request`. For more information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * If you provide an individual checksum, Amazon S3 ignores any provided `ChecksumAlgorithm` parameter. + * + * This checksum algorithm must be the same for all parts and it match the checksum value supplied in the + * `CreateMultipartUpload` request. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32 checksum of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 32-bit CRC32C checksum of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumCrc32C; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 160-bit SHA-1 digest of the object. For more information, + * see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha1; + + /** + * This header can be used as a data integrity check to verify that the data received is the same data that was + * originally sent. This header specifies the base64-encoded, 256-bit SHA-256 digest of the object. For more + * information, see Checking object integrity [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html + * + * @var string|null + */ + private $checksumSha256; + + /** + * Object key for which the multipart upload was initiated. + * + * @required + * + * @var string|null + */ + private $key; + + /** + * Part number of part being uploaded. This is a positive integer between 1 and 10,000. + * + * @required + * + * @var int|null + */ + private $partNumber; + + /** + * Upload ID identifying the multipart upload whose part is being uploaded. + * + * @required + * + * @var string|null + */ + private $uploadId; + + /** + * Specifies the algorithm to use to when encrypting the object (for example, AES256). + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * Specifies the customer-provided encryption key for Amazon S3 to use in encrypting data. This value is used to store + * the object and then it is discarded; Amazon S3 does not store the encryption key. The key must be appropriate for use + * with the algorithm specified in the `x-amz-server-side-encryption-customer-algorithm header`. This must be the same + * encryption key specified in the initiate multipart upload request. + * + * @var string|null + */ + private $sseCustomerKey; + + /** + * Specifies the 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a + * message integrity check to ensure that the encryption key was transmitted without error. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * @var RequestPayer::*|null + */ + private $requestPayer; + + /** + * The account ID of the expected bucket owner. If the bucket is owned by a different account, the request fails with + * the HTTP status code `403 Forbidden` (access denied). + * + * @var string|null + */ + private $expectedBucketOwner; + + /** + * @param array{ + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Key?: string, + * PartNumber?: int, + * UploadId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * } $input + */ + public function __construct(array $input = []) + { + $this->body = $input['Body'] ?? null; + $this->bucket = $input['Bucket'] ?? null; + $this->contentLength = $input['ContentLength'] ?? null; + $this->contentMd5 = $input['ContentMD5'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->key = $input['Key'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + $this->uploadId = $input['UploadId'] ?? null; + $this->sseCustomerAlgorithm = $input['SSECustomerAlgorithm'] ?? null; + $this->sseCustomerKey = $input['SSECustomerKey'] ?? null; + $this->sseCustomerKeyMd5 = $input['SSECustomerKeyMD5'] ?? null; + $this->requestPayer = $input['RequestPayer'] ?? null; + $this->expectedBucketOwner = $input['ExpectedBucketOwner'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Key?: string, + * PartNumber?: int, + * UploadId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|UploadPartRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return string|resource|(callable(int): string)|iterable|null + */ + public function getBody() + { + return $this->body; + } + + public function getBucket(): ?string + { + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getContentLength(): ?int + { + return $this->contentLength; + } + + public function getContentMd5(): ?string + { + return $this->contentMd5; + } + + public function getExpectedBucketOwner(): ?string + { + return $this->expectedBucketOwner; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + /** + * @return RequestPayer::*|null + */ + public function getRequestPayer(): ?string + { + return $this->requestPayer; + } + + public function getSseCustomerAlgorithm(): ?string + { + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKey(): ?string + { + return $this->sseCustomerKey; + } + + public function getSseCustomerKeyMd5(): ?string + { + return $this->sseCustomerKeyMd5; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = []; + if (null !== $this->contentLength) { + $headers['Content-Length'] = (string) $this->contentLength; + } + if (null !== $this->contentMd5) { + $headers['Content-MD5'] = $this->contentMd5; + } + if (null !== $this->checksumAlgorithm) { + if (!ChecksumAlgorithm::exists($this->checksumAlgorithm)) { + throw new InvalidArgument(sprintf('Invalid parameter "ChecksumAlgorithm" for "%s". The value "%s" is not a valid "ChecksumAlgorithm".', __CLASS__, $this->checksumAlgorithm)); + } + $headers['x-amz-sdk-checksum-algorithm'] = $this->checksumAlgorithm; + } + if (null !== $this->checksumCrc32) { + $headers['x-amz-checksum-crc32'] = $this->checksumCrc32; + } + if (null !== $this->checksumCrc32C) { + $headers['x-amz-checksum-crc32c'] = $this->checksumCrc32C; + } + if (null !== $this->checksumSha1) { + $headers['x-amz-checksum-sha1'] = $this->checksumSha1; + } + if (null !== $this->checksumSha256) { + $headers['x-amz-checksum-sha256'] = $this->checksumSha256; + } + if (null !== $this->sseCustomerAlgorithm) { + $headers['x-amz-server-side-encryption-customer-algorithm'] = $this->sseCustomerAlgorithm; + } + if (null !== $this->sseCustomerKey) { + $headers['x-amz-server-side-encryption-customer-key'] = $this->sseCustomerKey; + } + if (null !== $this->sseCustomerKeyMd5) { + $headers['x-amz-server-side-encryption-customer-key-MD5'] = $this->sseCustomerKeyMd5; + } + if (null !== $this->requestPayer) { + if (!RequestPayer::exists($this->requestPayer)) { + throw new InvalidArgument(sprintf('Invalid parameter "RequestPayer" for "%s". The value "%s" is not a valid "RequestPayer".', __CLASS__, $this->requestPayer)); + } + $headers['x-amz-request-payer'] = $this->requestPayer; + } + if (null !== $this->expectedBucketOwner) { + $headers['x-amz-expected-bucket-owner'] = $this->expectedBucketOwner; + } + + // Prepare query + $query = []; + if (null === $v = $this->partNumber) { + throw new InvalidArgument(sprintf('Missing parameter "PartNumber" for "%s". The value cannot be null.', __CLASS__)); + } + $query['partNumber'] = (string) $v; + if (null === $v = $this->uploadId) { + throw new InvalidArgument(sprintf('Missing parameter "UploadId" for "%s". The value cannot be null.', __CLASS__)); + } + $query['uploadId'] = $v; + + // Prepare URI + $uri = []; + if (null === $v = $this->bucket) { + throw new InvalidArgument(sprintf('Missing parameter "Bucket" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Bucket'] = $v; + if (null === $v = $this->key) { + throw new InvalidArgument(sprintf('Missing parameter "Key" for "%s". The value cannot be null.', __CLASS__)); + } + $uri['Key'] = $v; + $uriString = '/' . rawurlencode($uri['Bucket']) . '/' . str_replace('%2F', '/', rawurlencode($uri['Key'])); + + // Prepare Body + $body = $this->body ?? ''; + + // Return the Request + return new Request('PUT', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param string|resource|(callable(int): string)|iterable|null $value + */ + public function setBody($value): self + { + $this->body = $value; + + return $this; + } + + public function setBucket(?string $value): self + { + $this->bucket = $value; + + return $this; + } + + /** + * @param ChecksumAlgorithm::*|null $value + */ + public function setChecksumAlgorithm(?string $value): self + { + $this->checksumAlgorithm = $value; + + return $this; + } + + public function setChecksumCrc32(?string $value): self + { + $this->checksumCrc32 = $value; + + return $this; + } + + public function setChecksumCrc32C(?string $value): self + { + $this->checksumCrc32C = $value; + + return $this; + } + + public function setChecksumSha1(?string $value): self + { + $this->checksumSha1 = $value; + + return $this; + } + + public function setChecksumSha256(?string $value): self + { + $this->checksumSha256 = $value; + + return $this; + } + + public function setContentLength(?int $value): self + { + $this->contentLength = $value; + + return $this; + } + + public function setContentMd5(?string $value): self + { + $this->contentMd5 = $value; + + return $this; + } + + public function setExpectedBucketOwner(?string $value): self + { + $this->expectedBucketOwner = $value; + + return $this; + } + + public function setKey(?string $value): self + { + $this->key = $value; + + return $this; + } + + public function setPartNumber(?int $value): self + { + $this->partNumber = $value; + + return $this; + } + + /** + * @param RequestPayer::*|null $value + */ + public function setRequestPayer(?string $value): self + { + $this->requestPayer = $value; + + return $this; + } + + public function setSseCustomerAlgorithm(?string $value): self + { + $this->sseCustomerAlgorithm = $value; + + return $this; + } + + public function setSseCustomerKey(?string $value): self + { + $this->sseCustomerKey = $value; + + return $this; + } + + public function setSseCustomerKeyMd5(?string $value): self + { + $this->sseCustomerKeyMd5 = $value; + + return $this; + } + + public function setUploadId(?string $value): self + { + $this->uploadId = $value; + + return $this; + } +} diff --git a/vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php b/vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php new file mode 100644 index 000000000..efe26b296 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/AbortMultipartUploadOutput.php @@ -0,0 +1,32 @@ +initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/BucketExistsWaiter.php b/vendor/async-aws/s3/src/Result/BucketExistsWaiter.php new file mode 100644 index 000000000..7da4bc784 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/BucketExistsWaiter.php @@ -0,0 +1,49 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (301 === $response->getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (403 === $response->getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (404 === $response->getStatusCode()) { + return self::STATE_PENDING; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadBucketRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->bucketExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php b/vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php new file mode 100644 index 000000000..a0d16cb56 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/BucketNotExistsWaiter.php @@ -0,0 +1,37 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadBucketRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->bucketNotExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php b/vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php new file mode 100644 index 000000000..9299b067a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CompleteMultipartUploadOutput.php @@ -0,0 +1,273 @@ +initialize(); + + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + public function getKey(): ?string + { + $this->initialize(); + + return $this->key; + } + + public function getLocation(): ?string + { + $this->initialize(); + + return $this->location; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->location = ($v = $data->Location) ? (string) $v : null; + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->key = ($v = $data->Key) ? (string) $v : null; + $this->etag = ($v = $data->ETag) ? (string) $v : null; + $this->checksumCrc32 = ($v = $data->ChecksumCRC32) ? (string) $v : null; + $this->checksumCrc32C = ($v = $data->ChecksumCRC32C) ? (string) $v : null; + $this->checksumSha1 = ($v = $data->ChecksumSHA1) ? (string) $v : null; + $this->checksumSha256 = ($v = $data->ChecksumSHA256) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/s3/src/Result/CopyObjectOutput.php b/vendor/async-aws/s3/src/Result/CopyObjectOutput.php new file mode 100644 index 000000000..e518f272b --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CopyObjectOutput.php @@ -0,0 +1,202 @@ +initialize(); + + return $this->bucketKeyEnabled; + } + + public function getCopyObjectResult(): ?CopyObjectResult + { + $this->initialize(); + + return $this->copyObjectResult; + } + + public function getCopySourceVersionId(): ?string + { + $this->initialize(); + + return $this->copySourceVersionId; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + $this->initialize(); + + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->copySourceVersionId = $headers['x-amz-copy-source-version-id'][0] ?? null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->sseKmsEncryptionContext = $headers['x-amz-server-side-encryption-context'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->copyObjectResult = new CopyObjectResult([ + 'ETag' => ($v = $data->ETag) ? (string) $v : null, + 'LastModified' => ($v = $data->LastModified) ? new \DateTimeImmutable((string) $v) : null, + 'ChecksumCRC32' => ($v = $data->ChecksumCRC32) ? (string) $v : null, + 'ChecksumCRC32C' => ($v = $data->ChecksumCRC32C) ? (string) $v : null, + 'ChecksumSHA1' => ($v = $data->ChecksumSHA1) ? (string) $v : null, + 'ChecksumSHA256' => ($v = $data->ChecksumSHA256) ? (string) $v : null, + ]); + } +} diff --git a/vendor/async-aws/s3/src/Result/CreateBucketOutput.php b/vendor/async-aws/s3/src/Result/CreateBucketOutput.php new file mode 100644 index 000000000..441d7a2bf --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CreateBucketOutput.php @@ -0,0 +1,30 @@ +initialize(); + + return $this->location; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->location = $headers['location'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php b/vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php new file mode 100644 index 000000000..dbac5891a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/CreateMultipartUploadOutput.php @@ -0,0 +1,251 @@ +initialize(); + + return $this->abortDate; + } + + public function getAbortRuleId(): ?string + { + $this->initialize(); + + return $this->abortRuleId; + } + + public function getBucket(): ?string + { + $this->initialize(); + + return $this->bucket; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + $this->initialize(); + + return $this->checksumAlgorithm; + } + + public function getKey(): ?string + { + $this->initialize(); + + return $this->key; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + $this->initialize(); + + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getUploadId(): ?string + { + $this->initialize(); + + return $this->uploadId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->abortDate = isset($headers['x-amz-abort-date'][0]) ? new \DateTimeImmutable($headers['x-amz-abort-date'][0]) : null; + $this->abortRuleId = $headers['x-amz-abort-rule-id'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->sseKmsEncryptionContext = $headers['x-amz-server-side-encryption-context'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + $this->checksumAlgorithm = $headers['x-amz-checksum-algorithm'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->key = ($v = $data->Key) ? (string) $v : null; + $this->uploadId = ($v = $data->UploadId) ? (string) $v : null; + } +} diff --git a/vendor/async-aws/s3/src/Result/DeleteObjectOutput.php b/vendor/async-aws/s3/src/Result/DeleteObjectOutput.php new file mode 100644 index 000000000..f689fc1bf --- /dev/null +++ b/vendor/async-aws/s3/src/Result/DeleteObjectOutput.php @@ -0,0 +1,62 @@ +initialize(); + + return $this->deleteMarker; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->deleteMarker = isset($headers['x-amz-delete-marker'][0]) ? filter_var($headers['x-amz-delete-marker'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php b/vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php new file mode 100644 index 000000000..9b115a2a5 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/DeleteObjectTaggingOutput.php @@ -0,0 +1,30 @@ +initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php b/vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php new file mode 100644 index 000000000..a5988d4da --- /dev/null +++ b/vendor/async-aws/s3/src/Result/DeleteObjectsOutput.php @@ -0,0 +1,109 @@ +initialize(); + + return $this->deleted; + } + + /** + * @return Error[] + */ + public function getErrors(): array + { + $this->initialize(); + + return $this->errors; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->deleted = !$data->Deleted ? [] : $this->populateResultDeletedObjects($data->Deleted); + $this->errors = !$data->Error ? [] : $this->populateResultErrors($data->Error); + } + + /** + * @return DeletedObject[] + */ + private function populateResultDeletedObjects(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new DeletedObject([ + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'VersionId' => ($v = $item->VersionId) ? (string) $v : null, + 'DeleteMarker' => ($v = $item->DeleteMarker) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, + 'DeleteMarkerVersionId' => ($v = $item->DeleteMarkerVersionId) ? (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return Error[] + */ + private function populateResultErrors(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new Error([ + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'VersionId' => ($v = $item->VersionId) ? (string) $v : null, + 'Code' => ($v = $item->Code) ? (string) $v : null, + 'Message' => ($v = $item->Message) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php b/vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php new file mode 100644 index 000000000..0c0f02ab6 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetBucketCorsOutput.php @@ -0,0 +1,118 @@ +initialize(); + + return $this->corsRules; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $this->corsRules = !$data->CORSRule ? [] : $this->populateResultCORSRules($data->CORSRule); + } + + /** + * @return string[] + */ + private function populateResultAllowedHeaders(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return string[] + */ + private function populateResultAllowedMethods(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return string[] + */ + private function populateResultAllowedOrigins(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return CORSRule[] + */ + private function populateResultCORSRules(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new CORSRule([ + 'ID' => ($v = $item->ID) ? (string) $v : null, + 'AllowedHeaders' => !$item->AllowedHeader ? null : $this->populateResultAllowedHeaders($item->AllowedHeader), + 'AllowedMethods' => $this->populateResultAllowedMethods($item->AllowedMethod), + 'AllowedOrigins' => $this->populateResultAllowedOrigins($item->AllowedOrigin), + 'ExposeHeaders' => !$item->ExposeHeader ? null : $this->populateResultExposeHeaders($item->ExposeHeader), + 'MaxAgeSeconds' => ($v = $item->MaxAgeSeconds) ? (int) (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return string[] + */ + private function populateResultExposeHeaders(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php b/vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php new file mode 100644 index 000000000..ab48d8a70 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetBucketEncryptionOutput.php @@ -0,0 +1,51 @@ +initialize(); + + return $this->serverSideEncryptionConfiguration; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $this->serverSideEncryptionConfiguration = new ServerSideEncryptionConfiguration([ + 'Rules' => $this->populateResultServerSideEncryptionRules($data->Rule), + ]); + } + + /** + * @return ServerSideEncryptionRule[] + */ + private function populateResultServerSideEncryptionRules(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new ServerSideEncryptionRule([ + 'ApplyServerSideEncryptionByDefault' => !$item->ApplyServerSideEncryptionByDefault ? null : new ServerSideEncryptionByDefault([ + 'SSEAlgorithm' => (string) $item->ApplyServerSideEncryptionByDefault->SSEAlgorithm, + 'KMSMasterKeyID' => ($v = $item->ApplyServerSideEncryptionByDefault->KMSMasterKeyID) ? (string) $v : null, + ]), + 'BucketKeyEnabled' => ($v = $item->BucketKeyEnabled) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetObjectAclOutput.php b/vendor/async-aws/s3/src/Result/GetObjectAclOutput.php new file mode 100644 index 000000000..2d58c6e4a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetObjectAclOutput.php @@ -0,0 +1,95 @@ +initialize(); + + return $this->grants; + } + + public function getOwner(): ?Owner + { + $this->initialize(); + + return $this->owner; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->owner = !$data->Owner ? null : new Owner([ + 'DisplayName' => ($v = $data->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $data->Owner->ID) ? (string) $v : null, + ]); + $this->grants = !$data->AccessControlList ? [] : $this->populateResultGrants($data->AccessControlList); + } + + /** + * @return Grant[] + */ + private function populateResultGrants(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml->Grant as $item) { + $items[] = new Grant([ + 'Grantee' => !$item->Grantee ? null : new Grantee([ + 'DisplayName' => ($v = $item->Grantee->DisplayName) ? (string) $v : null, + 'EmailAddress' => ($v = $item->Grantee->EmailAddress) ? (string) $v : null, + 'ID' => ($v = $item->Grantee->ID) ? (string) $v : null, + 'Type' => (string) ($item->Grantee->attributes('xsi', true)['type'][0] ?? null), + 'URI' => ($v = $item->Grantee->URI) ? (string) $v : null, + ]), + 'Permission' => ($v = $item->Permission) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/GetObjectOutput.php b/vendor/async-aws/s3/src/Result/GetObjectOutput.php new file mode 100644 index 000000000..f4251efc3 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetObjectOutput.php @@ -0,0 +1,621 @@ + + */ + private $metadata; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header confirming the encryption algorithm used. + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header to provide round-trip message integrity verification of the customer-provided encryption key. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * If present, specifies the ID of the Key Management Service (KMS) symmetric encryption customer managed key that was + * used for the object. + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Indicates whether the object uses an S3 Bucket Key for server-side encryption with Key Management Service (KMS) keys + * (SSE-KMS). + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * Provides storage class information of the object. Amazon S3 returns this header for all objects except for S3 + * Standard storage class objects. + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * Amazon S3 can return this if your request involves a bucket that is either a source or destination in a replication + * rule. + * + * @var ReplicationStatus::*|null + */ + private $replicationStatus; + + /** + * The count of parts this object has. This value is only returned if you specify `partNumber` in your request and the + * object was uploaded as a multipart upload. + * + * @var int|null + */ + private $partsCount; + + /** + * The number of tags, if any, on the object. + * + * @var int|null + */ + private $tagCount; + + /** + * The Object Lock mode currently in place for this object. + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when this object's Object Lock will expire. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Indicates whether this object has an active legal hold. This field is only returned if you have permission to view an + * object's legal hold status. + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + public function getAcceptRanges(): ?string + { + $this->initialize(); + + return $this->acceptRanges; + } + + public function getBody(): ResultStream + { + $this->initialize(); + + return $this->body; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + $this->initialize(); + + return $this->cacheControl; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getContentDisposition(): ?string + { + $this->initialize(); + + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + $this->initialize(); + + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + $this->initialize(); + + return $this->contentLanguage; + } + + public function getContentLength(): ?int + { + $this->initialize(); + + return $this->contentLength; + } + + public function getContentRange(): ?string + { + $this->initialize(); + + return $this->contentRange; + } + + public function getContentType(): ?string + { + $this->initialize(); + + return $this->contentType; + } + + public function getDeleteMarker(): ?bool + { + $this->initialize(); + + return $this->deleteMarker; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + public function getExpires(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->expires; + } + + public function getLastModified(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->lastModified; + } + + /** + * @return array + */ + public function getMetadata(): array + { + $this->initialize(); + + return $this->metadata; + } + + public function getMissingMeta(): ?int + { + $this->initialize(); + + return $this->missingMeta; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + $this->initialize(); + + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + $this->initialize(); + + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->objectLockRetainUntilDate; + } + + public function getPartsCount(): ?int + { + $this->initialize(); + + return $this->partsCount; + } + + /** + * @return ReplicationStatus::*|null + */ + public function getReplicationStatus(): ?string + { + $this->initialize(); + + return $this->replicationStatus; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getRestore(): ?string + { + $this->initialize(); + + return $this->restore; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + $this->initialize(); + + return $this->storageClass; + } + + public function getTagCount(): ?int + { + $this->initialize(); + + return $this->tagCount; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + public function getWebsiteRedirectLocation(): ?string + { + $this->initialize(); + + return $this->websiteRedirectLocation; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->deleteMarker = isset($headers['x-amz-delete-marker'][0]) ? filter_var($headers['x-amz-delete-marker'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->acceptRanges = $headers['accept-ranges'][0] ?? null; + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->restore = $headers['x-amz-restore'][0] ?? null; + $this->lastModified = isset($headers['last-modified'][0]) ? new \DateTimeImmutable($headers['last-modified'][0]) : null; + $this->contentLength = isset($headers['content-length'][0]) ? (int) $headers['content-length'][0] : null; + $this->etag = $headers['etag'][0] ?? null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->missingMeta = isset($headers['x-amz-missing-meta'][0]) ? (int) $headers['x-amz-missing-meta'][0] : null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->cacheControl = $headers['cache-control'][0] ?? null; + $this->contentDisposition = $headers['content-disposition'][0] ?? null; + $this->contentEncoding = $headers['content-encoding'][0] ?? null; + $this->contentLanguage = $headers['content-language'][0] ?? null; + $this->contentRange = $headers['content-range'][0] ?? null; + $this->contentType = $headers['content-type'][0] ?? null; + $this->expires = isset($headers['expires'][0]) ? new \DateTimeImmutable($headers['expires'][0]) : null; + $this->websiteRedirectLocation = $headers['x-amz-website-redirect-location'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->storageClass = $headers['x-amz-storage-class'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + $this->replicationStatus = $headers['x-amz-replication-status'][0] ?? null; + $this->partsCount = isset($headers['x-amz-mp-parts-count'][0]) ? (int) $headers['x-amz-mp-parts-count'][0] : null; + $this->tagCount = isset($headers['x-amz-tagging-count'][0]) ? (int) $headers['x-amz-tagging-count'][0] : null; + $this->objectLockMode = $headers['x-amz-object-lock-mode'][0] ?? null; + $this->objectLockRetainUntilDate = isset($headers['x-amz-object-lock-retain-until-date'][0]) ? new \DateTimeImmutable($headers['x-amz-object-lock-retain-until-date'][0]) : null; + $this->objectLockLegalHoldStatus = $headers['x-amz-object-lock-legal-hold'][0] ?? null; + + $this->metadata = []; + foreach ($headers as $name => $value) { + if ('x-amz-meta-' === substr($name, 0, 11)) { + $this->metadata[substr($name, 11)] = $value[0]; + } + } + + $this->body = $response->toStream(); + } +} diff --git a/vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php b/vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php new file mode 100644 index 000000000..d868b8aaf --- /dev/null +++ b/vendor/async-aws/s3/src/Result/GetObjectTaggingOutput.php @@ -0,0 +1,67 @@ +initialize(); + + return $this->tagSet; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->tagSet = $this->populateResultTagSet($data->TagSet); + } + + /** + * @return Tag[] + */ + private function populateResultTagSet(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml->Tag as $item) { + $items[] = new Tag([ + 'Key' => (string) $item->Key, + 'Value' => (string) $item->Value, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/HeadObjectOutput.php b/vendor/async-aws/s3/src/Result/HeadObjectOutput.php new file mode 100644 index 000000000..7e2f78f56 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/HeadObjectOutput.php @@ -0,0 +1,641 @@ + + */ + private $metadata; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header confirming the encryption algorithm used. + * + * @var string|null + */ + private $sseCustomerAlgorithm; + + /** + * If server-side encryption with a customer-provided encryption key was requested, the response will include this + * header to provide round-trip message integrity verification of the customer-provided encryption key. + * + * @var string|null + */ + private $sseCustomerKeyMd5; + + /** + * If present, specifies the ID of the Key Management Service (KMS) symmetric encryption customer managed key that was + * used for the object. + * + * @var string|null + */ + private $sseKmsKeyId; + + /** + * Indicates whether the object uses an S3 Bucket Key for server-side encryption with Key Management Service (KMS) keys + * (SSE-KMS). + * + * @var bool|null + */ + private $bucketKeyEnabled; + + /** + * Provides storage class information of the object. Amazon S3 returns this header for all objects except for S3 + * Standard storage class objects. + * + * For more information, see Storage Classes [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * Amazon S3 can return this header if your request involves a bucket that is either a source or a destination in a + * replication rule. + * + * In replication, you have a source bucket on which you configure replication and destination bucket or buckets where + * Amazon S3 stores object replicas. When you request an object (`GetObject`) or object metadata (`HeadObject`) from + * these buckets, Amazon S3 will return the `x-amz-replication-status` header in the response as follows: + * + * - **If requesting an object from the source bucket**, Amazon S3 will return the `x-amz-replication-status` header if + * the object in your request is eligible for replication. + * + * For example, suppose that in your replication configuration, you specify object prefix `TaxDocs` requesting Amazon + * S3 to replicate objects with key prefix `TaxDocs`. Any objects you upload with this key name prefix, for example + * `TaxDocs/document1.pdf`, are eligible for replication. For any object request with this key name prefix, Amazon S3 + * will return the `x-amz-replication-status` header with value PENDING, COMPLETED or FAILED indicating object + * replication status. + * - **If requesting an object from a destination bucket**, Amazon S3 will return the `x-amz-replication-status` header + * with value REPLICA if the object in your request is a replica that Amazon S3 created and there is no replica + * modification replication in progress. + * - **When replicating objects to multiple destination buckets**, the `x-amz-replication-status` header acts + * differently. The header of the source object will only return a value of COMPLETED when replication is successful + * to all destinations. The header will remain at value PENDING until replication has completed for all destinations. + * If one or more destinations fails replication the header will return FAILED. + * + * For more information, see Replication [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html + * + * @var ReplicationStatus::*|null + */ + private $replicationStatus; + + /** + * The count of parts this object has. This value is only returned if you specify `partNumber` in your request and the + * object was uploaded as a multipart upload. + * + * @var int|null + */ + private $partsCount; + + /** + * The Object Lock mode, if any, that's in effect for this object. This header is only returned if the requester has the + * `s3:GetObjectRetention` permission. For more information about S3 Object Lock, see Object Lock [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html + * + * @var ObjectLockMode::*|null + */ + private $objectLockMode; + + /** + * The date and time when the Object Lock retention period expires. This header is only returned if the requester has + * the `s3:GetObjectRetention` permission. + * + * @var \DateTimeImmutable|null + */ + private $objectLockRetainUntilDate; + + /** + * Specifies whether a legal hold is in effect for this object. This header is only returned if the requester has the + * `s3:GetObjectLegalHold` permission. This header is not returned if the specified version of this object has never had + * a legal hold applied. For more information about S3 Object Lock, see Object Lock [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html + * + * @var ObjectLockLegalHoldStatus::*|null + */ + private $objectLockLegalHoldStatus; + + public function getAcceptRanges(): ?string + { + $this->initialize(); + + return $this->acceptRanges; + } + + /** + * @return ArchiveStatus::*|null + */ + public function getArchiveStatus(): ?string + { + $this->initialize(); + + return $this->archiveStatus; + } + + public function getBucketKeyEnabled(): ?bool + { + $this->initialize(); + + return $this->bucketKeyEnabled; + } + + public function getCacheControl(): ?string + { + $this->initialize(); + + return $this->cacheControl; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getContentDisposition(): ?string + { + $this->initialize(); + + return $this->contentDisposition; + } + + public function getContentEncoding(): ?string + { + $this->initialize(); + + return $this->contentEncoding; + } + + public function getContentLanguage(): ?string + { + $this->initialize(); + + return $this->contentLanguage; + } + + public function getContentLength(): ?int + { + $this->initialize(); + + return $this->contentLength; + } + + public function getContentType(): ?string + { + $this->initialize(); + + return $this->contentType; + } + + public function getDeleteMarker(): ?bool + { + $this->initialize(); + + return $this->deleteMarker; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + public function getExpires(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->expires; + } + + public function getLastModified(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->lastModified; + } + + /** + * @return array + */ + public function getMetadata(): array + { + $this->initialize(); + + return $this->metadata; + } + + public function getMissingMeta(): ?int + { + $this->initialize(); + + return $this->missingMeta; + } + + /** + * @return ObjectLockLegalHoldStatus::*|null + */ + public function getObjectLockLegalHoldStatus(): ?string + { + $this->initialize(); + + return $this->objectLockLegalHoldStatus; + } + + /** + * @return ObjectLockMode::*|null + */ + public function getObjectLockMode(): ?string + { + $this->initialize(); + + return $this->objectLockMode; + } + + public function getObjectLockRetainUntilDate(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->objectLockRetainUntilDate; + } + + public function getPartsCount(): ?int + { + $this->initialize(); + + return $this->partsCount; + } + + /** + * @return ReplicationStatus::*|null + */ + public function getReplicationStatus(): ?string + { + $this->initialize(); + + return $this->replicationStatus; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getRestore(): ?string + { + $this->initialize(); + + return $this->restore; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + $this->initialize(); + + return $this->storageClass; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + public function getWebsiteRedirectLocation(): ?string + { + $this->initialize(); + + return $this->websiteRedirectLocation; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->deleteMarker = isset($headers['x-amz-delete-marker'][0]) ? filter_var($headers['x-amz-delete-marker'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->acceptRanges = $headers['accept-ranges'][0] ?? null; + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->restore = $headers['x-amz-restore'][0] ?? null; + $this->archiveStatus = $headers['x-amz-archive-status'][0] ?? null; + $this->lastModified = isset($headers['last-modified'][0]) ? new \DateTimeImmutable($headers['last-modified'][0]) : null; + $this->contentLength = isset($headers['content-length'][0]) ? (int) $headers['content-length'][0] : null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->etag = $headers['etag'][0] ?? null; + $this->missingMeta = isset($headers['x-amz-missing-meta'][0]) ? (int) $headers['x-amz-missing-meta'][0] : null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->cacheControl = $headers['cache-control'][0] ?? null; + $this->contentDisposition = $headers['content-disposition'][0] ?? null; + $this->contentEncoding = $headers['content-encoding'][0] ?? null; + $this->contentLanguage = $headers['content-language'][0] ?? null; + $this->contentType = $headers['content-type'][0] ?? null; + $this->expires = isset($headers['expires'][0]) ? new \DateTimeImmutable($headers['expires'][0]) : null; + $this->websiteRedirectLocation = $headers['x-amz-website-redirect-location'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->storageClass = $headers['x-amz-storage-class'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + $this->replicationStatus = $headers['x-amz-replication-status'][0] ?? null; + $this->partsCount = isset($headers['x-amz-mp-parts-count'][0]) ? (int) $headers['x-amz-mp-parts-count'][0] : null; + $this->objectLockMode = $headers['x-amz-object-lock-mode'][0] ?? null; + $this->objectLockRetainUntilDate = isset($headers['x-amz-object-lock-retain-until-date'][0]) ? new \DateTimeImmutable($headers['x-amz-object-lock-retain-until-date'][0]) : null; + $this->objectLockLegalHoldStatus = $headers['x-amz-object-lock-legal-hold'][0] ?? null; + + $this->metadata = []; + foreach ($headers as $name => $value) { + if ('x-amz-meta-' === substr($name, 0, 11)) { + $this->metadata[substr($name, 11)] = $value[0]; + } + } + } +} diff --git a/vendor/async-aws/s3/src/Result/ListBucketsOutput.php b/vendor/async-aws/s3/src/Result/ListBucketsOutput.php new file mode 100644 index 000000000..a9126636d --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListBucketsOutput.php @@ -0,0 +1,81 @@ + + */ +class ListBucketsOutput extends Result implements \IteratorAggregate +{ + /** + * The list of buckets owned by the requester. + * + * @var Bucket[] + */ + private $buckets; + + /** + * The owner of the buckets listed. + * + * @var Owner|null + */ + private $owner; + + /** + * @return iterable + */ + public function getBuckets(): iterable + { + $this->initialize(); + + return $this->buckets; + } + + /** + * Iterates over Buckets. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + yield from $this->getBuckets(); + } + + public function getOwner(): ?Owner + { + $this->initialize(); + + return $this->owner; + } + + protected function populateResult(Response $response): void + { + $data = new \SimpleXMLElement($response->getContent()); + $this->buckets = !$data->Buckets ? [] : $this->populateResultBuckets($data->Buckets); + $this->owner = !$data->Owner ? null : new Owner([ + 'DisplayName' => ($v = $data->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $data->Owner->ID) ? (string) $v : null, + ]); + } + + /** + * @return Bucket[] + */ + private function populateResultBuckets(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml->Bucket as $item) { + $items[] = new Bucket([ + 'Name' => ($v = $item->Name) ? (string) $v : null, + 'CreationDate' => ($v = $item->CreationDate) ? new \DateTimeImmutable((string) $v) : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php b/vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php new file mode 100644 index 000000000..13c7aea51 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListMultipartUploadsOutput.php @@ -0,0 +1,402 @@ + + */ +class ListMultipartUploadsOutput extends Result implements \IteratorAggregate +{ + /** + * The name of the bucket to which the multipart upload was initiated. Does not return the access point ARN or access + * point alias if used. + * + * @var string|null + */ + private $bucket; + + /** + * The key at or after which the listing began. + * + * @var string|null + */ + private $keyMarker; + + /** + * Upload ID after which listing began. + * + * @var string|null + */ + private $uploadIdMarker; + + /** + * When a list is truncated, this element specifies the value that should be used for the key-marker request parameter + * in a subsequent request. + * + * @var string|null + */ + private $nextKeyMarker; + + /** + * When a prefix is provided in the request, this field contains the specified prefix. The result contains only keys + * starting with the specified prefix. + * + * @var string|null + */ + private $prefix; + + /** + * Contains the delimiter you specified in the request. If you don't specify a delimiter in your request, this element + * is absent from the response. + * + * @var string|null + */ + private $delimiter; + + /** + * When a list is truncated, this element specifies the value that should be used for the `upload-id-marker` request + * parameter in a subsequent request. + * + * @var string|null + */ + private $nextUploadIdMarker; + + /** + * Maximum number of multipart uploads that could have been included in the response. + * + * @var int|null + */ + private $maxUploads; + + /** + * Indicates whether the returned list of multipart uploads is truncated. A value of true indicates that the list was + * truncated. The list can be truncated if the number of multipart uploads exceeds the limit allowed or specified by max + * uploads. + * + * @var bool|null + */ + private $isTruncated; + + /** + * Container for elements related to a particular multipart upload. A response can contain zero or more `Upload` + * elements. + * + * @var MultipartUpload[] + */ + private $uploads; + + /** + * If you specify a delimiter in the request, then the result returns each distinct key prefix containing the delimiter + * in a `CommonPrefixes` element. The distinct key prefixes are returned in the `Prefix` child element. + * + * @var CommonPrefix[] + */ + private $commonPrefixes; + + /** + * Encoding type used by Amazon S3 to encode object keys in the response. + * + * If you specify the `encoding-type` request parameter, Amazon S3 includes this element in the response, and returns + * encoded key name values in the following response elements: + * + * `Delimiter`, `KeyMarker`, `Prefix`, `NextKeyMarker`, `Key`. + * + * @var EncodingType::*|null + */ + private $encodingType; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + public function getBucket(): ?string + { + $this->initialize(); + + return $this->bucket; + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getCommonPrefixes(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->commonPrefixes; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListMultipartUploadsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setKeyMarker($page->nextKeyMarker); + + $input->setUploadIdMarker($page->nextUploadIdMarker); + + $this->registerPrefetch($nextPage = $client->listMultipartUploads($input)); + } else { + $nextPage = null; + } + + yield from $page->commonPrefixes; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getDelimiter(): ?string + { + $this->initialize(); + + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + $this->initialize(); + + return $this->encodingType; + } + + public function getIsTruncated(): ?bool + { + $this->initialize(); + + return $this->isTruncated; + } + + /** + * Iterates over Uploads and CommonPrefixes. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListMultipartUploadsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setKeyMarker($page->nextKeyMarker); + + $input->setUploadIdMarker($page->nextUploadIdMarker); + + $this->registerPrefetch($nextPage = $client->listMultipartUploads($input)); + } else { + $nextPage = null; + } + + yield from $page->getUploads(true); + yield from $page->getCommonPrefixes(true); + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getKeyMarker(): ?string + { + $this->initialize(); + + return $this->keyMarker; + } + + public function getMaxUploads(): ?int + { + $this->initialize(); + + return $this->maxUploads; + } + + public function getNextKeyMarker(): ?string + { + $this->initialize(); + + return $this->nextKeyMarker; + } + + public function getNextUploadIdMarker(): ?string + { + $this->initialize(); + + return $this->nextUploadIdMarker; + } + + public function getPrefix(): ?string + { + $this->initialize(); + + return $this->prefix; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getUploadIdMarker(): ?string + { + $this->initialize(); + + return $this->uploadIdMarker; + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getUploads(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->uploads; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListMultipartUploadsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setKeyMarker($page->nextKeyMarker); + + $input->setUploadIdMarker($page->nextUploadIdMarker); + + $this->registerPrefetch($nextPage = $client->listMultipartUploads($input)); + } else { + $nextPage = null; + } + + yield from $page->uploads; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->keyMarker = ($v = $data->KeyMarker) ? (string) $v : null; + $this->uploadIdMarker = ($v = $data->UploadIdMarker) ? (string) $v : null; + $this->nextKeyMarker = ($v = $data->NextKeyMarker) ? (string) $v : null; + $this->prefix = ($v = $data->Prefix) ? (string) $v : null; + $this->delimiter = ($v = $data->Delimiter) ? (string) $v : null; + $this->nextUploadIdMarker = ($v = $data->NextUploadIdMarker) ? (string) $v : null; + $this->maxUploads = ($v = $data->MaxUploads) ? (int) (string) $v : null; + $this->isTruncated = ($v = $data->IsTruncated) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null; + $this->uploads = !$data->Upload ? [] : $this->populateResultMultipartUploadList($data->Upload); + $this->commonPrefixes = !$data->CommonPrefixes ? [] : $this->populateResultCommonPrefixList($data->CommonPrefixes); + $this->encodingType = ($v = $data->EncodingType) ? (string) $v : null; + } + + /** + * @return CommonPrefix[] + */ + private function populateResultCommonPrefixList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new CommonPrefix([ + 'Prefix' => ($v = $item->Prefix) ? (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return MultipartUpload[] + */ + private function populateResultMultipartUploadList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new MultipartUpload([ + 'UploadId' => ($v = $item->UploadId) ? (string) $v : null, + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'Initiated' => ($v = $item->Initiated) ? new \DateTimeImmutable((string) $v) : null, + 'StorageClass' => ($v = $item->StorageClass) ? (string) $v : null, + 'Owner' => !$item->Owner ? null : new Owner([ + 'DisplayName' => ($v = $item->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $item->Owner->ID) ? (string) $v : null, + ]), + 'Initiator' => !$item->Initiator ? null : new Initiator([ + 'ID' => ($v = $item->Initiator->ID) ? (string) $v : null, + 'DisplayName' => ($v = $item->Initiator->DisplayName) ? (string) $v : null, + ]), + 'ChecksumAlgorithm' => ($v = $item->ChecksumAlgorithm) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ListObjectsV2Output.php b/vendor/async-aws/s3/src/Result/ListObjectsV2Output.php new file mode 100644 index 000000000..49f4114c1 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListObjectsV2Output.php @@ -0,0 +1,438 @@ + + */ +class ListObjectsV2Output extends Result implements \IteratorAggregate +{ + /** + * Set to `false` if all of the results were returned. Set to `true` if more keys are available to return. If the number + * of results exceeds that specified by `MaxKeys`, all of the results might not be returned. + * + * @var bool|null + */ + private $isTruncated; + + /** + * Metadata about each object returned. + * + * @var AwsObject[] + */ + private $contents; + + /** + * The bucket name. + * + * When using this action with an access point, you must direct requests to the access point hostname. The access point + * hostname takes the form *AccessPointName*-*AccountId*.s3-accesspoint.*Region*.amazonaws.com. When using this action + * with an access point through the Amazon Web Services SDKs, you provide the access point ARN in place of the bucket + * name. For more information about access point ARNs, see Using access points [^1] in the *Amazon S3 User Guide*. + * + * When you use this action with Amazon S3 on Outposts, you must direct requests to the S3 on Outposts hostname. The S3 + * on Outposts hostname takes the form `*AccessPointName*-*AccountId*.*outpostID*.s3-outposts.*Region*.amazonaws.com`. + * When you use this action with S3 on Outposts through the Amazon Web Services SDKs, you provide the Outposts access + * point ARN in place of the bucket name. For more information about S3 on Outposts ARNs, see What is S3 on Outposts? + * [^2] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-access-points.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html + * + * @var string|null + */ + private $name; + + /** + * Keys that begin with the indicated prefix. + * + * @var string|null + */ + private $prefix; + + /** + * Causes keys that contain the same string between the `prefix` and the first occurrence of the delimiter to be rolled + * up into a single result element in the `CommonPrefixes` collection. These rolled-up keys are not returned elsewhere + * in the response. Each rolled-up result counts as only one return against the `MaxKeys` value. + * + * @var string|null + */ + private $delimiter; + + /** + * Sets the maximum number of keys returned in the response. By default, the action returns up to 1,000 key names. The + * response might contain fewer keys but will never contain more. + * + * @var int|null + */ + private $maxKeys; + + /** + * All of the keys (up to 1,000) rolled up into a common prefix count as a single return when calculating the number of + * returns. + * + * A response can contain `CommonPrefixes` only if you specify a delimiter. + * + * `CommonPrefixes` contains all (if there are any) keys between `Prefix` and the next occurrence of the string + * specified by a delimiter. + * + * `CommonPrefixes` lists keys that act like subdirectories in the directory specified by `Prefix`. + * + * For example, if the prefix is `notes/` and the delimiter is a slash (`/`) as in `notes/summer/july`, the common + * prefix is `notes/summer/`. All of the keys that roll up into a common prefix count as a single return when + * calculating the number of returns. + * + * @var CommonPrefix[] + */ + private $commonPrefixes; + + /** + * Encoding type used by Amazon S3 to encode object key names in the XML response. + * + * If you specify the `encoding-type` request parameter, Amazon S3 includes this element in the response, and returns + * encoded key name values in the following response elements: + * + * `Delimiter, Prefix, Key,` and `StartAfter`. + * + * @var EncodingType::*|null + */ + private $encodingType; + + /** + * `KeyCount` is the number of keys returned with this request. `KeyCount` will always be less than or equal to the + * `MaxKeys` field. For example, if you ask for 50 keys, your result will include 50 keys or fewer. + * + * @var int|null + */ + private $keyCount; + + /** + * If `ContinuationToken` was sent with the request, it is included in the response. + * + * @var string|null + */ + private $continuationToken; + + /** + * `NextContinuationToken` is sent when `isTruncated` is true, which means there are more keys in the bucket that can be + * listed. The next list requests to Amazon S3 can be continued with this `NextContinuationToken`. + * `NextContinuationToken` is obfuscated and is not a real key. + * + * @var string|null + */ + private $nextContinuationToken; + + /** + * If StartAfter was sent with the request, it is included in the response. + * + * @var string|null + */ + private $startAfter; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getCommonPrefixes(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->commonPrefixes; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListObjectsV2Request) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->nextContinuationToken) { + $input->setContinuationToken($page->nextContinuationToken); + + $this->registerPrefetch($nextPage = $client->listObjectsV2($input)); + } else { + $nextPage = null; + } + + yield from $page->commonPrefixes; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getContents(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->contents; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListObjectsV2Request) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->nextContinuationToken) { + $input->setContinuationToken($page->nextContinuationToken); + + $this->registerPrefetch($nextPage = $client->listObjectsV2($input)); + } else { + $nextPage = null; + } + + yield from $page->contents; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getContinuationToken(): ?string + { + $this->initialize(); + + return $this->continuationToken; + } + + public function getDelimiter(): ?string + { + $this->initialize(); + + return $this->delimiter; + } + + /** + * @return EncodingType::*|null + */ + public function getEncodingType(): ?string + { + $this->initialize(); + + return $this->encodingType; + } + + public function getIsTruncated(): ?bool + { + $this->initialize(); + + return $this->isTruncated; + } + + /** + * Iterates over Contents and CommonPrefixes. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListObjectsV2Request) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->nextContinuationToken) { + $input->setContinuationToken($page->nextContinuationToken); + + $this->registerPrefetch($nextPage = $client->listObjectsV2($input)); + } else { + $nextPage = null; + } + + yield from $page->getContents(true); + yield from $page->getCommonPrefixes(true); + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + public function getKeyCount(): ?int + { + $this->initialize(); + + return $this->keyCount; + } + + public function getMaxKeys(): ?int + { + $this->initialize(); + + return $this->maxKeys; + } + + public function getName(): ?string + { + $this->initialize(); + + return $this->name; + } + + public function getNextContinuationToken(): ?string + { + $this->initialize(); + + return $this->nextContinuationToken; + } + + public function getPrefix(): ?string + { + $this->initialize(); + + return $this->prefix; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + public function getStartAfter(): ?string + { + $this->initialize(); + + return $this->startAfter; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->isTruncated = ($v = $data->IsTruncated) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null; + $this->contents = !$data->Contents ? [] : $this->populateResultObjectList($data->Contents); + $this->name = ($v = $data->Name) ? (string) $v : null; + $this->prefix = ($v = $data->Prefix) ? (string) $v : null; + $this->delimiter = ($v = $data->Delimiter) ? (string) $v : null; + $this->maxKeys = ($v = $data->MaxKeys) ? (int) (string) $v : null; + $this->commonPrefixes = !$data->CommonPrefixes ? [] : $this->populateResultCommonPrefixList($data->CommonPrefixes); + $this->encodingType = ($v = $data->EncodingType) ? (string) $v : null; + $this->keyCount = ($v = $data->KeyCount) ? (int) (string) $v : null; + $this->continuationToken = ($v = $data->ContinuationToken) ? (string) $v : null; + $this->nextContinuationToken = ($v = $data->NextContinuationToken) ? (string) $v : null; + $this->startAfter = ($v = $data->StartAfter) ? (string) $v : null; + } + + /** + * @return list + */ + private function populateResultChecksumAlgorithmList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $a = ($v = $item) ? (string) $v : null; + if (null !== $a) { + $items[] = $a; + } + } + + return $items; + } + + /** + * @return CommonPrefix[] + */ + private function populateResultCommonPrefixList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new CommonPrefix([ + 'Prefix' => ($v = $item->Prefix) ? (string) $v : null, + ]); + } + + return $items; + } + + /** + * @return AwsObject[] + */ + private function populateResultObjectList(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new AwsObject([ + 'Key' => ($v = $item->Key) ? (string) $v : null, + 'LastModified' => ($v = $item->LastModified) ? new \DateTimeImmutable((string) $v) : null, + 'ETag' => ($v = $item->ETag) ? (string) $v : null, + 'ChecksumAlgorithm' => !$item->ChecksumAlgorithm ? null : $this->populateResultChecksumAlgorithmList($item->ChecksumAlgorithm), + 'Size' => ($v = $item->Size) ? (int) (string) $v : null, + 'StorageClass' => ($v = $item->StorageClass) ? (string) $v : null, + 'Owner' => !$item->Owner ? null : new Owner([ + 'DisplayName' => ($v = $item->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $item->Owner->ID) ? (string) $v : null, + ]), + 'RestoreStatus' => !$item->RestoreStatus ? null : new RestoreStatus([ + 'IsRestoreInProgress' => ($v = $item->RestoreStatus->IsRestoreInProgress) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null, + 'RestoreExpiryDate' => ($v = $item->RestoreStatus->RestoreExpiryDate) ? new \DateTimeImmutable((string) $v) : null, + ]), + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ListPartsOutput.php b/vendor/async-aws/s3/src/Result/ListPartsOutput.php new file mode 100644 index 000000000..80aff981e --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ListPartsOutput.php @@ -0,0 +1,352 @@ + + */ +class ListPartsOutput extends Result implements \IteratorAggregate +{ + /** + * If the bucket has a lifecycle rule configured with an action to abort incomplete multipart uploads and the prefix in + * the lifecycle rule matches the object name in the request, then the response includes this header indicating when the + * initiated multipart upload will become eligible for abort operation. For more information, see Aborting Incomplete + * Multipart Uploads Using a Bucket Lifecycle Configuration [^1]. + * + * The response will also include the `x-amz-abort-rule-id` header that will provide the ID of the lifecycle + * configuration rule that defines this action. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config + * + * @var \DateTimeImmutable|null + */ + private $abortDate; + + /** + * This header is returned along with the `x-amz-abort-date` header. It identifies applicable lifecycle configuration + * rule that defines the action to abort incomplete multipart uploads. + * + * @var string|null + */ + private $abortRuleId; + + /** + * The name of the bucket to which the multipart upload was initiated. Does not return the access point ARN or access + * point alias if used. + * + * @var string|null + */ + private $bucket; + + /** + * Object key for which the multipart upload was initiated. + * + * @var string|null + */ + private $key; + + /** + * Upload ID identifying the multipart upload whose parts are being listed. + * + * @var string|null + */ + private $uploadId; + + /** + * When a list is truncated, this element specifies the last part in the list, as well as the value to use for the + * part-number-marker request parameter in a subsequent request. + * + * @var int|null + */ + private $partNumberMarker; + + /** + * When a list is truncated, this element specifies the last part in the list, as well as the value to use for the + * `part-number-marker` request parameter in a subsequent request. + * + * @var int|null + */ + private $nextPartNumberMarker; + + /** + * Maximum number of parts that were allowed in the response. + * + * @var int|null + */ + private $maxParts; + + /** + * Indicates whether the returned list of parts is truncated. A true value indicates that the list was truncated. A list + * can be truncated if the number of parts exceeds the limit returned in the MaxParts element. + * + * @var bool|null + */ + private $isTruncated; + + /** + * Container for elements related to a particular part. A response can contain zero or more `Part` elements. + * + * @var Part[] + */ + private $parts; + + /** + * Container element that identifies who initiated the multipart upload. If the initiator is an Amazon Web Services + * account, this element provides the same information as the `Owner` element. If the initiator is an IAM User, this + * element provides the user ARN and display name. + * + * @var Initiator|null + */ + private $initiator; + + /** + * Container element that identifies the object owner, after the object is created. If multipart upload is initiated by + * an IAM user, this element provides the parent account ID and display name. + * + * @var Owner|null + */ + private $owner; + + /** + * Class of storage (STANDARD or REDUCED_REDUNDANCY) used to store the uploaded object. + * + * @var StorageClass::*|null + */ + private $storageClass; + + /** + * @var RequestCharged::*|null + */ + private $requestCharged; + + /** + * The algorithm that was used to create a checksum of the object. + * + * @var ChecksumAlgorithm::*|null + */ + private $checksumAlgorithm; + + public function getAbortDate(): ?\DateTimeImmutable + { + $this->initialize(); + + return $this->abortDate; + } + + public function getAbortRuleId(): ?string + { + $this->initialize(); + + return $this->abortRuleId; + } + + public function getBucket(): ?string + { + $this->initialize(); + + return $this->bucket; + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + $this->initialize(); + + return $this->checksumAlgorithm; + } + + public function getInitiator(): ?Initiator + { + $this->initialize(); + + return $this->initiator; + } + + public function getIsTruncated(): ?bool + { + $this->initialize(); + + return $this->isTruncated; + } + + /** + * Iterates over Parts. + * + * @return \Traversable + */ + public function getIterator(): \Traversable + { + yield from $this->getParts(); + } + + public function getKey(): ?string + { + $this->initialize(); + + return $this->key; + } + + public function getMaxParts(): ?int + { + $this->initialize(); + + return $this->maxParts; + } + + public function getNextPartNumberMarker(): ?int + { + $this->initialize(); + + return $this->nextPartNumberMarker; + } + + public function getOwner(): ?Owner + { + $this->initialize(); + + return $this->owner; + } + + public function getPartNumberMarker(): ?int + { + $this->initialize(); + + return $this->partNumberMarker; + } + + /** + * @param bool $currentPageOnly When true, iterates over items of the current page. Otherwise also fetch items in the next pages. + * + * @return iterable + */ + public function getParts(bool $currentPageOnly = false): iterable + { + if ($currentPageOnly) { + $this->initialize(); + yield from $this->parts; + + return; + } + + $client = $this->awsClient; + if (!$client instanceof S3Client) { + throw new InvalidArgument('missing client injected in paginated result'); + } + if (!$this->input instanceof ListPartsRequest) { + throw new InvalidArgument('missing last request injected in paginated result'); + } + $input = clone $this->input; + $page = $this; + while (true) { + $page->initialize(); + if ($page->isTruncated) { + $input->setPartNumberMarker($page->nextPartNumberMarker); + + $this->registerPrefetch($nextPage = $client->listParts($input)); + } else { + $nextPage = null; + } + + yield from $page->parts; + + if (null === $nextPage) { + break; + } + + $this->unregisterPrefetch($nextPage); + $page = $nextPage; + } + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + $this->initialize(); + + return $this->storageClass; + } + + public function getUploadId(): ?string + { + $this->initialize(); + + return $this->uploadId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->abortDate = isset($headers['x-amz-abort-date'][0]) ? new \DateTimeImmutable($headers['x-amz-abort-date'][0]) : null; + $this->abortRuleId = $headers['x-amz-abort-rule-id'][0] ?? null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + + $data = new \SimpleXMLElement($response->getContent()); + $this->bucket = ($v = $data->Bucket) ? (string) $v : null; + $this->key = ($v = $data->Key) ? (string) $v : null; + $this->uploadId = ($v = $data->UploadId) ? (string) $v : null; + $this->partNumberMarker = ($v = $data->PartNumberMarker) ? (int) (string) $v : null; + $this->nextPartNumberMarker = ($v = $data->NextPartNumberMarker) ? (int) (string) $v : null; + $this->maxParts = ($v = $data->MaxParts) ? (int) (string) $v : null; + $this->isTruncated = ($v = $data->IsTruncated) ? filter_var((string) $v, \FILTER_VALIDATE_BOOLEAN) : null; + $this->parts = !$data->Part ? [] : $this->populateResultParts($data->Part); + $this->initiator = !$data->Initiator ? null : new Initiator([ + 'ID' => ($v = $data->Initiator->ID) ? (string) $v : null, + 'DisplayName' => ($v = $data->Initiator->DisplayName) ? (string) $v : null, + ]); + $this->owner = !$data->Owner ? null : new Owner([ + 'DisplayName' => ($v = $data->Owner->DisplayName) ? (string) $v : null, + 'ID' => ($v = $data->Owner->ID) ? (string) $v : null, + ]); + $this->storageClass = ($v = $data->StorageClass) ? (string) $v : null; + $this->checksumAlgorithm = ($v = $data->ChecksumAlgorithm) ? (string) $v : null; + } + + /** + * @return Part[] + */ + private function populateResultParts(\SimpleXMLElement $xml): array + { + $items = []; + foreach ($xml as $item) { + $items[] = new Part([ + 'PartNumber' => ($v = $item->PartNumber) ? (int) (string) $v : null, + 'LastModified' => ($v = $item->LastModified) ? new \DateTimeImmutable((string) $v) : null, + 'ETag' => ($v = $item->ETag) ? (string) $v : null, + 'Size' => ($v = $item->Size) ? (int) (string) $v : null, + 'ChecksumCRC32' => ($v = $item->ChecksumCRC32) ? (string) $v : null, + 'ChecksumCRC32C' => ($v = $item->ChecksumCRC32C) ? (string) $v : null, + 'ChecksumSHA1' => ($v = $item->ChecksumSHA1) ? (string) $v : null, + 'ChecksumSHA256' => ($v = $item->ChecksumSHA256) ? (string) $v : null, + ]); + } + + return $items; + } +} diff --git a/vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php b/vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php new file mode 100644 index 000000000..cf689dfd6 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ObjectExistsWaiter.php @@ -0,0 +1,41 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + if (404 === $response->getStatusCode()) { + return self::STATE_PENDING; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadObjectRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->objectExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php b/vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php new file mode 100644 index 000000000..17c02ad4a --- /dev/null +++ b/vendor/async-aws/s3/src/Result/ObjectNotExistsWaiter.php @@ -0,0 +1,37 @@ +getStatusCode()) { + return self::STATE_SUCCESS; + } + + return null === $exception ? self::STATE_PENDING : self::STATE_FAILURE; + } + + protected function refreshState(): Waiter + { + if (!$this->awsClient instanceof S3Client) { + throw new InvalidArgument('missing client injected in waiter result'); + } + if (!$this->input instanceof HeadObjectRequest) { + throw new InvalidArgument('missing last request injected in waiter result'); + } + + return $this->awsClient->objectNotExists($this->input); + } +} diff --git a/vendor/async-aws/s3/src/Result/PutObjectAclOutput.php b/vendor/async-aws/s3/src/Result/PutObjectAclOutput.php new file mode 100644 index 000000000..99718958b --- /dev/null +++ b/vendor/async-aws/s3/src/Result/PutObjectAclOutput.php @@ -0,0 +1,32 @@ +initialize(); + + return $this->requestCharged; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/PutObjectOutput.php b/vendor/async-aws/s3/src/Result/PutObjectOutput.php new file mode 100644 index 000000000..8ec2e7af9 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/PutObjectOutput.php @@ -0,0 +1,259 @@ +initialize(); + + return $this->bucketKeyEnabled; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + public function getExpiration(): ?string + { + $this->initialize(); + + return $this->expiration; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsEncryptionContext(): ?string + { + $this->initialize(); + + return $this->sseKmsEncryptionContext; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + public function getVersionId(): ?string + { + $this->initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->expiration = $headers['x-amz-expiration'][0] ?? null; + $this->etag = $headers['etag'][0] ?? null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->sseKmsEncryptionContext = $headers['x-amz-server-side-encryption-context'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php b/vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php new file mode 100644 index 000000000..a0cedbab9 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/PutObjectTaggingOutput.php @@ -0,0 +1,30 @@ +initialize(); + + return $this->versionId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->versionId = $headers['x-amz-version-id'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/Result/UploadPartOutput.php b/vendor/async-aws/s3/src/Result/UploadPartOutput.php new file mode 100644 index 000000000..96a404150 --- /dev/null +++ b/vendor/async-aws/s3/src/Result/UploadPartOutput.php @@ -0,0 +1,206 @@ +initialize(); + + return $this->bucketKeyEnabled; + } + + public function getChecksumCrc32(): ?string + { + $this->initialize(); + + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + $this->initialize(); + + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + $this->initialize(); + + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + $this->initialize(); + + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + $this->initialize(); + + return $this->etag; + } + + /** + * @return RequestCharged::*|null + */ + public function getRequestCharged(): ?string + { + $this->initialize(); + + return $this->requestCharged; + } + + /** + * @return ServerSideEncryption::*|null + */ + public function getServerSideEncryption(): ?string + { + $this->initialize(); + + return $this->serverSideEncryption; + } + + public function getSseCustomerAlgorithm(): ?string + { + $this->initialize(); + + return $this->sseCustomerAlgorithm; + } + + public function getSseCustomerKeyMd5(): ?string + { + $this->initialize(); + + return $this->sseCustomerKeyMd5; + } + + public function getSseKmsKeyId(): ?string + { + $this->initialize(); + + return $this->sseKmsKeyId; + } + + protected function populateResult(Response $response): void + { + $headers = $response->getHeaders(); + + $this->serverSideEncryption = $headers['x-amz-server-side-encryption'][0] ?? null; + $this->etag = $headers['etag'][0] ?? null; + $this->checksumCrc32 = $headers['x-amz-checksum-crc32'][0] ?? null; + $this->checksumCrc32C = $headers['x-amz-checksum-crc32c'][0] ?? null; + $this->checksumSha1 = $headers['x-amz-checksum-sha1'][0] ?? null; + $this->checksumSha256 = $headers['x-amz-checksum-sha256'][0] ?? null; + $this->sseCustomerAlgorithm = $headers['x-amz-server-side-encryption-customer-algorithm'][0] ?? null; + $this->sseCustomerKeyMd5 = $headers['x-amz-server-side-encryption-customer-key-md5'][0] ?? null; + $this->sseKmsKeyId = $headers['x-amz-server-side-encryption-aws-kms-key-id'][0] ?? null; + $this->bucketKeyEnabled = isset($headers['x-amz-server-side-encryption-bucket-key-enabled'][0]) ? filter_var($headers['x-amz-server-side-encryption-bucket-key-enabled'][0], \FILTER_VALIDATE_BOOLEAN) : null; + $this->requestCharged = $headers['x-amz-request-charged'][0] ?? null; + } +} diff --git a/vendor/async-aws/s3/src/S3Client.php b/vendor/async-aws/s3/src/S3Client.php new file mode 100644 index 000000000..4fdba87f8 --- /dev/null +++ b/vendor/async-aws/s3/src/S3Client.php @@ -0,0 +1,2651 @@ +getResponse($input->request(), new RequestContext(['operation' => 'AbortMultipartUpload', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchUpload' => NoSuchUploadException::class, + ]])); + + return new AbortMultipartUploadOutput($response); + } + + /** + * @see headBucket + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|HeadBucketRequest $input + */ + public function bucketExists($input): BucketExistsWaiter + { + $input = HeadBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadBucket', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchBucket' => NoSuchBucketException::class, + ]])); + + return new BucketExistsWaiter($response, $this, $input); + } + + /** + * @see headBucket + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|HeadBucketRequest $input + */ + public function bucketNotExists($input): BucketNotExistsWaiter + { + $input = HeadBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadBucket', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchBucket' => NoSuchBucketException::class, + ]])); + + return new BucketNotExistsWaiter($response, $this, $input); + } + + /** + * Completes a multipart upload by assembling previously uploaded parts. + * + * You first initiate the multipart upload and then upload all parts using the UploadPart [^1] operation. After + * successfully uploading all relevant parts of an upload, you call this action to complete the upload. Upon receiving + * this request, Amazon S3 concatenates all the parts in ascending order by part number to create a new object. In the + * Complete Multipart Upload request, you must provide the parts list. You must ensure that the parts list is complete. + * This action concatenates the parts that you provide in the list. For each part in the list, you must provide the part + * number and the `ETag` value, returned after that part was uploaded. + * + * Processing of a Complete Multipart Upload request could take several minutes to complete. After Amazon S3 begins + * processing the request, it sends an HTTP response header that specifies a 200 OK response. While processing is in + * progress, Amazon S3 periodically sends white space characters to keep the connection from timing out. A request could + * fail after the initial 200 OK response has been sent. This means that a `200 OK` response can contain either a + * success or an error. If you call the S3 API directly, make sure to design your application to parse the contents of + * the response and handle it appropriately. If you use Amazon Web Services SDKs, SDKs handle this condition. The SDKs + * detect the embedded error and apply error handling per your configuration settings (including automatically retrying + * the request as appropriate). If the condition persists, the SDKs throws an exception (or, for the SDKs that don't use + * exceptions, they return the error). + * + * Note that if `CompleteMultipartUpload` fails, applications should be prepared to retry the failed requests. For more + * information, see Amazon S3 Error Best Practices [^2]. + * + * ! You cannot use `Content-Type: application/x-www-form-urlencoded` with Complete Multipart Upload requests. Also, if + * ! you do not provide a `Content-Type` header, `CompleteMultipartUpload` returns a 200 OK response. + * + * For more information about multipart uploads, see Uploading Objects Using Multipart Upload [^3]. + * + * For information about permissions required to use the multipart upload API, see Multipart Upload and Permissions + * [^4]. + * + * `CompleteMultipartUpload` has the following special errors: + * + * - Error code: `EntityTooSmall` + * + * - Description: Your proposed upload is smaller than the minimum allowed object size. Each part must be at least 5 + * MB in size, except the last part. + * - 400 Bad Request + * + * - Error code: `InvalidPart` + * + * - Description: One or more of the specified parts could not be found. The part might not have been uploaded, or the + * specified entity tag might not have matched the part's entity tag. + * - 400 Bad Request + * + * - Error code: `InvalidPartOrder` + * + * - Description: The list of parts was not in ascending order. The parts list must be specified in order by part + * number. + * - 400 Bad Request + * + * - Error code: `NoSuchUpload` + * + * - Description: The specified multipart upload does not exist. The upload ID might be invalid, or the multipart + * upload might have been aborted or completed. + * - 404 Not Found + * + * + * The following operations are related to `CompleteMultipartUpload`: + * + * - CreateMultipartUpload [^5] + * - UploadPart [^6] + * - AbortMultipartUpload [^7] + * - ListParts [^8] + * - ListMultipartUploads [^9] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ErrorBestPractices.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadComplete.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#completemultipartupload + * + * @param array{ + * Bucket: string, + * Key: string, + * MultipartUpload?: CompletedMultipartUpload|array, + * UploadId: string, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|CompleteMultipartUploadRequest $input + */ + public function completeMultipartUpload($input): CompleteMultipartUploadOutput + { + $input = CompleteMultipartUploadRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CompleteMultipartUpload', 'region' => $input->getRegion()])); + + return new CompleteMultipartUploadOutput($response); + } + + /** + * Creates a copy of an object that is already stored in Amazon S3. + * + * > You can store individual objects of up to 5 TB in Amazon S3. You create a copy of your object up to 5 GB in size in + * > a single atomic action using this API. However, to copy an object greater than 5 GB, you must use the multipart + * > upload Upload Part - Copy (UploadPartCopy) API. For more information, see Copy Object Using the REST Multipart + * > Upload API [^1]. + * + * All copy requests must be authenticated. Additionally, you must have *read* access to the source object and *write* + * access to the destination bucket. For more information, see REST Authentication [^2]. Both the Region that you want + * to copy the object from and the Region that you want to copy the object to must be enabled for your account. + * + * A copy request might return an error when Amazon S3 receives the copy request or while Amazon S3 is copying the + * files. If the error occurs before the copy action starts, you receive a standard Amazon S3 error. If the error occurs + * during the copy operation, the error response is embedded in the `200 OK` response. This means that a `200 OK` + * response can contain either a success or an error. If you call the S3 API directly, make sure to design your + * application to parse the contents of the response and handle it appropriately. If you use Amazon Web Services SDKs, + * SDKs handle this condition. The SDKs detect the embedded error and apply error handling per your configuration + * settings (including automatically retrying the request as appropriate). If the condition persists, the SDKs throws an + * exception (or, for the SDKs that don't use exceptions, they return the error). + * + * If the copy is successful, you receive a response with information about the copied object. + * + * > If the request is an HTTP 1.1 request, the response is chunk encoded. If it were not, it would not contain the + * > content-length, and you would need to read the entire body. + * + * The copy request charge is based on the storage class and Region that you specify for the destination object. The + * request can also result in a data retrieval charge for the source if the source storage class bills for data + * retrieval. For pricing information, see Amazon S3 pricing [^3]. + * + * ! Amazon S3 transfer acceleration does not support cross-Region copies. If you request a cross-Region copy using a + * ! transfer acceleration endpoint, you get a 400 `Bad Request` error. For more information, see Transfer Acceleration + * ! [^4]. + * + * - `Metadata`: + * + * When copying an object, you can preserve all metadata (the default) or specify new metadata. However, the access + * control list (ACL) is not preserved and is set to private for the user making the request. To override the default + * ACL setting, specify a new ACL when generating a copy request. For more information, see Using ACLs [^5]. + * + * To specify whether you want the object metadata copied from the source object or replaced with metadata provided in + * the request, you can optionally add the `x-amz-metadata-directive` header. When you grant permissions, you can use + * the `s3:x-amz-metadata-directive` condition key to enforce certain metadata behavior when objects are uploaded. For + * more information, see Specifying Conditions in a Policy [^6] in the *Amazon S3 User Guide*. For a complete list of + * Amazon S3-specific condition keys, see Actions, Resources, and Condition Keys for Amazon S3 [^7]. + * + * > `x-amz-website-redirect-location` is unique to each object and must be specified in the request headers to copy + * > the value. + * + * - `x-amz-copy-source-if Headers`: + * + * To only copy an object under certain conditions, such as whether the `Etag` matches or whether the object was + * modified before or after a specified date, use the following request parameters: + * + * - `x-amz-copy-source-if-match` + * - `x-amz-copy-source-if-none-match` + * - `x-amz-copy-source-if-unmodified-since` + * - `x-amz-copy-source-if-modified-since` + * + * If both the `x-amz-copy-source-if-match` and `x-amz-copy-source-if-unmodified-since` headers are present in the + * request and evaluate as follows, Amazon S3 returns `200 OK` and copies the data: + * + * - `x-amz-copy-source-if-match` condition evaluates to true + * - `x-amz-copy-source-if-unmodified-since` condition evaluates to false + * + * If both the `x-amz-copy-source-if-none-match` and `x-amz-copy-source-if-modified-since` headers are present in the + * request and evaluate as follows, Amazon S3 returns the `412 Precondition Failed` response code: + * + * - `x-amz-copy-source-if-none-match` condition evaluates to false + * - `x-amz-copy-source-if-modified-since` condition evaluates to true + * + * > All headers with the `x-amz-` prefix, including `x-amz-copy-source`, must be signed. + * + * - `Server-side encryption`: + * + * Amazon S3 automatically encrypts all new objects that are copied to an S3 bucket. When copying an object, if you + * don't specify encryption information in your copy request, the encryption setting of the target object is set to + * the default encryption configuration of the destination bucket. By default, all buckets have a base level of + * encryption configuration that uses server-side encryption with Amazon S3 managed keys (SSE-S3). If the destination + * bucket has a default encryption configuration that uses server-side encryption with Key Management Service (KMS) + * keys (SSE-KMS), dual-layer server-side encryption with Amazon Web Services KMS keys (DSSE-KMS), or server-side + * encryption with customer-provided encryption keys (SSE-C), Amazon S3 uses the corresponding KMS key, or a + * customer-provided key to encrypt the target object copy. + * + * When you perform a `CopyObject` operation, if you want to use a different type of encryption setting for the target + * object, you can use other appropriate encryption-related headers to encrypt the target object with a KMS key, an + * Amazon S3 managed key, or a customer-provided key. With server-side encryption, Amazon S3 encrypts your data as it + * writes your data to disks in its data centers and decrypts the data when you access it. If the encryption setting + * in your request is different from the default encryption configuration of the destination bucket, the encryption + * setting in your request takes precedence. If the source object for the copy is stored in Amazon S3 using SSE-C, you + * must provide the necessary encryption information in your request so that Amazon S3 can decrypt the object for + * copying. For more information about server-side encryption, see Using Server-Side Encryption [^8]. + * + * If a target object uses SSE-KMS, you can enable an S3 Bucket Key for the object. For more information, see Amazon + * S3 Bucket Keys [^9] in the *Amazon S3 User Guide*. + * - `Access Control List (ACL)-Specific Request Headers`: + * + * When copying an object, you can optionally use headers to grant ACL-based permissions. By default, all objects are + * private. Only the owner has full access control. When adding a new object, you can grant permissions to individual + * Amazon Web Services accounts or to predefined groups that are defined by Amazon S3. These permissions are then + * added to the ACL on the object. For more information, see Access Control List (ACL) Overview [^10] and Managing + * ACLs Using the REST API [^11]. + * + * If the bucket that you're copying objects to uses the bucket owner enforced setting for S3 Object Ownership, ACLs + * are disabled and no longer affect permissions. Buckets that use this setting only accept `PUT` requests that don't + * specify an ACL or `PUT` requests that specify bucket owner full control ACLs, such as the + * `bucket-owner-full-control` canned ACL or an equivalent form of this ACL expressed in the XML format. + * + * For more information, see Controlling ownership of objects and disabling ACLs [^12] in the *Amazon S3 User Guide*. + * + * > If your bucket uses the bucket owner enforced setting for Object Ownership, all objects written to the bucket by + * > any account will be owned by the bucket owner. + * + * - `Checksums`: + * + * When copying an object, if it has a checksum, that checksum will be copied to the new object by default. When you + * copy the object over, you can optionally specify a different checksum algorithm to use with the + * `x-amz-checksum-algorithm` header. + * - `Storage Class Options`: + * + * You can use the `CopyObject` action to change the storage class of an object that is already stored in Amazon S3 by + * using the `StorageClass` parameter. For more information, see Storage Classes [^13] in the *Amazon S3 User Guide*. + * + * If the source object's storage class is GLACIER, you must restore a copy of this object before you can use it as a + * source object for the copy operation. For more information, see RestoreObject [^14]. For more information, see + * Copying Objects [^15]. + * - `Versioning`: + * + * By default, `x-amz-copy-source` header identifies the current version of an object to copy. If the current version + * is a delete marker, Amazon S3 behaves as if the object was deleted. To copy a different version, use the + * `versionId` subresource. + * + * If you enable versioning on the target bucket, Amazon S3 generates a unique version ID for the object being copied. + * This version ID is different from the version ID of the source object. Amazon S3 returns the version ID of the + * copied object in the `x-amz-version-id` response header in the response. + * + * If you do not enable versioning or suspend it on the target bucket, the version ID that Amazon S3 generates is + * always null. + * + * The following operations are related to `CopyObject`: + * + * - PutObject [^16] + * - GetObject [^17] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjctsUsingRESTMPUapi.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html + * [^3]: http://aws.amazon.com/s3/pricing/ + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/dev/amazon-s3-policy-keys.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/dev/list_amazons3.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-key.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html + * [^12]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^13]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * [^14]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html + * [^15]: https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjectsExamples.html + * [^16]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * [^17]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectCOPY.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#copyobject + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket: string, + * CacheControl?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * CopySource: string, + * CopySourceIfMatch?: string, + * CopySourceIfModifiedSince?: \DateTimeImmutable|string, + * CopySourceIfNoneMatch?: string, + * CopySourceIfUnmodifiedSince?: \DateTimeImmutable|string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key: string, + * Metadata?: array, + * MetadataDirective?: MetadataDirective::*, + * TaggingDirective?: TaggingDirective::*, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * CopySourceSSECustomerAlgorithm?: string, + * CopySourceSSECustomerKey?: string, + * CopySourceSSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ExpectedSourceBucketOwner?: string, + * '@region'?: string|null, + * }|CopyObjectRequest $input + * + * @throws ObjectNotInActiveTierErrorException + */ + public function copyObject($input): CopyObjectOutput + { + $input = CopyObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CopyObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'ObjectNotInActiveTierError' => ObjectNotInActiveTierErrorException::class, + ]])); + + return new CopyObjectOutput($response); + } + + /** + * Creates a new S3 bucket. To create a bucket, you must register with Amazon S3 and have a valid Amazon Web Services + * Access Key ID to authenticate requests. Anonymous requests are never allowed to create buckets. By creating the + * bucket, you become the bucket owner. + * + * Not every string is an acceptable bucket name. For information about bucket naming restrictions, see Bucket naming + * rules [^1]. + * + * If you want to create an Amazon S3 on Outposts bucket, see Create Bucket [^2]. + * + * By default, the bucket is created in the US East (N. Virginia) Region. You can optionally specify a Region in the + * request body. You might choose a Region to optimize latency, minimize costs, or address regulatory requirements. For + * example, if you reside in Europe, you will probably find it advantageous to create buckets in the Europe (Ireland) + * Region. For more information, see Accessing a bucket [^3]. + * + * > If you send your create bucket request to the `s3.amazonaws.com` endpoint, the request goes to the `us-east-1` + * > Region. Accordingly, the signature calculations in Signature Version 4 must use `us-east-1` as the Region, even if + * > the location constraint in the request specifies another Region where the bucket is to be created. If you create a + * > bucket in a Region other than US East (N. Virginia), your application must be able to handle 307 redirect. For more + * > information, see Virtual hosting of buckets [^4]. + * + * - `Permissions`: + * + * In addition to `s3:CreateBucket`, the following permissions are required when your `CreateBucket` request includes + * specific headers: + * + * - **Access control lists (ACLs)** - If your `CreateBucket` request specifies access control list (ACL) permissions + * and the ACL is public-read, public-read-write, authenticated-read, or if you specify access permissions + * explicitly through any other ACL, both `s3:CreateBucket` and `s3:PutBucketAcl` permissions are needed. If the ACL + * for the `CreateBucket` request is private or if the request doesn't specify any ACLs, only `s3:CreateBucket` + * permission is needed. + * - **Object Lock** - If `ObjectLockEnabledForBucket` is set to true in your `CreateBucket` request, + * `s3:PutBucketObjectLockConfiguration` and `s3:PutBucketVersioning` permissions are required. + * - **S3 Object Ownership** - If your `CreateBucket` request includes the `x-amz-object-ownership` header, then the + * `s3:PutBucketOwnershipControls` permission is required. By default, `ObjectOwnership` is set to + * `BucketOWnerEnforced` and ACLs are disabled. We recommend keeping ACLs disabled, except in uncommon use cases + * where you must control access for each object individually. If you want to change the `ObjectOwnership` setting, + * you can use the `x-amz-object-ownership` header in your `CreateBucket` request to set the `ObjectOwnership` + * setting of your choice. For more information about S3 Object Ownership, see Controlling object ownership [^5] in + * the *Amazon S3 User Guide*. + * - **S3 Block Public Access** - If your specific use case requires granting public access to your S3 resources, you + * can disable Block Public Access. You can create a new bucket with Block Public Access enabled, then separately + * call the `DeletePublicAccessBlock` [^6] API. To use this operation, you must have the + * `s3:PutBucketPublicAccessBlock` permission. By default, all Block Public Access settings are enabled for new + * buckets. To avoid inadvertent exposure of your resources, we recommend keeping the S3 Block Public Access + * settings enabled. For more information about S3 Block Public Access, see Blocking public access to your Amazon S3 + * storage [^7] in the *Amazon S3 User Guide*. + * + * + * ! If your `CreateBucket` request sets `BucketOwnerEnforced` for Amazon S3 Object Ownership and specifies a bucket ACL + * ! that provides access to an external Amazon Web Services account, your request fails with a `400` error and returns + * ! the `InvalidBucketAcLWithObjectOwnership` error code. For more information, see Setting Object Ownership on an + * ! existing bucket [^8] in the *Amazon S3 User Guide*. + * + * The following operations are related to `CreateBucket`: + * + * - PutObject [^9] + * - DeleteBucket [^10] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_CreateBucket.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html#access-bucket-intro + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeletePublicAccessBlock.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-ownership-existing-bucket.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUT.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createbucket + * + * @param array{ + * ACL?: BucketCannedACL::*, + * Bucket: string, + * CreateBucketConfiguration?: CreateBucketConfiguration|array, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * ObjectLockEnabledForBucket?: bool, + * ObjectOwnership?: ObjectOwnership::*, + * '@region'?: string|null, + * }|CreateBucketRequest $input + * + * @throws BucketAlreadyExistsException + * @throws BucketAlreadyOwnedByYouException + */ + public function createBucket($input): CreateBucketOutput + { + $input = CreateBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CreateBucket', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'BucketAlreadyExists' => BucketAlreadyExistsException::class, + 'BucketAlreadyOwnedByYou' => BucketAlreadyOwnedByYouException::class, + ]])); + + return new CreateBucketOutput($response); + } + + /** + * This action initiates a multipart upload and returns an upload ID. This upload ID is used to associate all of the + * parts in the specific multipart upload. You specify this upload ID in each of your subsequent upload part requests + * (see UploadPart [^1]). You also include this upload ID in the final request to either complete or abort the multipart + * upload request. + * + * For more information about multipart uploads, see Multipart Upload Overview [^2]. + * + * If you have configured a lifecycle rule to abort incomplete multipart uploads, the upload must complete within the + * number of days specified in the bucket lifecycle configuration. Otherwise, the incomplete multipart upload becomes + * eligible for an abort action and Amazon S3 aborts the multipart upload. For more information, see Aborting Incomplete + * Multipart Uploads Using a Bucket Lifecycle Configuration [^3]. + * + * For information about the permissions required to use the multipart upload API, see Multipart Upload and Permissions + * [^4]. + * + * For request signing, multipart upload is just a series of regular requests. You initiate a multipart upload, send one + * or more requests to upload parts, and then complete the multipart upload process. You sign each request individually. + * There is nothing special about signing multipart upload requests. For more information about signing, see + * Authenticating Requests (Amazon Web Services Signature Version 4) [^5]. + * + * > After you initiate a multipart upload and upload one or more parts, to stop being charged for storing the uploaded + * > parts, you must either complete or abort the multipart upload. Amazon S3 frees up the space used to store the parts + * > and stop charging you for storing them only after you either complete or abort a multipart upload. + * + * Server-side encryption is for data encryption at rest. Amazon S3 encrypts your data as it writes it to disks in its + * data centers and decrypts it when you access it. Amazon S3 automatically encrypts all new objects that are uploaded + * to an S3 bucket. When doing a multipart upload, if you don't specify encryption information in your request, the + * encryption setting of the uploaded parts is set to the default encryption configuration of the destination bucket. By + * default, all buckets have a base level of encryption configuration that uses server-side encryption with Amazon S3 + * managed keys (SSE-S3). If the destination bucket has a default encryption configuration that uses server-side + * encryption with an Key Management Service (KMS) key (SSE-KMS), or a customer-provided encryption key (SSE-C), Amazon + * S3 uses the corresponding KMS key, or a customer-provided key to encrypt the uploaded parts. When you perform a + * CreateMultipartUpload operation, if you want to use a different type of encryption setting for the uploaded parts, + * you can request that Amazon S3 encrypts the object with a KMS key, an Amazon S3 managed key, or a customer-provided + * key. If the encryption setting in your request is different from the default encryption configuration of the + * destination bucket, the encryption setting in your request takes precedence. If you choose to provide your own + * encryption key, the request headers you provide in UploadPart [^6] and UploadPartCopy [^7] requests must match the + * headers you used in the request to initiate the upload by using `CreateMultipartUpload`. You can request that Amazon + * S3 save the uploaded parts encrypted with server-side encryption with an Amazon S3 managed key (SSE-S3), an Key + * Management Service (KMS) key (SSE-KMS), or a customer-provided encryption key (SSE-C). + * + * To perform a multipart upload with encryption by using an Amazon Web Services KMS key, the requester must have + * permission to the `kms:Decrypt` and `kms:GenerateDataKey*` actions on the key. These permissions are required because + * Amazon S3 must decrypt and read data from the encrypted file parts before it completes the multipart upload. For more + * information, see Multipart upload API and permissions [^8] and Protecting data using server-side encryption with + * Amazon Web Services KMS [^9] in the *Amazon S3 User Guide*. + * + * If your Identity and Access Management (IAM) user or role is in the same Amazon Web Services account as the KMS key, + * then you must have these permissions on the key policy. If your IAM user or role belongs to a different account than + * the key, then you must have the permissions on both the key policy and your IAM user or role. + * + * For more information, see Protecting Data Using Server-Side Encryption [^10]. + * + * - `Access Permissions`: + * + * When copying an object, you can optionally specify the accounts or groups that should be granted specific + * permissions on the new object. There are two ways to grant the permissions using the request headers: + * + * - Specify a canned ACL with the `x-amz-acl` request header. For more information, see Canned ACL [^11]. + * - Specify access permissions explicitly with the `x-amz-grant-read`, `x-amz-grant-read-acp`, + * `x-amz-grant-write-acp`, and `x-amz-grant-full-control` headers. These parameters map to the set of permissions + * that Amazon S3 supports in an ACL. For more information, see Access Control List (ACL) Overview [^12]. + * + * You can use either a canned ACL or specify access permissions explicitly. You cannot do both. + * - `Server-Side- Encryption-Specific Request Headers`: + * + * Amazon S3 encrypts data by using server-side encryption with an Amazon S3 managed key (SSE-S3) by default. + * Server-side encryption is for data encryption at rest. Amazon S3 encrypts your data as it writes it to disks in its + * data centers and decrypts it when you access it. You can request that Amazon S3 encrypts data at rest by using + * server-side encryption with other key options. The option you use depends on whether you want to use KMS keys + * (SSE-KMS) or provide your own encryption keys (SSE-C). + * + * - Use KMS keys (SSE-KMS) that include the Amazon Web Services managed key (`aws/s3`) and KMS customer managed keys + * stored in Key Management Service (KMS) – If you want Amazon Web Services to manage the keys used to encrypt + * data, specify the following headers in the request. + * + * - `x-amz-server-side-encryption` + * - `x-amz-server-side-encryption-aws-kms-key-id` + * - `x-amz-server-side-encryption-context` + * + * > If you specify `x-amz-server-side-encryption:aws:kms`, but don't provide + * > `x-amz-server-side-encryption-aws-kms-key-id`, Amazon S3 uses the Amazon Web Services managed key (`aws/s3` + * > key) in KMS to protect the data. + * + * ! All `GET` and `PUT` requests for an object protected by KMS fail if you don't make them by using Secure Sockets + * ! Layer (SSL), Transport Layer Security (TLS), or Signature Version 4. + * + * For more information about server-side encryption with KMS keys (SSE-KMS), see Protecting Data Using Server-Side + * Encryption with KMS keys [^13]. + * - Use customer-provided encryption keys (SSE-C) – If you want to manage your own encryption keys, provide all the + * following headers in the request. + * + * - `x-amz-server-side-encryption-customer-algorithm` + * - `x-amz-server-side-encryption-customer-key` + * - `x-amz-server-side-encryption-customer-key-MD5` + * + * For more information about server-side encryption with customer-provided encryption keys (SSE-C), see Protecting + * data using server-side encryption with customer-provided encryption keys (SSE-C) [^14]. + * + * - `Access-Control-List (ACL)-Specific Request Headers`: + * + * You also can use the following access control–related headers with this operation. By default, all objects are + * private. Only the owner has full access control. When adding a new object, you can grant permissions to individual + * Amazon Web Services accounts or to predefined groups defined by Amazon S3. These permissions are then added to the + * access control list (ACL) on the object. For more information, see Using ACLs [^15]. With this operation, you can + * grant access permissions using one of the following two methods: + * + * - Specify a canned ACL (`x-amz-acl`) — Amazon S3 supports a set of predefined ACLs, known as *canned ACLs*. Each + * canned ACL has a predefined set of grantees and permissions. For more information, see Canned ACL [^16]. + * - Specify access permissions explicitly — To explicitly grant access permissions to specific Amazon Web Services + * accounts or groups, use the following headers. Each header maps to specific permissions that Amazon S3 supports + * in an ACL. For more information, see Access Control List (ACL) Overview [^17]. In the header, you specify a list + * of grantees who get the specific permission. To grant permissions explicitly, use: + * + * - `x-amz-grant-read` + * - `x-amz-grant-write` + * - `x-amz-grant-read-acp` + * - `x-amz-grant-write-acp` + * - `x-amz-grant-full-control` + * + * You specify each grantee as a type=value pair, where the type is one of the following: + * + * - `id` – if the value specified is the canonical user ID of an Amazon Web Services account + * - `uri` – if you are granting permissions to a predefined group + * - `emailAddress` – if the value specified is the email address of an Amazon Web Services account + * + * > Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^18] in the + * > Amazon Web Services General Reference. + * + * + * For example, the following `x-amz-grant-read` header grants the Amazon Web Services accounts identified by + * account IDs permissions to read object data and its metadata: + * + * `x-amz-grant-read: id="11112222333", id="444455556666" ` + * + * + * The following operations are related to `CreateMultipartUpload`: + * + * - UploadPart [^19] + * - CompleteMultipartUpload [^20] + * - AbortMultipartUpload [^21] + * - ListParts [^22] + * - ListMultipartUploads [^23] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html#mpu-abort-incomplete-mpu-lifecycle-config + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html#mpuAndPermissions + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL + * [^12]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^13]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html + * [^14]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html + * [^15]: https://docs.aws.amazon.com/AmazonS3/latest/dev/S3_ACLs_UsingACLs.html + * [^16]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL + * [^17]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^18]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * [^19]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^20]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^21]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^22]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^23]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#createmultipartupload + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * Bucket: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentType?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|CreateMultipartUploadRequest $input + */ + public function createMultipartUpload($input): CreateMultipartUploadOutput + { + $input = CreateMultipartUploadRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'CreateMultipartUpload', 'region' => $input->getRegion()])); + + return new CreateMultipartUploadOutput($response); + } + + /** + * Deletes the S3 bucket. All objects (including all object versions and delete markers) in the bucket must be deleted + * before the bucket itself can be deleted. + * + * The following operations are related to `DeleteBucket`: + * + * - CreateBucket [^1] + * - DeleteObject [^2] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETE.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deletebucket + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketRequest $input + */ + public function deleteBucket($input): Result + { + $input = DeleteBucketRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteBucket', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Deletes the `cors` configuration information set for the bucket. + * + * To use this operation, you must have permission to perform the `s3:PutBucketCORS` action. The bucket owner has this + * permission by default and can grant this permission to others. + * + * For information about `cors`, see Enabling Cross-Origin Resource Sharing [^1] in the *Amazon S3 User Guide*. + * + * **Related Resources** + * + * - PutBucketCors [^2] + * - RESTOPTIONSobject [^3] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketDELETEcors.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deletebucketcors + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteBucketCorsRequest $input + */ + public function deleteBucketCors($input): Result + { + $input = DeleteBucketCorsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteBucketCors', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Removes the null version (if there is one) of an object and inserts a delete marker, which becomes the latest version + * of the object. If there isn't a null version, Amazon S3 does not remove any objects but will still respond that the + * command was successful. + * + * To remove a specific version, you must use the version Id subresource. Using this subresource permanently deletes the + * version. If the object deleted is a delete marker, Amazon S3 sets the response header, `x-amz-delete-marker`, to + * true. + * + * If the object you want to delete is in a bucket where the bucket versioning configuration is MFA Delete enabled, you + * must include the `x-amz-mfa` request header in the DELETE `versionId` request. Requests that include `x-amz-mfa` must + * use HTTPS. + * + * For more information about MFA Delete, see Using MFA Delete [^1]. To see sample requests that use versioning, see + * Sample Request [^2]. + * + * You can delete objects by explicitly calling DELETE Object or configure its lifecycle (PutBucketLifecycle [^3]) to + * enable Amazon S3 to remove them for you. If you want to block users or accounts from removing or deleting objects + * from your bucket, you must deny them the `s3:DeleteObject`, `s3:DeleteObjectVersion`, and + * `s3:PutLifeCycleConfiguration` actions. + * + * The following action is related to `DeleteObject`: + * + * - PutObject [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMFADelete.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectDELETE.html#ExampleVersionObjectDelete + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycle.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectDELETE.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deleteobject + * + * @param array{ + * Bucket: string, + * Key: string, + * MFA?: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectRequest $input + */ + public function deleteObject($input): DeleteObjectOutput + { + $input = DeleteObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteObject', 'region' => $input->getRegion()])); + + return new DeleteObjectOutput($response); + } + + /** + * Removes the entire tag set from the specified object. For more information about managing object tags, see Object + * Tagging [^1]. + * + * To use this operation, you must have permission to perform the `s3:DeleteObjectTagging` action. + * + * To delete tags of a specific object version, add the `versionId` query parameter in the request. You will need + * permission for the `s3:DeleteObjectVersionTagging` action. + * + * The following operations are related to `DeleteObjectTagging`: + * + * - PutObjectTagging [^2] + * - GetObjectTagging [^3] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deleteobjecttagging + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|DeleteObjectTaggingRequest $input + */ + public function deleteObjectTagging($input): DeleteObjectTaggingOutput + { + $input = DeleteObjectTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteObjectTagging', 'region' => $input->getRegion()])); + + return new DeleteObjectTaggingOutput($response); + } + + /** + * This action enables you to delete multiple objects from a bucket using a single HTTP request. If you know the object + * keys that you want to delete, then this action provides a suitable alternative to sending individual delete requests, + * reducing per-request overhead. + * + * The request contains a list of up to 1000 keys that you want to delete. In the XML, you provide the object key names, + * and optionally, version IDs if you want to delete a specific version of the object from a versioning-enabled bucket. + * For each key, Amazon S3 performs a delete action and returns the result of that delete, success, or failure, in the + * response. Note that if the object specified in the request is not found, Amazon S3 returns the result as deleted. + * + * The action supports two modes for the response: verbose and quiet. By default, the action uses verbose mode in which + * the response includes the result of deletion of each key in your request. In quiet mode the response includes only + * keys where the delete action encountered an error. For a successful deletion, the action does not return any + * information about the delete in the response body. + * + * When performing this action on an MFA Delete enabled bucket, that attempts to delete any versioned objects, you must + * include an MFA token. If you do not provide one, the entire request will fail, even if there are non-versioned + * objects you are trying to delete. If you provide an invalid token, whether there are versioned keys in the request or + * not, the entire Multi-Object Delete request will fail. For information about MFA Delete, see MFA Delete [^1]. + * + * Finally, the Content-MD5 header is required for all Multi-Object Delete requests. Amazon S3 uses the header value to + * ensure that your request body has not been altered in transit. + * + * The following operations are related to `DeleteObjects`: + * + * - CreateMultipartUpload [^2] + * - UploadPart [^3] + * - CompleteMultipartUpload [^4] + * - ListParts [^5] + * - AbortMultipartUpload [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html#MultiFactorAuthenticationDelete + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/multiobjectdeleteapi.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#deleteobjects + * + * @param array{ + * Bucket: string, + * Delete: Delete|array, + * MFA?: string, + * RequestPayer?: RequestPayer::*, + * BypassGovernanceRetention?: bool, + * ExpectedBucketOwner?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * '@region'?: string|null, + * }|DeleteObjectsRequest $input + */ + public function deleteObjects($input): DeleteObjectsOutput + { + $input = DeleteObjectsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'DeleteObjects', 'region' => $input->getRegion()])); + + return new DeleteObjectsOutput($response); + } + + /** + * Returns the Cross-Origin Resource Sharing (CORS) configuration information set for the bucket. + * + * To use this operation, you must have permission to perform the `s3:GetBucketCORS` action. By default, the bucket + * owner has this permission and can grant it to others. + * + * To use this API operation against an access point, provide the alias of the access point in place of the bucket name. + * + * To use this API operation against an Object Lambda access point, provide the alias of the Object Lambda access point + * in place of the bucket name. If the Object Lambda access point alias in a request is not valid, the error code + * `InvalidAccessPointAliasError` is returned. For more information about `InvalidAccessPointAliasError`, see List of + * Error Codes [^1]. + * + * For more information about CORS, see Enabling Cross-Origin Resource Sharing [^2]. + * + * The following operations are related to `GetBucketCors`: + * + * - PutBucketCors [^3] + * - DeleteBucketCors [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketGETcors.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getbucketcors + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketCorsRequest $input + */ + public function getBucketCors($input): GetBucketCorsOutput + { + $input = GetBucketCorsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetBucketCors', 'region' => $input->getRegion()])); + + return new GetBucketCorsOutput($response); + } + + /** + * Returns the default encryption configuration for an Amazon S3 bucket. By default, all buckets have a default + * encryption configuration that uses server-side encryption with Amazon S3 managed keys (SSE-S3). For information about + * the bucket default encryption feature, see Amazon S3 Bucket Default Encryption [^1] in the *Amazon S3 User Guide*. + * + * To use this operation, you must have permission to perform the `s3:GetEncryptionConfiguration` action. The bucket + * owner has this permission by default. The bucket owner can grant this permission to others. For more information + * about permissions, see Permissions Related to Bucket Subresource Operations [^2] and Managing Access Permissions to + * Your Amazon S3 Resources [^3]. + * + * The following operations are related to `GetBucketEncryption`: + * + * - PutBucketEncryption [^4] + * - DeleteBucketEncryption [^5] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/bucket-encryption.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketEncryption.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getbucketencryption + * + * @param array{ + * Bucket: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetBucketEncryptionRequest $input + */ + public function getBucketEncryption($input): GetBucketEncryptionOutput + { + $input = GetBucketEncryptionRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetBucketEncryption', 'region' => $input->getRegion()])); + + return new GetBucketEncryptionOutput($response); + } + + /** + * Retrieves objects from Amazon S3. To use `GET`, you must have `READ` access to the object. If you grant `READ` access + * to the anonymous user, you can return the object without using an authorization header. + * + * An Amazon S3 bucket has no directory hierarchy such as you would find in a typical computer file system. You can, + * however, create a logical hierarchy by using object key names that imply a folder structure. For example, instead of + * naming an object `sample.jpg`, you can name it `photos/2006/February/sample.jpg`. + * + * To get an object from such a logical hierarchy, specify the full key name for the object in the `GET` operation. For + * a virtual hosted-style request example, if you have the object `photos/2006/February/sample.jpg`, specify the + * resource as `/photos/2006/February/sample.jpg`. For a path-style request example, if you have the object + * `photos/2006/February/sample.jpg` in the bucket named `examplebucket`, specify the resource as + * `/examplebucket/photos/2006/February/sample.jpg`. For more information about request types, see HTTP Host Header + * Bucket Specification [^1]. + * + * For more information about returning the ACL of an object, see GetObjectAcl [^2]. + * + * If the object you are retrieving is stored in the S3 Glacier Flexible Retrieval or S3 Glacier Deep Archive storage + * class, or S3 Intelligent-Tiering Archive or S3 Intelligent-Tiering Deep Archive tiers, before you can retrieve the + * object you must first restore a copy using RestoreObject [^3]. Otherwise, this action returns an `InvalidObjectState` + * error. For information about restoring archived objects, see Restoring Archived Objects [^4]. + * + * Encryption request headers, like `x-amz-server-side-encryption`, should not be sent for GET requests if your object + * uses server-side encryption with Key Management Service (KMS) keys (SSE-KMS), dual-layer server-side encryption with + * Amazon Web Services KMS keys (DSSE-KMS), or server-side encryption with Amazon S3 managed encryption keys (SSE-S3). + * If your object does use these types of keys, you’ll get an HTTP 400 Bad Request error. + * + * If you encrypt an object by using server-side encryption with customer-provided encryption keys (SSE-C) when you + * store the object in Amazon S3, then when you GET the object, you must use the following headers: + * + * - `x-amz-server-side-encryption-customer-algorithm` + * - `x-amz-server-side-encryption-customer-key` + * - `x-amz-server-side-encryption-customer-key-MD5` + * + * For more information about SSE-C, see Server-Side Encryption (Using Customer-Provided Encryption Keys) [^5]. + * + * Assuming you have the relevant permission to read object tags, the response also returns the `x-amz-tagging-count` + * header that provides the count of number of tags associated with the object. You can use GetObjectTagging [^6] to + * retrieve the tag set associated with an object. + * + * - `Permissions`: + * + * You need the relevant read object (or version) permission for this operation. For more information, see Specifying + * Permissions in a Policy [^7]. If the object that you request doesn’t exist, the error that Amazon S3 returns + * depends on whether you also have the `s3:ListBucket` permission. + * + * If you have the `s3:ListBucket` permission on the bucket, Amazon S3 returns an HTTP status code 404 (Not Found) + * error. + * + * If you don’t have the `s3:ListBucket` permission, Amazon S3 returns an HTTP status code 403 ("access denied") + * error. + * - `Versioning`: + * + * By default, the `GET` action returns the current version of an object. To return a different version, use the + * `versionId` subresource. + * + * > - If you supply a `versionId`, you need the `s3:GetObjectVersion` permission to access a specific version of an + * > object. If you request a specific version, you do not need to have the `s3:GetObject` permission. If you + * > request the current version without a specific version ID, only `s3:GetObject` permission is required. + * > `s3:GetObjectVersion` permission won't be required. + * > - If the current version of the object is a delete marker, Amazon S3 behaves as if the object was deleted and + * > includes `x-amz-delete-marker: true` in the response. + * > + * + * For more information about versioning, see PutBucketVersioning [^8]. + * - `Overriding Response Header Values`: + * + * There are times when you want to override certain response header values in a `GET` response. For example, you + * might override the `Content-Disposition` response header value in your `GET` request. + * + * You can override values for a set of response headers using the following query parameters. These response header + * values are sent only on a successful request, that is, when status code 200 OK is returned. The set of headers you + * can override using these parameters is a subset of the headers that Amazon S3 accepts when you create an object. + * The response headers that you can override for the `GET` response are `Content-Type`, `Content-Language`, + * `Expires`, `Cache-Control`, `Content-Disposition`, and `Content-Encoding`. To override these header values in the + * `GET` response, you use the following request parameters. + * + * > You must sign the request, either using an Authorization header or a presigned URL, when using these parameters. + * > They cannot be used with an unsigned (anonymous) request. + * + * - `response-content-type` + * - `response-content-language` + * - `response-expires` + * - `response-cache-control` + * - `response-content-disposition` + * - `response-content-encoding` + * + * - `Overriding Response Header Values`: + * + * If both of the `If-Match` and `If-Unmodified-Since` headers are present in the request as follows: `If-Match` + * condition evaluates to `true`, and; `If-Unmodified-Since` condition evaluates to `false`; then, S3 returns 200 OK + * and the data requested. + * + * If both of the `If-None-Match` and `If-Modified-Since` headers are present in the request as follows:` + * If-None-Match` condition evaluates to `false`, and; `If-Modified-Since` condition evaluates to `true`; then, S3 + * returns 304 Not Modified response code. + * + * For more information about conditional requests, see RFC 7232 [^9]. + * + * The following operations are related to `GetObject`: + * + * - ListBuckets [^10] + * - GetObjectAcl [^11] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#VirtualHostingSpecifyBucket + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_RestoreObject.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/restoring-objects.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketVersioning.html + * [^9]: https://tools.ietf.org/html/rfc7232 + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getobject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * ResponseCacheControl?: string, + * ResponseContentDisposition?: string, + * ResponseContentEncoding?: string, + * ResponseContentLanguage?: string, + * ResponseContentType?: string, + * ResponseExpires?: \DateTimeImmutable|string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|GetObjectRequest $input + * + * @throws NoSuchKeyException + * @throws InvalidObjectStateException + */ + public function getObject($input): GetObjectOutput + { + $input = GetObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + 'InvalidObjectState' => InvalidObjectStateException::class, + ]])); + + return new GetObjectOutput($response); + } + + /** + * Returns the access control list (ACL) of an object. To use this operation, you must have `s3:GetObjectAcl` + * permissions or `READ_ACP` access to the object. For more information, see Mapping of ACL permissions and access + * policy permissions [^1] in the *Amazon S3 User Guide*. + * + * This action is not supported by Amazon S3 on Outposts. + * + * By default, GET returns ACL information about the current version of an object. To return ACL information about a + * different version, use the versionId subresource. + * + * > If your bucket uses the bucket owner enforced setting for S3 Object Ownership, requests to read ACLs are still + * > supported and return the `bucket-owner-full-control` ACL with the owner being the account that created the bucket. + * > For more information, see Controlling object ownership and disabling ACLs [^2] in the *Amazon S3 User Guide*. + * + * The following operations are related to `GetObjectAcl`: + * + * - GetObject [^3] + * - GetObjectAttributes [^4] + * - DeleteObject [^5] + * - PutObject [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#acl-access-policy-permission-mapping + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGETacl.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAcl.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getobjectacl + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|GetObjectAclRequest $input + * + * @throws NoSuchKeyException + */ + public function getObjectAcl($input): GetObjectAclOutput + { + $input = GetObjectAclRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetObjectAcl', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new GetObjectAclOutput($response); + } + + /** + * Returns the tag-set of an object. You send the GET request against the tagging subresource associated with the + * object. + * + * To use this operation, you must have permission to perform the `s3:GetObjectTagging` action. By default, the GET + * action returns information about current version of an object. For a versioned bucket, you can have multiple versions + * of an object in your bucket. To retrieve tags of any other version, use the versionId query parameter. You also need + * permission for the `s3:GetObjectVersionTagging` action. + * + * By default, the bucket owner has this permission and can grant this permission to others. + * + * For information about the Amazon S3 object tagging feature, see Object Tagging [^1]. + * + * The following actions are related to `GetObjectTagging`: + * + * - DeleteObjectTagging [^2] + * - GetObjectAttributes [^3] + * - PutObjectTagging [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#getobjecttagging + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|GetObjectTaggingRequest $input + */ + public function getObjectTagging($input): GetObjectTaggingOutput + { + $input = GetObjectTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'GetObjectTagging', 'region' => $input->getRegion()])); + + return new GetObjectTaggingOutput($response); + } + + /** + * The `HEAD` action retrieves metadata from an object without returning the object itself. This action is useful if + * you're only interested in an object's metadata. To use `HEAD`, you must have READ access to the object. + * + * A `HEAD` request has the same options as a `GET` action on an object. The response is identical to the `GET` response + * except that there is no response body. Because of this, if the `HEAD` request generates an error, it returns a + * generic `400 Bad Request`, `403 Forbidden` or `404 Not Found` code. It is not possible to retrieve the exact + * exception beyond these error codes. + * + * If you encrypt an object by using server-side encryption with customer-provided encryption keys (SSE-C) when you + * store the object in Amazon S3, then when you retrieve the metadata from the object, you must use the following + * headers: + * + * - `x-amz-server-side-encryption-customer-algorithm` + * - `x-amz-server-side-encryption-customer-key` + * - `x-amz-server-side-encryption-customer-key-MD5` + * + * For more information about SSE-C, see Server-Side Encryption (Using Customer-Provided Encryption Keys) [^1]. + * + * > - Encryption request headers, like `x-amz-server-side-encryption`, should not be sent for `GET` requests if your + * > object uses server-side encryption with Key Management Service (KMS) keys (SSE-KMS), dual-layer server-side + * > encryption with Amazon Web Services KMS keys (DSSE-KMS), or server-side encryption with Amazon S3 managed + * > encryption keys (SSE-S3). If your object does use these types of keys, you’ll get an HTTP 400 Bad Request + * > error. + * > - The last modified property in this case is the creation date of the object. + * > + * + * Request headers are limited to 8 KB in size. For more information, see Common Request Headers [^2]. + * + * Consider the following when using request headers: + * + * - Consideration 1 – If both of the `If-Match` and `If-Unmodified-Since` headers are present in the request as + * follows: + * + * - `If-Match` condition evaluates to `true`, and; + * - `If-Unmodified-Since` condition evaluates to `false`; + * + * Then Amazon S3 returns `200 OK` and the data requested. + * - Consideration 2 – If both of the `If-None-Match` and `If-Modified-Since` headers are present in the request as + * follows: + * + * - `If-None-Match` condition evaluates to `false`, and; + * - `If-Modified-Since` condition evaluates to `true`; + * + * Then Amazon S3 returns the `304 Not Modified` response code. + * + * For more information about conditional requests, see RFC 7232 [^3]. + * + * - `Permissions`: + * + * You need the relevant read object (or version) permission for this operation. For more information, see Actions, + * resources, and condition keys for Amazon S3 [^4]. If the object you request doesn't exist, the error that Amazon S3 + * returns depends on whether you also have the s3:ListBucket permission. + * + * - If you have the `s3:ListBucket` permission on the bucket, Amazon S3 returns an HTTP status code 404 error. + * - If you don’t have the `s3:ListBucket` permission, Amazon S3 returns an HTTP status code 403 error. + * + * + * The following actions are related to `HeadObject`: + * + * - GetObject [^5] + * - GetObjectAttributes [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html + * [^3]: https://tools.ietf.org/html/rfc7232 + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/list_amazons3.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectHEAD.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#headobject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + * + * @throws NoSuchKeyException + */ + public function headObject($input): HeadObjectOutput + { + $input = HeadObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new HeadObjectOutput($response); + } + + /** + * Returns a list of all buckets owned by the authenticated sender of the request. To use this operation, you must have + * the `s3:ListAllMyBuckets` permission. + * + * For information about Amazon S3 buckets, see Creating, configuring, and working with Amazon S3 buckets [^1]. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-buckets-s3.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTServiceGET.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listbuckets + * + * @param array{ + * '@region'?: string|null, + * }|ListBucketsRequest $input + */ + public function listBuckets($input = []): ListBucketsOutput + { + $input = ListBucketsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListBuckets', 'region' => $input->getRegion()])); + + return new ListBucketsOutput($response); + } + + /** + * This action lists in-progress multipart uploads. An in-progress multipart upload is a multipart upload that has been + * initiated using the Initiate Multipart Upload request, but has not yet been completed or aborted. + * + * This action returns at most 1,000 multipart uploads in the response. 1,000 multipart uploads is the maximum number of + * uploads a response can include, which is also the default value. You can further limit the number of uploads in a + * response by specifying the `max-uploads` parameter in the response. If additional multipart uploads satisfy the list + * criteria, the response will contain an `IsTruncated` element with the value true. To list the additional multipart + * uploads, use the `key-marker` and `upload-id-marker` request parameters. + * + * In the response, the uploads are sorted by key. If your application has initiated more than one multipart upload + * using the same object key, then uploads in the response are first sorted by key. Additionally, uploads are sorted in + * ascending order within each key by the upload initiation time. + * + * For more information on multipart uploads, see Uploading Objects Using Multipart Upload [^1]. + * + * For information on permissions required to use the multipart upload API, see Multipart Upload and Permissions [^2]. + * + * The following operations are related to `ListMultipartUploads`: + * + * - CreateMultipartUpload [^3] + * - UploadPart [^4] + * - CompleteMultipartUpload [^5] + * - ListParts [^6] + * - AbortMultipartUpload [^7] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListMPUpload.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listmultipartuploads + * + * @param array{ + * Bucket: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * KeyMarker?: string, + * MaxUploads?: int, + * Prefix?: string, + * UploadIdMarker?: string, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|ListMultipartUploadsRequest $input + */ + public function listMultipartUploads($input): ListMultipartUploadsOutput + { + $input = ListMultipartUploadsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListMultipartUploads', 'region' => $input->getRegion()])); + + return new ListMultipartUploadsOutput($response, $this, $input); + } + + /** + * Returns some or all (up to 1,000) of the objects in a bucket with each request. You can use the request parameters as + * selection criteria to return a subset of the objects in a bucket. A `200 OK` response can contain valid or invalid + * XML. Make sure to design your application to parse the contents of the response and handle it appropriately. Objects + * are returned sorted in an ascending order of the respective key names in the list. For more information about listing + * objects, see Listing object keys programmatically [^1] in the *Amazon S3 User Guide*. + * + * To use this operation, you must have READ access to the bucket. + * + * To use this action in an Identity and Access Management (IAM) policy, you must have permission to perform the + * `s3:ListBucket` action. The bucket owner has this permission by default and can grant this permission to others. For + * more information about permissions, see Permissions Related to Bucket Subresource Operations [^2] and Managing Access + * Permissions to Your Amazon S3 Resources [^3] in the *Amazon S3 User Guide*. + * + * ! This section describes the latest revision of this action. We recommend that you use this revised API operation for + * ! application development. For backward compatibility, Amazon S3 continues to support the prior version of this API + * ! operation, ListObjects [^4]. + * + * To get a list of your buckets, see ListBuckets [^5]. + * + * The following operations are related to `ListObjectsV2`: + * + * - GetObject [^6] + * - PutObject [^7] + * - CreateBucket [^8] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/ListingKeysUsingAPIs.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listobjectsv2 + * + * @param array{ + * Bucket: string, + * Delimiter?: string, + * EncodingType?: EncodingType::*, + * MaxKeys?: int, + * Prefix?: string, + * ContinuationToken?: string, + * FetchOwner?: bool, + * StartAfter?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * OptionalObjectAttributes?: array, + * '@region'?: string|null, + * }|ListObjectsV2Request $input + * + * @throws NoSuchBucketException + */ + public function listObjectsV2($input): ListObjectsV2Output + { + $input = ListObjectsV2Request::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListObjectsV2', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchBucket' => NoSuchBucketException::class, + ]])); + + return new ListObjectsV2Output($response, $this, $input); + } + + /** + * Lists the parts that have been uploaded for a specific multipart upload. This operation must include the upload ID, + * which you obtain by sending the initiate multipart upload request (see CreateMultipartUpload [^1]). This request + * returns a maximum of 1,000 uploaded parts. The default number of parts returned is 1,000 parts. You can restrict the + * number of parts returned by specifying the `max-parts` request parameter. If your multipart upload consists of more + * than 1,000 parts, the response returns an `IsTruncated` field with the value of true, and a `NextPartNumberMarker` + * element. In subsequent `ListParts` requests you can include the part-number-marker query string parameter and set its + * value to the `NextPartNumberMarker` field value from the previous response. + * + * If the upload was created using a checksum algorithm, you will need to have permission to the `kms:Decrypt` action + * for the request to succeed. + * + * For more information on multipart uploads, see Uploading Objects Using Multipart Upload [^2]. + * + * For information on permissions required to use the multipart upload API, see Multipart Upload and Permissions [^3]. + * + * The following operations are related to `ListParts`: + * + * - CreateMultipartUpload [^4] + * - UploadPart [^5] + * - CompleteMultipartUpload [^6] + * - AbortMultipartUpload [^7] + * - GetObjectAttributes [^8] + * - ListMultipartUploads [^9] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListParts.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listparts + * + * @param array{ + * Bucket: string, + * Key: string, + * MaxParts?: int, + * PartNumberMarker?: int, + * UploadId: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * '@region'?: string|null, + * }|ListPartsRequest $input + */ + public function listParts($input): ListPartsOutput + { + $input = ListPartsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'ListParts', 'region' => $input->getRegion()])); + + return new ListPartsOutput($response, $this, $input); + } + + /** + * @see headObject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + */ + public function objectExists($input): ObjectExistsWaiter + { + $input = HeadObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new ObjectExistsWaiter($response, $this, $input); + } + + /** + * @see headObject + * + * @param array{ + * Bucket: string, + * IfMatch?: string, + * IfModifiedSince?: \DateTimeImmutable|string, + * IfNoneMatch?: string, + * IfUnmodifiedSince?: \DateTimeImmutable|string, + * Key: string, + * Range?: string, + * VersionId?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * PartNumber?: int, + * ExpectedBucketOwner?: string, + * ChecksumMode?: ChecksumMode::*, + * '@region'?: string|null, + * }|HeadObjectRequest $input + */ + public function objectNotExists($input): ObjectNotExistsWaiter + { + $input = HeadObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'HeadObject', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new ObjectNotExistsWaiter($response, $this, $input); + } + + /** + * Sets the `cors` configuration for your bucket. If the configuration exists, Amazon S3 replaces it. + * + * To use this operation, you must be allowed to perform the `s3:PutBucketCORS` action. By default, the bucket owner has + * this permission and can grant it to others. + * + * You set this configuration on a bucket so that the bucket can service cross-origin requests. For example, you might + * want to enable a request whose origin is `http://www.example.com` to access your Amazon S3 bucket at + * `my.example.bucket.com` by using the browser's `XMLHttpRequest` capability. + * + * To enable cross-origin resource sharing (CORS) on a bucket, you add the `cors` subresource to the bucket. The `cors` + * subresource is an XML document in which you configure rules that identify origins and the HTTP methods that can be + * executed on your bucket. The document is limited to 64 KB in size. + * + * When Amazon S3 receives a cross-origin request (or a pre-flight OPTIONS request) against a bucket, it evaluates the + * `cors` configuration on the bucket and uses the first `CORSRule` rule that matches the incoming browser request to + * enable a cross-origin request. For a rule to match, the following conditions must be met: + * + * - The request's `Origin` header must match `AllowedOrigin` elements. + * - The request method (for example, GET, PUT, HEAD, and so on) or the `Access-Control-Request-Method` header in case + * of a pre-flight `OPTIONS` request must be one of the `AllowedMethod` elements. + * - Every header specified in the `Access-Control-Request-Headers` request header of a pre-flight request must match an + * `AllowedHeader` element. + * + * For more information about CORS, go to Enabling Cross-Origin Resource Sharing [^1] in the *Amazon S3 User Guide*. + * + * The following operations are related to `PutBucketCors`: + * + * - GetBucketCors [^2] + * - DeleteBucketCors [^3] + * - RESTOPTIONSobject [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketCors.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketCors.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTOPTIONSobject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTcors.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketCors.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putbucketcors + * + * @param array{ + * Bucket: string, + * CORSConfiguration: CORSConfiguration|array, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketCorsRequest $input + */ + public function putBucketCors($input): Result + { + $input = PutBucketCorsRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutBucketCors', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Enables notifications of specified events for a bucket. For more information about event notifications, see + * Configuring Event Notifications [^1]. + * + * Using this API, you can replace an existing notification configuration. The configuration is an XML file that defines + * the event types that you want Amazon S3 to publish and the destination where you want Amazon S3 to publish an event + * notification when it detects an event of the specified type. + * + * By default, your bucket has no event notifications configured. That is, the notification configuration will be an + * empty `NotificationConfiguration`. + * + * `` + * + * `` + * + * This action replaces the existing notification configuration with the configuration you include in the request body. + * + * After Amazon S3 receives this request, it first verifies that any Amazon Simple Notification Service (Amazon SNS) or + * Amazon Simple Queue Service (Amazon SQS) destination exists, and that the bucket owner has permission to publish to + * it by sending a test notification. In the case of Lambda destinations, Amazon S3 verifies that the Lambda function + * permissions grant Amazon S3 permission to invoke the function from the Amazon S3 bucket. For more information, see + * Configuring Notifications for Amazon S3 Events [^2]. + * + * You can disable notifications by adding the empty NotificationConfiguration element. + * + * For more information about the number of event notification configurations that you can create per bucket, see Amazon + * S3 service quotas [^3] in *Amazon Web Services General Reference*. + * + * By default, only the bucket owner can configure notifications on a bucket. However, bucket owners can use a bucket + * policy to grant permission to other users to set this configuration with the required `s3:PutBucketNotification` + * permission. + * + * > The PUT notification is an atomic operation. For example, suppose your notification configuration includes SNS + * > topic, SQS queue, and Lambda function configurations. When you send a PUT request with this configuration, Amazon + * > S3 sends test messages to your SNS topic. If the message fails, the entire PUT action will fail, and Amazon S3 will + * > not add the configuration to your bucket. + * + * If the configuration in the request body includes only one `TopicConfiguration` specifying only the + * `s3:ReducedRedundancyLostObject` event type, the response will also include the `x-amz-sns-test-message-id` header + * containing the message ID of the test notification sent to the topic. + * + * The following action is related to `PutBucketNotificationConfiguration`: + * + * - GetBucketNotificationConfiguration [^4] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html + * [^3]: https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3 + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotificationConfiguration.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putbucketnotificationconfiguration + * + * @param array{ + * Bucket: string, + * NotificationConfiguration: NotificationConfiguration|array, + * ExpectedBucketOwner?: string, + * SkipDestinationValidation?: bool, + * '@region'?: string|null, + * }|PutBucketNotificationConfigurationRequest $input + */ + public function putBucketNotificationConfiguration($input): Result + { + $input = PutBucketNotificationConfigurationRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutBucketNotificationConfiguration', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Sets the tags for a bucket. + * + * Use tags to organize your Amazon Web Services bill to reflect your own cost structure. To do this, sign up to get + * your Amazon Web Services account bill with tag key values included. Then, to see the cost of combined resources, + * organize your billing information according to resources with the same tag key values. For example, you can tag + * several resources with a specific application name, and then organize your billing information to see the total cost + * of that application across several services. For more information, see Cost Allocation and Tagging [^1] and Using + * Cost Allocation in Amazon S3 Bucket Tags [^2]. + * + * > When this operation sets the tags for a bucket, it will overwrite any current tags the bucket already has. You + * > cannot use this operation to add tags to an existing list of tags. + * + * To use this operation, you must have permissions to perform the `s3:PutBucketTagging` action. The bucket owner has + * this permission by default and can grant this permission to others. For more information about permissions, see + * Permissions Related to Bucket Subresource Operations [^3] and Managing Access Permissions to Your Amazon S3 Resources + * [^4]. + * + * `PutBucketTagging` has the following special errors: + * + * - Error code: `InvalidTagError` + * + * - Description: The tag provided was not a valid tag. This error can occur if the tag did not pass input validation. + * For information about tag restrictions, see User-Defined Tag Restrictions [^5] and Amazon Web Services-Generated + * Cost Allocation Tag Restrictions [^6]. + * + * - Error code: `MalformedXMLError` + * + * - Description: The XML provided does not match the schema. + * + * - Error code: `OperationAbortedError ` + * + * - Description: A conflicting conditional action is currently in progress against this resource. Please try again. + * + * - Error code: `InternalError` + * + * - Description: The service was unable to apply the provided tag to the bucket. + * + * + * The following operations are related to `PutBucketTagging`: + * + * - GetBucketTagging [^7] + * - DeleteBucketTagging [^8] + * + * [^1]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/CostAllocTagging.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-bucket-subresources + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html + * [^5]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html + * [^6]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/aws-tag-restrictions.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucketTagging.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTBucketPUTtagging.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putbuckettagging + * + * @param array{ + * Bucket: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging: Tagging|array, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutBucketTaggingRequest $input + */ + public function putBucketTagging($input): Result + { + $input = PutBucketTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutBucketTagging', 'region' => $input->getRegion()])); + + return new Result($response); + } + + /** + * Adds an object to a bucket. You must have WRITE permissions on a bucket to add an object to it. + * + * > Amazon S3 never adds partial objects; if you receive a success response, Amazon S3 added the entire object to the + * > bucket. You cannot use `PutObject` to only update a single piece of metadata for an existing object. You must put + * > the entire object with updated metadata if you want to update some values. + * + * Amazon S3 is a distributed system. If it receives multiple write requests for the same object simultaneously, it + * overwrites all but the last object written. To prevent objects from being deleted or overwritten, you can use Amazon + * S3 Object Lock [^1]. + * + * To ensure that data is not corrupted traversing the network, use the `Content-MD5` header. When you use this header, + * Amazon S3 checks the object against the provided MD5 value and, if they do not match, returns an error. Additionally, + * you can calculate the MD5 while putting an object to Amazon S3 and compare the returned ETag to the calculated MD5 + * value. + * + * > - To successfully complete the `PutObject` request, you must have the `s3:PutObject` in your IAM permissions. + * > - To successfully change the objects acl of your `PutObject` request, you must have the `s3:PutObjectAcl` in your + * > IAM permissions. + * > - To successfully set the tag-set with your `PutObject` request, you must have the `s3:PutObjectTagging` in your + * > IAM permissions. + * > - The `Content-MD5` header is required for any request to upload an object with a retention period configured using + * > Amazon S3 Object Lock. For more information about Amazon S3 Object Lock, see Amazon S3 Object Lock Overview [^2] + * > in the *Amazon S3 User Guide*. + * > + * + * You have four mutually exclusive options to protect data using server-side encryption in Amazon S3, depending on how + * you choose to manage the encryption keys. Specifically, the encryption key options are Amazon S3 managed keys + * (SSE-S3), Amazon Web Services KMS keys (SSE-KMS or DSSE-KMS), and customer-provided keys (SSE-C). Amazon S3 encrypts + * data with server-side encryption by using Amazon S3 managed keys (SSE-S3) by default. You can optionally tell Amazon + * S3 to encrypt data at rest by using server-side encryption with other key options. For more information, see Using + * Server-Side Encryption [^3]. + * + * When adding a new object, you can use headers to grant ACL-based permissions to individual Amazon Web Services + * accounts or to predefined groups defined by Amazon S3. These permissions are then added to the ACL on the object. By + * default, all objects are private. Only the owner has full access control. For more information, see Access Control + * List (ACL) Overview [^4] and Managing ACLs Using the REST API [^5]. + * + * If the bucket that you're uploading objects to uses the bucket owner enforced setting for S3 Object Ownership, ACLs + * are disabled and no longer affect permissions. Buckets that use this setting only accept PUT requests that don't + * specify an ACL or PUT requests that specify bucket owner full control ACLs, such as the `bucket-owner-full-control` + * canned ACL or an equivalent form of this ACL expressed in the XML format. PUT requests that contain other ACLs (for + * example, custom grants to certain Amazon Web Services accounts) fail and return a `400` error with the error code + * `AccessControlListNotSupported`. For more information, see Controlling ownership of objects and disabling ACLs [^6] + * in the *Amazon S3 User Guide*. + * + * > If your bucket uses the bucket owner enforced setting for Object Ownership, all objects written to the bucket by + * > any account will be owned by the bucket owner. + * + * By default, Amazon S3 uses the STANDARD Storage Class to store newly created objects. The STANDARD storage class + * provides high durability and high availability. Depending on performance needs, you can specify a different Storage + * Class. Amazon S3 on Outposts only uses the OUTPOSTS Storage Class. For more information, see Storage Classes [^7] in + * the *Amazon S3 User Guide*. + * + * If you enable versioning for a bucket, Amazon S3 automatically generates a unique version ID for the object being + * stored. Amazon S3 returns this ID in the response. When you enable versioning for a bucket, if Amazon S3 receives + * multiple write requests for the same object simultaneously, it stores all of the objects. For more information about + * versioning, see Adding Objects to Versioning-Enabled Buckets [^8]. For information about returning the versioning + * state of a bucket, see GetBucketVersioning [^9]. + * + * For more information about related Amazon S3 APIs, see the following: + * + * - CopyObject [^10] + * - DeleteObject [^11] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock-overview.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/dev/AddingObjectstoVersioningEnabledBuckets.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketVersioning.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUT.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobject + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket: string, + * CacheControl?: string, + * ContentDisposition?: string, + * ContentEncoding?: string, + * ContentLanguage?: string, + * ContentLength?: int, + * ContentMD5?: string, + * ContentType?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Expires?: \DateTimeImmutable|string, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWriteACP?: string, + * Key: string, + * Metadata?: array, + * ServerSideEncryption?: ServerSideEncryption::*, + * StorageClass?: StorageClass::*, + * WebsiteRedirectLocation?: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * SSEKMSKeyId?: string, + * SSEKMSEncryptionContext?: string, + * BucketKeyEnabled?: bool, + * RequestPayer?: RequestPayer::*, + * Tagging?: string, + * ObjectLockMode?: ObjectLockMode::*, + * ObjectLockRetainUntilDate?: \DateTimeImmutable|string, + * ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectRequest $input + */ + public function putObject($input): PutObjectOutput + { + $input = PutObjectRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObject', 'region' => $input->getRegion()])); + + return new PutObjectOutput($response); + } + + /** + * Uses the `acl` subresource to set the access control list (ACL) permissions for a new or existing object in an S3 + * bucket. You must have `WRITE_ACP` permission to set the ACL of an object. For more information, see What permissions + * can I grant? [^1] in the *Amazon S3 User Guide*. + * + * This action is not supported by Amazon S3 on Outposts. + * + * Depending on your application needs, you can choose to set the ACL on an object using either the request body or the + * headers. For example, if you have an existing application that updates a bucket ACL using the request body, you can + * continue to use that approach. For more information, see Access Control List (ACL) Overview [^2] in the *Amazon S3 + * User Guide*. + * + * ! If your bucket uses the bucket owner enforced setting for S3 Object Ownership, ACLs are disabled and no longer + * ! affect permissions. You must use policies to grant access to your bucket and the objects in it. Requests to set + * ! ACLs or update ACLs fail and return the `AccessControlListNotSupported` error code. Requests to read ACLs are still + * ! supported. For more information, see Controlling object ownership [^3] in the *Amazon S3 User Guide*. + * + * - `Permissions`: + * + * You can set access permissions using one of the following methods: + * + * - Specify a canned ACL with the `x-amz-acl` request header. Amazon S3 supports a set of predefined ACLs, known as + * canned ACLs. Each canned ACL has a predefined set of grantees and permissions. Specify the canned ACL name as the + * value of `x-amz-ac`l. If you use this header, you cannot use other access control-specific headers in your + * request. For more information, see Canned ACL [^4]. + * - Specify access permissions explicitly with the `x-amz-grant-read`, `x-amz-grant-read-acp`, + * `x-amz-grant-write-acp`, and `x-amz-grant-full-control` headers. When using these headers, you specify explicit + * access permissions and grantees (Amazon Web Services accounts or Amazon S3 groups) who will receive the + * permission. If you use these ACL-specific headers, you cannot use `x-amz-acl` header to set a canned ACL. These + * parameters map to the set of permissions that Amazon S3 supports in an ACL. For more information, see Access + * Control List (ACL) Overview [^5]. + * + * You specify each grantee as a type=value pair, where the type is one of the following: + * + * - `id` – if the value specified is the canonical user ID of an Amazon Web Services account + * - `uri` – if you are granting permissions to a predefined group + * - `emailAddress` – if the value specified is the email address of an Amazon Web Services account + * + * > Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^6] in the Amazon + * > Web Services General Reference. + * + * + * For example, the following `x-amz-grant-read` header grants list objects permission to the two Amazon Web + * Services accounts identified by their email addresses. + * + * `x-amz-grant-read: emailAddress="xyz@amazon.com", emailAddress="abc@amazon.com" ` + * + * You can use either a canned ACL or specify access permissions explicitly. You cannot do both. + * - `Grantee Values`: + * + * You can specify the person (grantee) to whom you're assigning access rights (using request elements) in the + * following ways: + * + * - By the person's ID: + * + * `<>ID<><>GranteesEmail<> + * ` + * + * DisplayName is optional and ignored in the request. + * - By URI: + * + * `<>http://acs.amazonaws.com/groups/global/AuthenticatedUsers<>` + * - By Email address: + * + * `<>Grantees@email.com<>lt;/Grantee>` + * + * The grantee is resolved to the CanonicalUser and, in a response to a GET Object acl request, appears as the + * CanonicalUser. + * + * > Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^7] in the Amazon + * > Web Services General Reference. + * + * + * - `Versioning`: + * + * The ACL of an object is set at the object version level. By default, PUT sets the ACL of the current version of an + * object. To set the ACL of a different version, use the `versionId` subresource. + * + * The following operations are related to `PutObjectAcl`: + * + * - CopyObject [^8] + * - GetObject [^9] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#permissions + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html + * [^6]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * [^7]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectPUTacl.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectAcl.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobjectacl + * + * @param array{ + * ACL?: ObjectCannedACL::*, + * AccessControlPolicy?: AccessControlPolicy|array, + * Bucket: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * GrantFullControl?: string, + * GrantRead?: string, + * GrantReadACP?: string, + * GrantWrite?: string, + * GrantWriteACP?: string, + * Key: string, + * RequestPayer?: RequestPayer::*, + * VersionId?: string, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|PutObjectAclRequest $input + * + * @throws NoSuchKeyException + */ + public function putObjectAcl($input): PutObjectAclOutput + { + $input = PutObjectAclRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObjectAcl', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'NoSuchKey' => NoSuchKeyException::class, + ]])); + + return new PutObjectAclOutput($response); + } + + /** + * Sets the supplied tag-set to an object that already exists in a bucket. + * + * A tag is a key-value pair. You can associate tags with an object by sending a PUT request against the tagging + * subresource that is associated with the object. You can retrieve tags by sending a GET request. For more information, + * see GetObjectTagging [^1]. + * + * For tagging-related restrictions related to characters and encodings, see Tag Restrictions [^2]. Note that Amazon S3 + * limits the maximum number of tags to 10 tags per object. + * + * To use this operation, you must have permission to perform the `s3:PutObjectTagging` action. By default, the bucket + * owner has this permission and can grant this permission to others. + * + * To put tags of any other version, use the `versionId` query parameter. You also need permission for the + * `s3:PutObjectVersionTagging` action. + * + * For information about the Amazon S3 object tagging feature, see Object Tagging [^3]. + * + * `PutObjectTagging` has the following special errors: + * + * - - *Code: InvalidTagError * + * - - *Cause: The tag provided was not a valid tag. This error can occur if the tag did not pass input validation. For + * - more information, see Object Tagging [^4].* + * - + * - - *Code: MalformedXMLError * + * - - *Cause: The XML provided does not match the schema.* + * - + * - - *Code: OperationAbortedError * + * - - *Cause: A conflicting conditional action is currently in progress against this resource. Please try again.* + * - + * - - *Code: InternalError* + * - - *Cause: The service was unable to apply the provided tag to the object.* + * - + * + * The following operations are related to `PutObjectTagging`: + * + * - GetObjectTagging [^5] + * - DeleteObjectTagging [^6] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * [^2]: https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-tagging.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectTagging.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjectTagging.html + * + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectTagging.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#putobjecttagging + * + * @param array{ + * Bucket: string, + * Key: string, + * VersionId?: string, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * Tagging: Tagging|array, + * ExpectedBucketOwner?: string, + * RequestPayer?: RequestPayer::*, + * '@region'?: string|null, + * }|PutObjectTaggingRequest $input + */ + public function putObjectTagging($input): PutObjectTaggingOutput + { + $input = PutObjectTaggingRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'PutObjectTagging', 'region' => $input->getRegion()])); + + return new PutObjectTaggingOutput($response); + } + + /** + * Uploads a part in a multipart upload. + * + * > In this operation, you provide part data in your request. However, you have an option to specify your existing + * > Amazon S3 object as a data source for the part you are uploading. To upload a part from an existing object, you use + * > the UploadPartCopy [^1] operation. + * + * You must initiate a multipart upload (see CreateMultipartUpload [^2]) before you can upload any part. In response to + * your initiate request, Amazon S3 returns an upload ID, a unique identifier, that you must include in your upload part + * request. + * + * Part numbers can be any number from 1 to 10,000, inclusive. A part number uniquely identifies a part and also defines + * its position within the object being created. If you upload a new part using the same part number that was used with + * a previous part, the previously uploaded part is overwritten. + * + * For information about maximum and minimum part sizes and other multipart upload specifications, see Multipart upload + * limits [^3] in the *Amazon S3 User Guide*. + * + * To ensure that data is not corrupted when traversing the network, specify the `Content-MD5` header in the upload part + * request. Amazon S3 checks the part data against the provided MD5 value. If they do not match, Amazon S3 returns an + * error. + * + * If the upload request is signed with Signature Version 4, then Amazon Web Services S3 uses the `x-amz-content-sha256` + * header as a checksum instead of `Content-MD5`. For more information see Authenticating Requests: Using the + * Authorization Header (Amazon Web Services Signature Version 4) [^4]. + * + * **Note:** After you initiate multipart upload and upload one or more parts, you must either complete or abort + * multipart upload in order to stop getting charged for storage of the uploaded parts. Only after you either complete + * or abort multipart upload, Amazon S3 frees up the parts storage and stops charging you for the parts storage. + * + * For more information on multipart uploads, go to Multipart Upload Overview [^5] in the *Amazon S3 User Guide *. + * + * For information on the permissions required to use the multipart upload API, go to Multipart Upload and Permissions + * [^6] in the *Amazon S3 User Guide*. + * + * Server-side encryption is for data encryption at rest. Amazon S3 encrypts your data as it writes it to disks in its + * data centers and decrypts it when you access it. You have three mutually exclusive options to protect data using + * server-side encryption in Amazon S3, depending on how you choose to manage the encryption keys. Specifically, the + * encryption key options are Amazon S3 managed keys (SSE-S3), Amazon Web Services KMS keys (SSE-KMS), and + * Customer-Provided Keys (SSE-C). Amazon S3 encrypts data with server-side encryption using Amazon S3 managed keys + * (SSE-S3) by default. You can optionally tell Amazon S3 to encrypt data at rest using server-side encryption with + * other key options. The option you use depends on whether you want to use KMS keys (SSE-KMS) or provide your own + * encryption key (SSE-C). If you choose to provide your own encryption key, the request headers you provide in the + * request must match the headers you used in the request to initiate the upload by using CreateMultipartUpload [^7]. + * For more information, go to Using Server-Side Encryption [^8] in the *Amazon S3 User Guide*. + * + * Server-side encryption is supported by the S3 Multipart Upload actions. Unless you are using a customer-provided + * encryption key (SSE-C), you don't need to specify the encryption parameters in each UploadPart request. Instead, you + * only need to specify the server-side encryption parameters in the initial Initiate Multipart request. For more + * information, see CreateMultipartUpload [^9]. + * + * If you requested server-side encryption using a customer-provided encryption key (SSE-C) in your initiate multipart + * upload request, you must provide identical encryption information in each part upload using the following headers. + * + * - x-amz-server-side-encryption-customer-algorithm + * - x-amz-server-side-encryption-customer-key + * - x-amz-server-side-encryption-customer-key-MD5 + * + * `UploadPart` has the following special errors: + * + * - - *Code: NoSuchUpload* + * - - *Cause: The specified multipart upload does not exist. The upload ID might be invalid, or the multipart upload + * - might have been aborted or completed.* + * - - * HTTP Status Code: 404 Not Found * + * - - *SOAP Fault Code Prefix: Client* + * - + * + * The following operations are related to `UploadPart`: + * + * - CreateMultipartUpload [^10] + * - CompleteMultipartUpload [^11] + * - AbortMultipartUpload [^12] + * - ListParts [^13] + * - ListMultipartUploads [^14] + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPartCopy.html + * [^2]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^3]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/qfacts.html + * [^4]: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html + * [^5]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuoverview.html + * [^6]: https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html + * [^7]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^8]: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html + * [^9]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^10]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html + * [^11]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html + * [^12]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html + * [^13]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html + * [^14]: https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html + * + * @see http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPart.html + * @see https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#uploadpart + * + * @param array{ + * Body?: string|resource|(callable(int): string)|iterable, + * Bucket: string, + * ContentLength?: int, + * ContentMD5?: string, + * ChecksumAlgorithm?: ChecksumAlgorithm::*, + * ChecksumCRC32?: string, + * ChecksumCRC32C?: string, + * ChecksumSHA1?: string, + * ChecksumSHA256?: string, + * Key: string, + * PartNumber: int, + * UploadId: string, + * SSECustomerAlgorithm?: string, + * SSECustomerKey?: string, + * SSECustomerKeyMD5?: string, + * RequestPayer?: RequestPayer::*, + * ExpectedBucketOwner?: string, + * '@region'?: string|null, + * }|UploadPartRequest $input + */ + public function uploadPart($input): UploadPartOutput + { + $input = UploadPartRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'UploadPart', 'region' => $input->getRegion()])); + + return new UploadPartOutput($response); + } + + protected function getAwsErrorFactory(): AwsErrorFactoryInterface + { + return new XmlAwsErrorFactory(); + } + + protected function getEndpoint(string $uri, array $query, ?string $region): string + { + $uriParts = explode('/', $uri, 3); + $bucket = explode('?', $uriParts[1] ?? '', 2)[0]; + $uriWithOutBucket = substr($uriParts[1] ?? '', \strlen($bucket)) . ($uriParts[2] ?? ''); + $bucketLen = \strlen($bucket); + $configuration = $this->getConfiguration(); + + if ( + $bucketLen < 3 || $bucketLen > 63 + || filter_var($bucket, \FILTER_VALIDATE_IP) // Cannot look like an IP address + || !preg_match('/^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$/', $bucket) // Bucket cannot have dot (because of TLS) + || filter_var(parse_url($configuration->get('endpoint'), \PHP_URL_HOST), \FILTER_VALIDATE_IP) // Custom endpoint cannot look like an IP address + || filter_var($configuration->get('pathStyleEndpoint'), \FILTER_VALIDATE_BOOLEAN) + ) { + return parent::getEndpoint($uri, $query, $region); + } + + return preg_replace('|https?://|', '${0}' . $bucket . '.', parent::getEndpoint('/' . $uriWithOutBucket, $query, $region)); + } + + protected function getEndpointMetadata(?string $region): array + { + if (null === $region) { + return [ + 'endpoint' => 'https://s3.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + } + + switch ($region) { + case 'af-south-1': + case 'ap-east-1': + case 'ap-northeast-1': + case 'ap-northeast-2': + case 'ap-northeast-3': + case 'ap-south-1': + case 'ap-south-2': + case 'ap-southeast-1': + case 'ap-southeast-2': + case 'ap-southeast-3': + case 'ap-southeast-4': + case 'ca-central-1': + case 'eu-central-1': + case 'eu-central-2': + case 'eu-north-1': + case 'eu-south-1': + case 'eu-south-2': + case 'eu-west-1': + case 'eu-west-2': + case 'eu-west-3': + case 'il-central-1': + case 'me-central-1': + case 'me-south-1': + case 'sa-east-1': + case 'us-east-1': + case 'us-east-2': + case 'us-gov-east-1': + case 'us-gov-west-1': + case 'us-west-1': + case 'us-west-2': + return [ + 'endpoint' => "https://s3.$region.amazonaws.com", + 'signRegion' => $region, + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'cn-north-1': + case 'cn-northwest-1': + return [ + 'endpoint' => "https://s3.$region.amazonaws.com.cn", + 'signRegion' => $region, + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 's3-external-1': + return [ + 'endpoint' => 'https://s3-external-1.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-ca-central-1': + return [ + 'endpoint' => 'https://s3-fips.ca-central-1.amazonaws.com', + 'signRegion' => 'ca-central-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-east-1': + return [ + 'endpoint' => 'https://s3-fips.us-east-1.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-east-2': + return [ + 'endpoint' => 'https://s3-fips.us-east-2.amazonaws.com', + 'signRegion' => 'us-east-2', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-west-1': + return [ + 'endpoint' => 'https://s3-fips.us-west-1.amazonaws.com', + 'signRegion' => 'us-west-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-west-2': + return [ + 'endpoint' => 'https://s3-fips.us-west-2.amazonaws.com', + 'signRegion' => 'us-west-2', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-gov-east-1': + return [ + 'endpoint' => 'https://s3-fips.us-gov-east-1.amazonaws.com', + 'signRegion' => 'us-gov-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'fips-us-gov-west-1': + return [ + 'endpoint' => 'https://s3-fips.us-gov-west-1.amazonaws.com', + 'signRegion' => 'us-gov-west-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'us-iso-east-1': + case 'us-iso-west-1': + return [ + 'endpoint' => "https://s3.$region.c2s.ic.gov", + 'signRegion' => $region, + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + case 'us-isob-east-1': + return [ + 'endpoint' => 'https://s3.us-isob-east-1.sc2s.sgov.gov', + 'signRegion' => 'us-isob-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + } + + return [ + 'endpoint' => 'https://s3.amazonaws.com', + 'signRegion' => 'us-east-1', + 'signService' => 's3', + 'signVersions' => ['s3v4'], + ]; + } + + protected function getServiceCode(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 's3'; + } + + protected function getSignatureScopeName(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 's3'; + } + + protected function getSignatureVersion(): string + { + @trigger_error('Using the client with an old version of Core is deprecated. Run "composer update async-aws/core".', \E_USER_DEPRECATED); + + return 's3v4'; + } + + protected function getSignerFactories(): array + { + return [ + 's3v4' => function (string $service, string $region) { + $configuration = $this->getConfiguration(); + $options = []; + + // We need async-aws/core: 1.8 or above to use sendChunkedBody. + if (Configuration::optionExists('sendChunkedBody')) { + $options['sendChunkedBody'] = filter_var($configuration->get('sendChunkedBody'), \FILTER_VALIDATE_BOOLEAN); + } + + return new SignerV4ForS3($service, $region, $options); + }, + ] + parent::getSignerFactories(); + } +} diff --git a/vendor/async-aws/s3/src/Signer/SignerV4ForS3.php b/vendor/async-aws/s3/src/Signer/SignerV4ForS3.php new file mode 100644 index 000000000..dad5c97db --- /dev/null +++ b/vendor/async-aws/s3/src/Signer/SignerV4ForS3.php @@ -0,0 +1,173 @@ + + */ +class SignerV4ForS3 extends SignerV4 +{ + private const ALGORITHM_CHUNK = 'AWS4-HMAC-SHA256-PAYLOAD'; + private const CHUNK_SIZE = 64 * 1024; + + private const MD5_OPERATIONS = [ + 'DeleteObjects' => true, + 'PutBucketCors' => true, + 'PutBucketLifecycle' => true, + 'PutBucketLifecycleConfiguration' => true, + 'PutBucketPolicy' => true, + 'PutBucketTagging' => true, + 'PutBucketReplication' => true, + 'PutObjectLegalHold' => true, + 'PutObjectRetention' => true, + 'PutObjectLockConfiguration' => true, + ]; + + /** + * @var bool + */ + private $sendChunkedBody; + + /** + * @param array{ + * sendChunkedBody?: bool, + * } $s3SignerOptions + */ + public function __construct(string $scopeName, string $region, array $s3SignerOptions = []) + { + parent::__construct($scopeName, $region); + + $this->sendChunkedBody = $s3SignerOptions[Configuration::OPTION_SEND_CHUNKED_BODY] ?? false; + unset($s3SignerOptions[Configuration::OPTION_SEND_CHUNKED_BODY]); + + if (!empty($s3SignerOptions)) { + throw new InvalidArgument(sprintf('Invalid option(s) "%s" passed to "%s::%s". ', implode('", "', array_keys($s3SignerOptions)), __CLASS__, __METHOD__)); + } + } + + public function sign(Request $request, Credentials $credentials, RequestContext $context): void + { + if ((null === ($operation = $context->getOperation()) || isset(self::MD5_OPERATIONS[$operation])) && !$request->hasHeader('content-md5')) { + $request->setHeader('content-md5', base64_encode($request->getBody()->hash('md5', true))); + } + + if (!$request->hasHeader('x-amz-content-sha256')) { + $request->setHeader('x-amz-content-sha256', $request->getBody()->hash()); + } + + parent::sign($request, $credentials, $context); + } + + protected function buildBodyDigest(Request $request, bool $isPresign): string + { + if ($isPresign) { + $request->setHeader('x-amz-content-sha256', 'UNSIGNED-PAYLOAD'); + + return 'UNSIGNED-PAYLOAD'; + } + + return parent::buildBodyDigest($request, $isPresign); + } + + /** + * Amazon S3 does not double-encode the path component in the canonical request. + */ + protected function buildCanonicalPath(Request $request): string + { + return '/' . ltrim($request->getUri(), '/'); + } + + protected function convertBodyToStream(SigningContext $context): void + { + $request = $context->getRequest(); + $body = $request->getBody(); + if ($request->hasHeader('content-length')) { + $contentLength = (int) $request->getHeader('content-length'); + } else { + $contentLength = $body->length(); + } + + // If content length is unknown, use the rewindable stream to read it once locally in order to get the length + if (null === $contentLength) { + $request->setBody($body = RewindableStream::create($body)); + $body->read(); + $contentLength = $body->length(); + } + + // no need to stream small body. It's simple to convert it to string directly + if ($contentLength < self::CHUNK_SIZE || !$this->sendChunkedBody) { + if ($body instanceof ReadOnceResultStream) { + $request->setBody(RewindableStream::create($body)); + } + + return; + } + + // Add content-encoding for chunked stream if available + $customEncoding = $request->getHeader('content-encoding'); + + // Convert the body into a chunked stream + $request->setHeader('content-encoding', $customEncoding ? "aws-chunked, $customEncoding" : 'aws-chunked'); + $request->setHeader('x-amz-decoded-content-length', (string) $contentLength); + $request->setHeader('x-amz-content-sha256', 'STREAMING-' . self::ALGORITHM_CHUNK); + + // Compute size of content + metadata used sign each Chunk + $chunkCount = (int) ceil($contentLength / self::CHUNK_SIZE); + $fullChunkCount = $chunkCount * self::CHUNK_SIZE === $contentLength ? $chunkCount : ($chunkCount - 1); + $metaLength = \strlen(";chunk-signature=\r\n\r\n") + 64; + $request->setHeader('content-length', (string) ($contentLength + $fullChunkCount * ($metaLength + \strlen(dechex(self::CHUNK_SIZE))) + ($chunkCount - $fullChunkCount) * ($metaLength + \strlen(dechex($contentLength % self::CHUNK_SIZE))) + $metaLength + 1)); + $body = RewindableStream::create(IterableStream::create((function (RequestStream $body) use ($context): iterable { + $now = $context->getNow(); + $credentialString = $context->getCredentialString(); + $signingKey = $context->getSigningKey(); + $signature = $context->getSignature(); + foreach (FixedSizeStream::create($body, self::CHUNK_SIZE) as $chunk) { + $stringToSign = $this->buildChunkStringToSign($now, $credentialString, $signature, $chunk); + $context->setSignature($signature = $this->buildSignature($stringToSign, $signingKey)); + yield sprintf("%s;chunk-signature=%s\r\n", dechex(\strlen($chunk)), $signature) . "$chunk\r\n"; + } + + $stringToSign = $this->buildChunkStringToSign($now, $credentialString, $signature, ''); + $context->setSignature($signature = $this->buildSignature($stringToSign, $signingKey)); + + yield sprintf("%s;chunk-signature=%s\r\n\r\n", dechex(0), $signature); + })($body))); + + $request->setBody($body); + } + + private function buildChunkStringToSign(\DateTimeImmutable $now, string $credentialString, string $signature, string $chunk): string + { + static $emptyHash; + $emptyHash = $emptyHash ?? hash('sha256', ''); + + return implode("\n", [ + self::ALGORITHM_CHUNK, + $now->format('Ymd\THis\Z'), + $credentialString, + $signature, + $emptyHash, + hash('sha256', $chunk), + ]); + } + + private function buildSignature(string $stringToSign, string $signingKey): string + { + return hash_hmac('sha256', $stringToSign, $signingKey); + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php b/vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php new file mode 100644 index 000000000..117ad9f21 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/AccessControlPolicy.php @@ -0,0 +1,79 @@ +, + * Owner?: null|Owner|array, + * } $input + */ + public function __construct(array $input) + { + $this->grants = isset($input['Grants']) ? array_map([Grant::class, 'create'], $input['Grants']) : null; + $this->owner = isset($input['Owner']) ? Owner::create($input['Owner']) : null; + } + + /** + * @param array{ + * Grants?: null|array, + * Owner?: null|Owner|array, + * }|AccessControlPolicy $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return Grant[] + */ + public function getGrants(): array + { + return $this->grants ?? []; + } + + public function getOwner(): ?Owner + { + return $this->owner; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->grants) { + $node->appendChild($nodeList = $document->createElement('AccessControlList')); + foreach ($v as $item) { + $nodeList->appendChild($child = $document->createElement('Grant')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->owner) { + $node->appendChild($child = $document->createElement('Owner')); + + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/AwsObject.php b/vendor/async-aws/s3/src/ValueObject/AwsObject.php new file mode 100644 index 000000000..30f8e57bf --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/AwsObject.php @@ -0,0 +1,169 @@ +|null + */ + private $checksumAlgorithm; + + /** + * Size in bytes of the object. + * + * @var int|null + */ + private $size; + + /** + * The class of storage used to store the object. + * + * @var ObjectStorageClass::*|null + */ + private $storageClass; + + /** + * The owner of the object. + * + * @var Owner|null + */ + private $owner; + + /** + * Specifies the restoration status of an object. Objects in certain storage classes must be restored before they can be + * retrieved. For more information about these storage classes and how to work with archived objects, see Working with + * archived objects [^1] in the *Amazon S3 User Guide*. + * + * [^1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/archived-objects.html + * + * @var RestoreStatus|null + */ + private $restoreStatus; + + /** + * @param array{ + * Key?: null|string, + * LastModified?: null|\DateTimeImmutable, + * ETag?: null|string, + * ChecksumAlgorithm?: null|array, + * Size?: null|int, + * StorageClass?: null|ObjectStorageClass::*, + * Owner?: null|Owner|array, + * RestoreStatus?: null|RestoreStatus|array, + * } $input + */ + public function __construct(array $input) + { + $this->key = $input['Key'] ?? null; + $this->lastModified = $input['LastModified'] ?? null; + $this->etag = $input['ETag'] ?? null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + $this->size = $input['Size'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->owner = isset($input['Owner']) ? Owner::create($input['Owner']) : null; + $this->restoreStatus = isset($input['RestoreStatus']) ? RestoreStatus::create($input['RestoreStatus']) : null; + } + + /** + * @param array{ + * Key?: null|string, + * LastModified?: null|\DateTimeImmutable, + * ETag?: null|string, + * ChecksumAlgorithm?: null|array, + * Size?: null|int, + * StorageClass?: null|ObjectStorageClass::*, + * Owner?: null|Owner|array, + * RestoreStatus?: null|RestoreStatus|array, + * }|AwsObject $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getChecksumAlgorithm(): array + { + return $this->checksumAlgorithm ?? []; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getLastModified(): ?\DateTimeImmutable + { + return $this->lastModified; + } + + public function getOwner(): ?Owner + { + return $this->owner; + } + + public function getRestoreStatus(): ?RestoreStatus + { + return $this->restoreStatus; + } + + public function getSize(): ?int + { + return $this->size; + } + + /** + * @return ObjectStorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Bucket.php b/vendor/async-aws/s3/src/ValueObject/Bucket.php new file mode 100644 index 000000000..1e3800e66 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Bucket.php @@ -0,0 +1,58 @@ +name = $input['Name'] ?? null; + $this->creationDate = $input['CreationDate'] ?? null; + } + + /** + * @param array{ + * Name?: null|string, + * CreationDate?: null|\DateTimeImmutable, + * }|Bucket $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getCreationDate(): ?\DateTimeImmutable + { + return $this->creationDate; + } + + public function getName(): ?string + { + return $this->name; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php b/vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php new file mode 100644 index 000000000..7d7e30014 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CORSConfiguration.php @@ -0,0 +1,71 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->corsRules = isset($input['CORSRules']) ? array_map([CORSRule::class, 'create'], $input['CORSRules']) : $this->throwException(new InvalidArgument('Missing required field "CORSRules".')); + } + + /** + * @param array{ + * CORSRules: array, + * }|CORSConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return CORSRule[] + */ + public function getCorsRules(): array + { + return $this->corsRules; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->corsRules; + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('CORSRule')); + + $item->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CORSRule.php b/vendor/async-aws/s3/src/ValueObject/CORSRule.php new file mode 100644 index 000000000..161030cbc --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CORSRule.php @@ -0,0 +1,174 @@ +id = $input['ID'] ?? null; + $this->allowedHeaders = $input['AllowedHeaders'] ?? null; + $this->allowedMethods = $input['AllowedMethods'] ?? $this->throwException(new InvalidArgument('Missing required field "AllowedMethods".')); + $this->allowedOrigins = $input['AllowedOrigins'] ?? $this->throwException(new InvalidArgument('Missing required field "AllowedOrigins".')); + $this->exposeHeaders = $input['ExposeHeaders'] ?? null; + $this->maxAgeSeconds = $input['MaxAgeSeconds'] ?? null; + } + + /** + * @param array{ + * ID?: null|string, + * AllowedHeaders?: null|string[], + * AllowedMethods: string[], + * AllowedOrigins: string[], + * ExposeHeaders?: null|string[], + * MaxAgeSeconds?: null|int, + * }|CORSRule $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return string[] + */ + public function getAllowedHeaders(): array + { + return $this->allowedHeaders ?? []; + } + + /** + * @return string[] + */ + public function getAllowedMethods(): array + { + return $this->allowedMethods; + } + + /** + * @return string[] + */ + public function getAllowedOrigins(): array + { + return $this->allowedOrigins; + } + + /** + * @return string[] + */ + public function getExposeHeaders(): array + { + return $this->exposeHeaders ?? []; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getMaxAgeSeconds(): ?int + { + return $this->maxAgeSeconds; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('ID', $v)); + } + if (null !== $v = $this->allowedHeaders) { + foreach ($v as $item) { + $node->appendChild($document->createElement('AllowedHeader', $item)); + } + } + $v = $this->allowedMethods; + foreach ($v as $item) { + $node->appendChild($document->createElement('AllowedMethod', $item)); + } + + $v = $this->allowedOrigins; + foreach ($v as $item) { + $node->appendChild($document->createElement('AllowedOrigin', $item)); + } + + if (null !== $v = $this->exposeHeaders) { + foreach ($v as $item) { + $node->appendChild($document->createElement('ExposeHeader', $item)); + } + } + if (null !== $v = $this->maxAgeSeconds) { + $node->appendChild($document->createElement('MaxAgeSeconds', (string) $v)); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CommonPrefix.php b/vendor/async-aws/s3/src/ValueObject/CommonPrefix.php new file mode 100644 index 000000000..ca0256337 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CommonPrefix.php @@ -0,0 +1,43 @@ +prefix = $input['Prefix'] ?? null; + } + + /** + * @param array{ + * Prefix?: null|string, + * }|CommonPrefix $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getPrefix(): ?string + { + return $this->prefix; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php b/vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php new file mode 100644 index 000000000..44e088101 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CompletedMultipartUpload.php @@ -0,0 +1,60 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->parts = isset($input['Parts']) ? array_map([CompletedPart::class, 'create'], $input['Parts']) : null; + } + + /** + * @param array{ + * Parts?: null|array, + * }|CompletedMultipartUpload $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return CompletedPart[] + */ + public function getParts(): array + { + return $this->parts ?? []; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->parts) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('Part')); + + $item->requestBody($child, $document); + } + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CompletedPart.php b/vendor/async-aws/s3/src/ValueObject/CompletedPart.php new file mode 100644 index 000000000..ff679d1d4 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CompletedPart.php @@ -0,0 +1,157 @@ +etag = $input['ETag'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + $this->partNumber = $input['PartNumber'] ?? null; + } + + /** + * @param array{ + * ETag?: null|string, + * ChecksumCRC32?: null|string, + * ChecksumCRC32C?: null|string, + * ChecksumSHA1?: null|string, + * ChecksumSHA256?: null|string, + * PartNumber?: null|int, + * }|CompletedPart $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->etag) { + $node->appendChild($document->createElement('ETag', $v)); + } + if (null !== $v = $this->checksumCrc32) { + $node->appendChild($document->createElement('ChecksumCRC32', $v)); + } + if (null !== $v = $this->checksumCrc32C) { + $node->appendChild($document->createElement('ChecksumCRC32C', $v)); + } + if (null !== $v = $this->checksumSha1) { + $node->appendChild($document->createElement('ChecksumSHA1', $v)); + } + if (null !== $v = $this->checksumSha256) { + $node->appendChild($document->createElement('ChecksumSHA256', $v)); + } + if (null !== $v = $this->partNumber) { + $node->appendChild($document->createElement('PartNumber', (string) $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php b/vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php new file mode 100644 index 000000000..bca5cbc46 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CopyObjectResult.php @@ -0,0 +1,132 @@ +etag = $input['ETag'] ?? null; + $this->lastModified = $input['LastModified'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + } + + /** + * @param array{ + * ETag?: null|string, + * LastModified?: null|\DateTimeImmutable, + * ChecksumCRC32?: null|string, + * ChecksumCRC32C?: null|string, + * ChecksumSHA1?: null|string, + * ChecksumSHA256?: null|string, + * }|CopyObjectResult $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getLastModified(): ?\DateTimeImmutable + { + return $this->lastModified; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php b/vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php new file mode 100644 index 000000000..c87fc55a7 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/CreateBucketConfiguration.php @@ -0,0 +1,61 @@ +locationConstraint = $input['LocationConstraint'] ?? null; + } + + /** + * @param array{ + * LocationConstraint?: null|BucketLocationConstraint::*, + * }|CreateBucketConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return BucketLocationConstraint::*|null + */ + public function getLocationConstraint(): ?string + { + return $this->locationConstraint; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->locationConstraint) { + if (!BucketLocationConstraint::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "LocationConstraint" for "%s". The value "%s" is not a valid "BucketLocationConstraint".', __CLASS__, $v)); + } + $node->appendChild($document->createElement('LocationConstraint', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Delete.php b/vendor/async-aws/s3/src/ValueObject/Delete.php new file mode 100644 index 000000000..461c4233d --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Delete.php @@ -0,0 +1,86 @@ +, + * Quiet?: null|bool, + * } $input + */ + public function __construct(array $input) + { + $this->objects = isset($input['Objects']) ? array_map([ObjectIdentifier::class, 'create'], $input['Objects']) : $this->throwException(new InvalidArgument('Missing required field "Objects".')); + $this->quiet = $input['Quiet'] ?? null; + } + + /** + * @param array{ + * Objects: array, + * Quiet?: null|bool, + * }|Delete $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ObjectIdentifier[] + */ + public function getObjects(): array + { + return $this->objects; + } + + public function getQuiet(): ?bool + { + return $this->quiet; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->objects; + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('Object')); + + $item->requestBody($child, $document); + } + + if (null !== $v = $this->quiet) { + $node->appendChild($document->createElement('Quiet', $v ? 'true' : 'false')); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/DeletedObject.php b/vendor/async-aws/s3/src/ValueObject/DeletedObject.php new file mode 100644 index 000000000..63b892c73 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/DeletedObject.php @@ -0,0 +1,88 @@ +key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->deleteMarker = $input['DeleteMarker'] ?? null; + $this->deleteMarkerVersionId = $input['DeleteMarkerVersionId'] ?? null; + } + + /** + * @param array{ + * Key?: null|string, + * VersionId?: null|string, + * DeleteMarker?: null|bool, + * DeleteMarkerVersionId?: null|string, + * }|DeletedObject $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDeleteMarker(): ?bool + { + return $this->deleteMarker; + } + + public function getDeleteMarkerVersionId(): ?string + { + return $this->deleteMarkerVersionId; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Error.php b/vendor/async-aws/s3/src/ValueObject/Error.php new file mode 100644 index 000000000..76757f941 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Error.php @@ -0,0 +1,563 @@ +key = $input['Key'] ?? null; + $this->versionId = $input['VersionId'] ?? null; + $this->code = $input['Code'] ?? null; + $this->message = $input['Message'] ?? null; + } + + /** + * @param array{ + * Key?: null|string, + * VersionId?: null|string, + * Code?: null|string, + * Message?: null|string, + * }|Error $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getCode(): ?string + { + return $this->code; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getMessage(): ?string + { + return $this->message; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php b/vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php new file mode 100644 index 000000000..af46db007 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/EventBridgeConfiguration.php @@ -0,0 +1,24 @@ +name = $input['Name'] ?? null; + $this->value = $input['Value'] ?? null; + } + + /** + * @param array{ + * Name?: null|FilterRuleName::*, + * Value?: null|string, + * }|FilterRule $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return FilterRuleName::*|null + */ + public function getName(): ?string + { + return $this->name; + } + + public function getValue(): ?string + { + return $this->value; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->name) { + if (!FilterRuleName::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "Name" for "%s". The value "%s" is not a valid "FilterRuleName".', __CLASS__, $v)); + } + $node->appendChild($document->createElement('Name', $v)); + } + if (null !== $v = $this->value) { + $node->appendChild($document->createElement('Value', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Grant.php b/vendor/async-aws/s3/src/ValueObject/Grant.php new file mode 100644 index 000000000..7e2796aab --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Grant.php @@ -0,0 +1,80 @@ +grantee = isset($input['Grantee']) ? Grantee::create($input['Grantee']) : null; + $this->permission = $input['Permission'] ?? null; + } + + /** + * @param array{ + * Grantee?: null|Grantee|array, + * Permission?: null|Permission::*, + * }|Grant $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getGrantee(): ?Grantee + { + return $this->grantee; + } + + /** + * @return Permission::*|null + */ + public function getPermission(): ?string + { + return $this->permission; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->grantee) { + $node->appendChild($child = $document->createElement('Grantee')); + $child->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $v->requestBody($child, $document); + } + if (null !== $v = $this->permission) { + if (!Permission::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "Permission" for "%s". The value "%s" is not a valid "Permission".', __CLASS__, $v)); + } + $node->appendChild($document->createElement('Permission', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Grantee.php b/vendor/async-aws/s3/src/ValueObject/Grantee.php new file mode 100644 index 000000000..02ec9e48c --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Grantee.php @@ -0,0 +1,155 @@ + Using email addresses to specify a grantee is only supported in the following Amazon Web Services Regions: + * > + * > - US East (N. Virginia) + * > - US West (N. California) + * > - US West (Oregon) + * > - Asia Pacific (Singapore) + * > - Asia Pacific (Sydney) + * > - Asia Pacific (Tokyo) + * > - Europe (Ireland) + * > - South America (São Paulo) + * > + * > For a list of all the Amazon S3 supported Regions and endpoints, see Regions and Endpoints [^1] in the Amazon Web + * > Services General Reference. + * + * [^1]: https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region + * + * @var string|null + */ + private $emailAddress; + + /** + * The canonical user ID of the grantee. + * + * @var string|null + */ + private $id; + + /** + * Type of grantee. + * + * @var Type::* + */ + private $type; + + /** + * URI of the grantee group. + * + * @var string|null + */ + private $uri; + + /** + * @param array{ + * DisplayName?: null|string, + * EmailAddress?: null|string, + * ID?: null|string, + * Type: Type::*, + * URI?: null|string, + * } $input + */ + public function __construct(array $input) + { + $this->displayName = $input['DisplayName'] ?? null; + $this->emailAddress = $input['EmailAddress'] ?? null; + $this->id = $input['ID'] ?? null; + $this->type = $input['Type'] ?? $this->throwException(new InvalidArgument('Missing required field "Type".')); + $this->uri = $input['URI'] ?? null; + } + + /** + * @param array{ + * DisplayName?: null|string, + * EmailAddress?: null|string, + * ID?: null|string, + * Type: Type::*, + * URI?: null|string, + * }|Grantee $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDisplayName(): ?string + { + return $this->displayName; + } + + public function getEmailAddress(): ?string + { + return $this->emailAddress; + } + + public function getId(): ?string + { + return $this->id; + } + + /** + * @return Type::* + */ + public function getType(): string + { + return $this->type; + } + + public function getUri(): ?string + { + return $this->uri; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->displayName) { + $node->appendChild($document->createElement('DisplayName', $v)); + } + if (null !== $v = $this->emailAddress) { + $node->appendChild($document->createElement('EmailAddress', $v)); + } + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('ID', $v)); + } + $v = $this->type; + if (!Type::exists($v)) { + throw new InvalidArgument(sprintf('Invalid parameter "xsi:type" for "%s". The value "%s" is not a valid "Type".', __CLASS__, $v)); + } + $node->setAttribute('xsi:type', $v); + if (null !== $v = $this->uri) { + $node->appendChild($document->createElement('URI', $v)); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Initiator.php b/vendor/async-aws/s3/src/ValueObject/Initiator.php new file mode 100644 index 000000000..92ac8cc85 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Initiator.php @@ -0,0 +1,57 @@ +id = $input['ID'] ?? null; + $this->displayName = $input['DisplayName'] ?? null; + } + + /** + * @param array{ + * ID?: null|string, + * DisplayName?: null|string, + * }|Initiator $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDisplayName(): ?string + { + return $this->displayName; + } + + public function getId(): ?string + { + return $this->id; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php b/vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php new file mode 100644 index 000000000..93560e896 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/LambdaFunctionConfiguration.php @@ -0,0 +1,124 @@ + + */ + private $events; + + /** + * @var NotificationConfigurationFilter|null + */ + private $filter; + + /** + * @param array{ + * Id?: null|string, + * LambdaFunctionArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * } $input + */ + public function __construct(array $input) + { + $this->id = $input['Id'] ?? null; + $this->lambdaFunctionArn = $input['LambdaFunctionArn'] ?? $this->throwException(new InvalidArgument('Missing required field "LambdaFunctionArn".')); + $this->events = $input['Events'] ?? $this->throwException(new InvalidArgument('Missing required field "Events".')); + $this->filter = isset($input['Filter']) ? NotificationConfigurationFilter::create($input['Filter']) : null; + } + + /** + * @param array{ + * Id?: null|string, + * LambdaFunctionArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * }|LambdaFunctionConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getEvents(): array + { + return $this->events; + } + + public function getFilter(): ?NotificationConfigurationFilter + { + return $this->filter; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getLambdaFunctionArn(): string + { + return $this->lambdaFunctionArn; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('Id', $v)); + } + $v = $this->lambdaFunctionArn; + $node->appendChild($document->createElement('CloudFunction', $v)); + $v = $this->events; + foreach ($v as $item) { + if (!Event::exists($item)) { + throw new InvalidArgument(sprintf('Invalid parameter "Event" for "%s". The value "%s" is not a valid "Event".', __CLASS__, $item)); + } + $node->appendChild($document->createElement('Event', $item)); + } + + if (null !== $v = $this->filter) { + $node->appendChild($child = $document->createElement('Filter')); + + $v->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/MultipartUpload.php b/vendor/async-aws/s3/src/ValueObject/MultipartUpload.php new file mode 100644 index 000000000..2123ffc64 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/MultipartUpload.php @@ -0,0 +1,140 @@ +uploadId = $input['UploadId'] ?? null; + $this->key = $input['Key'] ?? null; + $this->initiated = $input['Initiated'] ?? null; + $this->storageClass = $input['StorageClass'] ?? null; + $this->owner = isset($input['Owner']) ? Owner::create($input['Owner']) : null; + $this->initiator = isset($input['Initiator']) ? Initiator::create($input['Initiator']) : null; + $this->checksumAlgorithm = $input['ChecksumAlgorithm'] ?? null; + } + + /** + * @param array{ + * UploadId?: null|string, + * Key?: null|string, + * Initiated?: null|\DateTimeImmutable, + * StorageClass?: null|StorageClass::*, + * Owner?: null|Owner|array, + * Initiator?: null|Initiator|array, + * ChecksumAlgorithm?: null|ChecksumAlgorithm::*, + * }|MultipartUpload $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ChecksumAlgorithm::*|null + */ + public function getChecksumAlgorithm(): ?string + { + return $this->checksumAlgorithm; + } + + public function getInitiated(): ?\DateTimeImmutable + { + return $this->initiated; + } + + public function getInitiator(): ?Initiator + { + return $this->initiator; + } + + public function getKey(): ?string + { + return $this->key; + } + + public function getOwner(): ?Owner + { + return $this->owner; + } + + /** + * @return StorageClass::*|null + */ + public function getStorageClass(): ?string + { + return $this->storageClass; + } + + public function getUploadId(): ?string + { + return $this->uploadId; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php b/vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php new file mode 100644 index 000000000..1ed51523e --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/NotificationConfiguration.php @@ -0,0 +1,129 @@ +, + * QueueConfigurations?: null|array, + * LambdaFunctionConfigurations?: null|array, + * EventBridgeConfiguration?: null|EventBridgeConfiguration|array, + * } $input + */ + public function __construct(array $input) + { + $this->topicConfigurations = isset($input['TopicConfigurations']) ? array_map([TopicConfiguration::class, 'create'], $input['TopicConfigurations']) : null; + $this->queueConfigurations = isset($input['QueueConfigurations']) ? array_map([QueueConfiguration::class, 'create'], $input['QueueConfigurations']) : null; + $this->lambdaFunctionConfigurations = isset($input['LambdaFunctionConfigurations']) ? array_map([LambdaFunctionConfiguration::class, 'create'], $input['LambdaFunctionConfigurations']) : null; + $this->eventBridgeConfiguration = isset($input['EventBridgeConfiguration']) ? EventBridgeConfiguration::create($input['EventBridgeConfiguration']) : null; + } + + /** + * @param array{ + * TopicConfigurations?: null|array, + * QueueConfigurations?: null|array, + * LambdaFunctionConfigurations?: null|array, + * EventBridgeConfiguration?: null|EventBridgeConfiguration|array, + * }|NotificationConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getEventBridgeConfiguration(): ?EventBridgeConfiguration + { + return $this->eventBridgeConfiguration; + } + + /** + * @return LambdaFunctionConfiguration[] + */ + public function getLambdaFunctionConfigurations(): array + { + return $this->lambdaFunctionConfigurations ?? []; + } + + /** + * @return QueueConfiguration[] + */ + public function getQueueConfigurations(): array + { + return $this->queueConfigurations ?? []; + } + + /** + * @return TopicConfiguration[] + */ + public function getTopicConfigurations(): array + { + return $this->topicConfigurations ?? []; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->topicConfigurations) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('TopicConfiguration')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->queueConfigurations) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('QueueConfiguration')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->lambdaFunctionConfigurations) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('CloudFunctionConfiguration')); + + $item->requestBody($child, $document); + } + } + if (null !== $v = $this->eventBridgeConfiguration) { + $node->appendChild($child = $document->createElement('EventBridgeConfiguration')); + + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php b/vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php new file mode 100644 index 000000000..d50acbabe --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/NotificationConfigurationFilter.php @@ -0,0 +1,54 @@ +key = isset($input['Key']) ? S3KeyFilter::create($input['Key']) : null; + } + + /** + * @param array{ + * Key?: null|S3KeyFilter|array, + * }|NotificationConfigurationFilter $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): ?S3KeyFilter + { + return $this->key; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->key) { + $node->appendChild($child = $document->createElement('S3Key')); + + $v->requestBody($child, $document); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php b/vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php new file mode 100644 index 000000000..39308f337 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ObjectIdentifier.php @@ -0,0 +1,83 @@ +key = $input['Key'] ?? $this->throwException(new InvalidArgument('Missing required field "Key".')); + $this->versionId = $input['VersionId'] ?? null; + } + + /** + * @param array{ + * Key: string, + * VersionId?: null|string, + * }|ObjectIdentifier $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): string + { + return $this->key; + } + + public function getVersionId(): ?string + { + return $this->versionId; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->key; + $node->appendChild($document->createElement('Key', $v)); + if (null !== $v = $this->versionId) { + $node->appendChild($document->createElement('VersionId', $v)); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Owner.php b/vendor/async-aws/s3/src/ValueObject/Owner.php new file mode 100644 index 000000000..43f1910a0 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Owner.php @@ -0,0 +1,79 @@ +displayName = $input['DisplayName'] ?? null; + $this->id = $input['ID'] ?? null; + } + + /** + * @param array{ + * DisplayName?: null|string, + * ID?: null|string, + * }|Owner $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getDisplayName(): ?string + { + return $this->displayName; + } + + public function getId(): ?string + { + return $this->id; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->displayName) { + $node->appendChild($document->createElement('DisplayName', $v)); + } + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('ID', $v)); + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Part.php b/vendor/async-aws/s3/src/ValueObject/Part.php new file mode 100644 index 000000000..3c873eac2 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Part.php @@ -0,0 +1,162 @@ +partNumber = $input['PartNumber'] ?? null; + $this->lastModified = $input['LastModified'] ?? null; + $this->etag = $input['ETag'] ?? null; + $this->size = $input['Size'] ?? null; + $this->checksumCrc32 = $input['ChecksumCRC32'] ?? null; + $this->checksumCrc32C = $input['ChecksumCRC32C'] ?? null; + $this->checksumSha1 = $input['ChecksumSHA1'] ?? null; + $this->checksumSha256 = $input['ChecksumSHA256'] ?? null; + } + + /** + * @param array{ + * PartNumber?: null|int, + * LastModified?: null|\DateTimeImmutable, + * ETag?: null|string, + * Size?: null|int, + * ChecksumCRC32?: null|string, + * ChecksumCRC32C?: null|string, + * ChecksumSHA1?: null|string, + * ChecksumSHA256?: null|string, + * }|Part $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getChecksumCrc32(): ?string + { + return $this->checksumCrc32; + } + + public function getChecksumCrc32C(): ?string + { + return $this->checksumCrc32C; + } + + public function getChecksumSha1(): ?string + { + return $this->checksumSha1; + } + + public function getChecksumSha256(): ?string + { + return $this->checksumSha256; + } + + public function getEtag(): ?string + { + return $this->etag; + } + + public function getLastModified(): ?\DateTimeImmutable + { + return $this->lastModified; + } + + public function getPartNumber(): ?int + { + return $this->partNumber; + } + + public function getSize(): ?int + { + return $this->size; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php b/vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php new file mode 100644 index 000000000..29a6c78d1 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/QueueConfiguration.php @@ -0,0 +1,123 @@ + + */ + private $events; + + /** + * @var NotificationConfigurationFilter|null + */ + private $filter; + + /** + * @param array{ + * Id?: null|string, + * QueueArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * } $input + */ + public function __construct(array $input) + { + $this->id = $input['Id'] ?? null; + $this->queueArn = $input['QueueArn'] ?? $this->throwException(new InvalidArgument('Missing required field "QueueArn".')); + $this->events = $input['Events'] ?? $this->throwException(new InvalidArgument('Missing required field "Events".')); + $this->filter = isset($input['Filter']) ? NotificationConfigurationFilter::create($input['Filter']) : null; + } + + /** + * @param array{ + * Id?: null|string, + * QueueArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * }|QueueConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getEvents(): array + { + return $this->events; + } + + public function getFilter(): ?NotificationConfigurationFilter + { + return $this->filter; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getQueueArn(): string + { + return $this->queueArn; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('Id', $v)); + } + $v = $this->queueArn; + $node->appendChild($document->createElement('Queue', $v)); + $v = $this->events; + foreach ($v as $item) { + if (!Event::exists($item)) { + throw new InvalidArgument(sprintf('Invalid parameter "Event" for "%s". The value "%s" is not a valid "Event".', __CLASS__, $item)); + } + $node->appendChild($document->createElement('Event', $item)); + } + + if (null !== $v = $this->filter) { + $node->appendChild($child = $document->createElement('Filter')); + + $v->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/RestoreStatus.php b/vendor/async-aws/s3/src/ValueObject/RestoreStatus.php new file mode 100644 index 000000000..9bb53275b --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/RestoreStatus.php @@ -0,0 +1,72 @@ +isRestoreInProgress = $input['IsRestoreInProgress'] ?? null; + $this->restoreExpiryDate = $input['RestoreExpiryDate'] ?? null; + } + + /** + * @param array{ + * IsRestoreInProgress?: null|bool, + * RestoreExpiryDate?: null|\DateTimeImmutable, + * }|RestoreStatus $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getIsRestoreInProgress(): ?bool + { + return $this->isRestoreInProgress; + } + + public function getRestoreExpiryDate(): ?\DateTimeImmutable + { + return $this->restoreExpiryDate; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php b/vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php new file mode 100644 index 000000000..4cd6925ed --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/S3KeyFilter.php @@ -0,0 +1,56 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->filterRules = isset($input['FilterRules']) ? array_map([FilterRule::class, 'create'], $input['FilterRules']) : null; + } + + /** + * @param array{ + * FilterRules?: null|array, + * }|S3KeyFilter $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return FilterRule[] + */ + public function getFilterRules(): array + { + return $this->filterRules ?? []; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->filterRules) { + foreach ($v as $item) { + $node->appendChild($child = $document->createElement('FilterRule')); + + $item->requestBody($child, $document); + } + } + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php new file mode 100644 index 000000000..36f4a6384 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionByDefault.php @@ -0,0 +1,92 @@ +sseAlgorithm = $input['SSEAlgorithm'] ?? $this->throwException(new InvalidArgument('Missing required field "SSEAlgorithm".')); + $this->kmsMasterKeyId = $input['KMSMasterKeyID'] ?? null; + } + + /** + * @param array{ + * SSEAlgorithm: ServerSideEncryption::*, + * KMSMasterKeyID?: null|string, + * }|ServerSideEncryptionByDefault $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKmsMasterKeyId(): ?string + { + return $this->kmsMasterKeyId; + } + + /** + * @return ServerSideEncryption::* + */ + public function getSseAlgorithm(): string + { + return $this->sseAlgorithm; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php new file mode 100644 index 000000000..5b598b2b6 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionConfiguration.php @@ -0,0 +1,54 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->rules = isset($input['Rules']) ? array_map([ServerSideEncryptionRule::class, 'create'], $input['Rules']) : $this->throwException(new InvalidArgument('Missing required field "Rules".')); + } + + /** + * @param array{ + * Rules: array, + * }|ServerSideEncryptionConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return ServerSideEncryptionRule[] + */ + public function getRules(): array + { + return $this->rules; + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php new file mode 100644 index 000000000..ded004a3f --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/ServerSideEncryptionRule.php @@ -0,0 +1,63 @@ +applyServerSideEncryptionByDefault = isset($input['ApplyServerSideEncryptionByDefault']) ? ServerSideEncryptionByDefault::create($input['ApplyServerSideEncryptionByDefault']) : null; + $this->bucketKeyEnabled = $input['BucketKeyEnabled'] ?? null; + } + + /** + * @param array{ + * ApplyServerSideEncryptionByDefault?: null|ServerSideEncryptionByDefault|array, + * BucketKeyEnabled?: null|bool, + * }|ServerSideEncryptionRule $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getApplyServerSideEncryptionByDefault(): ?ServerSideEncryptionByDefault + { + return $this->applyServerSideEncryptionByDefault; + } + + public function getBucketKeyEnabled(): ?bool + { + return $this->bucketKeyEnabled; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Tag.php b/vendor/async-aws/s3/src/ValueObject/Tag.php new file mode 100644 index 000000000..13affe7d1 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Tag.php @@ -0,0 +1,77 @@ +key = $input['Key'] ?? $this->throwException(new InvalidArgument('Missing required field "Key".')); + $this->value = $input['Value'] ?? $this->throwException(new InvalidArgument('Missing required field "Value".')); + } + + /** + * @param array{ + * Key: string, + * Value: string, + * }|Tag $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + public function getKey(): string + { + return $this->key; + } + + public function getValue(): string + { + return $this->value; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->key; + $node->appendChild($document->createElement('Key', $v)); + $v = $this->value; + $node->appendChild($document->createElement('Value', $v)); + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/Tagging.php b/vendor/async-aws/s3/src/ValueObject/Tagging.php new file mode 100644 index 000000000..fb586ddfd --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/Tagging.php @@ -0,0 +1,69 @@ +, + * } $input + */ + public function __construct(array $input) + { + $this->tagSet = isset($input['TagSet']) ? array_map([Tag::class, 'create'], $input['TagSet']) : $this->throwException(new InvalidArgument('Missing required field "TagSet".')); + } + + /** + * @param array{ + * TagSet: array, + * }|Tagging $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return Tag[] + */ + public function getTagSet(): array + { + return $this->tagSet; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + $v = $this->tagSet; + + $node->appendChild($nodeList = $document->createElement('TagSet')); + foreach ($v as $item) { + $nodeList->appendChild($child = $document->createElement('Tag')); + + $item->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php b/vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php new file mode 100644 index 000000000..6f1eb0050 --- /dev/null +++ b/vendor/async-aws/s3/src/ValueObject/TopicConfiguration.php @@ -0,0 +1,126 @@ + + */ + private $events; + + /** + * @var NotificationConfigurationFilter|null + */ + private $filter; + + /** + * @param array{ + * Id?: null|string, + * TopicArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * } $input + */ + public function __construct(array $input) + { + $this->id = $input['Id'] ?? null; + $this->topicArn = $input['TopicArn'] ?? $this->throwException(new InvalidArgument('Missing required field "TopicArn".')); + $this->events = $input['Events'] ?? $this->throwException(new InvalidArgument('Missing required field "Events".')); + $this->filter = isset($input['Filter']) ? NotificationConfigurationFilter::create($input['Filter']) : null; + } + + /** + * @param array{ + * Id?: null|string, + * TopicArn: string, + * Events: array, + * Filter?: null|NotificationConfigurationFilter|array, + * }|TopicConfiguration $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return list + */ + public function getEvents(): array + { + return $this->events; + } + + public function getFilter(): ?NotificationConfigurationFilter + { + return $this->filter; + } + + public function getId(): ?string + { + return $this->id; + } + + public function getTopicArn(): string + { + return $this->topicArn; + } + + /** + * @internal + */ + public function requestBody(\DOMElement $node, \DOMDocument $document): void + { + if (null !== $v = $this->id) { + $node->appendChild($document->createElement('Id', $v)); + } + $v = $this->topicArn; + $node->appendChild($document->createElement('Topic', $v)); + $v = $this->events; + foreach ($v as $item) { + if (!Event::exists($item)) { + throw new InvalidArgument(sprintf('Invalid parameter "Event" for "%s". The value "%s" is not a valid "Event".', __CLASS__, $item)); + } + $node->appendChild($document->createElement('Event', $item)); + } + + if (null !== $v = $this->filter) { + $node->appendChild($child = $document->createElement('Filter')); + + $v->requestBody($child, $document); + } + } + + /** + * @return never + */ + private function throwException(\Throwable $exception) + { + throw $exception; + } +} diff --git a/vendor/autoload.php b/vendor/autoload.php index 717a7011d..a0b938724 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,24 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + trigger_error( + $err, + E_USER_ERROR + ); +} + require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9::getLoader(); +return ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea::getLoader(); diff --git a/vendor/bin/jp.php b/vendor/bin/jp.php index e4ea10a0f..fc4e0a769 120000 --- a/vendor/bin/jp.php +++ b/vendor/bin/jp.php @@ -1 +1,119 @@ -../mtdowling/jmespath.php/bin/jp.php \ No newline at end of file +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php'); + } +} + +return include __DIR__ . '/..'.'/mtdowling/jmespath.php/bin/jp.php'; diff --git a/vendor/bin/jp.php.bat b/vendor/bin/jp.php.bat new file mode 100644 index 000000000..9af045e20 --- /dev/null +++ b/vendor/bin/jp.php.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/jp.php +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index dc02dfb11..7824d8f7e 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -37,57 +37,126 @@ * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + // PSR-4 + /** + * @var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var list + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ private $prefixesPsr0 = array(); + /** + * @var list + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var array + */ private $missingClasses = array(); + + /** @var string|null */ private $apcuPrefix; + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); } + /** + * @return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return list + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return list + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return array Array of classname => path + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param array $classMap Class to filename map + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,22 +171,25 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -126,19 +198,19 @@ public function add($prefix, $paths, $prepend = false) $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -147,25 +219,28 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -175,18 +250,18 @@ public function addPsr4($prefix, $paths, $prepend = false) throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -195,8 +270,10 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +288,12 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +313,8 @@ public function setPsr4($prefix, $paths) * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -256,6 +337,8 @@ public function getUseIncludePath() * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -276,10 +359,12 @@ public function isClassMapAuthoritative() * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -296,33 +381,55 @@ public function getApcuPrefix() * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } } /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } } /** * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -367,6 +474,21 @@ public function findFile($class) return $file; } + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -377,7 +499,7 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { @@ -432,14 +554,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 000000000..51e734a77 --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 8a6aeb3bb..dd28fe712 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2,7 +2,7 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( @@ -29,4 +29,11 @@ 'AWS\\CRT\\NativeResource' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/NativeResource.php', 'AWS\\CRT\\OptionValue' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Options.php', 'AWS\\CRT\\Options' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Options.php', + 'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', + 'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', + 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', + 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', + 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', + 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', ); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index c1bf4f1fb..82860d3f7 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -2,13 +2,15 @@ // autoload_files.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', - '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', + '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', 'b067bc7112e384b61c701452d53a14a8' => $vendorDir . '/mtdowling/jmespath.php/src/JmesPath.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc0125d..15a2ff3ad 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index a9ebd9f44..f1f91bc2a 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -2,16 +2,26 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), + 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), + 'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'), + 'Symfony\\Contracts\\HttpClient\\' => array($vendorDir . '/symfony/http-client-contracts'), + 'Symfony\\Component\\HttpClient\\' => array($vendorDir . '/symfony/http-client'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'), 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), + 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), + 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'JmesPath\\' => array($vendorDir . '/mtdowling/jmespath.php/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src'), + 'AsyncAws\\S3\\' => array($vendorDir . '/async-aws/s3/src'), + 'AsyncAws\\Core\\' => array($vendorDir . '/async-aws/core/src'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index d13c299d8..d14ad96f4 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9 +class ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea { private static $loader; @@ -13,58 +13,38 @@ public static function loadClassLoader($class) } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit40514c60e4fd367b9870ef577edbc7b9', 'loadClassLoader')); + require __DIR__ . '/platform_check.php'; - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + spl_autoload_register(array('ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); + spl_autoload_unregister(array('ComposerAutoloaderInit1be153197e5434e9f4e42506e8945cea', 'loadClassLoader')); - call_user_func(\Composer\Autoload\ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInit1be153197e5434e9f4e42506e8945cea::getInitializer($loader)); $loader->register(true); - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequire40514c60e4fd367b9870ef577edbc7b9($fileIdentifier, $file); + $filesToLoad = \Composer\Autoload\ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); } return $loader; } } - -function composerRequire40514c60e4fd367b9870ef577edbc7b9($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index c6135b405..bbbad9f74 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,12 +4,14 @@ namespace Composer\Autoload; -class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 +class ComposerStaticInit1be153197e5434e9f4e42506e8945cea { public static $files = array ( + '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', - '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', + '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', 'b067bc7112e384b61c701452d53a14a8' => __DIR__ . '/..' . '/mtdowling/jmespath.php/src/JmesPath.php', @@ -19,12 +21,20 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 public static $prefixLengthsPsr4 = array ( 'S' => array ( + 'Symfony\\Polyfill\\Php80\\' => 23, + 'Symfony\\Polyfill\\Php73\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Contracts\\Service\\' => 26, + 'Symfony\\Contracts\\HttpClient\\' => 29, + 'Symfony\\Component\\HttpClient\\' => 29, ), 'P' => array ( + 'Psr\\Log\\' => 8, 'Psr\\Http\\Message\\' => 17, 'Psr\\Http\\Client\\' => 16, + 'Psr\\Container\\' => 14, + 'Psr\\Cache\\' => 10, ), 'J' => array ( @@ -39,23 +49,57 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 'A' => array ( 'Aws\\' => 4, + 'AsyncAws\\S3\\' => 12, + 'AsyncAws\\Core\\' => 14, ), ); public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Php80\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', + ), + 'Symfony\\Polyfill\\Php73\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php73', + ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), + 'Symfony\\Contracts\\Service\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/service-contracts', + ), + 'Symfony\\Contracts\\HttpClient\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/http-client-contracts', + ), + 'Symfony\\Component\\HttpClient\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/http-client', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), 'Psr\\Http\\Message\\' => array ( - 0 => __DIR__ . '/..' . '/psr/http-factory/src', - 1 => __DIR__ . '/..' . '/psr/http-message/src', + 0 => __DIR__ . '/..' . '/psr/http-message/src', + 1 => __DIR__ . '/..' . '/psr/http-factory/src', ), 'Psr\\Http\\Client\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-client/src', ), + 'Psr\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/container/src', + ), + 'Psr\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/cache/src', + ), 'JmesPath\\' => array ( 0 => __DIR__ . '/..' . '/mtdowling/jmespath.php/src', @@ -76,6 +120,14 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 array ( 0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src', ), + 'AsyncAws\\S3\\' => + array ( + 0 => __DIR__ . '/..' . '/async-aws/s3/src', + ), + 'AsyncAws\\Core\\' => + array ( + 0 => __DIR__ . '/..' . '/async-aws/core/src', + ), ); public static $classMap = array ( @@ -102,14 +154,21 @@ class ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9 'AWS\\CRT\\NativeResource' => __DIR__ . '/..' . '/aws/aws-crt-php/src/AWS/CRT/NativeResource.php', 'AWS\\CRT\\OptionValue' => __DIR__ . '/..' . '/aws/aws-crt-php/src/AWS/CRT/Options.php', 'AWS\\CRT\\Options' => __DIR__ . '/..' . '/aws/aws-crt-php/src/AWS/CRT/Options.php', + 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', + 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', + 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', + 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', + 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit40514c60e4fd367b9870ef577edbc7b9::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit1be153197e5434e9f4e42506e8945cea::$classMap; }, null, ClassLoader::class); } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index b9c7349c9..88e788383 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,804 +1,1539 @@ -[ - { - "name": "aws/aws-crt-php", - "version": "v1.2.1", - "version_normalized": "1.2.1.0", - "source": { - "type": "git", - "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", - "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", - "yoast/phpunit-polyfills": "^1.0" - }, - "suggest": { - "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." - }, - "time": "2023-03-24T20:22:19+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "AWS SDK Common Runtime Team", - "email": "aws-sdk-common-runtime@amazon.com" - } - ], - "description": "AWS Common Runtime for PHP", - "homepage": "https://github.com/awslabs/aws-crt-php", - "keywords": [ - "amazon", - "aws", - "crt", - "sdk" - ] - }, - { - "name": "aws/aws-sdk-php", - "version": "3.269.1", - "version_normalized": "3.269.1.0", - "source": { - "type": "git", - "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", - "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", - "shasum": "" - }, - "require": { - "aws/aws-crt-php": "^1.0.4", - "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" - }, - "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", - "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" - }, - "suggest": { - "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", - "doctrine/cache": "To use the DoctrineCacheAdapter", - "ext-curl": "To send requests using cURL", - "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", - "ext-sockets": "To use client-side monitoring" - }, - "time": "2023-04-27T18:22:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "Aws\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Amazon Web Services", - "homepage": "http://aws.amazon.com" - } - ], - "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", - "homepage": "http://aws.amazon.com/sdkforphp", - "keywords": [ - "amazon", - "aws", - "cloud", - "dynamodb", - "ec2", - "glacier", - "s3", - "sdk" - ] - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.5.1", - "version_normalized": "7.5.1.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b964ca597e86b752cd994f27293e9fa6b6a95ed9", - "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", - "psr/log": "^1.1 || ^2.0 || ^3.0" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "time": "2023-04-17T16:30:08+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Jeremy Lindblom", - "email": "jeremeamia@gmail.com", - "homepage": "https://github.com/jeremeamia" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "psr-18", - "psr-7", - "rest", - "web service" - ] - }, - { - "name": "guzzlehttp/promises", - "version": "1.5.2", - "version_normalized": "1.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "time": "2022-08-28T14:55:35+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.5-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/functions_include.php" - ], - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ] - }, - { - "name": "guzzlehttp/psr7", - "version": "2.5.0", - "version_normalized": "2.5.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "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" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "time": "2023-04-17T16:11:26+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ] - }, - { - "name": "mtdowling/jmespath.php", - "version": "2.6.1", - "version_normalized": "2.6.1.0", - "source": { - "type": "git", - "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0", - "symfony/polyfill-mbstring": "^1.17" - }, - "require-dev": { - "composer/xdebug-handler": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^7.5.15" - }, - "time": "2021-06-14T00:11:39+00:00", - "bin": [ - "bin/jp.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "src/JmesPath.php" - ], - "psr-4": { - "JmesPath\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Declaratively specify how to extract elements from a JSON document", - "keywords": [ - "json", - "jsonpath" - ] - }, - { - "name": "psr/http-client", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:12:12+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ] - }, - { - "name": "psr/http-factory", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:10:41+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/http-message", - "version": "1.1", - "version_normalized": "1.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "time": "2023-04-04T09:50:52+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ] - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "version_normalized": "3.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "time": "2019-03-08T08:55:37+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders." - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2022-01-02T09:53:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "function.php" - ] - }, - "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": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", - "version_normalized": "1.27.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "time": "2022-11-03T14:55:06+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.27-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "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 for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ] - } -] +{ + "packages": [ + { + "name": "async-aws/core", + "version": "1.20.0", + "version_normalized": "1.20.0.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/core.git", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/core/zipball/e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "reference": "e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/http-client": "^4.4.16 || ^5.1.7 || ^6.0 || ^7.0", + "symfony/http-client-contracts": "^1.1.8 || ^2.0 || ^3.0", + "symfony/service-contracts": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "async-aws/s3": "<1.1", + "symfony/http-client": "5.2.0" + }, + "time": "2023-08-07T20:00:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.20-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "AsyncAws\\Core\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Core package to integrate with AWS. This is a lightweight AWS SDK provider by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "sdk", + "sts" + ], + "support": { + "source": "https://github.com/async-aws/core/tree/1.20.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "install-path": "../async-aws/core" + }, + { + "name": "async-aws/s3", + "version": "2.0.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/async-aws/s3.git", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/async-aws/s3/zipball/1486ae6592a8f870da60dfc29bfc98390c7b9092", + "reference": "1486ae6592a8f870da60dfc29bfc98390c7b9092", + "shasum": "" + }, + "require": { + "async-aws/core": "^1.9", + "ext-dom": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-simplexml": "*", + "php": "^7.2.5 || ^8.0" + }, + "time": "2023-08-07T20:00:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.15-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "AsyncAws\\S3\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "S3 client, part of the AWS SDK provided by AsyncAws.", + "keywords": [ + "amazon", + "async-aws", + "aws", + "s3", + "sdk" + ], + "support": { + "source": "https://github.com/async-aws/s3/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/jderusse", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "install-path": "../async-aws/s3" + }, + { + "name": "aws/aws-crt-php", + "version": "v1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/1926277fc71d253dfa820271ac5987bdb193ccf5", + "reference": "1926277fc71d253dfa820271ac5987bdb193ccf5", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "time": "2023-03-24T20:22:19+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "install-path": "../aws/aws-crt-php" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.269.1", + "version_normalized": "3.269.1.0", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", + "reference": "03b0b8984c46c469c70bfb05fea7b1ac9b859a8e", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.0.4", + "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" + }, + "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", + "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" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "time": "2023-04-27T18:22:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "install-path": "../aws/aws-sdk-php" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.5.1", + "version_normalized": "7.5.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b964ca597e86b752cd994f27293e9fa6b6a95ed9", + "reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "time": "2023-04-17T16:30:08+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "install-path": "../guzzlehttp/guzzle" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.2", + "version_normalized": "1.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "b94b2807d85443f9719887892882d0329d1e2598" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "time": "2022-08-28T14:55:35+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "install-path": "../guzzlehttp/promises" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.5.0", + "version_normalized": "2.5.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "b635f279edd83fc275f822a1188157ffea568ff6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", + "reference": "b635f279edd83fc275f822a1188157ffea568ff6", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "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" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "time": "2023-04-17T16:11:26+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "install-path": "../guzzlehttp/psr7" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.6.1", + "version_normalized": "2.6.1.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^7.5.15" + }, + "time": "2021-06-14T00:11:39+00:00", + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "install-path": "../mtdowling/jmespath.php" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-08-06T20:24:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "install-path": "../psr/cache" + }, + { + "name": "psr/container", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "time": "2021-03-05T17:36:06+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "install-path": "../psr/container" + }, + { + "name": "psr/http-client", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-04-10T20:12:12+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "install-path": "../psr/http-client" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-04-10T20:10:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-factory" + }, + { + "name": "psr/http-message", + "version": "1.1", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2023-04-04T09:50:52+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-message" + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2021-05-03T11:20:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "install-path": "../psr/log" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "time": "2019-03-08T08:55:37+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "install-path": "../ralouphie/getallheaders" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2022-01-02T09:53:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.php" + ] + }, + "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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "install-path": "../symfony/deprecation-contracts" + }, + { + "name": "symfony/http-client", + "version": "v5.4.26", + "version_normalized": "5.4.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/19d48ef7f38e5057ed1789a503cd3eccef039bce", + "reference": "19d48ef7f38e5057ed1789a503cd3eccef039bce", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.4", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "2.4" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "time": "2023-07-03T12:14:50+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "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": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v5.4.26" + }, + "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" + } + ], + "install-path": "../symfony/http-client" + }, + { + "name": "symfony/http-client-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "reference": "ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "time": "2022-04-12T15:48:08+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "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": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.2" + }, + "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" + } + ], + "install-path": "../symfony/http-client-contracts" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "version_normalized": "1.27.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2022-11-03T14:55:06+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "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 for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "install-path": "../symfony/polyfill-mbstring" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.28.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" + } + ], + "install-path": "../symfony/polyfill-php73" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.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" + } + ], + "install-path": "../symfony/polyfill-php80" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "time": "2022-05-30T19:17:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, + "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" + } + ], + "install-path": "../symfony/service-contracts" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 000000000..c49f47d19 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,257 @@ + array( + 'name' => '__root__', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '18a48a414f663c2bb6718ddbd4000a40164ae8f8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '18a48a414f663c2bb6718ddbd4000a40164ae8f8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'async-aws/core' => array( + 'pretty_version' => '1.20.0', + 'version' => '1.20.0.0', + 'reference' => 'e7a42c5cd0af44c4f3df0c4d228fe574c8ae4b68', + 'type' => 'library', + 'install_path' => __DIR__ . '/../async-aws/core', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'async-aws/s3' => array( + 'pretty_version' => '2.0.0', + 'version' => '2.0.0.0', + 'reference' => '1486ae6592a8f870da60dfc29bfc98390c7b9092', + 'type' => 'library', + 'install_path' => __DIR__ . '/../async-aws/s3', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'aws/aws-crt-php' => array( + 'pretty_version' => 'v1.2.1', + 'version' => '1.2.1.0', + 'reference' => '1926277fc71d253dfa820271ac5987bdb193ccf5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../aws/aws-crt-php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'aws/aws-sdk-php' => array( + 'pretty_version' => '3.269.1', + 'version' => '3.269.1.0', + 'reference' => '03b0b8984c46c469c70bfb05fea7b1ac9b859a8e', + 'type' => 'library', + 'install_path' => __DIR__ . '/../aws/aws-sdk-php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/guzzle' => array( + 'pretty_version' => '7.5.1', + 'version' => '7.5.1.0', + 'reference' => 'b964ca597e86b752cd994f27293e9fa6b6a95ed9', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/promises' => array( + 'pretty_version' => '1.5.2', + 'version' => '1.5.2.0', + 'reference' => 'b94b2807d85443f9719887892882d0329d1e2598', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/promises', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'guzzlehttp/psr7' => array( + 'pretty_version' => '2.5.0', + 'version' => '2.5.0.0', + 'reference' => 'b635f279edd83fc275f822a1188157ffea568ff6', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/psr7', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'mtdowling/jmespath.php' => array( + 'pretty_version' => '2.6.1', + 'version' => '2.6.1.0', + 'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb', + 'type' => 'library', + 'install_path' => __DIR__ . '/../mtdowling/jmespath.php', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'php-http/async-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '*', + ), + ), + 'php-http/client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '*', + ), + ), + 'psr/cache' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/container' => array( + 'pretty_version' => '1.1.1', + 'version' => '1.1.1.0', + 'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/container', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => '0955afe48220520692d2d09f7ab7e0f93ffd6a31', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/http-factory' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-factory', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-factory-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/http-message' => array( + 'pretty_version' => '1.1', + 'version' => '1.1.0.0', + 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-message-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'ralouphie/getallheaders' => array( + 'pretty_version' => '3.0.3', + 'version' => '3.0.3.0', + 'reference' => '120b605dfeb996808c31b6477290a714d356e822', + 'type' => 'library', + 'install_path' => __DIR__ . '/../ralouphie/getallheaders', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client' => array( + 'pretty_version' => 'v5.4.26', + 'version' => '5.4.26.0', + 'reference' => '19d48ef7f38e5057ed1789a503cd3eccef039bce', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/http-client', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => 'ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/http-client-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/http-client-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '2.4', + ), + ), + 'symfony/polyfill-mbstring' => array( + 'pretty_version' => 'v1.27.0', + 'version' => '1.27.0.0', + 'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php73' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => 'fe2f306d1d9d346a7fee353d0d5012e401e984b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php73', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php80' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php80', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/service-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/service-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 000000000..a8b98d5ce --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70205)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/vendor/psr/cache/CHANGELOG.md b/vendor/psr/cache/CHANGELOG.md new file mode 100644 index 000000000..58ddab05a --- /dev/null +++ b/vendor/psr/cache/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 1.0.1 - 2016-08-06 + +### Fixed + +- Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr +- Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr +- Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell +- For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell + +## 1.0.0 - 2015-12-11 + +Initial stable release; reflects accepted PSR-6 specification diff --git a/vendor/psr/cache/LICENSE.txt b/vendor/psr/cache/LICENSE.txt new file mode 100644 index 000000000..b1c2c97b9 --- /dev/null +++ b/vendor/psr/cache/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2015 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/psr/cache/README.md b/vendor/psr/cache/README.md new file mode 100644 index 000000000..c8706ceea --- /dev/null +++ b/vendor/psr/cache/README.md @@ -0,0 +1,9 @@ +PSR Cache +========= + +This repository holds all interfaces defined by +[PSR-6](http://www.php-fig.org/psr/psr-6/). + +Note that this is not a Cache implementation of its own. It is merely an +interface that describes a Cache implementation. See the specification for more +details. diff --git a/vendor/psr/cache/composer.json b/vendor/psr/cache/composer.json new file mode 100644 index 000000000..e828fec94 --- /dev/null +++ b/vendor/psr/cache/composer.json @@ -0,0 +1,25 @@ +{ + "name": "psr/cache", + "description": "Common interface for caching libraries", + "keywords": ["psr", "psr-6", "cache"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/psr/cache/src/CacheException.php b/vendor/psr/cache/src/CacheException.php new file mode 100644 index 000000000..e27f22f8d --- /dev/null +++ b/vendor/psr/cache/src/CacheException.php @@ -0,0 +1,10 @@ +=7.2.0" + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + } +} diff --git a/vendor/psr/container/src/ContainerExceptionInterface.php b/vendor/psr/container/src/ContainerExceptionInterface.php new file mode 100644 index 000000000..cf10b8b4f --- /dev/null +++ b/vendor/psr/container/src/ContainerExceptionInterface.php @@ -0,0 +1,10 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 000000000..67f852d1d --- /dev/null +++ b/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 000000000..2206cfde4 --- /dev/null +++ b/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,125 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 000000000..c8f7293b1 --- /dev/null +++ b/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,30 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/vendor/psr/log/Psr/Log/Test/DummyTest.php b/vendor/psr/log/Psr/Log/Test/DummyTest.php new file mode 100644 index 000000000..9638c1101 --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/DummyTest.php @@ -0,0 +1,18 @@ + ". + * + * Example ->error('Foo') would yield "error Foo". + * + * @return string[] + */ + abstract public function getLogs(); + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException \Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + } + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextCanContainAnything() + { + $closed = fopen('php://memory', 'r'); + fclose($closed); + + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest), + 'object' => new \DateTime, + 'resource' => fopen('php://memory', 'r'), + 'closed' => $closed, + ); + + $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!' + ); + $this->assertEquals($expected, $this->getLogs()); + } +} diff --git a/vendor/psr/log/Psr/Log/Test/TestLogger.php b/vendor/psr/log/Psr/Log/Test/TestLogger.php new file mode 100644 index 000000000..1be323049 --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/TestLogger.php @@ -0,0 +1,147 @@ + $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + $this->recordsByLevel = []; + } +} diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md new file mode 100644 index 000000000..a9f20c437 --- /dev/null +++ b/vendor/psr/log/README.md @@ -0,0 +1,58 @@ +PSR Log +======= + +This repository holds all interfaces/classes/traits related to +[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Note that this is not a logger of its own. It is merely an interface that +describes a logger. See the specification for more details. + +Installation +------------ + +```bash +composer require psr/log +``` + +Usage +----- + +If you need a logger, you can use the interface like this: + +```php +logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + try { + $this->doSomethingElse(); + } catch (Exception $exception) { + $this->logger->error('Oh no!', array('exception' => $exception)); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json new file mode 100644 index 000000000..ca0569537 --- /dev/null +++ b/vendor/psr/log/composer.json @@ -0,0 +1,26 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + } +} diff --git a/vendor/symfony/http-client-contracts/.gitignore b/vendor/symfony/http-client-contracts/.gitignore new file mode 100644 index 000000000..c49a5d8df --- /dev/null +++ b/vendor/symfony/http-client-contracts/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/vendor/symfony/http-client-contracts/CHANGELOG.md b/vendor/symfony/http-client-contracts/CHANGELOG.md new file mode 100644 index 000000000..7932e2613 --- /dev/null +++ b/vendor/symfony/http-client-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/vendor/symfony/http-client-contracts/ChunkInterface.php b/vendor/symfony/http-client-contracts/ChunkInterface.php new file mode 100644 index 000000000..0800cb366 --- /dev/null +++ b/vendor/symfony/http-client-contracts/ChunkInterface.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * The interface of chunks returned by ResponseStreamInterface::current(). + * + * When the chunk is first, last or timeout, the content MUST be empty. + * When an unchecked timeout or a network error occurs, a TransportExceptionInterface + * MUST be thrown by the destructor unless one was already thrown by another method. + * + * @author Nicolas Grekas + */ +interface ChunkInterface +{ + /** + * Tells when the idle timeout has been reached. + * + * @throws TransportExceptionInterface on a network error + */ + public function isTimeout(): bool; + + /** + * Tells when headers just arrived. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function isFirst(): bool; + + /** + * Tells when the body just completed. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function isLast(): bool; + + /** + * Returns a [status code, headers] tuple when a 1xx status code was just received. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function getInformationalStatus(): ?array; + + /** + * Returns the content of the response chunk. + * + * @throws TransportExceptionInterface on a network error or when the idle timeout is reached + */ + public function getContent(): string; + + /** + * Returns the offset of the chunk in the response body. + */ + public function getOffset(): int; + + /** + * In case of error, returns the message that describes it. + */ + public function getError(): ?string; +} diff --git a/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php new file mode 100644 index 000000000..22d2b456a --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/ClientExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a 4xx response is returned. + * + * @author Nicolas Grekas + */ +interface ClientExceptionInterface extends HttpExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php new file mode 100644 index 000000000..971a7a29b --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/DecodingExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a content-type cannot be decoded to the expected representation. + * + * @author Nicolas Grekas + */ +interface DecodingExceptionInterface extends ExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php new file mode 100644 index 000000000..e553b47a1 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * The base interface for all exceptions in the contract. + * + * @author Nicolas Grekas + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php new file mode 100644 index 000000000..17865ed36 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/HttpExceptionInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * Base interface for HTTP-related exceptions. + * + * @author Anton Chernikov + */ +interface HttpExceptionInterface extends ExceptionInterface +{ + public function getResponse(): ResponseInterface; +} diff --git a/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php new file mode 100644 index 000000000..edd9b8a9b --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/RedirectionExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a 3xx response is returned and the "max_redirects" option has been reached. + * + * @author Nicolas Grekas + */ +interface RedirectionExceptionInterface extends HttpExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php new file mode 100644 index 000000000..9bfe1354b --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/ServerExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When a 5xx response is returned. + * + * @author Nicolas Grekas + */ +interface ServerExceptionInterface extends HttpExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php new file mode 100644 index 000000000..08acf9fb6 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/TimeoutExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When an idle timeout occurs. + * + * @author Nicolas Grekas + */ +interface TimeoutExceptionInterface extends TransportExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php b/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php new file mode 100644 index 000000000..0c8d131a0 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Exception/TransportExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Exception; + +/** + * When any error happens at the transport level. + * + * @author Nicolas Grekas + */ +interface TransportExceptionInterface extends ExceptionInterface +{ +} diff --git a/vendor/symfony/http-client-contracts/HttpClientInterface.php b/vendor/symfony/http-client-contracts/HttpClientInterface.php new file mode 100644 index 000000000..158c1a7d0 --- /dev/null +++ b/vendor/symfony/http-client-contracts/HttpClientInterface.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\Test\HttpClientTestCase; + +/** + * Provides flexible methods for requesting HTTP resources synchronously or asynchronously. + * + * @see HttpClientTestCase for a reference test suite + * + * @method static withOptions(array $options) Returns a new instance of the client with new default options + * + * @author Nicolas Grekas + */ +interface HttpClientInterface +{ + public const OPTIONS_DEFAULTS = [ + 'auth_basic' => null, // array|string - an array containing the username as first value, and optionally the + // password as the second one; or string like username:password - enabling HTTP Basic + // authentication (RFC 7617) + 'auth_bearer' => null, // string - a token enabling HTTP Bearer authorization (RFC 6750) + 'query' => [], // string[] - associative array of query string values to merge with the request's URL + 'headers' => [], // iterable|string[]|string[][] - headers names provided as keys or as part of values + 'body' => '', // array|string|resource|\Traversable|\Closure - the callback SHOULD yield a string + // smaller than the amount requested as argument; the empty string signals EOF; if + // an array is passed, it is meant as a form payload of field names and values + 'json' => null, // mixed - if set, implementations MUST set the "body" option to the JSON-encoded + // value and set the "content-type" header to a JSON-compatible value if it is not + // explicitly defined in the headers option - typically "application/json" + 'user_data' => null, // mixed - any extra data to attach to the request (scalar, callable, object...) that + // MUST be available via $response->getInfo('user_data') - not used internally + 'max_redirects' => 20, // int - the maximum number of redirects to follow; a value lower than or equal to 0 + // means redirects should not be followed; "Authorization" and "Cookie" headers MUST + // NOT follow except for the initial host name + 'http_version' => null, // string - defaults to the best supported version, typically 1.1 or 2.0 + 'base_uri' => null, // string - the URI to resolve relative URLs, following rules in RFC 3986, section 2 + 'buffer' => true, // bool|resource|\Closure - whether the content of the response should be buffered or not, + // or a stream resource where the response body should be written, + // or a closure telling if/where the response should be buffered based on its headers + 'on_progress' => null, // callable(int $dlNow, int $dlSize, array $info) - throwing any exceptions MUST abort + // the request; it MUST be called on DNS resolution, on arrival of headers and on + // completion; it SHOULD be called on upload/download of data and at least 1/s + 'resolve' => [], // string[] - a map of host to IP address that SHOULD replace DNS resolution + 'proxy' => null, // string - by default, the proxy-related env vars handled by curl SHOULD be honored + 'no_proxy' => null, // string - a comma separated list of hosts that do not require a proxy to be reached + 'timeout' => null, // float - the idle timeout - defaults to ini_get('default_socket_timeout') + 'max_duration' => 0, // float - the maximum execution time for the request+response as a whole; + // a value lower than or equal to 0 means it is unlimited + 'bindto' => '0', // string - the interface or the local socket to bind to + 'verify_peer' => true, // see https://php.net/context.ssl for the following options + 'verify_host' => true, + 'cafile' => null, + 'capath' => null, + 'local_cert' => null, + 'local_pk' => null, + 'passphrase' => null, + 'ciphers' => null, + 'peer_fingerprint' => null, + 'capture_peer_cert_chain' => false, + 'extra' => [], // array - additional options that can be ignored if unsupported, unlike regular options + ]; + + /** + * Requests an HTTP resource. + * + * Responses MUST be lazy, but their status code MUST be + * checked even if none of their public methods are called. + * + * Implementations are not required to support all options described above; they can also + * support more custom options; but in any case, they MUST throw a TransportExceptionInterface + * when an unsupported option is passed. + * + * @throws TransportExceptionInterface When an unsupported option is passed + */ + public function request(string $method, string $url, array $options = []): ResponseInterface; + + /** + * Yields responses chunk by chunk as they complete. + * + * @param ResponseInterface|iterable $responses One or more responses created by the current HTTP client + * @param float|null $timeout The idle timeout before yielding timeout chunks + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface; +} diff --git a/vendor/symfony/http-client-contracts/LICENSE b/vendor/symfony/http-client-contracts/LICENSE new file mode 100644 index 000000000..74cdc2dbf --- /dev/null +++ b/vendor/symfony/http-client-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/http-client-contracts/README.md b/vendor/symfony/http-client-contracts/README.md new file mode 100644 index 000000000..03b3a69b7 --- /dev/null +++ b/vendor/symfony/http-client-contracts/README.md @@ -0,0 +1,9 @@ +Symfony HttpClient Contracts +============================ + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful - and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/main/README.md for more information. diff --git a/vendor/symfony/http-client-contracts/ResponseInterface.php b/vendor/symfony/http-client-contracts/ResponseInterface.php new file mode 100644 index 000000000..df7148816 --- /dev/null +++ b/vendor/symfony/http-client-contracts/ResponseInterface.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * A (lazily retrieved) HTTP response. + * + * @author Nicolas Grekas + */ +interface ResponseInterface +{ + /** + * Gets the HTTP status code of the response. + * + * @throws TransportExceptionInterface when a network error occurs + */ + public function getStatusCode(): int; + + /** + * Gets the HTTP headers of the response. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @return string[][] The headers of the response keyed by header names in lowercase + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function getHeaders(bool $throw = true): array; + + /** + * Gets the response body as a string. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function getContent(bool $throw = true): string; + + /** + * Gets the response body decoded as array, typically from a JSON payload. + * + * @param bool $throw Whether an exception should be thrown on 3/4/5xx status codes + * + * @throws DecodingExceptionInterface When the body cannot be decoded to an array + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function toArray(bool $throw = true): array; + + /** + * Closes the response stream and all related buffers. + * + * No further chunk will be yielded after this method has been called. + */ + public function cancel(): void; + + /** + * Returns info coming from the transport layer. + * + * This method SHOULD NOT throw any ExceptionInterface and SHOULD be non-blocking. + * The returned info is "live": it can be empty and can change from one call to + * another, as the request/response progresses. + * + * The following info MUST be returned: + * - canceled (bool) - true if the response was canceled using ResponseInterface::cancel(), false otherwise + * - error (string|null) - the error message when the transfer was aborted, null otherwise + * - http_code (int) - the last response code or 0 when it is not known yet + * - http_method (string) - the HTTP verb of the last request + * - redirect_count (int) - the number of redirects followed while executing the request + * - redirect_url (string|null) - the resolved location of redirect responses, null otherwise + * - response_headers (array) - an array modelled after the special $http_response_header variable + * - start_time (float) - the time when the request was sent or 0.0 when it's pending + * - url (string) - the last effective URL of the request + * - user_data (mixed) - the value of the "user_data" request option, null if not set + * + * When the "capture_peer_cert_chain" option is true, the "peer_certificate_chain" + * attribute SHOULD list the peer certificates as an array of OpenSSL X.509 resources. + * + * Other info SHOULD be named after curl_getinfo()'s associative return value. + * + * @return mixed An array of all available info, or one of them when $type is + * provided, or null when an unsupported type is requested + */ + public function getInfo(string $type = null); +} diff --git a/vendor/symfony/http-client-contracts/ResponseStreamInterface.php b/vendor/symfony/http-client-contracts/ResponseStreamInterface.php new file mode 100644 index 000000000..fa3e5db6c --- /dev/null +++ b/vendor/symfony/http-client-contracts/ResponseStreamInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient; + +/** + * Yields response chunks, returned by HttpClientInterface::stream(). + * + * @author Nicolas Grekas + * + * @extends \Iterator + */ +interface ResponseStreamInterface extends \Iterator +{ + public function key(): ResponseInterface; + + public function current(): ChunkInterface; +} diff --git a/vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php b/vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php new file mode 100644 index 000000000..30a704975 --- /dev/null +++ b/vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php @@ -0,0 +1,192 @@ + $v) { + switch ($k) { + default: + if (0 !== strpos($k, 'HTTP_')) { + continue 2; + } + // no break + case 'SERVER_NAME': + case 'SERVER_PROTOCOL': + case 'REQUEST_URI': + case 'REQUEST_METHOD': + case 'PHP_AUTH_USER': + case 'PHP_AUTH_PW': + $vars[$k] = $v; + } +} + +$json = json_encode($vars, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); + +switch ($vars['REQUEST_URI']) { + default: + exit; + + case '/head': + header('Content-Length: '.strlen($json), true); + break; + + case '/': + case '/?a=a&b=b': + case 'http://127.0.0.1:8057/': + case 'http://localhost:8057/': + ob_start('ob_gzhandler'); + break; + + case '/103': + header('HTTP/1.1 103 Early Hints'); + header('Link: ; rel=preload; as=style', false); + header('Link: ; rel=preload; as=script', false); + flush(); + usleep(1000); + echo "HTTP/1.1 200 OK\r\n"; + echo "Date: Fri, 26 May 2017 10:02:11 GMT\r\n"; + echo "Content-Length: 13\r\n"; + echo "\r\n"; + echo 'Here the body'; + exit; + + case '/404': + header('Content-Type: application/json', true, 404); + break; + + case '/404-gzipped': + header('Content-Type: text/plain', true, 404); + ob_start('ob_gzhandler'); + @ob_flush(); + flush(); + usleep(300000); + echo 'some text'; + exit; + + case '/301': + if ('Basic Zm9vOmJhcg==' === $vars['HTTP_AUTHORIZATION']) { + header('Location: http://127.0.0.1:8057/302', true, 301); + } + break; + + case '/301/bad-tld': + header('Location: http://foo.example.', true, 301); + break; + + case '/301/invalid': + header('Location: //?foo=bar', true, 301); + break; + + case '/302': + if (!isset($vars['HTTP_AUTHORIZATION'])) { + header('Location: http://localhost:8057/', true, 302); + } + break; + + case '/302/relative': + header('Location: ..', true, 302); + break; + + case '/304': + header('Content-Length: 10', true, 304); + echo '12345'; + + return; + + case '/307': + header('Location: http://localhost:8057/post', true, 307); + break; + + case '/length-broken': + header('Content-Length: 1000'); + break; + + case '/post': + $output = json_encode($_POST + ['REQUEST_METHOD' => $vars['REQUEST_METHOD']], \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); + header('Content-Type: application/json', true); + header('Content-Length: '.strlen($output)); + echo $output; + exit; + + case '/timeout-header': + usleep(300000); + break; + + case '/timeout-body': + echo '<1>'; + @ob_flush(); + flush(); + usleep(500000); + echo '<2>'; + exit; + + case '/timeout-long': + ignore_user_abort(false); + sleep(1); + while (true) { + echo '<1>'; + @ob_flush(); + flush(); + usleep(500); + } + exit; + + case '/chunked': + header('Transfer-Encoding: chunked'); + echo "8\r\nSymfony \r\n5\r\nis aw\r\n6\r\nesome!\r\n0\r\n\r\n"; + exit; + + case '/chunked-broken': + header('Transfer-Encoding: chunked'); + echo "8\r\nSymfony \r\n5\r\nis aw\r\n6\r\ne"; + exit; + + case '/gzip-broken': + header('Content-Encoding: gzip'); + echo str_repeat('-', 1000); + exit; + + case '/max-duration': + ignore_user_abort(false); + while (true) { + echo '<1>'; + @ob_flush(); + flush(); + usleep(500); + } + exit; + + case '/json': + header('Content-Type: application/json'); + echo json_encode([ + 'documents' => [ + ['id' => '/json/1'], + ['id' => '/json/2'], + ['id' => '/json/3'], + ], + ]); + exit; + + case '/json/1': + case '/json/2': + case '/json/3': + header('Content-Type: application/json'); + echo json_encode([ + 'title' => $vars['REQUEST_URI'], + ]); + + exit; +} + +header('Content-Type: application/json', true); + +echo $json; diff --git a/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php b/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php new file mode 100644 index 000000000..7acd6b79c --- /dev/null +++ b/vendor/symfony/http-client-contracts/Test/HttpClientTestCase.php @@ -0,0 +1,1137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Test; + +use PHPUnit\Framework\TestCase; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TimeoutExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A reference test suite for HttpClientInterface implementations. + */ +abstract class HttpClientTestCase extends TestCase +{ + public static function setUpBeforeClass(): void + { + TestHttpServer::start(); + } + + abstract protected function getHttpClient(string $testCase): HttpClientInterface; + + public function testGetRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'headers' => ['Foo' => 'baR'], + 'user_data' => $data = new \stdClass(), + ]); + + $this->assertSame([], $response->getInfo('response_headers')); + $this->assertSame($data, $response->getInfo()['user_data']); + $this->assertSame(200, $response->getStatusCode()); + + $info = $response->getInfo(); + $this->assertNull($info['error']); + $this->assertSame(0, $info['redirect_count']); + $this->assertSame('HTTP/1.1 200 OK', $info['response_headers'][0]); + $this->assertSame('Host: localhost:8057', $info['response_headers'][1]); + $this->assertSame('http://localhost:8057/', $info['url']); + + $headers = $response->getHeaders(); + + $this->assertSame('localhost:8057', $headers['host'][0]); + $this->assertSame(['application/json'], $headers['content-type']); + + $body = json_decode($response->getContent(), true); + $this->assertSame($body, $response->toArray()); + + $this->assertSame('HTTP/1.1', $body['SERVER_PROTOCOL']); + $this->assertSame('/', $body['REQUEST_URI']); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('localhost:8057', $body['HTTP_HOST']); + $this->assertSame('baR', $body['HTTP_FOO']); + + $response = $client->request('GET', 'http://localhost:8057/length-broken'); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testHeadRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('HEAD', 'http://localhost:8057/head', [ + 'headers' => ['Foo' => 'baR'], + 'user_data' => $data = new \stdClass(), + 'buffer' => false, + ]); + + $this->assertSame([], $response->getInfo('response_headers')); + $this->assertSame(200, $response->getStatusCode()); + + $info = $response->getInfo(); + $this->assertSame('HTTP/1.1 200 OK', $info['response_headers'][0]); + $this->assertSame('Host: localhost:8057', $info['response_headers'][1]); + + $headers = $response->getHeaders(); + + $this->assertSame('localhost:8057', $headers['host'][0]); + $this->assertSame(['application/json'], $headers['content-type']); + $this->assertTrue(0 < $headers['content-length'][0]); + + $this->assertSame('', $response->getContent()); + } + + public function testNonBufferedGetRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'buffer' => false, + 'headers' => ['Foo' => 'baR'], + ]); + + $body = $response->toArray(); + $this->assertSame('baR', $body['HTTP_FOO']); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testBufferSink() + { + $sink = fopen('php://temp', 'w+'); + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'buffer' => $sink, + 'headers' => ['Foo' => 'baR'], + ]); + + $body = $response->toArray(); + $this->assertSame('baR', $body['HTTP_FOO']); + + rewind($sink); + $sink = stream_get_contents($sink); + $this->assertSame($sink, $response->getContent()); + } + + public function testConditionalBuffering() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057'); + $firstContent = $response->getContent(); + $secondContent = $response->getContent(); + + $this->assertSame($firstContent, $secondContent); + + $response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () { return false; }]); + $response->getContent(); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testReentrantBufferCallback() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () use (&$response) { + $response->cancel(); + + return true; + }]); + + $this->assertSame(200, $response->getStatusCode()); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testThrowingBufferCallback() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057', ['buffer' => function () { + throw new \Exception('Boo.'); + }]); + + $this->assertSame(200, $response->getStatusCode()); + + $this->expectException(TransportExceptionInterface::class); + $this->expectExceptionMessage('Boo'); + $response->getContent(); + } + + public function testUnsupportedOption() + { + $client = $this->getHttpClient(__FUNCTION__); + + $this->expectException(\InvalidArgumentException::class); + $client->request('GET', 'http://localhost:8057', [ + 'capture_peer_cert' => 1.0, + ]); + } + + public function testHttpVersion() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'http_version' => 1.0, + ]); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('HTTP/1.0 200 OK', $response->getInfo('response_headers')[0]); + + $body = $response->toArray(); + + $this->assertSame('HTTP/1.0', $body['SERVER_PROTOCOL']); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('/', $body['REQUEST_URI']); + } + + public function testChunkedEncoding() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/chunked'); + + $this->assertSame(['chunked'], $response->getHeaders()['transfer-encoding']); + $this->assertSame('Symfony is awesome!', $response->getContent()); + + $response = $client->request('GET', 'http://localhost:8057/chunked-broken'); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testClientError() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/404'); + + $client->stream($response)->valid(); + + $this->assertSame(404, $response->getInfo('http_code')); + + try { + $response->getHeaders(); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + } + + try { + $response->getContent(); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + } + + $this->assertSame(404, $response->getStatusCode()); + $this->assertSame(['application/json'], $response->getHeaders(false)['content-type']); + $this->assertNotEmpty($response->getContent(false)); + + $response = $client->request('GET', 'http://localhost:8057/404'); + + try { + foreach ($client->stream($response) as $chunk) { + $this->assertTrue($chunk->isFirst()); + } + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + } + } + + public function testIgnoreErrors() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/404'); + + $this->assertSame(404, $response->getStatusCode()); + } + + public function testDnsError() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/301/bad-tld'); + + try { + $response->getStatusCode(); + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + try { + $response->getStatusCode(); + $this->fail(TransportExceptionInterface::class.' still expected'); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + $response = $client->request('GET', 'http://localhost:8057/301/bad-tld'); + + try { + foreach ($client->stream($response) as $r => $chunk) { + } + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + $this->assertSame($response, $r); + $this->assertNotNull($chunk->getError()); + + $this->expectException(TransportExceptionInterface::class); + foreach ($client->stream($response) as $chunk) { + } + } + + public function testInlineAuth() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://foo:bar%3Dbar@localhost:8057'); + + $body = $response->toArray(); + + $this->assertSame('foo', $body['PHP_AUTH_USER']); + $this->assertSame('bar=bar', $body['PHP_AUTH_PW']); + } + + public function testBadRequestBody() + { + $client = $this->getHttpClient(__FUNCTION__); + + $this->expectException(TransportExceptionInterface::class); + + $response = $client->request('POST', 'http://localhost:8057/', [ + 'body' => function () { yield []; }, + ]); + + $response->getStatusCode(); + } + + public function test304() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/304', [ + 'headers' => ['If-Match' => '"abc"'], + 'buffer' => false, + ]); + + $this->assertSame(304, $response->getStatusCode()); + $this->assertSame('', $response->getContent(false)); + } + + /** + * @testWith [[]] + * [["Content-Length: 7"]] + */ + public function testRedirects(array $headers = []) + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('POST', 'http://localhost:8057/301', [ + 'auth_basic' => 'foo:bar', + 'headers' => $headers, + 'body' => function () { + yield 'foo=bar'; + }, + ]); + + $body = $response->toArray(); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('Basic Zm9vOmJhcg==', $body['HTTP_AUTHORIZATION']); + $this->assertSame('http://localhost:8057/', $response->getInfo('url')); + + $this->assertSame(2, $response->getInfo('redirect_count')); + $this->assertNull($response->getInfo('redirect_url')); + + $expected = [ + 'HTTP/1.1 301 Moved Permanently', + 'Location: http://127.0.0.1:8057/302', + 'Content-Type: application/json', + 'HTTP/1.1 302 Found', + 'Location: http://localhost:8057/', + 'Content-Type: application/json', + 'HTTP/1.1 200 OK', + 'Content-Type: application/json', + ]; + + $filteredHeaders = array_values(array_filter($response->getInfo('response_headers'), function ($h) { + return \in_array(substr($h, 0, 4), ['HTTP', 'Loca', 'Cont'], true) && 'Content-Encoding: gzip' !== $h; + })); + + $this->assertSame($expected, $filteredHeaders); + } + + public function testInvalidRedirect() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/301/invalid'); + + $this->assertSame(301, $response->getStatusCode()); + $this->assertSame(['//?foo=bar'], $response->getHeaders(false)['location']); + $this->assertSame(0, $response->getInfo('redirect_count')); + $this->assertNull($response->getInfo('redirect_url')); + + $this->expectException(RedirectionExceptionInterface::class); + $response->getHeaders(); + } + + public function testRelativeRedirects() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/302/relative'); + + $body = $response->toArray(); + + $this->assertSame('/', $body['REQUEST_URI']); + $this->assertNull($response->getInfo('redirect_url')); + + $response = $client->request('GET', 'http://localhost:8057/302/relative', [ + 'max_redirects' => 0, + ]); + + $this->assertSame(302, $response->getStatusCode()); + $this->assertSame('http://localhost:8057/', $response->getInfo('redirect_url')); + } + + public function testRedirect307() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/307', [ + 'body' => function () { + yield 'foo=bar'; + }, + 'max_redirects' => 0, + ]); + + $this->assertSame(307, $response->getStatusCode()); + + $response = $client->request('POST', 'http://localhost:8057/307', [ + 'body' => 'foo=bar', + ]); + + $body = $response->toArray(); + + $this->assertSame(['foo' => 'bar', 'REQUEST_METHOD' => 'POST'], $body); + } + + public function testMaxRedirects() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/301', [ + 'max_redirects' => 1, + 'auth_basic' => 'foo:bar', + ]); + + try { + $response->getHeaders(); + $this->fail(RedirectionExceptionInterface::class.' expected'); + } catch (RedirectionExceptionInterface $e) { + } + + $this->assertSame(302, $response->getStatusCode()); + $this->assertSame(1, $response->getInfo('redirect_count')); + $this->assertSame('http://localhost:8057/', $response->getInfo('redirect_url')); + + $expected = [ + 'HTTP/1.1 301 Moved Permanently', + 'Location: http://127.0.0.1:8057/302', + 'Content-Type: application/json', + 'HTTP/1.1 302 Found', + 'Location: http://localhost:8057/', + 'Content-Type: application/json', + ]; + + $filteredHeaders = array_values(array_filter($response->getInfo('response_headers'), function ($h) { + return \in_array(substr($h, 0, 4), ['HTTP', 'Loca', 'Cont'], true); + })); + + $this->assertSame($expected, $filteredHeaders); + } + + public function testStream() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057'); + $chunks = $client->stream($response); + $result = []; + + foreach ($chunks as $r => $chunk) { + if ($chunk->isTimeout()) { + $result[] = 't'; + } elseif ($chunk->isLast()) { + $result[] = 'l'; + } elseif ($chunk->isFirst()) { + $result[] = 'f'; + } + } + + $this->assertSame($response, $r); + $this->assertSame(['f', 'l'], $result); + + $chunk = null; + $i = 0; + + foreach ($client->stream($response) as $chunk) { + ++$i; + } + + $this->assertSame(1, $i); + $this->assertTrue($chunk->isLast()); + } + + public function testAddToStream() + { + $client = $this->getHttpClient(__FUNCTION__); + + $r1 = $client->request('GET', 'http://localhost:8057'); + + $completed = []; + + $pool = [$r1]; + + while ($pool) { + $chunks = $client->stream($pool); + $pool = []; + + foreach ($chunks as $r => $chunk) { + if (!$chunk->isLast()) { + continue; + } + + if ($r1 === $r) { + $r2 = $client->request('GET', 'http://localhost:8057'); + $pool[] = $r2; + } + + $completed[] = $r; + } + } + + $this->assertSame([$r1, $r2], $completed); + } + + public function testCompleteTypeError() + { + $client = $this->getHttpClient(__FUNCTION__); + + $this->expectException(\TypeError::class); + $client->stream(123); + } + + public function testOnProgress() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'headers' => ['Content-Length' => 14], + 'body' => 'foo=0123456789', + 'on_progress' => function (...$state) use (&$steps) { $steps[] = $state; }, + ]); + + $body = $response->toArray(); + + $this->assertSame(['foo' => '0123456789', 'REQUEST_METHOD' => 'POST'], $body); + $this->assertSame([0, 0], \array_slice($steps[0], 0, 2)); + $lastStep = \array_slice($steps, -1)[0]; + $this->assertSame([57, 57], \array_slice($lastStep, 0, 2)); + $this->assertSame('http://localhost:8057/post', $steps[0][2]['url']); + } + + public function testPostJson() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'json' => ['foo' => 'bar'], + ]); + + $body = $response->toArray(); + + $this->assertStringContainsString('json', $body['content-type']); + unset($body['content-type']); + $this->assertSame(['foo' => 'bar', 'REQUEST_METHOD' => 'POST'], $body); + } + + public function testPostArray() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'body' => ['foo' => 'bar'], + ]); + + $this->assertSame(['foo' => 'bar', 'REQUEST_METHOD' => 'POST'], $response->toArray()); + } + + public function testPostResource() + { + $client = $this->getHttpClient(__FUNCTION__); + + $h = fopen('php://temp', 'w+'); + fwrite($h, 'foo=0123456789'); + rewind($h); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'body' => $h, + ]); + + $body = $response->toArray(); + + $this->assertSame(['foo' => '0123456789', 'REQUEST_METHOD' => 'POST'], $body); + } + + public function testPostCallback() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('POST', 'http://localhost:8057/post', [ + 'body' => function () { + yield 'foo'; + yield ''; + yield '='; + yield '0123456789'; + }, + ]); + + $this->assertSame(['foo' => '0123456789', 'REQUEST_METHOD' => 'POST'], $response->toArray()); + } + + public function testCancel() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-header'); + + $response->cancel(); + $this->expectException(TransportExceptionInterface::class); + $response->getHeaders(); + } + + public function testInfoOnCanceledResponse() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://localhost:8057/timeout-header'); + + $this->assertFalse($response->getInfo('canceled')); + $response->cancel(); + $this->assertTrue($response->getInfo('canceled')); + } + + public function testCancelInStream() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/404'); + + foreach ($client->stream($response) as $chunk) { + $response->cancel(); + } + + $this->expectException(TransportExceptionInterface::class); + + foreach ($client->stream($response) as $chunk) { + } + } + + public function testOnProgressCancel() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body', [ + 'on_progress' => function ($dlNow) { + if (0 < $dlNow) { + throw new \Exception('Aborting the request.'); + } + }, + ]); + + try { + foreach ($client->stream([$response]) as $chunk) { + } + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + $this->assertSame('Aborting the request.', $e->getPrevious()->getMessage()); + } + + $this->assertNotNull($response->getInfo('error')); + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testOnProgressError() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body', [ + 'on_progress' => function ($dlNow) { + if (0 < $dlNow) { + throw new \Error('BUG.'); + } + }, + ]); + + try { + foreach ($client->stream([$response]) as $chunk) { + } + $this->fail('Error expected'); + } catch (\Error $e) { + $this->assertSame('BUG.', $e->getMessage()); + } + + $this->assertNotNull($response->getInfo('error')); + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testResolve() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://symfony.com:8057/', [ + 'resolve' => ['symfony.com' => '127.0.0.1'], + ]); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame(200, $client->request('GET', 'http://symfony.com:8057/')->getStatusCode()); + + $response = null; + $this->expectException(TransportExceptionInterface::class); + $client->request('GET', 'http://symfony.com:8057/', ['timeout' => 1]); + } + + public function testIdnResolve() + { + $client = $this->getHttpClient(__FUNCTION__); + + $response = $client->request('GET', 'http://0-------------------------------------------------------------0.com:8057/', [ + 'resolve' => ['0-------------------------------------------------------------0.com' => '127.0.0.1'], + ]); + + $this->assertSame(200, $response->getStatusCode()); + + $response = $client->request('GET', 'http://Bücher.example:8057/', [ + 'resolve' => ['xn--bcher-kva.example' => '127.0.0.1'], + ]); + + $this->assertSame(200, $response->getStatusCode()); + } + + public function testNotATimeout() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-header', [ + 'timeout' => 0.9, + ]); + sleep(1); + $this->assertSame(200, $response->getStatusCode()); + } + + public function testTimeoutOnAccess() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-header', [ + 'timeout' => 0.1, + ]); + + $this->expectException(TransportExceptionInterface::class); + $response->getHeaders(); + } + + public function testTimeoutIsNotAFatalError() + { + usleep(300000); // wait for the previous test to release the server + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body', [ + 'timeout' => 0.25, + ]); + + try { + $response->getContent(); + $this->fail(TimeoutExceptionInterface::class.' expected'); + } catch (TimeoutExceptionInterface $e) { + } + + for ($i = 0; $i < 10; ++$i) { + try { + $this->assertSame('<1><2>', $response->getContent()); + break; + } catch (TimeoutExceptionInterface $e) { + } + } + + if (10 === $i) { + throw $e; + } + } + + public function testTimeoutOnStream() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body'); + + $this->assertSame(200, $response->getStatusCode()); + $chunks = $client->stream([$response], 0.2); + + $result = []; + + foreach ($chunks as $r => $chunk) { + if ($chunk->isTimeout()) { + $result[] = 't'; + } else { + $result[] = $chunk->getContent(); + } + } + + $this->assertSame(['<1>', 't'], $result); + + $chunks = $client->stream([$response]); + + foreach ($chunks as $r => $chunk) { + $this->assertSame('<2>', $chunk->getContent()); + $this->assertSame('<1><2>', $r->getContent()); + + return; + } + + $this->fail('The response should have completed'); + } + + public function testUncheckedTimeoutThrows() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body'); + $chunks = $client->stream([$response], 0.1); + + $this->expectException(TransportExceptionInterface::class); + + foreach ($chunks as $r => $chunk) { + } + } + + public function testTimeoutWithActiveConcurrentStream() + { + $p1 = TestHttpServer::start(8067); + $p2 = TestHttpServer::start(8077); + + $client = $this->getHttpClient(__FUNCTION__); + $streamingResponse = $client->request('GET', 'http://localhost:8067/max-duration'); + $blockingResponse = $client->request('GET', 'http://localhost:8077/timeout-body', [ + 'timeout' => 0.25, + ]); + + $this->assertSame(200, $streamingResponse->getStatusCode()); + $this->assertSame(200, $blockingResponse->getStatusCode()); + + $this->expectException(TransportExceptionInterface::class); + + try { + $blockingResponse->getContent(); + } finally { + $p1->stop(); + $p2->stop(); + } + } + + public function testTimeoutOnInitialize() + { + $p1 = TestHttpServer::start(8067); + $p2 = TestHttpServer::start(8077); + + $client = $this->getHttpClient(__FUNCTION__); + $start = microtime(true); + $responses = []; + + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + + try { + foreach ($responses as $response) { + try { + $response->getContent(); + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + } + } + $responses = []; + + $duration = microtime(true) - $start; + + $this->assertLessThan(1.0, $duration); + } finally { + $p1->stop(); + $p2->stop(); + } + } + + public function testTimeoutOnDestruct() + { + $p1 = TestHttpServer::start(8067); + $p2 = TestHttpServer::start(8077); + + $client = $this->getHttpClient(__FUNCTION__); + $start = microtime(true); + $responses = []; + + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8067/timeout-header', ['timeout' => 0.25]); + $responses[] = $client->request('GET', 'http://localhost:8077/timeout-header', ['timeout' => 0.25]); + + try { + while ($response = array_shift($responses)) { + try { + unset($response); + $this->fail(TransportExceptionInterface::class.' expected'); + } catch (TransportExceptionInterface $e) { + } + } + + $duration = microtime(true) - $start; + + $this->assertLessThan(1.0, $duration); + } finally { + $p1->stop(); + $p2->stop(); + } + } + + public function testDestruct() + { + $client = $this->getHttpClient(__FUNCTION__); + + $start = microtime(true); + $client->request('GET', 'http://localhost:8057/timeout-long'); + $client = null; + $duration = microtime(true) - $start; + + $this->assertGreaterThan(1, $duration); + $this->assertLessThan(4, $duration); + } + + public function testGetContentAfterDestruct() + { + $client = $this->getHttpClient(__FUNCTION__); + + try { + $client->request('GET', 'http://localhost:8057/404'); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + $this->assertSame('GET', $e->getResponse()->toArray(false)['REQUEST_METHOD']); + } + } + + public function testGetEncodedContentAfterDestruct() + { + $client = $this->getHttpClient(__FUNCTION__); + + try { + $client->request('GET', 'http://localhost:8057/404-gzipped'); + $this->fail(ClientExceptionInterface::class.' expected'); + } catch (ClientExceptionInterface $e) { + $this->assertSame('some text', $e->getResponse()->getContent(false)); + } + } + + public function testProxy() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/', [ + 'proxy' => 'http://localhost:8057', + ]); + + $body = $response->toArray(); + $this->assertSame('localhost:8057', $body['HTTP_HOST']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); + + $response = $client->request('GET', 'http://localhost:8057/', [ + 'proxy' => 'http://foo:b%3Dar@localhost:8057', + ]); + + $body = $response->toArray(); + $this->assertSame('Basic Zm9vOmI9YXI=', $body['HTTP_PROXY_AUTHORIZATION']); + + $_SERVER['http_proxy'] = 'http://localhost:8057'; + try { + $response = $client->request('GET', 'http://localhost:8057/'); + $body = $response->toArray(); + $this->assertSame('localhost:8057', $body['HTTP_HOST']); + $this->assertMatchesRegularExpression('#^http://(localhost|127\.0\.0\.1):8057/$#', $body['REQUEST_URI']); + } finally { + unset($_SERVER['http_proxy']); + } + } + + public function testNoProxy() + { + putenv('no_proxy='.$_SERVER['no_proxy'] = 'example.com, localhost'); + + try { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/', [ + 'proxy' => 'http://localhost:8057', + ]); + + $body = $response->toArray(); + + $this->assertSame('HTTP/1.1', $body['SERVER_PROTOCOL']); + $this->assertSame('/', $body['REQUEST_URI']); + $this->assertSame('GET', $body['REQUEST_METHOD']); + } finally { + putenv('no_proxy'); + unset($_SERVER['no_proxy']); + } + } + + /** + * @requires extension zlib + */ + public function testAutoEncodingRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057'); + + $this->assertSame(200, $response->getStatusCode()); + + $headers = $response->getHeaders(); + + $this->assertSame(['Accept-Encoding'], $headers['vary']); + $this->assertStringContainsString('gzip', $headers['content-encoding'][0]); + + $body = $response->toArray(); + + $this->assertStringContainsString('gzip', $body['HTTP_ACCEPT_ENCODING']); + } + + public function testBaseUri() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', '../404', [ + 'base_uri' => 'http://localhost:8057/abc/', + ]); + + $this->assertSame(404, $response->getStatusCode()); + $this->assertSame(['application/json'], $response->getHeaders(false)['content-type']); + } + + public function testQuery() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/?a=a', [ + 'query' => ['b' => 'b'], + ]); + + $body = $response->toArray(); + $this->assertSame('GET', $body['REQUEST_METHOD']); + $this->assertSame('/?a=a&b=b', $body['REQUEST_URI']); + } + + public function testInformationalResponse() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/103'); + + $this->assertSame('Here the body', $response->getContent()); + $this->assertSame(200, $response->getStatusCode()); + } + + public function testInformationalResponseStream() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/103'); + + $chunks = []; + foreach ($client->stream($response) as $chunk) { + $chunks[] = $chunk; + } + + $this->assertSame(103, $chunks[0]->getInformationalStatus()[0]); + $this->assertSame(['; rel=preload; as=style', '; rel=preload; as=script'], $chunks[0]->getInformationalStatus()[1]['link']); + $this->assertTrue($chunks[1]->isFirst()); + $this->assertSame('Here the body', $chunks[2]->getContent()); + $this->assertTrue($chunks[3]->isLast()); + $this->assertNull($chunks[3]->getInformationalStatus()); + + $this->assertSame(['date', 'content-length'], array_keys($response->getHeaders())); + $this->assertContains('Link: ; rel=preload; as=style', $response->getInfo('response_headers')); + } + + /** + * @requires extension zlib + */ + public function testUserlandEncodingRequest() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057', [ + 'headers' => ['Accept-Encoding' => 'gzip'], + ]); + + $headers = $response->getHeaders(); + + $this->assertSame(['Accept-Encoding'], $headers['vary']); + $this->assertStringContainsString('gzip', $headers['content-encoding'][0]); + + $body = $response->getContent(); + $this->assertSame("\x1F", $body[0]); + + $body = json_decode(gzdecode($body), true); + $this->assertSame('gzip', $body['HTTP_ACCEPT_ENCODING']); + } + + /** + * @requires extension zlib + */ + public function testGzipBroken() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/gzip-broken'); + + $this->expectException(TransportExceptionInterface::class); + $response->getContent(); + } + + public function testMaxDuration() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/max-duration', [ + 'max_duration' => 0.1, + ]); + + $start = microtime(true); + + try { + $response->getContent(); + } catch (TransportExceptionInterface $e) { + $this->addToAssertionCount(1); + } + + $duration = microtime(true) - $start; + + $this->assertLessThan(10, $duration); + } + + public function testWithOptions() + { + $client = $this->getHttpClient(__FUNCTION__); + if (!method_exists($client, 'withOptions')) { + $this->markTestSkipped(sprintf('Not implementing "%s::withOptions()" is deprecated.', get_debug_type($client))); + } + + $client2 = $client->withOptions(['base_uri' => 'http://localhost:8057/']); + + $this->assertNotSame($client, $client2); + $this->assertSame(\get_class($client), \get_class($client2)); + + $response = $client2->request('GET', '/'); + $this->assertSame(200, $response->getStatusCode()); + } +} diff --git a/vendor/symfony/http-client-contracts/Test/TestHttpServer.php b/vendor/symfony/http-client-contracts/Test/TestHttpServer.php new file mode 100644 index 000000000..55a744aef --- /dev/null +++ b/vendor/symfony/http-client-contracts/Test/TestHttpServer.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\HttpClient\Test; + +use Symfony\Component\Process\PhpExecutableFinder; +use Symfony\Component\Process\Process; + +class TestHttpServer +{ + private static $process = []; + + /** + * @return Process + */ + public static function start(int $port = 8057) + { + if (isset(self::$process[$port])) { + self::$process[$port]->stop(); + } else { + register_shutdown_function(static function () use ($port) { + self::$process[$port]->stop(); + }); + } + + $finder = new PhpExecutableFinder(); + $process = new Process(array_merge([$finder->find(false)], $finder->findArguments(), ['-dopcache.enable=0', '-dvariables_order=EGPCS', '-S', '127.0.0.1:'.$port])); + $process->setWorkingDirectory(__DIR__.'/Fixtures/web'); + $process->start(); + self::$process[$port] = $process; + + do { + usleep(50000); + } while (!@fopen('http://127.0.0.1:'.$port, 'r')); + + return $process; + } +} diff --git a/vendor/symfony/http-client-contracts/composer.json b/vendor/symfony/http-client-contracts/composer.json new file mode 100644 index 000000000..b76cab852 --- /dev/null +++ b/vendor/symfony/http-client-contracts/composer.json @@ -0,0 +1,37 @@ +{ + "name": "symfony/http-client-contracts", + "type": "library", + "description": "Generic abstractions related to HTTP clients", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\HttpClient\\": "" } + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + } +} diff --git a/vendor/symfony/http-client/AmpHttpClient.php b/vendor/symfony/http-client/AmpHttpClient.php new file mode 100644 index 000000000..2ab7e27f7 --- /dev/null +++ b/vendor/symfony/http-client/AmpHttpClient.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Amp\CancelledException; +use Amp\Http\Client\DelegateHttpClient; +use Amp\Http\Client\InterceptedHttpClient; +use Amp\Http\Client\PooledHttpClient; +use Amp\Http\Client\Request; +use Amp\Http\Tunnel\Http1TunnelConnector; +use Amp\Promise; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\AmpClientState; +use Symfony\Component\HttpClient\Response\AmpResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +if (!interface_exists(DelegateHttpClient::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\AmpHttpClient" as the "amphp/http-client" package is not installed. Try running "composer require amphp/http-client:^4.2.1".'); +} + +if (!interface_exists(Promise::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\AmpHttpClient" as the installed "amphp/http-client" is not compatible with this version of "symfony/http-client". Try downgrading "amphp/http-client" to "^4.2.1".'); +} + +/** + * A portable implementation of the HttpClientInterface contracts based on Amp's HTTP client. + * + * @author Nicolas Grekas + */ +final class AmpHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + use LoggerAwareTrait; + + private $defaultOptions = self::OPTIONS_DEFAULTS; + private static $emptyDefaults = self::OPTIONS_DEFAULTS; + + /** @var AmpClientState */ + private $multi; + + /** + * @param array $defaultOptions Default requests' options + * @param callable|null $clientConfigurator A callable that builds a {@see DelegateHttpClient} from a {@see PooledHttpClient}; + * passing null builds an {@see InterceptedHttpClient} with 2 retries on failures + * @param int $maxHostConnections The maximum number of connections to a single host + * @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public function __construct(array $defaultOptions = [], callable $clientConfigurator = null, int $maxHostConnections = 6, int $maxPendingPushes = 50) + { + $this->defaultOptions['buffer'] = $this->defaultOptions['buffer'] ?? \Closure::fromCallable([__CLASS__, 'shouldBuffer']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + + $this->multi = new AmpClientState($clientConfigurator, $maxHostConnections, $maxPendingPushes, $this->logger); + } + + /** + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + * + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); + + $options['proxy'] = self::getProxy($options['proxy'], $url, $options['no_proxy']); + + if (null !== $options['proxy'] && !class_exists(Http1TunnelConnector::class)) { + throw new \LogicException('You cannot use the "proxy" option as the "amphp/http-tunnel" package is not installed. Try running "composer require amphp/http-tunnel".'); + } + + if ($options['bindto']) { + if (0 === strpos($options['bindto'], 'if!')) { + throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.'); + } + if (0 === strpos($options['bindto'], 'host!')) { + $options['bindto'] = substr($options['bindto'], 5); + } + } + + if (('' !== $options['body'] || 'POST' === $method || isset($options['normalized_headers']['content-length'])) && !isset($options['normalized_headers']['content-type'])) { + $options['headers'][] = 'Content-Type: application/x-www-form-urlencoded'; + } + + if (!isset($options['normalized_headers']['user-agent'])) { + $options['headers'][] = 'User-Agent: Symfony HttpClient/Amp'; + } + + if (0 < $options['max_duration']) { + $options['timeout'] = min($options['max_duration'], $options['timeout']); + } + + if ($options['resolve']) { + $this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCache; + } + + if ($options['peer_fingerprint'] && !isset($options['peer_fingerprint']['pin-sha256'])) { + throw new TransportException(__CLASS__.' supports only "pin-sha256" fingerprints.'); + } + + $request = new Request(implode('', $url), $method); + + if ($options['http_version']) { + switch ((float) $options['http_version']) { + case 1.0: $request->setProtocolVersions(['1.0']); break; + case 1.1: $request->setProtocolVersions(['1.1', '1.0']); break; + default: $request->setProtocolVersions(['2', '1.1', '1.0']); break; + } + } + + foreach ($options['headers'] as $v) { + $h = explode(': ', $v, 2); + $request->addHeader($h[0], $h[1]); + } + + $request->setTcpConnectTimeout(1000 * $options['timeout']); + $request->setTlsHandshakeTimeout(1000 * $options['timeout']); + $request->setTransferTimeout(1000 * $options['max_duration']); + if (method_exists($request, 'setInactivityTimeout')) { + $request->setInactivityTimeout(0); + } + + if ('' !== $request->getUri()->getUserInfo() && !$request->hasHeader('authorization')) { + $auth = explode(':', $request->getUri()->getUserInfo(), 2); + $auth = array_map('rawurldecode', $auth) + [1 => '']; + $request->setHeader('Authorization', 'Basic '.base64_encode(implode(':', $auth))); + } + + return new AmpResponse($this->multi, $request, $options, $this->logger); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof AmpResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of AmpResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(AmpResponse::stream($responses, $timeout)); + } + + public function reset() + { + $this->multi->dnsCache = []; + + foreach ($this->multi->pushedResponses as $authority => $pushedResponses) { + foreach ($pushedResponses as [$pushedUrl, $pushDeferred]) { + $pushDeferred->fail(new CancelledException()); + + if ($this->logger) { + $this->logger->debug(sprintf('Unused pushed response: "%s"', $pushedUrl)); + } + } + } + + $this->multi->pushedResponses = []; + } +} diff --git a/vendor/symfony/http-client/AsyncDecoratorTrait.php b/vendor/symfony/http-client/AsyncDecoratorTrait.php new file mode 100644 index 000000000..aff402d83 --- /dev/null +++ b/vendor/symfony/http-client/AsyncDecoratorTrait.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Response\AsyncResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; + +/** + * Eases with processing responses while streaming them. + * + * @author Nicolas Grekas + */ +trait AsyncDecoratorTrait +{ + use DecoratorTrait; + + /** + * {@inheritdoc} + * + * @return AsyncResponse + */ + abstract public function request(string $method, string $url, array $options = []): ResponseInterface; + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof AsyncResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of AsyncResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(AsyncResponse::stream($responses, $timeout, static::class)); + } +} diff --git a/vendor/symfony/http-client/CHANGELOG.md b/vendor/symfony/http-client/CHANGELOG.md new file mode 100644 index 000000000..7c2fc2273 --- /dev/null +++ b/vendor/symfony/http-client/CHANGELOG.md @@ -0,0 +1,54 @@ +CHANGELOG +========= + +5.4 +--- + + * Add `MockHttpClient::setResponseFactory()` method to be able to set response factory after client creating + +5.3 +--- + + * Implement `HttpClientInterface::withOptions()` from `symfony/contracts` v2.4 + * Add `DecoratorTrait` to ease writing simple decorators + +5.2.0 +----- + + * added `AsyncDecoratorTrait` to ease processing responses without breaking async + * added support for pausing responses with a new `pause_handler` callable exposed as an info item + * added `StreamableInterface` to ease turning responses into PHP streams + * added `MockResponse::getRequestMethod()` and `getRequestUrl()` to allow inspecting which request has been sent + * added `EventSourceHttpClient` a Server-Sent events stream implementing the [EventSource specification](https://www.w3.org/TR/eventsource/#eventsource) + * added option "extra.curl" to allow setting additional curl options in `CurlHttpClient` + * added `RetryableHttpClient` to automatically retry failed HTTP requests. + * added `extra.trace_content` option to `TraceableHttpClient` to prevent it from keeping the content in memory + +5.1.0 +----- + + * added `NoPrivateNetworkHttpClient` decorator + * added `AmpHttpClient`, a portable HTTP/2 implementation based on Amp + * added `LoggerAwareInterface` to `ScopingHttpClient` and `TraceableHttpClient` + * made `HttpClient::create()` return an `AmpHttpClient` when `amphp/http-client` is found but curl is not or too old + +4.4.0 +----- + + * added `canceled` to `ResponseInterface::getInfo()` + * added `HttpClient::createForBaseUri()` + * added `HttplugClient` with support for sync and async requests + * added `max_duration` option + * added support for NTLM authentication + * added `StreamWrapper` to cast any `ResponseInterface` instances to PHP streams. + * added `$response->toStream()` to cast responses to regular PHP streams + * made `Psr18Client` implement relevant PSR-17 factories and have streaming responses + * added `TraceableHttpClient`, `HttpClientDataCollector` and `HttpClientPass` to integrate with the web profiler + * allow enabling buffering conditionally with a Closure + * allow option "buffer" to be a stream resource + * allow arbitrary values for the "json" option + +4.3.0 +----- + + * added the component diff --git a/vendor/symfony/http-client/CachingHttpClient.php b/vendor/symfony/http-client/CachingHttpClient.php new file mode 100644 index 000000000..e1d7023d9 --- /dev/null +++ b/vendor/symfony/http-client/CachingHttpClient.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Response\MockResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpCache\HttpCache; +use Symfony\Component\HttpKernel\HttpCache\StoreInterface; +use Symfony\Component\HttpKernel\HttpClientKernel; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Adds caching on top of an HTTP client. + * + * The implementation buffers responses in memory and doesn't stream directly from the network. + * You can disable/enable this layer by setting option "no_cache" under "extra" to true/false. + * By default, caching is enabled unless the "buffer" option is set to false. + * + * @author Nicolas Grekas + */ +class CachingHttpClient implements HttpClientInterface, ResetInterface +{ + use HttpClientTrait; + + private $client; + private $cache; + private $defaultOptions = self::OPTIONS_DEFAULTS; + + public function __construct(HttpClientInterface $client, StoreInterface $store, array $defaultOptions = []) + { + if (!class_exists(HttpClientKernel::class)) { + throw new \LogicException(sprintf('Using "%s" requires that the HttpKernel component version 4.3 or higher is installed, try running "composer require symfony/http-kernel:^5.4".', __CLASS__)); + } + + $this->client = $client; + $kernel = new HttpClientKernel($client); + $this->cache = new HttpCache($kernel, $store, null, $defaultOptions); + + unset($defaultOptions['debug']); + unset($defaultOptions['default_ttl']); + unset($defaultOptions['private_headers']); + unset($defaultOptions['allow_reload']); + unset($defaultOptions['allow_revalidate']); + unset($defaultOptions['stale_while_revalidate']); + unset($defaultOptions['stale_if_error']); + unset($defaultOptions['trace_level']); + unset($defaultOptions['trace_header']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = $this->prepareRequest($method, $url, $options, $this->defaultOptions, true); + $url = implode('', $url); + + if (!empty($options['body']) || !empty($options['extra']['no_cache']) || !\in_array($method, ['GET', 'HEAD', 'OPTIONS'])) { + return $this->client->request($method, $url, $options); + } + + $request = Request::create($url, $method); + $request->attributes->set('http_client_options', $options); + + foreach ($options['normalized_headers'] as $name => $values) { + if ('cookie' !== $name) { + foreach ($values as $value) { + $request->headers->set($name, substr($value, 2 + \strlen($name)), false); + } + + continue; + } + + foreach ($values as $cookies) { + foreach (explode('; ', substr($cookies, \strlen('Cookie: '))) as $cookie) { + if ('' !== $cookie) { + $cookie = explode('=', $cookie, 2); + $request->cookies->set($cookie[0], $cookie[1] ?? ''); + } + } + } + } + + $response = $this->cache->handle($request); + $response = new MockResponse($response->getContent(), [ + 'http_code' => $response->getStatusCode(), + 'response_headers' => $response->headers->allPreserveCase(), + ]); + + return MockResponse::fromRequest($method, $url, $options, $response); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof ResponseInterface) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of ResponseInterface objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + $mockResponses = []; + $clientResponses = []; + + foreach ($responses as $response) { + if ($response instanceof MockResponse) { + $mockResponses[] = $response; + } else { + $clientResponses[] = $response; + } + } + + if (!$mockResponses) { + return $this->client->stream($clientResponses, $timeout); + } + + if (!$clientResponses) { + return new ResponseStream(MockResponse::stream($mockResponses, $timeout)); + } + + return new ResponseStream((function () use ($mockResponses, $clientResponses, $timeout) { + yield from MockResponse::stream($mockResponses, $timeout); + yield $this->client->stream($clientResponses, $timeout); + })()); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} diff --git a/vendor/symfony/http-client/Chunk/DataChunk.php b/vendor/symfony/http-client/Chunk/DataChunk.php new file mode 100644 index 000000000..37ca84854 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/DataChunk.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +use Symfony\Contracts\HttpClient\ChunkInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class DataChunk implements ChunkInterface +{ + private $offset = 0; + private $content = ''; + + public function __construct(int $offset = 0, string $content = '') + { + $this->offset = $offset; + $this->content = $content; + } + + /** + * {@inheritdoc} + */ + public function isTimeout(): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + public function isFirst(): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + public function isLast(): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + public function getInformationalStatus(): ?array + { + return null; + } + + /** + * {@inheritdoc} + */ + public function getContent(): string + { + return $this->content; + } + + /** + * {@inheritdoc} + */ + public function getOffset(): int + { + return $this->offset; + } + + /** + * {@inheritdoc} + */ + public function getError(): ?string + { + return null; + } +} diff --git a/vendor/symfony/http-client/Chunk/ErrorChunk.php b/vendor/symfony/http-client/Chunk/ErrorChunk.php new file mode 100644 index 000000000..a19f43362 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/ErrorChunk.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +use Symfony\Component\HttpClient\Exception\TimeoutException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Contracts\HttpClient\ChunkInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class ErrorChunk implements ChunkInterface +{ + private $didThrow = false; + private $offset; + private $errorMessage; + private $error; + + /** + * @param \Throwable|string $error + */ + public function __construct(int $offset, $error) + { + $this->offset = $offset; + + if (\is_string($error)) { + $this->errorMessage = $error; + } else { + $this->error = $error; + $this->errorMessage = $error->getMessage(); + } + } + + /** + * {@inheritdoc} + */ + public function isTimeout(): bool + { + $this->didThrow = true; + + if (null !== $this->error) { + throw new TransportException($this->errorMessage, 0, $this->error); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function isFirst(): bool + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function isLast(): bool + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function getInformationalStatus(): ?array + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function getContent(): string + { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + + /** + * {@inheritdoc} + */ + public function getOffset(): int + { + return $this->offset; + } + + /** + * {@inheritdoc} + */ + public function getError(): ?string + { + return $this->errorMessage; + } + + /** + * @return bool Whether the wrapped error has been thrown or not + */ + public function didThrow(bool $didThrow = null): bool + { + if (null !== $didThrow && $this->didThrow !== $didThrow) { + return !$this->didThrow = $didThrow; + } + + return $this->didThrow; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + if (!$this->didThrow) { + $this->didThrow = true; + throw null !== $this->error ? new TransportException($this->errorMessage, 0, $this->error) : new TimeoutException($this->errorMessage); + } + } +} diff --git a/vendor/symfony/http-client/Chunk/FirstChunk.php b/vendor/symfony/http-client/Chunk/FirstChunk.php new file mode 100644 index 000000000..d891ca856 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/FirstChunk.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class FirstChunk extends DataChunk +{ + /** + * {@inheritdoc} + */ + public function isFirst(): bool + { + return true; + } +} diff --git a/vendor/symfony/http-client/Chunk/InformationalChunk.php b/vendor/symfony/http-client/Chunk/InformationalChunk.php new file mode 100644 index 000000000..c4452f15a --- /dev/null +++ b/vendor/symfony/http-client/Chunk/InformationalChunk.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class InformationalChunk extends DataChunk +{ + private $status; + + public function __construct(int $statusCode, array $headers) + { + $this->status = [$statusCode, $headers]; + } + + /** + * {@inheritdoc} + */ + public function getInformationalStatus(): ?array + { + return $this->status; + } +} diff --git a/vendor/symfony/http-client/Chunk/LastChunk.php b/vendor/symfony/http-client/Chunk/LastChunk.php new file mode 100644 index 000000000..84095d392 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/LastChunk.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class LastChunk extends DataChunk +{ + /** + * {@inheritdoc} + */ + public function isLast(): bool + { + return true; + } +} diff --git a/vendor/symfony/http-client/Chunk/ServerSentEvent.php b/vendor/symfony/http-client/Chunk/ServerSentEvent.php new file mode 100644 index 000000000..f7ff4b963 --- /dev/null +++ b/vendor/symfony/http-client/Chunk/ServerSentEvent.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Chunk; + +use Symfony\Contracts\HttpClient\ChunkInterface; + +/** + * @author Antoine Bluchet + * @author Nicolas Grekas + */ +final class ServerSentEvent extends DataChunk implements ChunkInterface +{ + private $data = ''; + private $id = ''; + private $type = 'message'; + private $retry = 0; + + public function __construct(string $content) + { + parent::__construct(-1, $content); + + // remove BOM + if (0 === strpos($content, "\xEF\xBB\xBF")) { + $content = substr($content, 3); + } + + foreach (preg_split("/(?:\r\n|[\r\n])/", $content) as $line) { + if (0 === $i = strpos($line, ':')) { + continue; + } + + $i = false === $i ? \strlen($line) : $i; + $field = substr($line, 0, $i); + $i += 1 + (' ' === ($line[1 + $i] ?? '')); + + switch ($field) { + case 'id': $this->id = substr($line, $i); break; + case 'event': $this->type = substr($line, $i); break; + case 'data': $this->data .= ('' === $this->data ? '' : "\n").substr($line, $i); break; + case 'retry': + $retry = substr($line, $i); + + if ('' !== $retry && \strlen($retry) === strspn($retry, '0123456789')) { + $this->retry = $retry / 1000.0; + } + break; + } + } + } + + public function getId(): string + { + return $this->id; + } + + public function getType(): string + { + return $this->type; + } + + public function getData(): string + { + return $this->data; + } + + public function getRetry(): float + { + return $this->retry; + } +} diff --git a/vendor/symfony/http-client/CurlHttpClient.php b/vendor/symfony/http-client/CurlHttpClient.php new file mode 100644 index 000000000..ef6d700cc --- /dev/null +++ b/vendor/symfony/http-client/CurlHttpClient.php @@ -0,0 +1,552 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\CurlClientState; +use Symfony\Component\HttpClient\Internal\PushedResponse; +use Symfony\Component\HttpClient\Response\CurlResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * A performant implementation of the HttpClientInterface contracts based on the curl extension. + * + * This provides fully concurrent HTTP requests, with transparent + * HTTP/2 push when a curl version that supports it is installed. + * + * @author Nicolas Grekas + */ +final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + + private $defaultOptions = self::OPTIONS_DEFAULTS + [ + 'auth_ntlm' => null, // array|string - an array containing the username as first value, and optionally the + // password as the second one; or string like username:password - enabling NTLM auth + 'extra' => [ + 'curl' => [], // A list of extra curl options indexed by their corresponding CURLOPT_* + ], + ]; + private static $emptyDefaults = self::OPTIONS_DEFAULTS + ['auth_ntlm' => null]; + + /** + * @var LoggerInterface|null + */ + private $logger; + + /** + * An internal object to share state between the client and its responses. + * + * @var CurlClientState + */ + private $multi; + + /** + * @param array $defaultOptions Default request's options + * @param int $maxHostConnections The maximum number of connections to a single host + * @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public function __construct(array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50) + { + if (!\extension_loaded('curl')) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\CurlHttpClient" as the "curl" extension is not installed.'); + } + + $this->defaultOptions['buffer'] = $this->defaultOptions['buffer'] ?? \Closure::fromCallable([__CLASS__, 'shouldBuffer']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + + $this->multi = new CurlClientState($maxHostConnections, $maxPendingPushes); + } + + public function setLogger(LoggerInterface $logger): void + { + $this->logger = $this->multi->logger = $logger; + } + + /** + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + * + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); + $scheme = $url['scheme']; + $authority = $url['authority']; + $host = parse_url($authority, \PHP_URL_HOST); + $proxy = self::getProxyUrl($options['proxy'], $url); + $url = implode('', $url); + + if (!isset($options['normalized_headers']['user-agent'])) { + $options['headers'][] = 'User-Agent: Symfony HttpClient/Curl'; + } + + $curlopts = [ + \CURLOPT_URL => $url, + \CURLOPT_TCP_NODELAY => true, + \CURLOPT_PROTOCOLS => \CURLPROTO_HTTP | \CURLPROTO_HTTPS, + \CURLOPT_REDIR_PROTOCOLS => \CURLPROTO_HTTP | \CURLPROTO_HTTPS, + \CURLOPT_FOLLOWLOCATION => true, + \CURLOPT_MAXREDIRS => 0 < $options['max_redirects'] ? $options['max_redirects'] : 0, + \CURLOPT_COOKIEFILE => '', // Keep track of cookies during redirects + \CURLOPT_TIMEOUT => 0, + \CURLOPT_PROXY => $proxy, + \CURLOPT_NOPROXY => $options['no_proxy'] ?? $_SERVER['no_proxy'] ?? $_SERVER['NO_PROXY'] ?? '', + \CURLOPT_SSL_VERIFYPEER => $options['verify_peer'], + \CURLOPT_SSL_VERIFYHOST => $options['verify_host'] ? 2 : 0, + \CURLOPT_CAINFO => $options['cafile'], + \CURLOPT_CAPATH => $options['capath'], + \CURLOPT_SSL_CIPHER_LIST => $options['ciphers'], + \CURLOPT_SSLCERT => $options['local_cert'], + \CURLOPT_SSLKEY => $options['local_pk'], + \CURLOPT_KEYPASSWD => $options['passphrase'], + \CURLOPT_CERTINFO => $options['capture_peer_cert_chain'], + ]; + + if (1.0 === (float) $options['http_version']) { + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0; + } elseif (1.1 === (float) $options['http_version']) { + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; + } elseif (\defined('CURL_VERSION_HTTP2') && (\CURL_VERSION_HTTP2 & CurlClientState::$curlVersion['features']) && ('https:' === $scheme || 2.0 === (float) $options['http_version'])) { + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0; + } + + if (isset($options['auth_ntlm'])) { + $curlopts[\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM; + $curlopts[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; + + if (\is_array($options['auth_ntlm'])) { + $count = \count($options['auth_ntlm']); + if ($count <= 0 || $count > 2) { + throw new InvalidArgumentException(sprintf('Option "auth_ntlm" must contain 1 or 2 elements, %d given.', $count)); + } + + $options['auth_ntlm'] = implode(':', $options['auth_ntlm']); + } + + if (!\is_string($options['auth_ntlm'])) { + throw new InvalidArgumentException(sprintf('Option "auth_ntlm" must be a string or an array, "%s" given.', get_debug_type($options['auth_ntlm']))); + } + + $curlopts[\CURLOPT_USERPWD] = $options['auth_ntlm']; + } + + if (!\ZEND_THREAD_SAFE) { + $curlopts[\CURLOPT_DNS_USE_GLOBAL_CACHE] = false; + } + + if (\defined('CURLOPT_HEADEROPT') && \defined('CURLHEADER_SEPARATE')) { + $curlopts[\CURLOPT_HEADEROPT] = \CURLHEADER_SEPARATE; + } + + // curl's resolve feature varies by host:port but ours varies by host only, let's handle this with our own DNS map + if (isset($this->multi->dnsCache->hostnames[$host])) { + $options['resolve'] += [$host => $this->multi->dnsCache->hostnames[$host]]; + } + + if ($options['resolve'] || $this->multi->dnsCache->evictions) { + // First reset any old DNS cache entries then add the new ones + $resolve = $this->multi->dnsCache->evictions; + $this->multi->dnsCache->evictions = []; + $port = parse_url($authority, \PHP_URL_PORT) ?: ('http:' === $scheme ? 80 : 443); + + if ($resolve && 0x072A00 > CurlClientState::$curlVersion['version_number']) { + // DNS cache removals require curl 7.42 or higher + $this->multi->reset(); + } + + foreach ($options['resolve'] as $host => $ip) { + $resolve[] = null === $ip ? "-$host:$port" : "$host:$port:$ip"; + $this->multi->dnsCache->hostnames[$host] = $ip; + $this->multi->dnsCache->removals["-$host:$port"] = "-$host:$port"; + } + + $curlopts[\CURLOPT_RESOLVE] = $resolve; + } + + if ('POST' === $method) { + // Use CURLOPT_POST to have browser-like POST-to-GET redirects for 301, 302 and 303 + $curlopts[\CURLOPT_POST] = true; + } elseif ('HEAD' === $method) { + $curlopts[\CURLOPT_NOBODY] = true; + } else { + $curlopts[\CURLOPT_CUSTOMREQUEST] = $method; + } + + if ('\\' !== \DIRECTORY_SEPARATOR && $options['timeout'] < 1) { + $curlopts[\CURLOPT_NOSIGNAL] = true; + } + + if (\extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) { + $options['headers'][] = 'Accept-Encoding: gzip'; // Expose only one encoding, some servers mess up when more are provided + } + $body = $options['body']; + + foreach ($options['headers'] as $i => $header) { + if (\is_string($body) && '' !== $body && 0 === stripos($header, 'Content-Length: ')) { + // Let curl handle Content-Length headers + unset($options['headers'][$i]); + continue; + } + if (':' === $header[-2] && \strlen($header) - 2 === strpos($header, ': ')) { + // curl requires a special syntax to send empty headers + $curlopts[\CURLOPT_HTTPHEADER][] = substr_replace($header, ';', -2); + } else { + $curlopts[\CURLOPT_HTTPHEADER][] = $header; + } + } + + // Prevent curl from sending its default Accept and Expect headers + foreach (['accept', 'expect'] as $header) { + if (!isset($options['normalized_headers'][$header][0])) { + $curlopts[\CURLOPT_HTTPHEADER][] = $header.':'; + } + } + + if (!\is_string($body)) { + if (\is_resource($body)) { + $curlopts[\CURLOPT_INFILE] = $body; + } else { + $eof = false; + $buffer = ''; + $curlopts[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use ($body, &$buffer, &$eof) { + return self::readRequestBody($length, $body, $buffer, $eof); + }; + } + + if (isset($options['normalized_headers']['content-length'][0])) { + $curlopts[\CURLOPT_INFILESIZE] = (int) substr($options['normalized_headers']['content-length'][0], \strlen('Content-Length: ')); + } + if (!isset($options['normalized_headers']['transfer-encoding'])) { + $curlopts[\CURLOPT_HTTPHEADER][] = 'Transfer-Encoding:'.(isset($curlopts[\CURLOPT_INFILESIZE]) ? '' : ' chunked'); + } + + if ('POST' !== $method) { + $curlopts[\CURLOPT_UPLOAD] = true; + + if (!isset($options['normalized_headers']['content-type']) && 0 !== ($curlopts[\CURLOPT_INFILESIZE] ?? null)) { + $curlopts[\CURLOPT_HTTPHEADER][] = 'Content-Type: application/x-www-form-urlencoded'; + } + } + } elseif ('' !== $body || 'POST' === $method) { + $curlopts[\CURLOPT_POSTFIELDS] = $body; + } + + if ($options['peer_fingerprint']) { + if (!isset($options['peer_fingerprint']['pin-sha256'])) { + throw new TransportException(__CLASS__.' supports only "pin-sha256" fingerprints.'); + } + + $curlopts[\CURLOPT_PINNEDPUBLICKEY] = 'sha256//'.implode(';sha256//', $options['peer_fingerprint']['pin-sha256']); + } + + if ($options['bindto']) { + if (file_exists($options['bindto'])) { + $curlopts[\CURLOPT_UNIX_SOCKET_PATH] = $options['bindto']; + } elseif (!str_starts_with($options['bindto'], 'if!') && preg_match('/^(.*):(\d+)$/', $options['bindto'], $matches)) { + $curlopts[\CURLOPT_INTERFACE] = $matches[1]; + $curlopts[\CURLOPT_LOCALPORT] = $matches[2]; + } else { + $curlopts[\CURLOPT_INTERFACE] = $options['bindto']; + } + } + + if (0 < $options['max_duration']) { + $curlopts[\CURLOPT_TIMEOUT_MS] = 1000 * $options['max_duration']; + } + + if (!empty($options['extra']['curl']) && \is_array($options['extra']['curl'])) { + $this->validateExtraCurlOptions($options['extra']['curl']); + $curlopts += $options['extra']['curl']; + } + + if ($pushedResponse = $this->multi->pushedResponses[$url] ?? null) { + unset($this->multi->pushedResponses[$url]); + + if (self::acceptPushForRequest($method, $options, $pushedResponse)) { + $this->logger && $this->logger->debug(sprintf('Accepting pushed response: "%s %s"', $method, $url)); + + // Reinitialize the pushed response with request's options + $ch = $pushedResponse->handle; + $pushedResponse = $pushedResponse->response; + $pushedResponse->__construct($this->multi, $url, $options, $this->logger); + } else { + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s"', $url)); + $pushedResponse = null; + } + } + + if (!$pushedResponse) { + $ch = curl_init(); + $this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url)); + $curlopts += [\CURLOPT_SHARE => $this->multi->share]; + } + + foreach ($curlopts as $opt => $value) { + if (null !== $value && !curl_setopt($ch, $opt, $value) && \CURLOPT_CERTINFO !== $opt && (!\defined('CURLOPT_HEADEROPT') || \CURLOPT_HEADEROPT !== $opt)) { + $constantName = $this->findConstantName($opt); + throw new TransportException(sprintf('Curl option "%s" is not supported.', $constantName ?? $opt)); + } + } + + return $pushedResponse ?? new CurlResponse($this->multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host), CurlClientState::$curlVersion['version_number']); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof CurlResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of CurlResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + if (\is_resource($this->multi->handle) || $this->multi->handle instanceof \CurlMultiHandle) { + $active = 0; + while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active)) { + } + } + + return new ResponseStream(CurlResponse::stream($responses, $timeout)); + } + + public function reset() + { + $this->multi->reset(); + } + + /** + * Accepts pushed responses only if their headers related to authentication match the request. + */ + private static function acceptPushForRequest(string $method, array $options, PushedResponse $pushedResponse): bool + { + if ('' !== $options['body'] || $method !== $pushedResponse->requestHeaders[':method'][0]) { + return false; + } + + foreach (['proxy', 'no_proxy', 'bindto', 'local_cert', 'local_pk'] as $k) { + if ($options[$k] !== $pushedResponse->parentOptions[$k]) { + return false; + } + } + + foreach (['authorization', 'cookie', 'range', 'proxy-authorization'] as $k) { + $normalizedHeaders = $options['normalized_headers'][$k] ?? []; + foreach ($normalizedHeaders as $i => $v) { + $normalizedHeaders[$i] = substr($v, \strlen($k) + 2); + } + + if (($pushedResponse->requestHeaders[$k] ?? []) !== $normalizedHeaders) { + return false; + } + } + + return true; + } + + /** + * Wraps the request's body callback to allow it to return strings longer than curl requested. + */ + private static function readRequestBody(int $length, \Closure $body, string &$buffer, bool &$eof): string + { + if (!$eof && \strlen($buffer) < $length) { + if (!\is_string($data = $body($length))) { + throw new TransportException(sprintf('The return value of the "body" option callback must be a string, "%s" returned.', get_debug_type($data))); + } + + $buffer .= $data; + $eof = '' === $data; + } + + $data = substr($buffer, 0, $length); + $buffer = substr($buffer, $length); + + return $data; + } + + /** + * Resolves relative URLs on redirects and deals with authentication headers. + * + * Work around CVE-2018-1000007: Authorization and Cookie headers should not follow redirects - fixed in Curl 7.64 + */ + private static function createRedirectResolver(array $options, string $host): \Closure + { + $redirectHeaders = []; + if (0 < $options['max_redirects']) { + $redirectHeaders['host'] = $host; + $redirectHeaders['with_auth'] = $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) { + return 0 !== stripos($h, 'Host:'); + }); + + if (isset($options['normalized_headers']['authorization'][0]) || isset($options['normalized_headers']['cookie'][0])) { + $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) { + return 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:'); + }); + } + } + + return static function ($ch, string $location, bool $noContent) use (&$redirectHeaders, $options) { + try { + $location = self::parseUrl($location); + } catch (InvalidArgumentException $e) { + return null; + } + + if ($noContent && $redirectHeaders) { + $filterContentHeaders = static function ($h) { + return 0 !== stripos($h, 'Content-Length:') && 0 !== stripos($h, 'Content-Type:') && 0 !== stripos($h, 'Transfer-Encoding:'); + }; + $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], $filterContentHeaders); + $redirectHeaders['with_auth'] = array_filter($redirectHeaders['with_auth'], $filterContentHeaders); + } + + if ($redirectHeaders && $host = parse_url('http:'.$location['authority'], \PHP_URL_HOST)) { + $requestHeaders = $redirectHeaders['host'] === $host ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth']; + curl_setopt($ch, \CURLOPT_HTTPHEADER, $requestHeaders); + } elseif ($noContent && $redirectHeaders) { + curl_setopt($ch, \CURLOPT_HTTPHEADER, $redirectHeaders['with_auth']); + } + + $url = self::parseUrl(curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL)); + $url = self::resolveUrl($location, $url); + + curl_setopt($ch, \CURLOPT_PROXY, self::getProxyUrl($options['proxy'], $url)); + + return implode('', $url); + }; + } + + private function findConstantName(int $opt): ?string + { + $constants = array_filter(get_defined_constants(), static function ($v, $k) use ($opt) { + return $v === $opt && 'C' === $k[0] && (str_starts_with($k, 'CURLOPT_') || str_starts_with($k, 'CURLINFO_')); + }, \ARRAY_FILTER_USE_BOTH); + + return key($constants); + } + + /** + * Prevents overriding options that are set internally throughout the request. + */ + private function validateExtraCurlOptions(array $options): void + { + $curloptsToConfig = [ + // options used in CurlHttpClient + \CURLOPT_HTTPAUTH => 'auth_ntlm', + \CURLOPT_USERPWD => 'auth_ntlm', + \CURLOPT_RESOLVE => 'resolve', + \CURLOPT_NOSIGNAL => 'timeout', + \CURLOPT_HTTPHEADER => 'headers', + \CURLOPT_INFILE => 'body', + \CURLOPT_READFUNCTION => 'body', + \CURLOPT_INFILESIZE => 'body', + \CURLOPT_POSTFIELDS => 'body', + \CURLOPT_UPLOAD => 'body', + \CURLOPT_INTERFACE => 'bindto', + \CURLOPT_TIMEOUT_MS => 'max_duration', + \CURLOPT_TIMEOUT => 'max_duration', + \CURLOPT_MAXREDIRS => 'max_redirects', + \CURLOPT_POSTREDIR => 'max_redirects', + \CURLOPT_PROXY => 'proxy', + \CURLOPT_NOPROXY => 'no_proxy', + \CURLOPT_SSL_VERIFYPEER => 'verify_peer', + \CURLOPT_SSL_VERIFYHOST => 'verify_host', + \CURLOPT_CAINFO => 'cafile', + \CURLOPT_CAPATH => 'capath', + \CURLOPT_SSL_CIPHER_LIST => 'ciphers', + \CURLOPT_SSLCERT => 'local_cert', + \CURLOPT_SSLKEY => 'local_pk', + \CURLOPT_KEYPASSWD => 'passphrase', + \CURLOPT_CERTINFO => 'capture_peer_cert_chain', + \CURLOPT_USERAGENT => 'normalized_headers', + \CURLOPT_REFERER => 'headers', + // options used in CurlResponse + \CURLOPT_NOPROGRESS => 'on_progress', + \CURLOPT_PROGRESSFUNCTION => 'on_progress', + ]; + + if (\defined('CURLOPT_UNIX_SOCKET_PATH')) { + $curloptsToConfig[\CURLOPT_UNIX_SOCKET_PATH] = 'bindto'; + } + + if (\defined('CURLOPT_PINNEDPUBLICKEY')) { + $curloptsToConfig[\CURLOPT_PINNEDPUBLICKEY] = 'peer_fingerprint'; + } + + $curloptsToCheck = [ + \CURLOPT_PRIVATE, + \CURLOPT_HEADERFUNCTION, + \CURLOPT_WRITEFUNCTION, + \CURLOPT_VERBOSE, + \CURLOPT_STDERR, + \CURLOPT_RETURNTRANSFER, + \CURLOPT_URL, + \CURLOPT_FOLLOWLOCATION, + \CURLOPT_HEADER, + \CURLOPT_CONNECTTIMEOUT, + \CURLOPT_CONNECTTIMEOUT_MS, + \CURLOPT_HTTP_VERSION, + \CURLOPT_PORT, + \CURLOPT_DNS_USE_GLOBAL_CACHE, + \CURLOPT_PROTOCOLS, + \CURLOPT_REDIR_PROTOCOLS, + \CURLOPT_COOKIEFILE, + \CURLINFO_REDIRECT_COUNT, + ]; + + if (\defined('CURLOPT_HTTP09_ALLOWED')) { + $curloptsToCheck[] = \CURLOPT_HTTP09_ALLOWED; + } + + if (\defined('CURLOPT_HEADEROPT')) { + $curloptsToCheck[] = \CURLOPT_HEADEROPT; + } + + $methodOpts = [ + \CURLOPT_POST, + \CURLOPT_PUT, + \CURLOPT_CUSTOMREQUEST, + \CURLOPT_HTTPGET, + \CURLOPT_NOBODY, + ]; + + foreach ($options as $opt => $optValue) { + if (isset($curloptsToConfig[$opt])) { + $constName = $this->findConstantName($opt) ?? $opt; + throw new InvalidArgumentException(sprintf('Cannot set "%s" with "extra.curl", use option "%s" instead.', $constName, $curloptsToConfig[$opt])); + } + + if (\in_array($opt, $methodOpts)) { + throw new InvalidArgumentException('The HTTP method cannot be overridden using "extra.curl".'); + } + + if (\in_array($opt, $curloptsToCheck)) { + $constName = $this->findConstantName($opt) ?? $opt; + throw new InvalidArgumentException(sprintf('Cannot set "%s" with "extra.curl".', $constName)); + } + } + } +} diff --git a/vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php b/vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php new file mode 100644 index 000000000..192578636 --- /dev/null +++ b/vendor/symfony/http-client/DataCollector/HttpClientDataCollector.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\DataCollector; + +use Symfony\Component\HttpClient\TraceableHttpClient; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; +use Symfony\Component\VarDumper\Caster\ImgStub; + +/** + * @author Jérémy Romey + */ +final class HttpClientDataCollector extends DataCollector implements LateDataCollectorInterface +{ + /** + * @var TraceableHttpClient[] + */ + private $clients = []; + + public function registerClient(string $name, TraceableHttpClient $client) + { + $this->clients[$name] = $client; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Throwable $exception = null) + { + $this->lateCollect(); + } + + public function lateCollect() + { + $this->data['request_count'] = $this->data['request_count'] ?? 0; + $this->data['error_count'] = $this->data['error_count'] ?? 0; + $this->data += ['clients' => []]; + + foreach ($this->clients as $name => $client) { + [$errorCount, $traces] = $this->collectOnClient($client); + + $this->data['clients'] += [ + $name => [ + 'traces' => [], + 'error_count' => 0, + ], + ]; + + $this->data['clients'][$name]['traces'] = array_merge($this->data['clients'][$name]['traces'], $traces); + $this->data['request_count'] += \count($traces); + $this->data['error_count'] += $errorCount; + $this->data['clients'][$name]['error_count'] += $errorCount; + + $client->reset(); + } + } + + public function getClients(): array + { + return $this->data['clients'] ?? []; + } + + public function getRequestCount(): int + { + return $this->data['request_count'] ?? 0; + } + + public function getErrorCount(): int + { + return $this->data['error_count'] ?? 0; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return 'http_client'; + } + + public function reset() + { + $this->data = [ + 'clients' => [], + 'request_count' => 0, + 'error_count' => 0, + ]; + } + + private function collectOnClient(TraceableHttpClient $client): array + { + $traces = $client->getTracedRequests(); + $errorCount = 0; + $baseInfo = [ + 'response_headers' => 1, + 'retry_count' => 1, + 'redirect_count' => 1, + 'redirect_url' => 1, + 'user_data' => 1, + 'error' => 1, + 'url' => 1, + ]; + + foreach ($traces as $i => $trace) { + if (400 <= ($trace['info']['http_code'] ?? 0)) { + ++$errorCount; + } + + $info = $trace['info']; + $traces[$i]['http_code'] = $info['http_code'] ?? 0; + + unset($info['filetime'], $info['http_code'], $info['ssl_verify_result'], $info['content_type']); + + if (($info['http_method'] ?? null) === $trace['method']) { + unset($info['http_method']); + } + + if (($info['url'] ?? null) === $trace['url']) { + unset($info['url']); + } + + foreach ($info as $k => $v) { + if (!$v || (is_numeric($v) && 0 > $v)) { + unset($info[$k]); + } + } + + if (\is_string($content = $trace['content'])) { + $contentType = 'application/octet-stream'; + + foreach ($info['response_headers'] ?? [] as $h) { + if (0 === stripos($h, 'content-type: ')) { + $contentType = substr($h, \strlen('content-type: ')); + break; + } + } + + if (0 === strpos($contentType, 'image/') && class_exists(ImgStub::class)) { + $content = new ImgStub($content, $contentType, ''); + } else { + $content = [$content]; + } + + $content = ['response_content' => $content]; + } elseif (\is_array($content)) { + $content = ['response_json' => $content]; + } else { + $content = []; + } + + if (isset($info['retry_count'])) { + $content['retries'] = $info['previous_info']; + unset($info['previous_info']); + } + + $debugInfo = array_diff_key($info, $baseInfo); + $info = ['info' => $debugInfo] + array_diff_key($info, $debugInfo) + $content; + unset($traces[$i]['info']); // break PHP reference used by TraceableHttpClient + $traces[$i]['info'] = $this->cloneVar($info); + $traces[$i]['options'] = $this->cloneVar($trace['options']); + } + + return [$errorCount, $traces]; + } +} diff --git a/vendor/symfony/http-client/DecoratorTrait.php b/vendor/symfony/http-client/DecoratorTrait.php new file mode 100644 index 000000000..790fc32a5 --- /dev/null +++ b/vendor/symfony/http-client/DecoratorTrait.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Eases with writing decorators. + * + * @author Nicolas Grekas + */ +trait DecoratorTrait +{ + private $client; + + public function __construct(HttpClientInterface $client = null) + { + $this->client = $client ?? HttpClient::create(); + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + return $this->client->request($method, $url, $options); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->client->stream($responses, $timeout); + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} diff --git a/vendor/symfony/http-client/DependencyInjection/HttpClientPass.php b/vendor/symfony/http-client/DependencyInjection/HttpClientPass.php new file mode 100644 index 000000000..8f3c3c534 --- /dev/null +++ b/vendor/symfony/http-client/DependencyInjection/HttpClientPass.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\DependencyInjection; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\HttpClient\TraceableHttpClient; + +final class HttpClientPass implements CompilerPassInterface +{ + private $clientTag; + + public function __construct(string $clientTag = 'http_client.client') + { + if (0 < \func_num_args()) { + trigger_deprecation('symfony/http-client', '5.3', 'Configuring "%s" is deprecated.', __CLASS__); + } + + $this->clientTag = $clientTag; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition('data_collector.http_client')) { + return; + } + + foreach ($container->findTaggedServiceIds($this->clientTag) as $id => $tags) { + $container->register('.debug.'.$id, TraceableHttpClient::class) + ->setArguments([new Reference('.debug.'.$id.'.inner'), new Reference('debug.stopwatch', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]) + ->addTag('kernel.reset', ['method' => 'reset']) + ->setDecoratedService($id, null, 5); + $container->getDefinition('data_collector.http_client') + ->addMethodCall('registerClient', [$id, new Reference('.debug.'.$id)]); + } + } +} diff --git a/vendor/symfony/http-client/EventSourceHttpClient.php b/vendor/symfony/http-client/EventSourceHttpClient.php new file mode 100644 index 000000000..60e4e821d --- /dev/null +++ b/vendor/symfony/http-client/EventSourceHttpClient.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Chunk\ServerSentEvent; +use Symfony\Component\HttpClient\Exception\EventSourceException; +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Component\HttpClient\Response\AsyncResponse; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * @author Antoine Bluchet + * @author Nicolas Grekas + */ +final class EventSourceHttpClient implements HttpClientInterface, ResetInterface +{ + use AsyncDecoratorTrait, HttpClientTrait { + AsyncDecoratorTrait::withOptions insteadof HttpClientTrait; + } + + private $reconnectionTime; + + public function __construct(HttpClientInterface $client = null, float $reconnectionTime = 10.0) + { + $this->client = $client ?? HttpClient::create(); + $this->reconnectionTime = $reconnectionTime; + } + + public function connect(string $url, array $options = []): ResponseInterface + { + return $this->request('GET', $url, self::mergeDefaultOptions($options, [ + 'buffer' => false, + 'headers' => [ + 'Accept' => 'text/event-stream', + 'Cache-Control' => 'no-cache', + ], + ], true)); + } + + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $state = new class() { + public $buffer = null; + public $lastEventId = null; + public $reconnectionTime; + public $lastError = null; + }; + $state->reconnectionTime = $this->reconnectionTime; + + if ($accept = self::normalizeHeaders($options['headers'] ?? [])['accept'] ?? []) { + $state->buffer = \in_array($accept, [['Accept: text/event-stream'], ['accept: text/event-stream']], true) ? '' : null; + + if (null !== $state->buffer) { + $options['extra']['trace_content'] = false; + } + } + + return new AsyncResponse($this->client, $method, $url, $options, static function (ChunkInterface $chunk, AsyncContext $context) use ($state, $method, $url, $options) { + if (null !== $state->buffer) { + $context->setInfo('reconnection_time', $state->reconnectionTime); + $isTimeout = false; + } + $lastError = $state->lastError; + $state->lastError = null; + + try { + $isTimeout = $chunk->isTimeout(); + + if (null !== $chunk->getInformationalStatus() || $context->getInfo('canceled')) { + yield $chunk; + + return; + } + } catch (TransportExceptionInterface $e) { + $state->lastError = $lastError ?? microtime(true); + + if (null === $state->buffer || ($isTimeout && microtime(true) - $state->lastError < $state->reconnectionTime)) { + yield $chunk; + } else { + $options['headers']['Last-Event-ID'] = $state->lastEventId; + $state->buffer = ''; + $state->lastError = microtime(true); + $context->getResponse()->cancel(); + $context->replaceRequest($method, $url, $options); + if ($isTimeout) { + yield $chunk; + } else { + $context->pause($state->reconnectionTime); + } + } + + return; + } + + if ($chunk->isFirst()) { + if (preg_match('/^text\/event-stream(;|$)/i', $context->getHeaders()['content-type'][0] ?? '')) { + $state->buffer = ''; + } elseif (null !== $lastError || (null !== $state->buffer && 200 === $context->getStatusCode())) { + throw new EventSourceException(sprintf('Response content-type is "%s" while "text/event-stream" was expected for "%s".', $context->getHeaders()['content-type'][0] ?? '', $context->getInfo('url'))); + } else { + $context->passthru(); + } + + if (null === $lastError) { + yield $chunk; + } + + return; + } + + $rx = '/((?:\r\n|[\r\n]){2,})/'; + $content = $state->buffer.$chunk->getContent(); + + if ($chunk->isLast()) { + $rx = substr_replace($rx, '|$', -2, 0); + } + $events = preg_split($rx, $content, -1, \PREG_SPLIT_DELIM_CAPTURE); + $state->buffer = array_pop($events); + + for ($i = 0; isset($events[$i]); $i += 2) { + $event = new ServerSentEvent($events[$i].$events[1 + $i]); + + if ('' !== $event->getId()) { + $context->setInfo('last_event_id', $state->lastEventId = $event->getId()); + } + + if ($event->getRetry()) { + $context->setInfo('reconnection_time', $state->reconnectionTime = $event->getRetry()); + } + + yield $event; + } + + if (preg_match('/^(?::[^\r\n]*+(?:\r\n|[\r\n]))+$/m', $state->buffer)) { + $content = $state->buffer; + $state->buffer = ''; + + yield $context->createChunk($content); + } + + if ($chunk->isLast()) { + yield $chunk; + } + }); + } +} diff --git a/vendor/symfony/http-client/Exception/ClientException.php b/vendor/symfony/http-client/Exception/ClientException.php new file mode 100644 index 000000000..4264534c0 --- /dev/null +++ b/vendor/symfony/http-client/Exception/ClientException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; + +/** + * Represents a 4xx response. + * + * @author Nicolas Grekas + */ +final class ClientException extends \RuntimeException implements ClientExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/symfony/http-client/Exception/EventSourceException.php b/vendor/symfony/http-client/Exception/EventSourceException.php new file mode 100644 index 000000000..30ab7957c --- /dev/null +++ b/vendor/symfony/http-client/Exception/EventSourceException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; + +/** + * @author Nicolas Grekas + */ +final class EventSourceException extends \RuntimeException implements DecodingExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/HttpExceptionTrait.php b/vendor/symfony/http-client/Exception/HttpExceptionTrait.php new file mode 100644 index 000000000..8cbaa1cd1 --- /dev/null +++ b/vendor/symfony/http-client/Exception/HttpExceptionTrait.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait HttpExceptionTrait +{ + private $response; + + public function __construct(ResponseInterface $response) + { + $this->response = $response; + $code = $response->getInfo('http_code'); + $url = $response->getInfo('url'); + $message = sprintf('HTTP %d returned for "%s".', $code, $url); + + $httpCodeFound = false; + $isJson = false; + foreach (array_reverse($response->getInfo('response_headers')) as $h) { + if (str_starts_with($h, 'HTTP/')) { + if ($httpCodeFound) { + break; + } + + $message = sprintf('%s returned for "%s".', $h, $url); + $httpCodeFound = true; + } + + if (0 === stripos($h, 'content-type:')) { + if (preg_match('/\bjson\b/i', $h)) { + $isJson = true; + } + + if ($httpCodeFound) { + break; + } + } + } + + // Try to guess a better error message using common API error formats + // The MIME type isn't explicitly checked because some formats inherit from others + // Ex: JSON:API follows RFC 7807 semantics, Hydra can be used in any JSON-LD-compatible format + if ($isJson && $body = json_decode($response->getContent(false), true)) { + if (isset($body['hydra:title']) || isset($body['hydra:description'])) { + // see http://www.hydra-cg.com/spec/latest/core/#description-of-http-status-codes-and-errors + $separator = isset($body['hydra:title'], $body['hydra:description']) ? "\n\n" : ''; + $message = ($body['hydra:title'] ?? '').$separator.($body['hydra:description'] ?? ''); + } elseif ((isset($body['title']) || isset($body['detail'])) + && (\is_scalar($body['title'] ?? '') && \is_scalar($body['detail'] ?? ''))) { + // see RFC 7807 and https://jsonapi.org/format/#error-objects + $separator = isset($body['title'], $body['detail']) ? "\n\n" : ''; + $message = ($body['title'] ?? '').$separator.($body['detail'] ?? ''); + } + } + + parent::__construct($message, $code); + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } +} diff --git a/vendor/symfony/http-client/Exception/InvalidArgumentException.php b/vendor/symfony/http-client/Exception/InvalidArgumentException.php new file mode 100644 index 000000000..6c2fae76f --- /dev/null +++ b/vendor/symfony/http-client/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Nicolas Grekas + */ +final class InvalidArgumentException extends \InvalidArgumentException implements TransportExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/JsonException.php b/vendor/symfony/http-client/Exception/JsonException.php new file mode 100644 index 000000000..54502e626 --- /dev/null +++ b/vendor/symfony/http-client/Exception/JsonException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; + +/** + * Thrown by responses' toArray() method when their content cannot be JSON-decoded. + * + * @author Nicolas Grekas + */ +final class JsonException extends \JsonException implements DecodingExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/RedirectionException.php b/vendor/symfony/http-client/Exception/RedirectionException.php new file mode 100644 index 000000000..5b936702c --- /dev/null +++ b/vendor/symfony/http-client/Exception/RedirectionException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; + +/** + * Represents a 3xx response. + * + * @author Nicolas Grekas + */ +final class RedirectionException extends \RuntimeException implements RedirectionExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/symfony/http-client/Exception/ServerException.php b/vendor/symfony/http-client/Exception/ServerException.php new file mode 100644 index 000000000..c6f827310 --- /dev/null +++ b/vendor/symfony/http-client/Exception/ServerException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; + +/** + * Represents a 5xx response. + * + * @author Nicolas Grekas + */ +final class ServerException extends \RuntimeException implements ServerExceptionInterface +{ + use HttpExceptionTrait; +} diff --git a/vendor/symfony/http-client/Exception/TimeoutException.php b/vendor/symfony/http-client/Exception/TimeoutException.php new file mode 100644 index 000000000..a9155cc8f --- /dev/null +++ b/vendor/symfony/http-client/Exception/TimeoutException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\TimeoutExceptionInterface; + +/** + * @author Nicolas Grekas + */ +final class TimeoutException extends TransportException implements TimeoutExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/Exception/TransportException.php b/vendor/symfony/http-client/Exception/TransportException.php new file mode 100644 index 000000000..a3a80c6dc --- /dev/null +++ b/vendor/symfony/http-client/Exception/TransportException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Exception; + +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Nicolas Grekas + */ +class TransportException extends \RuntimeException implements TransportExceptionInterface +{ +} diff --git a/vendor/symfony/http-client/HttpClient.php b/vendor/symfony/http-client/HttpClient.php new file mode 100644 index 000000000..8de6f9f48 --- /dev/null +++ b/vendor/symfony/http-client/HttpClient.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Amp\Http\Client\Connection\ConnectionLimitingPool; +use Amp\Promise; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A factory to instantiate the best possible HTTP client for the runtime. + * + * @author Nicolas Grekas + */ +final class HttpClient +{ + /** + * @param array $defaultOptions Default request's options + * @param int $maxHostConnections The maximum number of connections to a single host + * @param int $maxPendingPushes The maximum number of pushed responses to accept in the queue + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public static function create(array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50): HttpClientInterface + { + if ($amp = class_exists(ConnectionLimitingPool::class) && interface_exists(Promise::class)) { + if (!\extension_loaded('curl')) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + + // Skip curl when HTTP/2 push is unsupported or buggy, see https://bugs.php.net/77535 + if (\PHP_VERSION_ID < 70217 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70304) || !\defined('CURLMOPT_PUSHFUNCTION')) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + + static $curlVersion = null; + $curlVersion = $curlVersion ?? curl_version(); + + // HTTP/2 push crashes before curl 7.61 + if (0x073D00 > $curlVersion['version_number'] || !(\CURL_VERSION_HTTP2 & $curlVersion['features'])) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + } + + if (\extension_loaded('curl')) { + if ('\\' !== \DIRECTORY_SEPARATOR || isset($defaultOptions['cafile']) || isset($defaultOptions['capath']) || \ini_get('curl.cainfo') || \ini_get('openssl.cafile') || \ini_get('openssl.capath')) { + return new CurlHttpClient($defaultOptions, $maxHostConnections, $maxPendingPushes); + } + + @trigger_error('Configure the "curl.cainfo", "openssl.cafile" or "openssl.capath" php.ini setting to enable the CurlHttpClient', \E_USER_WARNING); + } + + if ($amp) { + return new AmpHttpClient($defaultOptions, null, $maxHostConnections, $maxPendingPushes); + } + + @trigger_error((\extension_loaded('curl') ? 'Upgrade' : 'Install').' the curl extension or run "composer require amphp/http-client:^4.2.1" to perform async HTTP operations, including full HTTP/2 support', \E_USER_NOTICE); + + return new NativeHttpClient($defaultOptions, $maxHostConnections); + } + + /** + * Creates a client that adds options (e.g. authentication headers) only when the request URL matches the provided base URI. + */ + public static function createForBaseUri(string $baseUri, array $defaultOptions = [], int $maxHostConnections = 6, int $maxPendingPushes = 50): HttpClientInterface + { + $client = self::create([], $maxHostConnections, $maxPendingPushes); + + return ScopingHttpClient::forBaseUri($client, $baseUri, $defaultOptions); + } +} diff --git a/vendor/symfony/http-client/HttpClientTrait.php b/vendor/symfony/http-client/HttpClientTrait.php new file mode 100644 index 000000000..3d6044320 --- /dev/null +++ b/vendor/symfony/http-client/HttpClientTrait.php @@ -0,0 +1,710 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * Provides the common logic from writing HttpClientInterface implementations. + * + * All private methods are static to prevent implementers from creating memory leaks via circular references. + * + * @author Nicolas Grekas + */ +trait HttpClientTrait +{ + private static $CHUNK_SIZE = 16372; + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->defaultOptions = self::mergeDefaultOptions($options, $this->defaultOptions); + + return $clone; + } + + /** + * Validates and normalizes method, URL and options, and merges them with defaults. + * + * @throws InvalidArgumentException When a not-supported option is found + */ + private static function prepareRequest(?string $method, ?string $url, array $options, array $defaultOptions = [], bool $allowExtraOptions = false): array + { + if (null !== $method) { + if (\strlen($method) !== strspn($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')) { + throw new InvalidArgumentException(sprintf('Invalid HTTP method "%s", only uppercase letters are accepted.', $method)); + } + if (!$method) { + throw new InvalidArgumentException('The HTTP method cannot be empty.'); + } + } + + $options = self::mergeDefaultOptions($options, $defaultOptions, $allowExtraOptions); + + $buffer = $options['buffer'] ?? true; + + if ($buffer instanceof \Closure) { + $options['buffer'] = static function (array $headers) use ($buffer) { + if (!\is_bool($buffer = $buffer($headers))) { + if (!\is_array($bufferInfo = @stream_get_meta_data($buffer))) { + throw new \LogicException(sprintf('The closure passed as option "buffer" must return bool or stream resource, got "%s".', get_debug_type($buffer))); + } + + if (false === strpbrk($bufferInfo['mode'], 'acew+')) { + throw new \LogicException(sprintf('The stream returned by the closure passed as option "buffer" must be writeable, got mode "%s".', $bufferInfo['mode'])); + } + } + + return $buffer; + }; + } elseif (!\is_bool($buffer)) { + if (!\is_array($bufferInfo = @stream_get_meta_data($buffer))) { + throw new InvalidArgumentException(sprintf('Option "buffer" must be bool, stream resource or Closure, "%s" given.', get_debug_type($buffer))); + } + + if (false === strpbrk($bufferInfo['mode'], 'acew+')) { + throw new InvalidArgumentException(sprintf('The stream in option "buffer" must be writeable, mode "%s" given.', $bufferInfo['mode'])); + } + } + + if (isset($options['json'])) { + if (isset($options['body']) && '' !== $options['body']) { + throw new InvalidArgumentException('Define either the "json" or the "body" option, setting both is not supported.'); + } + $options['body'] = self::jsonEncode($options['json']); + unset($options['json']); + + if (!isset($options['normalized_headers']['content-type'])) { + $options['normalized_headers']['content-type'] = ['Content-Type: application/json']; + } + } + + if (!isset($options['normalized_headers']['accept'])) { + $options['normalized_headers']['accept'] = ['Accept: */*']; + } + + if (isset($options['body'])) { + $options['body'] = self::normalizeBody($options['body']); + + if (\is_string($options['body']) + && (string) \strlen($options['body']) !== substr($h = $options['normalized_headers']['content-length'][0] ?? '', 16) + && ('' !== $h || '' !== $options['body']) + ) { + if ('chunked' === substr($options['normalized_headers']['transfer-encoding'][0] ?? '', \strlen('Transfer-Encoding: '))) { + unset($options['normalized_headers']['transfer-encoding']); + $options['body'] = self::dechunk($options['body']); + } + + $options['normalized_headers']['content-length'] = [substr_replace($h ?: 'Content-Length: ', \strlen($options['body']), 16)]; + } + } + + if (isset($options['peer_fingerprint'])) { + $options['peer_fingerprint'] = self::normalizePeerFingerprint($options['peer_fingerprint']); + } + + // Validate on_progress + if (isset($options['on_progress']) && !\is_callable($onProgress = $options['on_progress'])) { + throw new InvalidArgumentException(sprintf('Option "on_progress" must be callable, "%s" given.', get_debug_type($onProgress))); + } + + if (\is_array($options['auth_basic'] ?? null)) { + $count = \count($options['auth_basic']); + if ($count <= 0 || $count > 2) { + throw new InvalidArgumentException(sprintf('Option "auth_basic" must contain 1 or 2 elements, "%s" given.', $count)); + } + + $options['auth_basic'] = implode(':', $options['auth_basic']); + } + + if (!\is_string($options['auth_basic'] ?? '')) { + throw new InvalidArgumentException(sprintf('Option "auth_basic" must be string or an array, "%s" given.', get_debug_type($options['auth_basic']))); + } + + if (isset($options['auth_bearer'])) { + if (!\is_string($options['auth_bearer'])) { + throw new InvalidArgumentException(sprintf('Option "auth_bearer" must be a string, "%s" given.', get_debug_type($options['auth_bearer']))); + } + if (preg_match('{[^\x21-\x7E]}', $options['auth_bearer'])) { + throw new InvalidArgumentException('Invalid character found in option "auth_bearer": '.json_encode($options['auth_bearer']).'.'); + } + } + + if (isset($options['auth_basic'], $options['auth_bearer'])) { + throw new InvalidArgumentException('Define either the "auth_basic" or the "auth_bearer" option, setting both is not supported.'); + } + + if (null !== $url) { + // Merge auth with headers + if (($options['auth_basic'] ?? false) && !($options['normalized_headers']['authorization'] ?? false)) { + $options['normalized_headers']['authorization'] = ['Authorization: Basic '.base64_encode($options['auth_basic'])]; + } + // Merge bearer with headers + if (($options['auth_bearer'] ?? false) && !($options['normalized_headers']['authorization'] ?? false)) { + $options['normalized_headers']['authorization'] = ['Authorization: Bearer '.$options['auth_bearer']]; + } + + unset($options['auth_basic'], $options['auth_bearer']); + + // Parse base URI + if (\is_string($options['base_uri'])) { + $options['base_uri'] = self::parseUrl($options['base_uri']); + } + + // Validate and resolve URL + $url = self::parseUrl($url, $options['query']); + $url = self::resolveUrl($url, $options['base_uri'], $defaultOptions['query'] ?? []); + } + + // Finalize normalization of options + $options['http_version'] = (string) ($options['http_version'] ?? '') ?: null; + if (0 > $options['timeout'] = (float) ($options['timeout'] ?? \ini_get('default_socket_timeout'))) { + $options['timeout'] = 172800.0; // 2 days + } + + $options['max_duration'] = isset($options['max_duration']) ? (float) $options['max_duration'] : 0; + $options['headers'] = array_merge(...array_values($options['normalized_headers'])); + + return [$url, $options]; + } + + /** + * @throws InvalidArgumentException When an invalid option is found + */ + private static function mergeDefaultOptions(array $options, array $defaultOptions, bool $allowExtraOptions = false): array + { + $options['normalized_headers'] = self::normalizeHeaders($options['headers'] ?? []); + + if ($defaultOptions['headers'] ?? false) { + $options['normalized_headers'] += self::normalizeHeaders($defaultOptions['headers']); + } + + $options['headers'] = array_merge(...array_values($options['normalized_headers']) ?: [[]]); + + if ($resolve = $options['resolve'] ?? false) { + $options['resolve'] = []; + foreach ($resolve as $k => $v) { + $options['resolve'][substr(self::parseUrl('http://'.$k)['authority'], 2)] = (string) $v; + } + } + + // Option "query" is never inherited from defaults + $options['query'] = $options['query'] ?? []; + + $options += $defaultOptions; + + if (isset(self::$emptyDefaults)) { + foreach (self::$emptyDefaults as $k => $v) { + if (!isset($options[$k])) { + $options[$k] = $v; + } + } + } + + if (isset($defaultOptions['extra'])) { + $options['extra'] += $defaultOptions['extra']; + } + + if ($resolve = $defaultOptions['resolve'] ?? false) { + foreach ($resolve as $k => $v) { + $options['resolve'] += [substr(self::parseUrl('http://'.$k)['authority'], 2) => (string) $v]; + } + } + + if ($allowExtraOptions || !$defaultOptions) { + return $options; + } + + // Look for unsupported options + foreach ($options as $name => $v) { + if (\array_key_exists($name, $defaultOptions) || 'normalized_headers' === $name) { + continue; + } + + if ('auth_ntlm' === $name) { + if (!\extension_loaded('curl')) { + $msg = 'try installing the "curl" extension to use "%s" instead.'; + } else { + $msg = 'try using "%s" instead.'; + } + + throw new InvalidArgumentException(sprintf('Option "auth_ntlm" is not supported by "%s", '.$msg, __CLASS__, CurlHttpClient::class)); + } + + $alternatives = []; + + foreach ($defaultOptions as $k => $v) { + if (levenshtein($name, $k) <= \strlen($name) / 3 || str_contains($k, $name)) { + $alternatives[] = $k; + } + } + + throw new InvalidArgumentException(sprintf('Unsupported option "%s" passed to "%s", did you mean "%s"?', $name, __CLASS__, implode('", "', $alternatives ?: array_keys($defaultOptions)))); + } + + return $options; + } + + /** + * @return string[][] + * + * @throws InvalidArgumentException When an invalid header is found + */ + private static function normalizeHeaders(array $headers): array + { + $normalizedHeaders = []; + + foreach ($headers as $name => $values) { + if (\is_object($values) && method_exists($values, '__toString')) { + $values = (string) $values; + } + + if (\is_int($name)) { + if (!\is_string($values)) { + throw new InvalidArgumentException(sprintf('Invalid value for header "%s": expected string, "%s" given.', $name, get_debug_type($values))); + } + [$name, $values] = explode(':', $values, 2); + $values = [ltrim($values)]; + } elseif (!is_iterable($values)) { + if (\is_object($values)) { + throw new InvalidArgumentException(sprintf('Invalid value for header "%s": expected string, "%s" given.', $name, get_debug_type($values))); + } + + $values = (array) $values; + } + + $lcName = strtolower($name); + $normalizedHeaders[$lcName] = []; + + foreach ($values as $value) { + $normalizedHeaders[$lcName][] = $value = $name.': '.$value; + + if (\strlen($value) !== strcspn($value, "\r\n\0")) { + throw new InvalidArgumentException(sprintf('Invalid header: CR/LF/NUL found in "%s".', $value)); + } + } + } + + return $normalizedHeaders; + } + + /** + * @param array|string|resource|\Traversable|\Closure $body + * + * @return string|resource|\Closure + * + * @throws InvalidArgumentException When an invalid body is passed + */ + private static function normalizeBody($body) + { + if (\is_array($body)) { + array_walk_recursive($body, $caster = static function (&$v) use (&$caster) { + if (\is_object($v)) { + if ($vars = get_object_vars($v)) { + array_walk_recursive($vars, $caster); + $v = $vars; + } elseif (method_exists($v, '__toString')) { + $v = (string) $v; + } + } + }); + + return http_build_query($body, '', '&'); + } + + if (\is_string($body)) { + return $body; + } + + $generatorToCallable = static function (\Generator $body): \Closure { + return static function () use ($body) { + while ($body->valid()) { + $chunk = $body->current(); + $body->next(); + + if ('' !== $chunk) { + return $chunk; + } + } + + return ''; + }; + }; + + if ($body instanceof \Generator) { + return $generatorToCallable($body); + } + + if ($body instanceof \Traversable) { + return $generatorToCallable((static function ($body) { yield from $body; })($body)); + } + + if ($body instanceof \Closure) { + $r = new \ReflectionFunction($body); + $body = $r->getClosure(); + + if ($r->isGenerator()) { + $body = $body(self::$CHUNK_SIZE); + + return $generatorToCallable($body); + } + + return $body; + } + + if (!\is_array(@stream_get_meta_data($body))) { + throw new InvalidArgumentException(sprintf('Option "body" must be string, stream resource, iterable or callable, "%s" given.', get_debug_type($body))); + } + + return $body; + } + + private static function dechunk(string $body): string + { + $h = fopen('php://temp', 'w+'); + stream_filter_append($h, 'dechunk', \STREAM_FILTER_WRITE); + fwrite($h, $body); + $body = stream_get_contents($h, -1, 0); + rewind($h); + ftruncate($h, 0); + + if (fwrite($h, '-') && '' !== stream_get_contents($h, -1, 0)) { + throw new TransportException('Request body has broken chunked encoding.'); + } + + return $body; + } + + /** + * @param string|string[] $fingerprint + * + * @throws InvalidArgumentException When an invalid fingerprint is passed + */ + private static function normalizePeerFingerprint($fingerprint): array + { + if (\is_string($fingerprint)) { + switch (\strlen($fingerprint = str_replace(':', '', $fingerprint))) { + case 32: $fingerprint = ['md5' => $fingerprint]; break; + case 40: $fingerprint = ['sha1' => $fingerprint]; break; + case 44: $fingerprint = ['pin-sha256' => [$fingerprint]]; break; + case 64: $fingerprint = ['sha256' => $fingerprint]; break; + default: throw new InvalidArgumentException(sprintf('Cannot auto-detect fingerprint algorithm for "%s".', $fingerprint)); + } + } elseif (\is_array($fingerprint)) { + foreach ($fingerprint as $algo => $hash) { + $fingerprint[$algo] = 'pin-sha256' === $algo ? (array) $hash : str_replace(':', '', $hash); + } + } else { + throw new InvalidArgumentException(sprintf('Option "peer_fingerprint" must be string or array, "%s" given.', get_debug_type($fingerprint))); + } + + return $fingerprint; + } + + /** + * @param mixed $value + * + * @throws InvalidArgumentException When the value cannot be json-encoded + */ + private static function jsonEncode($value, int $flags = null, int $maxDepth = 512): string + { + $flags = $flags ?? (\JSON_HEX_TAG | \JSON_HEX_APOS | \JSON_HEX_AMP | \JSON_HEX_QUOT | \JSON_PRESERVE_ZERO_FRACTION); + + try { + $value = json_encode($value, $flags | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0), $maxDepth); + } catch (\JsonException $e) { + throw new InvalidArgumentException('Invalid value for "json" option: '.$e->getMessage()); + } + + if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error() && (false === $value || !($flags & \JSON_PARTIAL_OUTPUT_ON_ERROR))) { + throw new InvalidArgumentException('Invalid value for "json" option: '.json_last_error_msg()); + } + + return $value; + } + + /** + * Resolves a URL against a base URI. + * + * @see https://tools.ietf.org/html/rfc3986#section-5.2.2 + * + * @throws InvalidArgumentException When an invalid URL is passed + */ + private static function resolveUrl(array $url, ?array $base, array $queryDefaults = []): array + { + if (null !== $base && '' === ($base['scheme'] ?? '').($base['authority'] ?? '')) { + throw new InvalidArgumentException(sprintf('Invalid "base_uri" option: host or scheme is missing in "%s".', implode('', $base))); + } + + if (null === $url['scheme'] && (null === $base || null === $base['scheme'])) { + throw new InvalidArgumentException(sprintf('Invalid URL: scheme is missing in "%s". Did you forget to add "http(s)://"?', implode('', $base ?? $url))); + } + + if (null === $base && '' === $url['scheme'].$url['authority']) { + throw new InvalidArgumentException(sprintf('Invalid URL: no "base_uri" option was provided and host or scheme is missing in "%s".', implode('', $url))); + } + + if (null !== $url['scheme']) { + $url['path'] = self::removeDotSegments($url['path'] ?? ''); + } else { + if (null !== $url['authority']) { + $url['path'] = self::removeDotSegments($url['path'] ?? ''); + } else { + if (null === $url['path']) { + $url['path'] = $base['path']; + $url['query'] = $url['query'] ?? $base['query']; + } else { + if ('/' !== $url['path'][0]) { + if (null === $base['path']) { + $url['path'] = '/'.$url['path']; + } else { + $segments = explode('/', $base['path']); + array_splice($segments, -1, 1, [$url['path']]); + $url['path'] = implode('/', $segments); + } + } + + $url['path'] = self::removeDotSegments($url['path']); + } + + $url['authority'] = $base['authority']; + + if ($queryDefaults) { + $url['query'] = '?'.self::mergeQueryString(substr($url['query'] ?? '', 1), $queryDefaults, false); + } + } + + $url['scheme'] = $base['scheme']; + } + + if ('' === ($url['path'] ?? '')) { + $url['path'] = '/'; + } + + if ('?' === ($url['query'] ?? '')) { + $url['query'] = null; + } + + return $url; + } + + /** + * Parses a URL and fixes its encoding if needed. + * + * @throws InvalidArgumentException When an invalid URL is passed + */ + private static function parseUrl(string $url, array $query = [], array $allowedSchemes = ['http' => 80, 'https' => 443]): array + { + if (false === $parts = parse_url($url)) { + throw new InvalidArgumentException(sprintf('Malformed URL "%s".', $url)); + } + + if ($query) { + $parts['query'] = self::mergeQueryString($parts['query'] ?? null, $query, true); + } + + $port = $parts['port'] ?? 0; + + if (null !== $scheme = $parts['scheme'] ?? null) { + if (!isset($allowedSchemes[$scheme = strtolower($scheme)])) { + throw new InvalidArgumentException(sprintf('Unsupported scheme in "%s".', $url)); + } + + $port = $allowedSchemes[$scheme] === $port ? 0 : $port; + $scheme .= ':'; + } + + if (null !== $host = $parts['host'] ?? null) { + if (!\defined('INTL_IDNA_VARIANT_UTS46') && preg_match('/[\x80-\xFF]/', $host)) { + throw new InvalidArgumentException(sprintf('Unsupported IDN "%s", try enabling the "intl" PHP extension or running "composer require symfony/polyfill-intl-idn".', $host)); + } + + $host = \defined('INTL_IDNA_VARIANT_UTS46') ? idn_to_ascii($host, \IDNA_DEFAULT | \IDNA_USE_STD3_RULES | \IDNA_CHECK_BIDI | \IDNA_CHECK_CONTEXTJ | \IDNA_NONTRANSITIONAL_TO_ASCII, \INTL_IDNA_VARIANT_UTS46) ?: strtolower($host) : strtolower($host); + $host .= $port ? ':'.$port : ''; + } + + foreach (['user', 'pass', 'path', 'query', 'fragment'] as $part) { + if (!isset($parts[$part])) { + continue; + } + + if (str_contains($parts[$part], '%')) { + // https://tools.ietf.org/html/rfc3986#section-2.3 + $parts[$part] = preg_replace_callback('/%(?:2[DE]|3[0-9]|[46][1-9A-F]|5F|[57][0-9A]|7E)++/i', function ($m) { return rawurldecode($m[0]); }, $parts[$part]); + } + + // https://tools.ietf.org/html/rfc3986#section-3.3 + $parts[$part] = preg_replace_callback("#[^-A-Za-z0-9._~!$&/'()[\]*+,;=:@{}%]++#", function ($m) { return rawurlencode($m[0]); }, $parts[$part]); + } + + return [ + 'scheme' => $scheme, + 'authority' => null !== $host ? '//'.(isset($parts['user']) ? $parts['user'].(isset($parts['pass']) ? ':'.$parts['pass'] : '').'@' : '').$host : null, + 'path' => isset($parts['path'][0]) ? $parts['path'] : null, + 'query' => isset($parts['query']) ? '?'.$parts['query'] : null, + 'fragment' => isset($parts['fragment']) ? '#'.$parts['fragment'] : null, + ]; + } + + /** + * Removes dot-segments from a path. + * + * @see https://tools.ietf.org/html/rfc3986#section-5.2.4 + */ + private static function removeDotSegments(string $path) + { + $result = ''; + + while (!\in_array($path, ['', '.', '..'], true)) { + if ('.' === $path[0] && (str_starts_with($path, $p = '../') || str_starts_with($path, $p = './'))) { + $path = substr($path, \strlen($p)); + } elseif ('/.' === $path || str_starts_with($path, '/./')) { + $path = substr_replace($path, '/', 0, 3); + } elseif ('/..' === $path || str_starts_with($path, '/../')) { + $i = strrpos($result, '/'); + $result = $i ? substr($result, 0, $i) : ''; + $path = substr_replace($path, '/', 0, 4); + } else { + $i = strpos($path, '/', 1) ?: \strlen($path); + $result .= substr($path, 0, $i); + $path = substr($path, $i); + } + } + + return $result; + } + + /** + * Merges and encodes a query array with a query string. + * + * @throws InvalidArgumentException When an invalid query-string value is passed + */ + private static function mergeQueryString(?string $queryString, array $queryArray, bool $replace): ?string + { + if (!$queryArray) { + return $queryString; + } + + $query = []; + + if (null !== $queryString) { + foreach (explode('&', $queryString) as $v) { + if ('' !== $v) { + $k = urldecode(explode('=', $v, 2)[0]); + $query[$k] = (isset($query[$k]) ? $query[$k].'&' : '').$v; + } + } + } + + if ($replace) { + foreach ($queryArray as $k => $v) { + if (null === $v) { + unset($query[$k]); + } + } + } + + $queryString = http_build_query($queryArray, '', '&', \PHP_QUERY_RFC3986); + $queryArray = []; + + if ($queryString) { + if (str_contains($queryString, '%')) { + // https://tools.ietf.org/html/rfc3986#section-2.3 + some chars not encoded by browsers + $queryString = strtr($queryString, [ + '%21' => '!', + '%24' => '$', + '%28' => '(', + '%29' => ')', + '%2A' => '*', + '%2F' => '/', + '%3A' => ':', + '%3B' => ';', + '%40' => '@', + '%5B' => '[', + '%5D' => ']', + ]); + } + + foreach (explode('&', $queryString) as $v) { + $queryArray[rawurldecode(explode('=', $v, 2)[0])] = $v; + } + } + + return implode('&', $replace ? array_replace($query, $queryArray) : ($query + $queryArray)); + } + + /** + * Loads proxy configuration from the same environment variables as curl when no proxy is explicitly set. + */ + private static function getProxy(?string $proxy, array $url, ?string $noProxy): ?array + { + if (null === $proxy = self::getProxyUrl($proxy, $url)) { + return null; + } + + $proxy = (parse_url($proxy) ?: []) + ['scheme' => 'http']; + + if (!isset($proxy['host'])) { + throw new TransportException('Invalid HTTP proxy: host is missing.'); + } + + if ('http' === $proxy['scheme']) { + $proxyUrl = 'tcp://'.$proxy['host'].':'.($proxy['port'] ?? '80'); + } elseif ('https' === $proxy['scheme']) { + $proxyUrl = 'ssl://'.$proxy['host'].':'.($proxy['port'] ?? '443'); + } else { + throw new TransportException(sprintf('Unsupported proxy scheme "%s": "http" or "https" expected.', $proxy['scheme'])); + } + + $noProxy = $noProxy ?? $_SERVER['no_proxy'] ?? $_SERVER['NO_PROXY'] ?? ''; + $noProxy = $noProxy ? preg_split('/[\s,]+/', $noProxy) : []; + + return [ + 'url' => $proxyUrl, + 'auth' => isset($proxy['user']) ? 'Basic '.base64_encode(rawurldecode($proxy['user']).':'.rawurldecode($proxy['pass'] ?? '')) : null, + 'no_proxy' => $noProxy, + ]; + } + + private static function getProxyUrl(?string $proxy, array $url): ?string + { + if (null !== $proxy) { + return $proxy; + } + + // Ignore HTTP_PROXY except on the CLI to work around httpoxy set of vulnerabilities + $proxy = $_SERVER['http_proxy'] ?? (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? $_SERVER['HTTP_PROXY'] ?? null : null) ?? $_SERVER['all_proxy'] ?? $_SERVER['ALL_PROXY'] ?? null; + + if ('https:' === $url['scheme']) { + $proxy = $_SERVER['https_proxy'] ?? $_SERVER['HTTPS_PROXY'] ?? $proxy; + } + + return $proxy; + } + + private static function shouldBuffer(array $headers): bool + { + if (null === $contentType = $headers['content-type'][0] ?? null) { + return false; + } + + if (false !== $i = strpos($contentType, ';')) { + $contentType = substr($contentType, 0, $i); + } + + return $contentType && preg_match('#^(?:text/|application/(?:.+\+)?(?:json|xml)$)#i', $contentType); + } +} diff --git a/vendor/symfony/http-client/HttpOptions.php b/vendor/symfony/http-client/HttpOptions.php new file mode 100644 index 000000000..da55f9965 --- /dev/null +++ b/vendor/symfony/http-client/HttpOptions.php @@ -0,0 +1,331 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * A helper providing autocompletion for available options. + * + * @see HttpClientInterface for a description of each options. + * + * @author Nicolas Grekas + */ +class HttpOptions +{ + private $options = []; + + public function toArray(): array + { + return $this->options; + } + + /** + * @return $this + */ + public function setAuthBasic(string $user, string $password = '') + { + $this->options['auth_basic'] = $user; + + if ('' !== $password) { + $this->options['auth_basic'] .= ':'.$password; + } + + return $this; + } + + /** + * @return $this + */ + public function setAuthBearer(string $token) + { + $this->options['auth_bearer'] = $token; + + return $this; + } + + /** + * @return $this + */ + public function setQuery(array $query) + { + $this->options['query'] = $query; + + return $this; + } + + /** + * @return $this + */ + public function setHeaders(iterable $headers) + { + $this->options['headers'] = $headers; + + return $this; + } + + /** + * @param array|string|resource|\Traversable|\Closure $body + * + * @return $this + */ + public function setBody($body) + { + $this->options['body'] = $body; + + return $this; + } + + /** + * @param mixed $json + * + * @return $this + */ + public function setJson($json) + { + $this->options['json'] = $json; + + return $this; + } + + /** + * @return $this + */ + public function setUserData($data) + { + $this->options['user_data'] = $data; + + return $this; + } + + /** + * @return $this + */ + public function setMaxRedirects(int $max) + { + $this->options['max_redirects'] = $max; + + return $this; + } + + /** + * @return $this + */ + public function setHttpVersion(string $version) + { + $this->options['http_version'] = $version; + + return $this; + } + + /** + * @return $this + */ + public function setBaseUri(string $uri) + { + $this->options['base_uri'] = $uri; + + return $this; + } + + /** + * @return $this + */ + public function buffer(bool $buffer) + { + $this->options['buffer'] = $buffer; + + return $this; + } + + /** + * @return $this + */ + public function setOnProgress(callable $callback) + { + $this->options['on_progress'] = $callback; + + return $this; + } + + /** + * @return $this + */ + public function resolve(array $hostIps) + { + $this->options['resolve'] = $hostIps; + + return $this; + } + + /** + * @return $this + */ + public function setProxy(string $proxy) + { + $this->options['proxy'] = $proxy; + + return $this; + } + + /** + * @return $this + */ + public function setNoProxy(string $noProxy) + { + $this->options['no_proxy'] = $noProxy; + + return $this; + } + + /** + * @return $this + */ + public function setTimeout(float $timeout) + { + $this->options['timeout'] = $timeout; + + return $this; + } + + /** + * @return $this + */ + public function setMaxDuration(float $maxDuration) + { + $this->options['max_duration'] = $maxDuration; + + return $this; + } + + /** + * @return $this + */ + public function bindTo(string $bindto) + { + $this->options['bindto'] = $bindto; + + return $this; + } + + /** + * @return $this + */ + public function verifyPeer(bool $verify) + { + $this->options['verify_peer'] = $verify; + + return $this; + } + + /** + * @return $this + */ + public function verifyHost(bool $verify) + { + $this->options['verify_host'] = $verify; + + return $this; + } + + /** + * @return $this + */ + public function setCaFile(string $cafile) + { + $this->options['cafile'] = $cafile; + + return $this; + } + + /** + * @return $this + */ + public function setCaPath(string $capath) + { + $this->options['capath'] = $capath; + + return $this; + } + + /** + * @return $this + */ + public function setLocalCert(string $cert) + { + $this->options['local_cert'] = $cert; + + return $this; + } + + /** + * @return $this + */ + public function setLocalPk(string $pk) + { + $this->options['local_pk'] = $pk; + + return $this; + } + + /** + * @return $this + */ + public function setPassphrase(string $passphrase) + { + $this->options['passphrase'] = $passphrase; + + return $this; + } + + /** + * @return $this + */ + public function setCiphers(string $ciphers) + { + $this->options['ciphers'] = $ciphers; + + return $this; + } + + /** + * @param string|array $fingerprint + * + * @return $this + */ + public function setPeerFingerprint($fingerprint) + { + $this->options['peer_fingerprint'] = $fingerprint; + + return $this; + } + + /** + * @return $this + */ + public function capturePeerCertChain(bool $capture) + { + $this->options['capture_peer_cert_chain'] = $capture; + + return $this; + } + + /** + * @return $this + */ + public function setExtra(string $name, $value) + { + $this->options['extra'][$name] = $value; + + return $this; + } +} diff --git a/vendor/symfony/http-client/HttplugClient.php b/vendor/symfony/http-client/HttplugClient.php new file mode 100644 index 000000000..2d9eec30f --- /dev/null +++ b/vendor/symfony/http-client/HttplugClient.php @@ -0,0 +1,276 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use GuzzleHttp\Promise\Promise as GuzzlePromise; +use GuzzleHttp\Promise\RejectedPromise; +use GuzzleHttp\Promise\Utils; +use Http\Client\Exception\NetworkException; +use Http\Client\Exception\RequestException; +use Http\Client\HttpAsyncClient; +use Http\Client\HttpClient as HttplugInterface; +use Http\Discovery\Exception\NotFoundException; +use Http\Discovery\Psr17FactoryDiscovery; +use Http\Message\RequestFactory; +use Http\Message\StreamFactory; +use Http\Message\UriFactory; +use Http\Promise\Promise; +use Nyholm\Psr7\Factory\Psr17Factory; +use Nyholm\Psr7\Request; +use Nyholm\Psr7\Uri; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriFactoryInterface; +use Psr\Http\Message\UriInterface; +use Symfony\Component\HttpClient\Internal\HttplugWaitLoop; +use Symfony\Component\HttpClient\Response\HttplugPromise; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\Service\ResetInterface; + +if (!interface_exists(HttplugInterface::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\HttplugClient" as the "php-http/httplug" package is not installed. Try running "composer require php-http/httplug".'); +} + +if (!interface_exists(RequestFactory::class)) { + throw new \LogicException('You cannot use "Symfony\Component\HttpClient\HttplugClient" as the "php-http/message-factory" package is not installed. Try running "composer require php-http/message-factory".'); +} + +/** + * An adapter to turn a Symfony HttpClientInterface into an Httplug client. + * + * Run "composer require nyholm/psr7" to install an efficient implementation of response + * and stream factories with flex-provided autowiring aliases. + * + * @author Nicolas Grekas + */ +final class HttplugClient implements HttplugInterface, HttpAsyncClient, RequestFactory, StreamFactory, UriFactory, ResetInterface +{ + private $client; + private $responseFactory; + private $streamFactory; + + /** + * @var \SplObjectStorage|null + */ + private $promisePool; + + private $waitLoop; + + public function __construct(HttpClientInterface $client = null, ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null) + { + $this->client = $client ?? HttpClient::create(); + $this->responseFactory = $responseFactory; + $this->streamFactory = $streamFactory ?? ($responseFactory instanceof StreamFactoryInterface ? $responseFactory : null); + $this->promisePool = class_exists(Utils::class) ? new \SplObjectStorage() : null; + + if (null === $this->responseFactory || null === $this->streamFactory) { + if (!class_exists(Psr17Factory::class) && !class_exists(Psr17FactoryDiscovery::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been provided. Try running "composer require nyholm/psr7".'); + } + + try { + $psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory() : null; + $this->responseFactory = $this->responseFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findResponseFactory(); + $this->streamFactory = $this->streamFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findStreamFactory(); + } catch (NotFoundException $e) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been found. Try running "composer require nyholm/psr7".', 0, $e); + } + } + + $this->waitLoop = new HttplugWaitLoop($this->client, $this->promisePool, $this->responseFactory, $this->streamFactory); + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request): Psr7ResponseInterface + { + try { + return $this->waitLoop->createPsr7Response($this->sendPsr7Request($request)); + } catch (TransportExceptionInterface $e) { + throw new NetworkException($e->getMessage(), $request, $e); + } + } + + /** + * {@inheritdoc} + * + * @return HttplugPromise + */ + public function sendAsyncRequest(RequestInterface $request): Promise + { + if (!$promisePool = $this->promisePool) { + throw new \LogicException(sprintf('You cannot use "%s()" as the "guzzlehttp/promises" package is not installed. Try running "composer require guzzlehttp/promises".', __METHOD__)); + } + + try { + $response = $this->sendPsr7Request($request, true); + } catch (NetworkException $e) { + return new HttplugPromise(new RejectedPromise($e)); + } + + $waitLoop = $this->waitLoop; + + $promise = new GuzzlePromise(static function () use ($response, $waitLoop) { + $waitLoop->wait($response); + }, static function () use ($response, $promisePool) { + $response->cancel(); + unset($promisePool[$response]); + }); + + $promisePool[$response] = [$request, $promise]; + + return new HttplugPromise($promise); + } + + /** + * Resolves pending promises that complete before the timeouts are reached. + * + * When $maxDuration is null and $idleTimeout is reached, promises are rejected. + * + * @return int The number of remaining pending promises + */ + public function wait(float $maxDuration = null, float $idleTimeout = null): int + { + return $this->waitLoop->wait(null, $maxDuration, $idleTimeout); + } + + /** + * {@inheritdoc} + */ + public function createRequest($method, $uri, array $headers = [], $body = null, $protocolVersion = '1.1'): RequestInterface + { + if ($this->responseFactory instanceof RequestFactoryInterface) { + $request = $this->responseFactory->createRequest($method, $uri); + } elseif (class_exists(Request::class)) { + $request = new Request($method, $uri); + } elseif (class_exists(Psr17FactoryDiscovery::class)) { + $request = Psr17FactoryDiscovery::findRequestFactory()->createRequest($method, $uri); + } else { + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + $request = $request + ->withProtocolVersion($protocolVersion) + ->withBody($this->createStream($body)) + ; + + foreach ($headers as $name => $value) { + $request = $request->withAddedHeader($name, $value); + } + + return $request; + } + + /** + * {@inheritdoc} + */ + public function createStream($body = null): StreamInterface + { + if ($body instanceof StreamInterface) { + return $body; + } + + if (\is_string($body ?? '')) { + $stream = $this->streamFactory->createStream($body ?? ''); + } elseif (\is_resource($body)) { + $stream = $this->streamFactory->createStreamFromResource($body); + } else { + throw new \InvalidArgumentException(sprintf('"%s()" expects string, resource or StreamInterface, "%s" given.', __METHOD__, get_debug_type($body))); + } + + if ($stream->isSeekable()) { + $stream->seek(0); + } + + return $stream; + } + + /** + * {@inheritdoc} + */ + public function createUri($uri): UriInterface + { + if ($uri instanceof UriInterface) { + return $uri; + } + + if ($this->responseFactory instanceof UriFactoryInterface) { + return $this->responseFactory->createUri($uri); + } + + if (class_exists(Uri::class)) { + return new Uri($uri); + } + + if (class_exists(Psr17FactoryDiscovery::class)) { + return Psr17FactoryDiscovery::findUrlFactory()->createUri($uri); + } + + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + $this->wait(); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } + + private function sendPsr7Request(RequestInterface $request, bool $buffer = null): ResponseInterface + { + try { + $body = $request->getBody(); + + if ($body->isSeekable()) { + $body->seek(0); + } + + $options = [ + 'headers' => $request->getHeaders(), + 'body' => $body->getContents(), + 'buffer' => $buffer, + ]; + + if ('1.0' === $request->getProtocolVersion()) { + $options['http_version'] = '1.0'; + } + + return $this->client->request($request->getMethod(), (string) $request->getUri(), $options); + } catch (\InvalidArgumentException $e) { + throw new RequestException($e->getMessage(), $request, $e); + } catch (TransportExceptionInterface $e) { + throw new NetworkException($e->getMessage(), $request, $e); + } + } +} diff --git a/vendor/symfony/http-client/Internal/AmpBody.php b/vendor/symfony/http-client/Internal/AmpBody.php new file mode 100644 index 000000000..b99742b13 --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpBody.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\ByteStream\InputStream; +use Amp\ByteStream\ResourceInputStream; +use Amp\Http\Client\RequestBody; +use Amp\Promise; +use Amp\Success; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class AmpBody implements RequestBody, InputStream +{ + private $body; + private $info; + private $onProgress; + private $offset = 0; + private $length = -1; + private $uploaded; + + public function __construct($body, &$info, \Closure $onProgress) + { + $this->body = $body; + $this->info = &$info; + $this->onProgress = $onProgress; + + if (\is_resource($body)) { + $this->offset = ftell($body); + $this->length = fstat($body)['size']; + $this->body = new ResourceInputStream($body); + } elseif (\is_string($body)) { + $this->length = \strlen($body); + } + } + + public function createBodyStream(): InputStream + { + if (null !== $this->uploaded) { + $this->uploaded = null; + + if (\is_string($this->body)) { + $this->offset = 0; + } elseif ($this->body instanceof ResourceInputStream) { + fseek($this->body->getResource(), $this->offset); + } + } + + return $this; + } + + public function getHeaders(): Promise + { + return new Success([]); + } + + public function getBodyLength(): Promise + { + return new Success($this->length - $this->offset); + } + + public function read(): Promise + { + $this->info['size_upload'] += $this->uploaded; + $this->uploaded = 0; + ($this->onProgress)(); + + $chunk = $this->doRead(); + $chunk->onResolve(function ($e, $data) { + if (null !== $data) { + $this->uploaded = \strlen($data); + } else { + $this->info['upload_content_length'] = $this->info['size_upload']; + } + }); + + return $chunk; + } + + public static function rewind(RequestBody $body): RequestBody + { + if (!$body instanceof self) { + return $body; + } + + $body->uploaded = null; + + if ($body->body instanceof ResourceInputStream) { + fseek($body->body->getResource(), $body->offset); + + return new $body($body->body, $body->info, $body->onProgress); + } + + if (\is_string($body->body)) { + $body->offset = 0; + } + + return $body; + } + + private function doRead(): Promise + { + if ($this->body instanceof ResourceInputStream) { + return $this->body->read(); + } + + if (null === $this->offset || !$this->length) { + return new Success(); + } + + if (\is_string($this->body)) { + $this->offset = null; + + return new Success($this->body); + } + + if ('' === $data = ($this->body)(16372)) { + $this->offset = null; + + return new Success(); + } + + if (!\is_string($data)) { + throw new TransportException(sprintf('Return value of the "body" option callback must be string, "%s" returned.', get_debug_type($data))); + } + + return new Success($data); + } +} diff --git a/vendor/symfony/http-client/Internal/AmpClientState.php b/vendor/symfony/http-client/Internal/AmpClientState.php new file mode 100644 index 000000000..3061f0802 --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpClientState.php @@ -0,0 +1,217 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\CancellationToken; +use Amp\Deferred; +use Amp\Http\Client\Connection\ConnectionLimitingPool; +use Amp\Http\Client\Connection\DefaultConnectionFactory; +use Amp\Http\Client\InterceptedHttpClient; +use Amp\Http\Client\Interceptor\RetryRequests; +use Amp\Http\Client\PooledHttpClient; +use Amp\Http\Client\Request; +use Amp\Http\Client\Response; +use Amp\Http\Tunnel\Http1TunnelConnector; +use Amp\Http\Tunnel\Https1TunnelConnector; +use Amp\Promise; +use Amp\Socket\Certificate; +use Amp\Socket\ClientTlsContext; +use Amp\Socket\ConnectContext; +use Amp\Socket\Connector; +use Amp\Socket\DnsConnector; +use Amp\Socket\SocketAddress; +use Amp\Success; +use Psr\Log\LoggerInterface; + +/** + * Internal representation of the Amp client's state. + * + * @author Nicolas Grekas + * + * @internal + */ +final class AmpClientState extends ClientState +{ + public $dnsCache = []; + public $responseCount = 0; + public $pushedResponses = []; + + private $clients = []; + private $clientConfigurator; + private $maxHostConnections; + private $maxPendingPushes; + private $logger; + + public function __construct(?callable $clientConfigurator, int $maxHostConnections, int $maxPendingPushes, ?LoggerInterface &$logger) + { + $this->clientConfigurator = $clientConfigurator ?? static function (PooledHttpClient $client) { + return new InterceptedHttpClient($client, new RetryRequests(2)); + }; + $this->maxHostConnections = $maxHostConnections; + $this->maxPendingPushes = $maxPendingPushes; + $this->logger = &$logger; + } + + /** + * @return Promise + */ + public function request(array $options, Request $request, CancellationToken $cancellation, array &$info, \Closure $onProgress, &$handle): Promise + { + if ($options['proxy']) { + if ($request->hasHeader('proxy-authorization')) { + $options['proxy']['auth'] = $request->getHeader('proxy-authorization'); + } + + // Matching "no_proxy" should follow the behavior of curl + $host = $request->getUri()->getHost(); + foreach ($options['proxy']['no_proxy'] as $rule) { + $dotRule = '.'.ltrim($rule, '.'); + + if ('*' === $rule || $host === $rule || substr($host, -\strlen($dotRule)) === $dotRule) { + $options['proxy'] = null; + break; + } + } + } + + $request = clone $request; + + if ($request->hasHeader('proxy-authorization')) { + $request->removeHeader('proxy-authorization'); + } + + if ($options['capture_peer_cert_chain']) { + $info['peer_certificate_chain'] = []; + } + + $request->addEventListener(new AmpListener($info, $options['peer_fingerprint']['pin-sha256'] ?? [], $onProgress, $handle)); + $request->setPushHandler(function ($request, $response) use ($options): Promise { + return $this->handlePush($request, $response, $options); + }); + + ($request->hasHeader('content-length') ? new Success((int) $request->getHeader('content-length')) : $request->getBody()->getBodyLength()) + ->onResolve(static function ($e, $bodySize) use (&$info) { + if (null !== $bodySize && 0 <= $bodySize) { + $info['upload_content_length'] = ((1 + $info['upload_content_length']) ?? 1) - 1 + $bodySize; + } + }); + + [$client, $connector] = $this->getClient($options); + $response = $client->request($request, $cancellation); + $response->onResolve(static function ($e) use ($connector, &$handle) { + if (null === $e) { + $handle = $connector->handle; + } + }); + + return $response; + } + + private function getClient(array $options): array + { + $options = [ + 'bindto' => $options['bindto'] ?: '0', + 'verify_peer' => $options['verify_peer'], + 'capath' => $options['capath'], + 'cafile' => $options['cafile'], + 'local_cert' => $options['local_cert'], + 'local_pk' => $options['local_pk'], + 'ciphers' => $options['ciphers'], + 'capture_peer_cert_chain' => $options['capture_peer_cert_chain'] || $options['peer_fingerprint'], + 'proxy' => $options['proxy'], + ]; + + $key = md5(serialize($options)); + + if (isset($this->clients[$key])) { + return $this->clients[$key]; + } + + $context = new ClientTlsContext(''); + $options['verify_peer'] || $context = $context->withoutPeerVerification(); + $options['cafile'] && $context = $context->withCaFile($options['cafile']); + $options['capath'] && $context = $context->withCaPath($options['capath']); + $options['local_cert'] && $context = $context->withCertificate(new Certificate($options['local_cert'], $options['local_pk'])); + $options['ciphers'] && $context = $context->withCiphers($options['ciphers']); + $options['capture_peer_cert_chain'] && $context = $context->withPeerCapturing(); + + $connector = $handleConnector = new class() implements Connector { + public $connector; + public $uri; + public $handle; + + public function connect(string $uri, ConnectContext $context = null, CancellationToken $token = null): Promise + { + $result = $this->connector->connect($this->uri ?? $uri, $context, $token); + $result->onResolve(function ($e, $socket) { + $this->handle = null !== $socket ? $socket->getResource() : false; + }); + + return $result; + } + }; + $connector->connector = new DnsConnector(new AmpResolver($this->dnsCache)); + + $context = (new ConnectContext()) + ->withTcpNoDelay() + ->withTlsContext($context); + + if ($options['bindto']) { + if (file_exists($options['bindto'])) { + $connector->uri = 'unix://'.$options['bindto']; + } else { + $context = $context->withBindTo($options['bindto']); + } + } + + if ($options['proxy']) { + $proxyUrl = parse_url($options['proxy']['url']); + $proxySocket = new SocketAddress($proxyUrl['host'], $proxyUrl['port']); + $proxyHeaders = $options['proxy']['auth'] ? ['Proxy-Authorization' => $options['proxy']['auth']] : []; + + if ('ssl' === $proxyUrl['scheme']) { + $connector = new Https1TunnelConnector($proxySocket, $context->getTlsContext(), $proxyHeaders, $connector); + } else { + $connector = new Http1TunnelConnector($proxySocket, $proxyHeaders, $connector); + } + } + + $maxHostConnections = 0 < $this->maxHostConnections ? $this->maxHostConnections : \PHP_INT_MAX; + $pool = new DefaultConnectionFactory($connector, $context); + $pool = ConnectionLimitingPool::byAuthority($maxHostConnections, $pool); + + return $this->clients[$key] = [($this->clientConfigurator)(new PooledHttpClient($pool)), $handleConnector]; + } + + private function handlePush(Request $request, Promise $response, array $options): Promise + { + $deferred = new Deferred(); + $authority = $request->getUri()->getAuthority(); + + if ($this->maxPendingPushes <= \count($this->pushedResponses[$authority] ?? [])) { + $fifoUrl = key($this->pushedResponses[$authority]); + unset($this->pushedResponses[$authority][$fifoUrl]); + $this->logger && $this->logger->debug(sprintf('Evicting oldest pushed response: "%s"', $fifoUrl)); + } + + $url = (string) $request->getUri(); + $this->logger && $this->logger->debug(sprintf('Queueing pushed response: "%s"', $url)); + $this->pushedResponses[$authority][] = [$url, $deferred, $request, $response, [ + 'proxy' => $options['proxy'], + 'bindto' => $options['bindto'], + 'local_cert' => $options['local_cert'], + 'local_pk' => $options['local_pk'], + ]]; + + return $deferred->promise(); + } +} diff --git a/vendor/symfony/http-client/Internal/AmpListener.php b/vendor/symfony/http-client/Internal/AmpListener.php new file mode 100644 index 000000000..cb3235bca --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpListener.php @@ -0,0 +1,183 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\Http\Client\Connection\Stream; +use Amp\Http\Client\EventListener; +use Amp\Http\Client\Request; +use Amp\Promise; +use Amp\Success; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class AmpListener implements EventListener +{ + private $info; + private $pinSha256; + private $onProgress; + private $handle; + + public function __construct(array &$info, array $pinSha256, \Closure $onProgress, &$handle) + { + $info += [ + 'connect_time' => 0.0, + 'pretransfer_time' => 0.0, + 'starttransfer_time' => 0.0, + 'total_time' => 0.0, + 'namelookup_time' => 0.0, + 'primary_ip' => '', + 'primary_port' => 0, + ]; + + $this->info = &$info; + $this->pinSha256 = $pinSha256; + $this->onProgress = $onProgress; + $this->handle = &$handle; + } + + public function startRequest(Request $request): Promise + { + $this->info['start_time'] = $this->info['start_time'] ?? microtime(true); + ($this->onProgress)(); + + return new Success(); + } + + public function startDnsResolution(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startConnectionCreation(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startTlsNegotiation(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startSendingRequest(Request $request, Stream $stream): Promise + { + $host = $stream->getRemoteAddress()->getHost(); + + if (false !== strpos($host, ':')) { + $host = '['.$host.']'; + } + + $this->info['primary_ip'] = $host; + $this->info['primary_port'] = $stream->getRemoteAddress()->getPort(); + $this->info['pretransfer_time'] = microtime(true) - $this->info['start_time']; + $this->info['debug'] .= sprintf("* Connected to %s (%s) port %d\n", $request->getUri()->getHost(), $host, $this->info['primary_port']); + + if ((isset($this->info['peer_certificate_chain']) || $this->pinSha256) && null !== $tlsInfo = $stream->getTlsInfo()) { + foreach ($tlsInfo->getPeerCertificates() as $cert) { + $this->info['peer_certificate_chain'][] = openssl_x509_read($cert->toPem()); + } + + if ($this->pinSha256) { + $pin = openssl_pkey_get_public($this->info['peer_certificate_chain'][0]); + $pin = openssl_pkey_get_details($pin)['key']; + $pin = \array_slice(explode("\n", $pin), 1, -2); + $pin = base64_decode(implode('', $pin)); + $pin = base64_encode(hash('sha256', $pin, true)); + + if (!\in_array($pin, $this->pinSha256, true)) { + throw new TransportException(sprintf('SSL public key does not match pinned public key for "%s".', $this->info['url'])); + } + } + } + ($this->onProgress)(); + + $uri = $request->getUri(); + $requestUri = $uri->getPath() ?: '/'; + + if ('' !== $query = $uri->getQuery()) { + $requestUri .= '?'.$query; + } + + if ('CONNECT' === $method = $request->getMethod()) { + $requestUri = $uri->getHost().': '.($uri->getPort() ?? ('https' === $uri->getScheme() ? 443 : 80)); + } + + $this->info['debug'] .= sprintf("> %s %s HTTP/%s \r\n", $method, $requestUri, $request->getProtocolVersions()[0]); + + foreach ($request->getRawHeaders() as [$name, $value]) { + $this->info['debug'] .= $name.': '.$value."\r\n"; + } + $this->info['debug'] .= "\r\n"; + + return new Success(); + } + + public function completeSendingRequest(Request $request, Stream $stream): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function startReceivingResponse(Request $request, Stream $stream): Promise + { + $this->info['starttransfer_time'] = microtime(true) - $this->info['start_time']; + ($this->onProgress)(); + + return new Success(); + } + + public function completeReceivingResponse(Request $request, Stream $stream): Promise + { + $this->handle = null; + ($this->onProgress)(); + + return new Success(); + } + + public function completeDnsResolution(Request $request): Promise + { + $this->info['namelookup_time'] = microtime(true) - $this->info['start_time']; + ($this->onProgress)(); + + return new Success(); + } + + public function completeConnectionCreation(Request $request): Promise + { + $this->info['connect_time'] = microtime(true) - $this->info['start_time']; + ($this->onProgress)(); + + return new Success(); + } + + public function completeTlsNegotiation(Request $request): Promise + { + ($this->onProgress)(); + + return new Success(); + } + + public function abort(Request $request, \Throwable $cause): Promise + { + return new Success(); + } +} diff --git a/vendor/symfony/http-client/Internal/AmpResolver.php b/vendor/symfony/http-client/Internal/AmpResolver.php new file mode 100644 index 000000000..d31476a58 --- /dev/null +++ b/vendor/symfony/http-client/Internal/AmpResolver.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Amp\Dns; +use Amp\Dns\Record; +use Amp\Promise; +use Amp\Success; + +/** + * Handles local overrides for the DNS resolver. + * + * @author Nicolas Grekas + * + * @internal + */ +class AmpResolver implements Dns\Resolver +{ + private $dnsMap; + + public function __construct(array &$dnsMap) + { + $this->dnsMap = &$dnsMap; + } + + public function resolve(string $name, int $typeRestriction = null): Promise + { + if (!isset($this->dnsMap[$name]) || !\in_array($typeRestriction, [Record::A, null], true)) { + return Dns\resolver()->resolve($name, $typeRestriction); + } + + return new Success([new Record($this->dnsMap[$name], Record::A, null)]); + } + + public function query(string $name, int $type): Promise + { + if (!isset($this->dnsMap[$name]) || Record::A !== $type) { + return Dns\resolver()->query($name, $type); + } + + return new Success([new Record($this->dnsMap[$name], Record::A, null)]); + } +} diff --git a/vendor/symfony/http-client/Internal/Canary.php b/vendor/symfony/http-client/Internal/Canary.php new file mode 100644 index 000000000..3d14b5fd1 --- /dev/null +++ b/vendor/symfony/http-client/Internal/Canary.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class Canary +{ + private $canceller; + + public function __construct(\Closure $canceller) + { + $this->canceller = $canceller; + } + + public function cancel() + { + if (($canceller = $this->canceller) instanceof \Closure) { + $this->canceller = null; + $canceller(); + } + } + + public function __destruct() + { + $this->cancel(); + } +} diff --git a/vendor/symfony/http-client/Internal/ClientState.php b/vendor/symfony/http-client/Internal/ClientState.php new file mode 100644 index 000000000..52fe3c8c0 --- /dev/null +++ b/vendor/symfony/http-client/Internal/ClientState.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * Internal representation of the client state. + * + * @author Alexander M. Turek + * + * @internal + */ +class ClientState +{ + public $handlesActivity = []; + public $openHandles = []; + public $lastTimeout; +} diff --git a/vendor/symfony/http-client/Internal/CurlClientState.php b/vendor/symfony/http-client/Internal/CurlClientState.php new file mode 100644 index 000000000..80473fee0 --- /dev/null +++ b/vendor/symfony/http-client/Internal/CurlClientState.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Response\CurlResponse; + +/** + * Internal representation of the cURL client's state. + * + * @author Alexander M. Turek + * + * @internal + */ +final class CurlClientState extends ClientState +{ + /** @var \CurlMultiHandle|resource|null */ + public $handle; + /** @var \CurlShareHandle|resource|null */ + public $share; + /** @var PushedResponse[] */ + public $pushedResponses = []; + /** @var DnsCache */ + public $dnsCache; + /** @var float[] */ + public $pauseExpiries = []; + public $execCounter = \PHP_INT_MIN; + /** @var LoggerInterface|null */ + public $logger; + public $performing = false; + + public static $curlVersion; + + public function __construct(int $maxHostConnections, int $maxPendingPushes) + { + self::$curlVersion = self::$curlVersion ?? curl_version(); + + $this->handle = curl_multi_init(); + $this->dnsCache = new DnsCache(); + $this->reset(); + + // Don't enable HTTP/1.1 pipelining: it forces responses to be sent in order + if (\defined('CURLPIPE_MULTIPLEX')) { + curl_multi_setopt($this->handle, \CURLMOPT_PIPELINING, \CURLPIPE_MULTIPLEX); + } + if (\defined('CURLMOPT_MAX_HOST_CONNECTIONS')) { + $maxHostConnections = curl_multi_setopt($this->handle, \CURLMOPT_MAX_HOST_CONNECTIONS, 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX) ? 0 : $maxHostConnections; + } + if (\defined('CURLMOPT_MAXCONNECTS') && 0 < $maxHostConnections) { + curl_multi_setopt($this->handle, \CURLMOPT_MAXCONNECTS, $maxHostConnections); + } + + // Skip configuring HTTP/2 push when it's unsupported or buggy, see https://bugs.php.net/77535 + if (0 >= $maxPendingPushes || \PHP_VERSION_ID < 70217 || (\PHP_VERSION_ID >= 70300 && \PHP_VERSION_ID < 70304)) { + return; + } + + // HTTP/2 push crashes before curl 7.61 + if (!\defined('CURLMOPT_PUSHFUNCTION') || 0x073D00 > self::$curlVersion['version_number'] || !(\CURL_VERSION_HTTP2 & self::$curlVersion['features'])) { + return; + } + + // Clone to prevent a circular reference + $multi = clone $this; + $multi->handle = null; + $multi->share = null; + $multi->pushedResponses = &$this->pushedResponses; + $multi->logger = &$this->logger; + $multi->handlesActivity = &$this->handlesActivity; + $multi->openHandles = &$this->openHandles; + + curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION, static function ($parent, $pushed, array $requestHeaders) use ($multi, $maxPendingPushes) { + return $multi->handlePush($parent, $pushed, $requestHeaders, $maxPendingPushes); + }); + } + + public function reset() + { + foreach ($this->pushedResponses as $url => $response) { + $this->logger && $this->logger->debug(sprintf('Unused pushed response: "%s"', $url)); + curl_multi_remove_handle($this->handle, $response->handle); + curl_close($response->handle); + } + + $this->pushedResponses = []; + $this->dnsCache->evictions = $this->dnsCache->evictions ?: $this->dnsCache->removals; + $this->dnsCache->removals = $this->dnsCache->hostnames = []; + + $this->share = curl_share_init(); + + curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_DNS); + curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_SSL_SESSION); + + if (\defined('CURL_LOCK_DATA_CONNECT') && \PHP_VERSION_ID >= 80000) { + curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_CONNECT); + } + } + + private function handlePush($parent, $pushed, array $requestHeaders, int $maxPendingPushes): int + { + $headers = []; + $origin = curl_getinfo($parent, \CURLINFO_EFFECTIVE_URL); + + foreach ($requestHeaders as $h) { + if (false !== $i = strpos($h, ':', 1)) { + $headers[substr($h, 0, $i)][] = substr($h, 1 + $i); + } + } + + if (!isset($headers[':method']) || !isset($headers[':scheme']) || !isset($headers[':authority']) || !isset($headers[':path'])) { + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response from "%s": pushed headers are invalid', $origin)); + + return \CURL_PUSH_DENY; + } + + $url = $headers[':scheme'][0].'://'.$headers[':authority'][0]; + + // curl before 7.65 doesn't validate the pushed ":authority" header, + // but this is a MUST in the HTTP/2 RFC; let's restrict pushes to the original host, + // ignoring domains mentioned as alt-name in the certificate for now (same as curl). + if (!str_starts_with($origin, $url.'/')) { + $this->logger && $this->logger->debug(sprintf('Rejecting pushed response from "%s": server is not authoritative for "%s"', $origin, $url)); + + return \CURL_PUSH_DENY; + } + + if ($maxPendingPushes <= \count($this->pushedResponses)) { + $fifoUrl = key($this->pushedResponses); + unset($this->pushedResponses[$fifoUrl]); + $this->logger && $this->logger->debug(sprintf('Evicting oldest pushed response: "%s"', $fifoUrl)); + } + + $url .= $headers[':path'][0]; + $this->logger && $this->logger->debug(sprintf('Queueing pushed response: "%s"', $url)); + + $this->pushedResponses[$url] = new PushedResponse(new CurlResponse($this, $pushed), $headers, $this->openHandles[(int) $parent][1] ?? [], $pushed); + + return \CURL_PUSH_OK; + } +} diff --git a/vendor/symfony/http-client/Internal/DnsCache.php b/vendor/symfony/http-client/Internal/DnsCache.php new file mode 100644 index 000000000..bd23f77f8 --- /dev/null +++ b/vendor/symfony/http-client/Internal/DnsCache.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * Cache for resolved DNS queries. + * + * @author Alexander M. Turek + * + * @internal + */ +final class DnsCache +{ + /** + * Resolved hostnames (hostname => IP address). + * + * @var string[] + */ + public $hostnames = []; + + /** + * @var string[] + */ + public $removals = []; + + /** + * @var string[] + */ + public $evictions = []; +} diff --git a/vendor/symfony/http-client/Internal/HttplugWaitLoop.php b/vendor/symfony/http-client/Internal/HttplugWaitLoop.php new file mode 100644 index 000000000..c61be22e3 --- /dev/null +++ b/vendor/symfony/http-client/Internal/HttplugWaitLoop.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Http\Client\Exception\NetworkException; +use Http\Promise\Promise; +use Psr\Http\Message\RequestInterface as Psr7RequestInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Symfony\Component\HttpClient\Response\StreamableInterface; +use Symfony\Component\HttpClient\Response\StreamWrapper; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class HttplugWaitLoop +{ + private $client; + private $promisePool; + private $responseFactory; + private $streamFactory; + + /** + * @param \SplObjectStorage|null $promisePool + */ + public function __construct(HttpClientInterface $client, ?\SplObjectStorage $promisePool, ResponseFactoryInterface $responseFactory, StreamFactoryInterface $streamFactory) + { + $this->client = $client; + $this->promisePool = $promisePool; + $this->responseFactory = $responseFactory; + $this->streamFactory = $streamFactory; + } + + public function wait(?ResponseInterface $pendingResponse, float $maxDuration = null, float $idleTimeout = null): int + { + if (!$this->promisePool) { + return 0; + } + + $guzzleQueue = \GuzzleHttp\Promise\Utils::queue(); + + if (0.0 === $remainingDuration = $maxDuration) { + $idleTimeout = 0.0; + } elseif (null !== $maxDuration) { + $startTime = microtime(true); + $idleTimeout = max(0.0, min($maxDuration / 5, $idleTimeout ?? $maxDuration)); + } + + do { + foreach ($this->client->stream($this->promisePool, $idleTimeout) as $response => $chunk) { + try { + if (null !== $maxDuration && $chunk->isTimeout()) { + goto check_duration; + } + + if ($chunk->isFirst()) { + // Deactivate throwing on 3/4/5xx + $response->getStatusCode(); + } + + if (!$chunk->isLast()) { + goto check_duration; + } + + if ([, $promise] = $this->promisePool[$response] ?? null) { + unset($this->promisePool[$response]); + $promise->resolve($this->createPsr7Response($response, true)); + } + } catch (\Exception $e) { + if ([$request, $promise] = $this->promisePool[$response] ?? null) { + unset($this->promisePool[$response]); + + if ($e instanceof TransportExceptionInterface) { + $e = new NetworkException($e->getMessage(), $request, $e); + } + + $promise->reject($e); + } + } + + $guzzleQueue->run(); + + if ($pendingResponse === $response) { + return $this->promisePool->count(); + } + + check_duration: + if (null !== $maxDuration && $idleTimeout && $idleTimeout > $remainingDuration = max(0.0, $maxDuration - microtime(true) + $startTime)) { + $idleTimeout = $remainingDuration / 5; + break; + } + } + + if (!$count = $this->promisePool->count()) { + return 0; + } + } while (null === $maxDuration || 0 < $remainingDuration); + + return $count; + } + + public function createPsr7Response(ResponseInterface $response, bool $buffer = false): Psr7ResponseInterface + { + $psrResponse = $this->responseFactory->createResponse($response->getStatusCode()); + + foreach ($response->getHeaders(false) as $name => $values) { + foreach ($values as $value) { + try { + $psrResponse = $psrResponse->withAddedHeader($name, $value); + } catch (\InvalidArgumentException $e) { + // ignore invalid header + } + } + } + + if ($response instanceof StreamableInterface) { + $body = $this->streamFactory->createStreamFromResource($response->toStream(false)); + } elseif (!$buffer) { + $body = $this->streamFactory->createStreamFromResource(StreamWrapper::createResource($response, $this->client)); + } else { + $body = $this->streamFactory->createStream($response->getContent(false)); + } + + if ($body->isSeekable()) { + $body->seek(0); + } + + return $psrResponse->withBody($body); + } +} diff --git a/vendor/symfony/http-client/Internal/NativeClientState.php b/vendor/symfony/http-client/Internal/NativeClientState.php new file mode 100644 index 000000000..20b2727f5 --- /dev/null +++ b/vendor/symfony/http-client/Internal/NativeClientState.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +/** + * Internal representation of the native client's state. + * + * @author Alexander M. Turek + * + * @internal + */ +final class NativeClientState extends ClientState +{ + /** @var int */ + public $id; + /** @var int */ + public $maxHostConnections = \PHP_INT_MAX; + /** @var int */ + public $responseCount = 0; + /** @var string[] */ + public $dnsCache = []; + /** @var bool */ + public $sleep = false; + /** @var int[] */ + public $hosts = []; + + public function __construct() + { + $this->id = random_int(\PHP_INT_MIN, \PHP_INT_MAX); + } + + public function reset() + { + $this->responseCount = 0; + $this->dnsCache = []; + $this->hosts = []; + } +} diff --git a/vendor/symfony/http-client/Internal/PushedResponse.php b/vendor/symfony/http-client/Internal/PushedResponse.php new file mode 100644 index 000000000..08fca60dc --- /dev/null +++ b/vendor/symfony/http-client/Internal/PushedResponse.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Internal; + +use Symfony\Component\HttpClient\Response\CurlResponse; + +/** + * A pushed response with its request headers. + * + * @author Alexander M. Turek + * + * @internal + */ +final class PushedResponse +{ + public $response; + + /** @var string[] */ + public $requestHeaders; + + public $parentOptions = []; + + public $handle; + + public function __construct(CurlResponse $response, array $requestHeaders, array $parentOptions, $handle) + { + $this->response = $response; + $this->requestHeaders = $requestHeaders; + $this->parentOptions = $parentOptions; + $this->handle = $handle; + } +} diff --git a/vendor/symfony/http-client/LICENSE b/vendor/symfony/http-client/LICENSE new file mode 100644 index 000000000..7536caeae --- /dev/null +++ b/vendor/symfony/http-client/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/http-client/MockHttpClient.php b/vendor/symfony/http-client/MockHttpClient.php new file mode 100644 index 000000000..fecba0ee5 --- /dev/null +++ b/vendor/symfony/http-client/MockHttpClient.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Response\MockResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * A test-friendly HttpClient that doesn't make actual HTTP requests. + * + * @author Nicolas Grekas + */ +class MockHttpClient implements HttpClientInterface, ResetInterface +{ + use HttpClientTrait; + + private $responseFactory; + private $requestsCount = 0; + private $defaultOptions = []; + + /** + * @param callable|callable[]|ResponseInterface|ResponseInterface[]|iterable|null $responseFactory + */ + public function __construct($responseFactory = null, ?string $baseUri = 'https://example.com') + { + $this->setResponseFactory($responseFactory); + $this->defaultOptions['base_uri'] = $baseUri; + } + + /** + * @param callable|callable[]|ResponseInterface|ResponseInterface[]|iterable|null $responseFactory + */ + public function setResponseFactory($responseFactory): void + { + if ($responseFactory instanceof ResponseInterface) { + $responseFactory = [$responseFactory]; + } + + if (!$responseFactory instanceof \Iterator && null !== $responseFactory && !\is_callable($responseFactory)) { + $responseFactory = (static function () use ($responseFactory) { + yield from $responseFactory; + })(); + } + + $this->responseFactory = $responseFactory; + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = $this->prepareRequest($method, $url, $options, $this->defaultOptions, true); + $url = implode('', $url); + + if (null === $this->responseFactory) { + $response = new MockResponse(); + } elseif (\is_callable($this->responseFactory)) { + $response = ($this->responseFactory)($method, $url, $options); + } elseif (!$this->responseFactory->valid()) { + throw new TransportException('The response factory iterator passed to MockHttpClient is empty.'); + } else { + $responseFactory = $this->responseFactory->current(); + $response = \is_callable($responseFactory) ? $responseFactory($method, $url, $options) : $responseFactory; + $this->responseFactory->next(); + } + ++$this->requestsCount; + + if (!$response instanceof ResponseInterface) { + throw new TransportException(sprintf('The response factory passed to MockHttpClient must return/yield an instance of ResponseInterface, "%s" given.', \is_object($response) ? \get_class($response) : \gettype($response))); + } + + return MockResponse::fromRequest($method, $url, $options, $response); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof ResponseInterface) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of MockResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(MockResponse::stream($responses, $timeout)); + } + + public function getRequestsCount(): int + { + return $this->requestsCount; + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->defaultOptions = self::mergeDefaultOptions($options, $this->defaultOptions, true); + + return $clone; + } + + public function reset() + { + $this->requestsCount = 0; + } +} diff --git a/vendor/symfony/http-client/NativeHttpClient.php b/vendor/symfony/http-client/NativeHttpClient.php new file mode 100644 index 000000000..63fcc1ca9 --- /dev/null +++ b/vendor/symfony/http-client/NativeHttpClient.php @@ -0,0 +1,468 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\NativeClientState; +use Symfony\Component\HttpClient\Response\NativeResponse; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * A portable implementation of the HttpClientInterface contracts based on PHP stream wrappers. + * + * PHP stream wrappers are able to fetch response bodies concurrently, + * but each request is opened synchronously. + * + * @author Nicolas Grekas + */ +final class NativeHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + use LoggerAwareTrait; + + private $defaultOptions = self::OPTIONS_DEFAULTS; + private static $emptyDefaults = self::OPTIONS_DEFAULTS; + + /** @var NativeClientState */ + private $multi; + + /** + * @param array $defaultOptions Default request's options + * @param int $maxHostConnections The maximum number of connections to open + * + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + */ + public function __construct(array $defaultOptions = [], int $maxHostConnections = 6) + { + $this->defaultOptions['buffer'] = $this->defaultOptions['buffer'] ?? \Closure::fromCallable([__CLASS__, 'shouldBuffer']); + + if ($defaultOptions) { + [, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions); + } + + $this->multi = new NativeClientState(); + $this->multi->maxHostConnections = 0 < $maxHostConnections ? $maxHostConnections : \PHP_INT_MAX; + } + + /** + * @see HttpClientInterface::OPTIONS_DEFAULTS for available options + * + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + [$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions); + + if ($options['bindto']) { + if (file_exists($options['bindto'])) { + throw new TransportException(__CLASS__.' cannot bind to local Unix sockets, use e.g. CurlHttpClient instead.'); + } + if (str_starts_with($options['bindto'], 'if!')) { + throw new TransportException(__CLASS__.' cannot bind to network interfaces, use e.g. CurlHttpClient instead.'); + } + if (str_starts_with($options['bindto'], 'host!')) { + $options['bindto'] = substr($options['bindto'], 5); + } + } + + $hasContentLength = isset($options['normalized_headers']['content-length']); + $hasBody = '' !== $options['body'] || 'POST' === $method || $hasContentLength; + + $options['body'] = self::getBodyAsString($options['body']); + + if ('chunked' === substr($options['normalized_headers']['transfer-encoding'][0] ?? '', \strlen('Transfer-Encoding: '))) { + unset($options['normalized_headers']['transfer-encoding']); + $options['headers'] = array_merge(...array_values($options['normalized_headers'])); + $options['body'] = self::dechunk($options['body']); + } + if ('' === $options['body'] && $hasBody && !$hasContentLength) { + $options['headers'][] = 'Content-Length: 0'; + } + if ($hasBody && !isset($options['normalized_headers']['content-type'])) { + $options['headers'][] = 'Content-Type: application/x-www-form-urlencoded'; + } + + if (\extension_loaded('zlib') && !isset($options['normalized_headers']['accept-encoding'])) { + // gzip is the most widely available algo, no need to deal with deflate + $options['headers'][] = 'Accept-Encoding: gzip'; + } + + if ($options['peer_fingerprint']) { + if (isset($options['peer_fingerprint']['pin-sha256']) && 1 === \count($options['peer_fingerprint'])) { + throw new TransportException(__CLASS__.' cannot verify "pin-sha256" fingerprints, please provide a "sha256" one.'); + } + + unset($options['peer_fingerprint']['pin-sha256']); + } + + $info = [ + 'response_headers' => [], + 'url' => $url, + 'error' => null, + 'canceled' => false, + 'http_method' => $method, + 'http_code' => 0, + 'redirect_count' => 0, + 'start_time' => 0.0, + 'connect_time' => 0.0, + 'redirect_time' => 0.0, + 'pretransfer_time' => 0.0, + 'starttransfer_time' => 0.0, + 'total_time' => 0.0, + 'namelookup_time' => 0.0, + 'size_upload' => 0, + 'size_download' => 0, + 'size_body' => \strlen($options['body']), + 'primary_ip' => '', + 'primary_port' => 'http:' === $url['scheme'] ? 80 : 443, + 'debug' => \extension_loaded('curl') ? '' : "* Enable the curl extension for better performance\n", + ]; + + if ($onProgress = $options['on_progress']) { + // Memoize the last progress to ease calling the callback periodically when no network transfer happens + $lastProgress = [0, 0]; + $maxDuration = 0 < $options['max_duration'] ? $options['max_duration'] : \INF; + $onProgress = static function (...$progress) use ($onProgress, &$lastProgress, &$info, $maxDuration) { + if ($info['total_time'] >= $maxDuration) { + throw new TransportException(sprintf('Max duration was reached for "%s".', implode('', $info['url']))); + } + + $progressInfo = $info; + $progressInfo['url'] = implode('', $info['url']); + unset($progressInfo['size_body']); + + if ($progress && -1 === $progress[0]) { + // Response completed + $lastProgress[0] = max($lastProgress); + } else { + $lastProgress = $progress ?: $lastProgress; + } + + $onProgress($lastProgress[0], $lastProgress[1], $progressInfo); + }; + } elseif (0 < $options['max_duration']) { + $maxDuration = $options['max_duration']; + $onProgress = static function () use (&$info, $maxDuration): void { + if ($info['total_time'] >= $maxDuration) { + throw new TransportException(sprintf('Max duration was reached for "%s".', implode('', $info['url']))); + } + }; + } + + // Always register a notification callback to compute live stats about the response + $notification = static function (int $code, int $severity, ?string $msg, int $msgCode, int $dlNow, int $dlSize) use ($onProgress, &$info) { + $info['total_time'] = microtime(true) - $info['start_time']; + + if (\STREAM_NOTIFY_PROGRESS === $code) { + $info['starttransfer_time'] = $info['starttransfer_time'] ?: $info['total_time']; + $info['size_upload'] += $dlNow ? 0 : $info['size_body']; + $info['size_download'] = $dlNow; + } elseif (\STREAM_NOTIFY_CONNECT === $code) { + $info['connect_time'] = $info['total_time']; + $info['debug'] .= $info['request_header']; + unset($info['request_header']); + } else { + return; + } + + if ($onProgress) { + $onProgress($dlNow, $dlSize); + } + }; + + if ($options['resolve']) { + $this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCache; + } + + $this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, implode('', $url))); + + if (!isset($options['normalized_headers']['user-agent'])) { + $options['headers'][] = 'User-Agent: Symfony HttpClient/Native'; + } + + if (0 < $options['max_duration']) { + $options['timeout'] = min($options['max_duration'], $options['timeout']); + } + + $bindto = $options['bindto']; + if (!$bindto && (70322 === \PHP_VERSION_ID || 70410 === \PHP_VERSION_ID)) { + $bindto = '0:0'; + } + + $context = [ + 'http' => [ + 'protocol_version' => min($options['http_version'] ?: '1.1', '1.1'), + 'method' => $method, + 'content' => $options['body'], + 'ignore_errors' => true, + 'curl_verify_ssl_peer' => $options['verify_peer'], + 'curl_verify_ssl_host' => $options['verify_host'], + 'auto_decode' => false, // Disable dechunk filter, it's incompatible with stream_select() + 'timeout' => $options['timeout'], + 'follow_location' => false, // We follow redirects ourselves - the native logic is too limited + ], + 'ssl' => array_filter([ + 'verify_peer' => $options['verify_peer'], + 'verify_peer_name' => $options['verify_host'], + 'cafile' => $options['cafile'], + 'capath' => $options['capath'], + 'local_cert' => $options['local_cert'], + 'local_pk' => $options['local_pk'], + 'passphrase' => $options['passphrase'], + 'ciphers' => $options['ciphers'], + 'peer_fingerprint' => $options['peer_fingerprint'], + 'capture_peer_cert_chain' => $options['capture_peer_cert_chain'], + 'allow_self_signed' => (bool) $options['peer_fingerprint'], + 'SNI_enabled' => true, + 'disable_compression' => true, + ], static function ($v) { return null !== $v; }), + 'socket' => [ + 'bindto' => $bindto, + 'tcp_nodelay' => true, + ], + ]; + + $context = stream_context_create($context, ['notification' => $notification]); + + $resolver = static function ($multi) use ($context, $options, $url, &$info, $onProgress) { + [$host, $port] = self::parseHostPort($url, $info); + + if (!isset($options['normalized_headers']['host'])) { + $options['headers'][] = 'Host: '.$host.$port; + } + + $proxy = self::getProxy($options['proxy'], $url, $options['no_proxy']); + + if (!self::configureHeadersAndProxy($context, $host, $options['headers'], $proxy, 'https:' === $url['scheme'])) { + $ip = self::dnsResolve($host, $multi, $info, $onProgress); + $url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host)); + } + + return [self::createRedirectResolver($options, $host, $proxy, $info, $onProgress), implode('', $url)]; + }; + + return new NativeResponse($this->multi, $context, implode('', $url), $options, $info, $resolver, $onProgress, $this->logger); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof NativeResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of NativeResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(NativeResponse::stream($responses, $timeout)); + } + + public function reset() + { + $this->multi->reset(); + } + + private static function getBodyAsString($body): string + { + if (\is_resource($body)) { + return stream_get_contents($body); + } + + if (!$body instanceof \Closure) { + return $body; + } + + $result = ''; + + while ('' !== $data = $body(self::$CHUNK_SIZE)) { + if (!\is_string($data)) { + throw new TransportException(sprintf('Return value of the "body" option callback must be string, "%s" returned.', get_debug_type($data))); + } + + $result .= $data; + } + + return $result; + } + + /** + * Extracts the host and the port from the URL. + */ + private static function parseHostPort(array $url, array &$info): array + { + if ($port = parse_url($url['authority'], \PHP_URL_PORT) ?: '') { + $info['primary_port'] = $port; + $port = ':'.$port; + } else { + $info['primary_port'] = 'http:' === $url['scheme'] ? 80 : 443; + } + + return [parse_url($url['authority'], \PHP_URL_HOST), $port]; + } + + /** + * Resolves the IP of the host using the local DNS cache if possible. + */ + private static function dnsResolve($host, NativeClientState $multi, array &$info, ?\Closure $onProgress): string + { + if (null === $ip = $multi->dnsCache[$host] ?? null) { + $info['debug'] .= "* Hostname was NOT found in DNS cache\n"; + $now = microtime(true); + + if (!$ip = gethostbynamel($host)) { + throw new TransportException(sprintf('Could not resolve host "%s".', $host)); + } + + $info['namelookup_time'] = microtime(true) - ($info['start_time'] ?: $now); + $multi->dnsCache[$host] = $ip = $ip[0]; + $info['debug'] .= "* Added {$host}:0:{$ip} to DNS cache\n"; + } else { + $info['debug'] .= "* Hostname was found in DNS cache\n"; + } + + $info['primary_ip'] = $ip; + + if ($onProgress) { + // Notify DNS resolution + $onProgress(); + } + + return $ip; + } + + /** + * Handles redirects - the native logic is too buggy to be used. + */ + private static function createRedirectResolver(array $options, string $host, ?array $proxy, array &$info, ?\Closure $onProgress): \Closure + { + $redirectHeaders = []; + if (0 < $maxRedirects = $options['max_redirects']) { + $redirectHeaders = ['host' => $host]; + $redirectHeaders['with_auth'] = $redirectHeaders['no_auth'] = array_filter($options['headers'], static function ($h) { + return 0 !== stripos($h, 'Host:'); + }); + + if (isset($options['normalized_headers']['authorization']) || isset($options['normalized_headers']['cookie'])) { + $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], static function ($h) { + return 0 !== stripos($h, 'Authorization:') && 0 !== stripos($h, 'Cookie:'); + }); + } + } + + return static function (NativeClientState $multi, ?string $location, $context) use (&$redirectHeaders, $proxy, &$info, $maxRedirects, $onProgress): ?string { + if (null === $location || $info['http_code'] < 300 || 400 <= $info['http_code']) { + $info['redirect_url'] = null; + + return null; + } + + try { + $url = self::parseUrl($location); + } catch (InvalidArgumentException $e) { + $info['redirect_url'] = null; + + return null; + } + + $url = self::resolveUrl($url, $info['url']); + $info['redirect_url'] = implode('', $url); + + if ($info['redirect_count'] >= $maxRedirects) { + return null; + } + + $info['url'] = $url; + ++$info['redirect_count']; + $info['redirect_time'] = microtime(true) - $info['start_time']; + + // Do like curl and browsers: turn POST to GET on 301, 302 and 303 + if (\in_array($info['http_code'], [301, 302, 303], true)) { + $options = stream_context_get_options($context)['http']; + + if ('POST' === $options['method'] || 303 === $info['http_code']) { + $info['http_method'] = $options['method'] = 'HEAD' === $options['method'] ? 'HEAD' : 'GET'; + $options['content'] = ''; + $filterContentHeaders = static function ($h) { + return 0 !== stripos($h, 'Content-Length:') && 0 !== stripos($h, 'Content-Type:') && 0 !== stripos($h, 'Transfer-Encoding:'); + }; + $options['header'] = array_filter($options['header'], $filterContentHeaders); + $redirectHeaders['no_auth'] = array_filter($redirectHeaders['no_auth'], $filterContentHeaders); + $redirectHeaders['with_auth'] = array_filter($redirectHeaders['with_auth'], $filterContentHeaders); + + stream_context_set_option($context, ['http' => $options]); + } + } + + [$host, $port] = self::parseHostPort($url, $info); + + if (false !== (parse_url($location, \PHP_URL_HOST) ?? false)) { + // Authorization and Cookie headers MUST NOT follow except for the initial host name + $requestHeaders = $redirectHeaders['host'] === $host ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth']; + $requestHeaders[] = 'Host: '.$host.$port; + $dnsResolve = !self::configureHeadersAndProxy($context, $host, $requestHeaders, $proxy, 'https:' === $url['scheme']); + } else { + $dnsResolve = isset(stream_context_get_options($context)['ssl']['peer_name']); + } + + if ($dnsResolve) { + $ip = self::dnsResolve($host, $multi, $info, $onProgress); + $url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host)); + } + + return implode('', $url); + }; + } + + private static function configureHeadersAndProxy($context, string $host, array $requestHeaders, ?array $proxy, bool $isSsl): bool + { + if (null === $proxy) { + stream_context_set_option($context, 'http', 'header', $requestHeaders); + stream_context_set_option($context, 'ssl', 'peer_name', $host); + + return false; + } + + // Matching "no_proxy" should follow the behavior of curl + + foreach ($proxy['no_proxy'] as $rule) { + $dotRule = '.'.ltrim($rule, '.'); + + if ('*' === $rule || $host === $rule || str_ends_with($host, $dotRule)) { + stream_context_set_option($context, 'http', 'proxy', null); + stream_context_set_option($context, 'http', 'request_fulluri', false); + stream_context_set_option($context, 'http', 'header', $requestHeaders); + stream_context_set_option($context, 'ssl', 'peer_name', $host); + + return false; + } + } + + if (null !== $proxy['auth']) { + $requestHeaders[] = 'Proxy-Authorization: '.$proxy['auth']; + } + + stream_context_set_option($context, 'http', 'proxy', $proxy['url']); + stream_context_set_option($context, 'http', 'request_fulluri', !$isSsl); + stream_context_set_option($context, 'http', 'header', $requestHeaders); + stream_context_set_option($context, 'ssl', 'peer_name', null); + + return true; + } +} diff --git a/vendor/symfony/http-client/NoPrivateNetworkHttpClient.php b/vendor/symfony/http-client/NoPrivateNetworkHttpClient.php new file mode 100644 index 000000000..911cce9da --- /dev/null +++ b/vendor/symfony/http-client/NoPrivateNetworkHttpClient.php @@ -0,0 +1,132 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpFoundation\IpUtils; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Decorator that blocks requests to private networks by default. + * + * @author Hallison Boaventura + */ +final class NoPrivateNetworkHttpClient implements HttpClientInterface, LoggerAwareInterface, ResetInterface +{ + use HttpClientTrait; + + private const PRIVATE_SUBNETS = [ + '127.0.0.0/8', + '10.0.0.0/8', + '192.168.0.0/16', + '172.16.0.0/12', + '169.254.0.0/16', + '0.0.0.0/8', + '240.0.0.0/4', + '::1/128', + 'fc00::/7', + 'fe80::/10', + '::ffff:0:0/96', + '::/128', + ]; + + private $client; + private $subnets; + + /** + * @param string|array|null $subnets String or array of subnets using CIDR notation that will be used by IpUtils. + * If null is passed, the standard private subnets will be used. + */ + public function __construct(HttpClientInterface $client, $subnets = null) + { + if (!(\is_array($subnets) || \is_string($subnets) || null === $subnets)) { + throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be of the type array, string or null. "%s" given.', __METHOD__, get_debug_type($subnets))); + } + + if (!class_exists(IpUtils::class)) { + throw new \LogicException(sprintf('You cannot use "%s" if the HttpFoundation component is not installed. Try running "composer require symfony/http-foundation".', __CLASS__)); + } + + $this->client = $client; + $this->subnets = $subnets; + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $onProgress = $options['on_progress'] ?? null; + if (null !== $onProgress && !\is_callable($onProgress)) { + throw new InvalidArgumentException(sprintf('Option "on_progress" must be callable, "%s" given.', get_debug_type($onProgress))); + } + + $subnets = $this->subnets; + $lastPrimaryIp = ''; + + $options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use ($onProgress, $subnets, &$lastPrimaryIp): void { + if ($info['primary_ip'] !== $lastPrimaryIp) { + if ($info['primary_ip'] && IpUtils::checkIp($info['primary_ip'], $subnets ?? self::PRIVATE_SUBNETS)) { + throw new TransportException(sprintf('IP "%s" is blocked for "%s".', $info['primary_ip'], $info['url'])); + } + + $lastPrimaryIp = $info['primary_ip']; + } + + null !== $onProgress && $onProgress($dlNow, $dlSize, $info); + }; + + return $this->client->request($method, $url, $options); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->client->stream($responses, $timeout); + } + + /** + * {@inheritdoc} + */ + public function setLogger(LoggerInterface $logger): void + { + if ($this->client instanceof LoggerAwareInterface) { + $this->client->setLogger($logger); + } + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} diff --git a/vendor/symfony/http-client/Psr18Client.php b/vendor/symfony/http-client/Psr18Client.php new file mode 100644 index 000000000..2ec758ae4 --- /dev/null +++ b/vendor/symfony/http-client/Psr18Client.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Http\Discovery\Exception\NotFoundException; +use Http\Discovery\Psr17FactoryDiscovery; +use Nyholm\Psr7\Factory\Psr17Factory; +use Nyholm\Psr7\Request; +use Nyholm\Psr7\Uri; +use Psr\Http\Client\ClientInterface; +use Psr\Http\Client\NetworkExceptionInterface; +use Psr\Http\Client\RequestExceptionInterface; +use Psr\Http\Message\RequestFactoryInterface; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseFactoryInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamFactoryInterface; +use Psr\Http\Message\StreamInterface; +use Psr\Http\Message\UriFactoryInterface; +use Psr\Http\Message\UriInterface; +use Symfony\Component\HttpClient\Response\StreamableInterface; +use Symfony\Component\HttpClient\Response\StreamWrapper; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\Service\ResetInterface; + +if (!interface_exists(RequestFactoryInterface::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as the "psr/http-factory" package is not installed. Try running "composer require nyholm/psr7".'); +} + +if (!interface_exists(ClientInterface::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as the "psr/http-client" package is not installed. Try running "composer require psr/http-client".'); +} + +/** + * An adapter to turn a Symfony HttpClientInterface into a PSR-18 ClientInterface. + * + * Run "composer require psr/http-client" to install the base ClientInterface. Run + * "composer require nyholm/psr7" to install an efficient implementation of response + * and stream factories with flex-provided autowiring aliases. + * + * @author Nicolas Grekas + */ +final class Psr18Client implements ClientInterface, RequestFactoryInterface, StreamFactoryInterface, UriFactoryInterface, ResetInterface +{ + private $client; + private $responseFactory; + private $streamFactory; + + public function __construct(HttpClientInterface $client = null, ResponseFactoryInterface $responseFactory = null, StreamFactoryInterface $streamFactory = null) + { + $this->client = $client ?? HttpClient::create(); + $this->responseFactory = $responseFactory; + $this->streamFactory = $streamFactory ?? ($responseFactory instanceof StreamFactoryInterface ? $responseFactory : null); + + if (null !== $this->responseFactory && null !== $this->streamFactory) { + return; + } + + if (!class_exists(Psr17Factory::class) && !class_exists(Psr17FactoryDiscovery::class)) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\Psr18Client" as no PSR-17 factories have been provided. Try running "composer require nyholm/psr7".'); + } + + try { + $psr17Factory = class_exists(Psr17Factory::class, false) ? new Psr17Factory() : null; + $this->responseFactory = $this->responseFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findResponseFactory(); + $this->streamFactory = $this->streamFactory ?? $psr17Factory ?? Psr17FactoryDiscovery::findStreamFactory(); + } catch (NotFoundException $e) { + throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\HttplugClient" as no PSR-17 factories have been found. Try running "composer require nyholm/psr7".', 0, $e); + } + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request): ResponseInterface + { + try { + $body = $request->getBody(); + + if ($body->isSeekable()) { + $body->seek(0); + } + + $options = [ + 'headers' => $request->getHeaders(), + 'body' => $body->getContents(), + ]; + + if ('1.0' === $request->getProtocolVersion()) { + $options['http_version'] = '1.0'; + } + + $response = $this->client->request($request->getMethod(), (string) $request->getUri(), $options); + + $psrResponse = $this->responseFactory->createResponse($response->getStatusCode()); + + foreach ($response->getHeaders(false) as $name => $values) { + foreach ($values as $value) { + try { + $psrResponse = $psrResponse->withAddedHeader($name, $value); + } catch (\InvalidArgumentException $e) { + // ignore invalid header + } + } + } + + $body = $response instanceof StreamableInterface ? $response->toStream(false) : StreamWrapper::createResource($response, $this->client); + $body = $this->streamFactory->createStreamFromResource($body); + + if ($body->isSeekable()) { + $body->seek(0); + } + + return $psrResponse->withBody($body); + } catch (TransportExceptionInterface $e) { + if ($e instanceof \InvalidArgumentException) { + throw new Psr18RequestException($e, $request); + } + + throw new Psr18NetworkException($e, $request); + } + } + + /** + * {@inheritdoc} + */ + public function createRequest(string $method, $uri): RequestInterface + { + if ($this->responseFactory instanceof RequestFactoryInterface) { + return $this->responseFactory->createRequest($method, $uri); + } + + if (class_exists(Request::class)) { + return new Request($method, $uri); + } + + if (class_exists(Psr17FactoryDiscovery::class)) { + return Psr17FactoryDiscovery::findRequestFactory()->createRequest($method, $uri); + } + + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + /** + * {@inheritdoc} + */ + public function createStream(string $content = ''): StreamInterface + { + $stream = $this->streamFactory->createStream($content); + + if ($stream->isSeekable()) { + $stream->seek(0); + } + + return $stream; + } + + /** + * {@inheritdoc} + */ + public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface + { + return $this->streamFactory->createStreamFromFile($filename, $mode); + } + + /** + * {@inheritdoc} + */ + public function createStreamFromResource($resource): StreamInterface + { + return $this->streamFactory->createStreamFromResource($resource); + } + + /** + * {@inheritdoc} + */ + public function createUri(string $uri = ''): UriInterface + { + if ($this->responseFactory instanceof UriFactoryInterface) { + return $this->responseFactory->createUri($uri); + } + + if (class_exists(Uri::class)) { + return new Uri($uri); + } + + if (class_exists(Psr17FactoryDiscovery::class)) { + return Psr17FactoryDiscovery::findUrlFactory()->createUri($uri); + } + + throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__)); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } +} + +/** + * @internal + */ +class Psr18NetworkException extends \RuntimeException implements NetworkExceptionInterface +{ + private $request; + + public function __construct(TransportExceptionInterface $e, RequestInterface $request) + { + parent::__construct($e->getMessage(), 0, $e); + $this->request = $request; + } + + public function getRequest(): RequestInterface + { + return $this->request; + } +} + +/** + * @internal + */ +class Psr18RequestException extends \InvalidArgumentException implements RequestExceptionInterface +{ + private $request; + + public function __construct(TransportExceptionInterface $e, RequestInterface $request) + { + parent::__construct($e->getMessage(), 0, $e); + $this->request = $request; + } + + public function getRequest(): RequestInterface + { + return $this->request; + } +} diff --git a/vendor/symfony/http-client/README.md b/vendor/symfony/http-client/README.md new file mode 100644 index 000000000..0c55ccc11 --- /dev/null +++ b/vendor/symfony/http-client/README.md @@ -0,0 +1,27 @@ +HttpClient component +==================== + +The HttpClient component provides powerful methods to fetch HTTP resources synchronously or asynchronously. + +Sponsor +------- + +The Httpclient component for Symfony 5.4/6.0 is [backed][1] by [Klaxoon][2]. + +Klaxoon is a platform that empowers organizations to run effective and +productive workshops easily in a hybrid environment. Anytime, Anywhere. + +Help Symfony by [sponsoring][3] its development! + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/http_client.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) + +[1]: https://symfony.com/backers +[2]: https://klaxoon.com +[3]: https://symfony.com/sponsor diff --git a/vendor/symfony/http-client/Response/AmpResponse.php b/vendor/symfony/http-client/Response/AmpResponse.php new file mode 100644 index 000000000..900c70d6e --- /dev/null +++ b/vendor/symfony/http-client/Response/AmpResponse.php @@ -0,0 +1,460 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Amp\ByteStream\StreamException; +use Amp\CancellationTokenSource; +use Amp\Coroutine; +use Amp\Deferred; +use Amp\Http\Client\HttpException; +use Amp\Http\Client\Request; +use Amp\Http\Client\Response; +use Amp\Loop; +use Amp\Promise; +use Amp\Success; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\InformationalChunk; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\HttpClientTrait; +use Symfony\Component\HttpClient\Internal\AmpBody; +use Symfony\Component\HttpClient\Internal\AmpClientState; +use Symfony\Component\HttpClient\Internal\Canary; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class AmpResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + use TransportResponseTrait; + + private static $nextId = 'a'; + + private $multi; + private $options; + private $onProgress; + + private static $delay; + + /** + * @internal + */ + public function __construct(AmpClientState $multi, Request $request, array $options, ?LoggerInterface $logger) + { + $this->multi = $multi; + $this->options = &$options; + $this->logger = $logger; + $this->timeout = $options['timeout']; + $this->shouldBuffer = $options['buffer']; + + if ($this->inflate = \extension_loaded('zlib') && !$request->hasHeader('accept-encoding')) { + $request->setHeader('Accept-Encoding', 'gzip'); + } + + $this->initializer = static function (self $response) { + return null !== $response->options; + }; + + $info = &$this->info; + $headers = &$this->headers; + $canceller = new CancellationTokenSource(); + $handle = &$this->handle; + + $info['url'] = (string) $request->getUri(); + $info['http_method'] = $request->getMethod(); + $info['start_time'] = null; + $info['redirect_url'] = null; + $info['redirect_time'] = 0.0; + $info['redirect_count'] = 0; + $info['size_upload'] = 0.0; + $info['size_download'] = 0.0; + $info['upload_content_length'] = -1.0; + $info['download_content_length'] = -1.0; + $info['user_data'] = $options['user_data']; + $info['max_duration'] = $options['max_duration']; + $info['debug'] = ''; + + $onProgress = $options['on_progress'] ?? static function () {}; + $onProgress = $this->onProgress = static function () use (&$info, $onProgress) { + $info['total_time'] = microtime(true) - $info['start_time']; + $onProgress((int) $info['size_download'], ((int) (1 + $info['download_content_length']) ?: 1) - 1, (array) $info); + }; + + $pauseDeferred = new Deferred(); + $pause = new Success(); + + $throttleWatcher = null; + + $this->id = $id = self::$nextId++; + Loop::defer(static function () use ($request, $multi, &$id, &$info, &$headers, $canceller, &$options, $onProgress, &$handle, $logger, &$pause) { + return new Coroutine(self::generateResponse($request, $multi, $id, $info, $headers, $canceller, $options, $onProgress, $handle, $logger, $pause)); + }); + + $info['pause_handler'] = static function (float $duration) use (&$throttleWatcher, &$pauseDeferred, &$pause) { + if (null !== $throttleWatcher) { + Loop::cancel($throttleWatcher); + } + + $pause = $pauseDeferred->promise(); + + if ($duration <= 0) { + $deferred = $pauseDeferred; + $pauseDeferred = new Deferred(); + $deferred->resolve(); + } else { + $throttleWatcher = Loop::delay(ceil(1000 * $duration), static function () use (&$pauseDeferred) { + $deferred = $pauseDeferred; + $pauseDeferred = new Deferred(); + $deferred->resolve(); + }); + } + }; + + $multi->lastTimeout = null; + $multi->openHandles[$id] = $id; + ++$multi->responseCount; + + $this->canary = new Canary(static function () use ($canceller, $multi, $id) { + $canceller->cancel(); + unset($multi->openHandles[$id], $multi->handlesActivity[$id]); + }); + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + return null !== $type ? $this->info[$type] ?? null : $this->info; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + try { + $this->doDestruct(); + } finally { + // Clear the DNS cache when all requests completed + if (0 >= --$this->multi->responseCount) { + $this->multi->responseCount = 0; + $this->multi->dnsCache = []; + } + } + } + + /** + * {@inheritdoc} + */ + private static function schedule(self $response, array &$runningResponses): void + { + if (isset($runningResponses[0])) { + $runningResponses[0][1][$response->id] = $response; + } else { + $runningResponses[0] = [$response->multi, [$response->id => $response]]; + } + + if (!isset($response->multi->openHandles[$response->id])) { + $response->multi->handlesActivity[$response->id][] = null; + $response->multi->handlesActivity[$response->id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } + } + + /** + * {@inheritdoc} + * + * @param AmpClientState $multi + */ + private static function perform(ClientState $multi, array &$responses = null): void + { + if ($responses) { + foreach ($responses as $response) { + try { + if ($response->info['start_time']) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + ($response->onProgress)(); + } + } catch (\Throwable $e) { + $multi->handlesActivity[$response->id][] = null; + $multi->handlesActivity[$response->id][] = $e; + } + } + } + } + + /** + * {@inheritdoc} + * + * @param AmpClientState $multi + */ + private static function select(ClientState $multi, float $timeout): int + { + $timeout += microtime(true); + self::$delay = Loop::defer(static function () use ($timeout) { + if (0 < $timeout -= microtime(true)) { + self::$delay = Loop::delay(ceil(1000 * $timeout), [Loop::class, 'stop']); + } else { + Loop::stop(); + } + }); + + Loop::run(); + + return null === self::$delay ? 1 : 0; + } + + private static function generateResponse(Request $request, AmpClientState $multi, string $id, array &$info, array &$headers, CancellationTokenSource $canceller, array &$options, \Closure $onProgress, &$handle, ?LoggerInterface $logger, Promise &$pause) + { + $request->setInformationalResponseHandler(static function (Response $response) use ($multi, $id, &$info, &$headers) { + self::addResponseHeaders($response, $info, $headers); + $multi->handlesActivity[$id][] = new InformationalChunk($response->getStatus(), $response->getHeaders()); + self::stopLoop(); + }); + + try { + /* @var Response $response */ + if (null === $response = yield from self::getPushedResponse($request, $multi, $info, $headers, $options, $logger)) { + $logger && $logger->info(sprintf('Request: "%s %s"', $info['http_method'], $info['url'])); + + $response = yield from self::followRedirects($request, $multi, $info, $headers, $canceller, $options, $onProgress, $handle, $logger, $pause); + } + + $options = null; + + $multi->handlesActivity[$id][] = new FirstChunk(); + + if ('HEAD' === $response->getRequest()->getMethod() || \in_array($info['http_code'], [204, 304], true)) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null; + self::stopLoop(); + + return; + } + + if ($response->hasHeader('content-length')) { + $info['download_content_length'] = (float) $response->getHeader('content-length'); + } + + $body = $response->getBody(); + + while (true) { + self::stopLoop(); + + yield $pause; + + if (null === $data = yield $body->read()) { + break; + } + + $info['size_download'] += \strlen($data); + $multi->handlesActivity[$id][] = $data; + } + + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null; + } catch (\Throwable $e) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = $e; + } finally { + $info['download_content_length'] = $info['size_download']; + } + + self::stopLoop(); + } + + private static function followRedirects(Request $originRequest, AmpClientState $multi, array &$info, array &$headers, CancellationTokenSource $canceller, array $options, \Closure $onProgress, &$handle, ?LoggerInterface $logger, Promise &$pause) + { + yield $pause; + + $originRequest->setBody(new AmpBody($options['body'], $info, $onProgress)); + $response = yield $multi->request($options, $originRequest, $canceller->getToken(), $info, $onProgress, $handle); + $previousUrl = null; + + while (true) { + self::addResponseHeaders($response, $info, $headers); + $status = $response->getStatus(); + + if (!\in_array($status, [301, 302, 303, 307, 308], true) || null === $location = $response->getHeader('location')) { + return $response; + } + + $urlResolver = new class() { + use HttpClientTrait { + parseUrl as public; + resolveUrl as public; + } + }; + + try { + $previousUrl = $previousUrl ?? $urlResolver::parseUrl($info['url']); + $location = $urlResolver::parseUrl($location); + $location = $urlResolver::resolveUrl($location, $previousUrl); + $info['redirect_url'] = implode('', $location); + } catch (InvalidArgumentException $e) { + return $response; + } + + if (0 >= $options['max_redirects'] || $info['redirect_count'] >= $options['max_redirects']) { + return $response; + } + + $logger && $logger->info(sprintf('Redirecting: "%s %s"', $status, $info['url'])); + + try { + // Discard body of redirects + while (null !== yield $response->getBody()->read()) { + } + } catch (HttpException|StreamException $e) { + // Ignore streaming errors on previous responses + } + + ++$info['redirect_count']; + $info['url'] = $info['redirect_url']; + $info['redirect_url'] = null; + $previousUrl = $location; + + $request = new Request($info['url'], $info['http_method']); + $request->setProtocolVersions($originRequest->getProtocolVersions()); + $request->setTcpConnectTimeout($originRequest->getTcpConnectTimeout()); + $request->setTlsHandshakeTimeout($originRequest->getTlsHandshakeTimeout()); + $request->setTransferTimeout($originRequest->getTransferTimeout()); + + if (\in_array($status, [301, 302, 303], true)) { + $originRequest->removeHeader('transfer-encoding'); + $originRequest->removeHeader('content-length'); + $originRequest->removeHeader('content-type'); + + // Do like curl and browsers: turn POST to GET on 301, 302 and 303 + if ('POST' === $response->getRequest()->getMethod() || 303 === $status) { + $info['http_method'] = 'HEAD' === $response->getRequest()->getMethod() ? 'HEAD' : 'GET'; + $request->setMethod($info['http_method']); + } + } else { + $request->setBody(AmpBody::rewind($response->getRequest()->getBody())); + } + + foreach ($originRequest->getRawHeaders() as [$name, $value]) { + $request->addHeader($name, $value); + } + + if ($request->getUri()->getAuthority() !== $originRequest->getUri()->getAuthority()) { + $request->removeHeader('authorization'); + $request->removeHeader('cookie'); + $request->removeHeader('host'); + } + + yield $pause; + + $response = yield $multi->request($options, $request, $canceller->getToken(), $info, $onProgress, $handle); + $info['redirect_time'] = microtime(true) - $info['start_time']; + } + } + + private static function addResponseHeaders(Response $response, array &$info, array &$headers): void + { + $info['http_code'] = $response->getStatus(); + + if ($headers) { + $info['debug'] .= "< \r\n"; + $headers = []; + } + + $h = sprintf('HTTP/%s %s %s', $response->getProtocolVersion(), $response->getStatus(), $response->getReason()); + $info['debug'] .= "< {$h}\r\n"; + $info['response_headers'][] = $h; + + foreach ($response->getRawHeaders() as [$name, $value]) { + $headers[strtolower($name)][] = $value; + $h = $name.': '.$value; + $info['debug'] .= "< {$h}\r\n"; + $info['response_headers'][] = $h; + } + + $info['debug'] .= "< \r\n"; + } + + /** + * Accepts pushed responses only if their headers related to authentication match the request. + */ + private static function getPushedResponse(Request $request, AmpClientState $multi, array &$info, array &$headers, array $options, ?LoggerInterface $logger) + { + if ('' !== $options['body']) { + return null; + } + + $authority = $request->getUri()->getAuthority(); + + foreach ($multi->pushedResponses[$authority] ?? [] as $i => [$pushedUrl, $pushDeferred, $pushedRequest, $pushedResponse, $parentOptions]) { + if ($info['url'] !== $pushedUrl || $info['http_method'] !== $pushedRequest->getMethod()) { + continue; + } + + foreach ($parentOptions as $k => $v) { + if ($options[$k] !== $v) { + continue 2; + } + } + + foreach (['authorization', 'cookie', 'range', 'proxy-authorization'] as $k) { + if ($pushedRequest->getHeaderArray($k) !== $request->getHeaderArray($k)) { + continue 2; + } + } + + $response = yield $pushedResponse; + + foreach ($response->getHeaderArray('vary') as $vary) { + foreach (preg_split('/\s*+,\s*+/', $vary) as $v) { + if ('*' === $v || ($pushedRequest->getHeaderArray($v) !== $request->getHeaderArray($v) && 'accept-encoding' !== strtolower($v))) { + $logger && $logger->debug(sprintf('Skipping pushed response: "%s"', $info['url'])); + continue 3; + } + } + } + + $pushDeferred->resolve(); + $logger && $logger->debug(sprintf('Accepting pushed response: "%s %s"', $info['http_method'], $info['url'])); + self::addResponseHeaders($response, $info, $headers); + unset($multi->pushedResponses[$authority][$i]); + + if (!$multi->pushedResponses[$authority]) { + unset($multi->pushedResponses[$authority]); + } + + return $response; + } + } + + private static function stopLoop(): void + { + if (null !== self::$delay) { + Loop::cancel(self::$delay); + self::$delay = null; + } + + Loop::defer([Loop::class, 'stop']); + } +} diff --git a/vendor/symfony/http-client/Response/AsyncContext.php b/vendor/symfony/http-client/Response/AsyncContext.php new file mode 100644 index 000000000..646458e13 --- /dev/null +++ b/vendor/symfony/http-client/Response/AsyncContext.php @@ -0,0 +1,195 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\DataChunk; +use Symfony\Component\HttpClient\Chunk\LastChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * A DTO to work with AsyncResponse. + * + * @author Nicolas Grekas + */ +final class AsyncContext +{ + private $passthru; + private $client; + private $response; + private $info = []; + private $content; + private $offset; + + public function __construct(&$passthru, HttpClientInterface $client, ResponseInterface &$response, array &$info, $content, int $offset) + { + $this->passthru = &$passthru; + $this->client = $client; + $this->response = &$response; + $this->info = &$info; + $this->content = $content; + $this->offset = $offset; + } + + /** + * Returns the HTTP status without consuming the response. + */ + public function getStatusCode(): int + { + return $this->response->getInfo('http_code'); + } + + /** + * Returns the headers without consuming the response. + */ + public function getHeaders(): array + { + $headers = []; + + foreach ($this->response->getInfo('response_headers') as $h) { + if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? ([123456789]\d\d)(?: |$)#', $h, $m)) { + $headers = []; + } elseif (2 === \count($m = explode(':', $h, 2))) { + $headers[strtolower($m[0])][] = ltrim($m[1]); + } + } + + return $headers; + } + + /** + * @return resource|null The PHP stream resource where the content is buffered, if it is + */ + public function getContent() + { + return $this->content; + } + + /** + * Creates a new chunk of content. + */ + public function createChunk(string $data): ChunkInterface + { + return new DataChunk($this->offset, $data); + } + + /** + * Pauses the request for the given number of seconds. + */ + public function pause(float $duration): void + { + if (\is_callable($pause = $this->response->getInfo('pause_handler'))) { + $pause($duration); + } elseif (0 < $duration) { + usleep(1E6 * $duration); + } + } + + /** + * Cancels the request and returns the last chunk to yield. + */ + public function cancel(): ChunkInterface + { + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + $this->response->cancel(); + + return new LastChunk(); + } + + /** + * Returns the current info of the response. + */ + public function getInfo(string $type = null) + { + if (null !== $type) { + return $this->info[$type] ?? $this->response->getInfo($type); + } + + return $this->info + $this->response->getInfo(); + } + + /** + * Attaches an info to the response. + * + * @return $this + */ + public function setInfo(string $type, $value): self + { + if ('canceled' === $type && $value !== $this->info['canceled']) { + throw new \LogicException('You cannot set the "canceled" info directly.'); + } + + if (null === $value) { + unset($this->info[$type]); + } else { + $this->info[$type] = $value; + } + + return $this; + } + + /** + * Returns the currently processed response. + */ + public function getResponse(): ResponseInterface + { + return $this->response; + } + + /** + * Replaces the currently processed response by doing a new request. + */ + public function replaceRequest(string $method, string $url, array $options = []): ResponseInterface + { + $this->info['previous_info'][] = $info = $this->response->getInfo(); + if (null !== $onProgress = $options['on_progress'] ?? null) { + $thisInfo = &$this->info; + $options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) { + $onProgress($dlNow, $dlSize, $thisInfo + $info); + }; + } + if (0 < ($info['max_duration'] ?? 0) && 0 < ($info['total_time'] ?? 0)) { + if (0 >= $options['max_duration'] = $info['max_duration'] - $info['total_time']) { + throw new TransportException(sprintf('Max duration was reached for "%s".', $info['url'])); + } + } + + return $this->response = $this->client->request($method, $url, ['buffer' => false] + $options); + } + + /** + * Replaces the currently processed response by another one. + */ + public function replaceResponse(ResponseInterface $response): ResponseInterface + { + $this->info['previous_info'][] = $this->response->getInfo(); + + return $this->response = $response; + } + + /** + * Replaces or removes the chunk filter iterator. + * + * @param ?callable(ChunkInterface, self): ?\Iterator $passthru + */ + public function passthru(callable $passthru = null): void + { + $this->passthru = $passthru ?? static function ($chunk, $context) { + $context->passthru = null; + + yield $chunk; + }; + } +} diff --git a/vendor/symfony/http-client/Response/AsyncResponse.php b/vendor/symfony/http-client/Response/AsyncResponse.php new file mode 100644 index 000000000..80c9f7da3 --- /dev/null +++ b/vendor/symfony/http-client/Response/AsyncResponse.php @@ -0,0 +1,478 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\LastChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * Provides a single extension point to process a response's content stream. + * + * @author Nicolas Grekas + */ +final class AsyncResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + + private const FIRST_CHUNK_YIELDED = 1; + private const LAST_CHUNK_YIELDED = 2; + + private $client; + private $response; + private $info = ['canceled' => false]; + private $passthru; + private $stream; + private $yieldedState; + + /** + * @param ?callable(ChunkInterface, AsyncContext): ?\Iterator $passthru + */ + public function __construct(HttpClientInterface $client, string $method, string $url, array $options, callable $passthru = null) + { + $this->client = $client; + $this->shouldBuffer = $options['buffer'] ?? true; + + if (null !== $onProgress = $options['on_progress'] ?? null) { + $thisInfo = &$this->info; + $options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) { + $onProgress($dlNow, $dlSize, $thisInfo + $info); + }; + } + $this->response = $client->request($method, $url, ['buffer' => false] + $options); + $this->passthru = $passthru; + $this->initializer = static function (self $response, float $timeout = null) { + if (null === $response->shouldBuffer) { + return false; + } + + while (true) { + foreach (self::stream([$response], $timeout) as $chunk) { + if ($chunk->isTimeout() && $response->passthru) { + foreach (self::passthru($response->client, $response, new ErrorChunk($response->offset, new TransportException($chunk->getError()))) as $chunk) { + if ($chunk->isFirst()) { + return false; + } + } + + continue 2; + } + + if ($chunk->isFirst()) { + return false; + } + } + + return false; + } + }; + if (\array_key_exists('user_data', $options)) { + $this->info['user_data'] = $options['user_data']; + } + if (\array_key_exists('max_duration', $options)) { + $this->info['max_duration'] = $options['max_duration']; + } + } + + public function getStatusCode(): int + { + if ($this->initializer) { + self::initialize($this); + } + + return $this->response->getStatusCode(); + } + + public function getHeaders(bool $throw = true): array + { + if ($this->initializer) { + self::initialize($this); + } + + $headers = $this->response->getHeaders(false); + + if ($throw) { + $this->checkStatusCode(); + } + + return $headers; + } + + public function getInfo(string $type = null) + { + if (null !== $type) { + return $this->info[$type] ?? $this->response->getInfo($type); + } + + return $this->info + $this->response->getInfo(); + } + + /** + * {@inheritdoc} + */ + public function toStream(bool $throw = true) + { + if ($throw) { + // Ensure headers arrived + $this->getHeaders(true); + } + + $handle = function () { + $stream = $this->response instanceof StreamableInterface ? $this->response->toStream(false) : StreamWrapper::createResource($this->response); + + return stream_get_meta_data($stream)['wrapper_data']->stream_cast(\STREAM_CAST_FOR_SELECT); + }; + + $stream = StreamWrapper::createResource($this); + stream_get_meta_data($stream)['wrapper_data'] + ->bindHandles($handle, $this->content); + + return $stream; + } + + /** + * {@inheritdoc} + */ + public function cancel(): void + { + if ($this->info['canceled']) { + return; + } + + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + $this->close(); + $client = $this->client; + $this->client = null; + + if (!$this->passthru) { + return; + } + + try { + foreach (self::passthru($client, $this, new LastChunk()) as $chunk) { + // no-op + } + + $this->passthru = null; + } catch (ExceptionInterface $e) { + // ignore any errors when canceling + } + } + + public function __destruct() + { + $httpException = null; + + if ($this->initializer && null === $this->getInfo('error')) { + try { + self::initialize($this, -0.0); + $this->getHeaders(true); + } catch (HttpExceptionInterface $httpException) { + // no-op + } + } + + if ($this->passthru && null === $this->getInfo('error')) { + $this->info['canceled'] = true; + + try { + foreach (self::passthru($this->client, $this, new LastChunk()) as $chunk) { + // no-op + } + } catch (ExceptionInterface $e) { + // ignore any errors when destructing + } + } + + if (null !== $httpException) { + throw $httpException; + } + } + + /** + * @internal + */ + public static function stream(iterable $responses, float $timeout = null, string $class = null): \Generator + { + while ($responses) { + $wrappedResponses = []; + $asyncMap = new \SplObjectStorage(); + $client = null; + + foreach ($responses as $r) { + if (!$r instanceof self) { + throw new \TypeError(sprintf('"%s::stream()" expects parameter 1 to be an iterable of AsyncResponse objects, "%s" given.', $class ?? static::class, get_debug_type($r))); + } + + if (null !== $e = $r->info['error'] ?? null) { + yield $r => $chunk = new ErrorChunk($r->offset, new TransportException($e)); + $chunk->didThrow() ?: $chunk->getContent(); + continue; + } + + if (null === $client) { + $client = $r->client; + } elseif ($r->client !== $client) { + throw new TransportException('Cannot stream AsyncResponse objects with many clients.'); + } + + $asyncMap[$r->response] = $r; + $wrappedResponses[] = $r->response; + + if ($r->stream) { + yield from self::passthruStream($response = $r->response, $r, new FirstChunk(), $asyncMap); + + if (!isset($asyncMap[$response])) { + array_pop($wrappedResponses); + } + + if ($r->response !== $response && !isset($asyncMap[$r->response])) { + $asyncMap[$r->response] = $r; + $wrappedResponses[] = $r->response; + } + } + } + + if (!$client || !$wrappedResponses) { + return; + } + + foreach ($client->stream($wrappedResponses, $timeout) as $response => $chunk) { + $r = $asyncMap[$response]; + + if (null === $chunk->getError()) { + if ($chunk->isFirst()) { + // Ensure no exception is thrown on destruct for the wrapped response + $r->response->getStatusCode(); + } elseif (0 === $r->offset && null === $r->content && $chunk->isLast()) { + $r->content = fopen('php://memory', 'w+'); + } + } + + if (!$r->passthru) { + if (null !== $chunk->getError() || $chunk->isLast()) { + unset($asyncMap[$response]); + } elseif (null !== $r->content && '' !== ($content = $chunk->getContent()) && \strlen($content) !== fwrite($r->content, $content)) { + $chunk = new ErrorChunk($r->offset, new TransportException(sprintf('Failed writing %d bytes to the response buffer.', \strlen($content)))); + $r->info['error'] = $chunk->getError(); + $r->response->cancel(); + } + + yield $r => $chunk; + continue; + } + + if (null !== $chunk->getError()) { + // no-op + } elseif ($chunk->isFirst()) { + $r->yieldedState = self::FIRST_CHUNK_YIELDED; + } elseif (self::FIRST_CHUNK_YIELDED !== $r->yieldedState && null === $chunk->getInformationalStatus()) { + throw new \LogicException(sprintf('Instance of "%s" is already consumed and cannot be managed by "%s". A decorated client should not call any of the response\'s methods in its "request()" method.', get_debug_type($response), $class ?? static::class)); + } + + foreach (self::passthru($r->client, $r, $chunk, $asyncMap) as $chunk) { + yield $r => $chunk; + } + + if ($r->response !== $response && isset($asyncMap[$response])) { + break; + } + } + + if (null === $chunk->getError() && $chunk->isLast()) { + $r->yieldedState = self::LAST_CHUNK_YIELDED; + } + if (null === $chunk->getError() && self::LAST_CHUNK_YIELDED !== $r->yieldedState && $r->response === $response && null !== $r->client) { + throw new \LogicException('A chunk passthru must yield an "isLast()" chunk before ending a stream.'); + } + + $responses = []; + foreach ($asyncMap as $response) { + $r = $asyncMap[$response]; + + if (null !== $r->client) { + $responses[] = $asyncMap[$response]; + } + } + } + } + + /** + * @param \SplObjectStorage|null $asyncMap + */ + private static function passthru(HttpClientInterface $client, self $r, ChunkInterface $chunk, \SplObjectStorage $asyncMap = null): \Generator + { + $r->stream = null; + $response = $r->response; + $context = new AsyncContext($r->passthru, $client, $r->response, $r->info, $r->content, $r->offset); + if (null === $stream = ($r->passthru)($chunk, $context)) { + if ($r->response === $response && (null !== $chunk->getError() || $chunk->isLast())) { + throw new \LogicException('A chunk passthru cannot swallow the last chunk.'); + } + + return; + } + + if (!$stream instanceof \Iterator) { + throw new \LogicException(sprintf('A chunk passthru must return an "Iterator", "%s" returned.', get_debug_type($stream))); + } + $r->stream = $stream; + + yield from self::passthruStream($response, $r, null, $asyncMap); + } + + /** + * @param \SplObjectStorage|null $asyncMap + */ + private static function passthruStream(ResponseInterface $response, self $r, ?ChunkInterface $chunk, ?\SplObjectStorage $asyncMap): \Generator + { + while (true) { + try { + if (null !== $chunk && $r->stream) { + $r->stream->next(); + } + + if (!$r->stream || !$r->stream->valid() || !$r->stream) { + $r->stream = null; + break; + } + } catch (\Throwable $e) { + unset($asyncMap[$response]); + $r->stream = null; + $r->info['error'] = $e->getMessage(); + $r->response->cancel(); + + yield $r => $chunk = new ErrorChunk($r->offset, $e); + $chunk->didThrow() ?: $chunk->getContent(); + break; + } + + $chunk = $r->stream->current(); + + if (!$chunk instanceof ChunkInterface) { + throw new \LogicException(sprintf('A chunk passthru must yield instances of "%s", "%s" yielded.', ChunkInterface::class, get_debug_type($chunk))); + } + + if (null !== $chunk->getError()) { + // no-op + } elseif ($chunk->isFirst()) { + $e = $r->openBuffer(); + + yield $r => $chunk; + + if ($r->initializer && null === $r->getInfo('error')) { + // Ensure the HTTP status code is always checked + $r->getHeaders(true); + } + + if (null === $e) { + continue; + } + + $r->response->cancel(); + $chunk = new ErrorChunk($r->offset, $e); + } elseif ('' !== $content = $chunk->getContent()) { + if (null !== $r->shouldBuffer) { + throw new \LogicException('A chunk passthru must yield an "isFirst()" chunk before any content chunk.'); + } + + if (null !== $r->content && \strlen($content) !== fwrite($r->content, $content)) { + $chunk = new ErrorChunk($r->offset, new TransportException(sprintf('Failed writing %d bytes to the response buffer.', \strlen($content)))); + $r->info['error'] = $chunk->getError(); + $r->response->cancel(); + } + } + + if (null !== $chunk->getError() || $chunk->isLast()) { + $stream = $r->stream; + $r->stream = null; + unset($asyncMap[$response]); + } + + if (null === $chunk->getError()) { + $r->offset += \strlen($content); + + yield $r => $chunk; + + if (!$chunk->isLast()) { + continue; + } + + $stream->next(); + + if ($stream->valid()) { + throw new \LogicException('A chunk passthru cannot yield after an "isLast()" chunk.'); + } + + $r->passthru = null; + } else { + if ($chunk instanceof ErrorChunk) { + $chunk->didThrow(false); + } else { + try { + $chunk = new ErrorChunk($chunk->getOffset(), !$chunk->isTimeout() ?: $chunk->getError()); + } catch (TransportExceptionInterface $e) { + $chunk = new ErrorChunk($chunk->getOffset(), $e); + } + } + + yield $r => $chunk; + $chunk->didThrow() ?: $chunk->getContent(); + } + + break; + } + } + + private function openBuffer(): ?\Throwable + { + if (null === $shouldBuffer = $this->shouldBuffer) { + throw new \LogicException('A chunk passthru cannot yield more than one "isFirst()" chunk.'); + } + + $e = $this->shouldBuffer = null; + + if ($shouldBuffer instanceof \Closure) { + try { + $shouldBuffer = $shouldBuffer($this->getHeaders(false)); + + if (null !== $e = $this->response->getInfo('error')) { + throw new TransportException($e); + } + } catch (\Throwable $e) { + $this->info['error'] = $e->getMessage(); + $this->response->cancel(); + } + } + + if (true === $shouldBuffer) { + $this->content = fopen('php://temp', 'w+'); + } elseif (\is_resource($shouldBuffer)) { + $this->content = $shouldBuffer; + } + + return $e; + } + + private function close(): void + { + $this->response->cancel(); + } +} diff --git a/vendor/symfony/http-client/Response/CommonResponseTrait.php b/vendor/symfony/http-client/Response/CommonResponseTrait.php new file mode 100644 index 000000000..11a8d6ca7 --- /dev/null +++ b/vendor/symfony/http-client/Response/CommonResponseTrait.php @@ -0,0 +1,185 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Exception\ClientException; +use Symfony\Component\HttpClient\Exception\JsonException; +use Symfony\Component\HttpClient\Exception\RedirectionException; +use Symfony\Component\HttpClient\Exception\ServerException; +use Symfony\Component\HttpClient\Exception\TransportException; + +/** + * Implements common logic for response classes. + * + * @author Nicolas Grekas + * + * @internal + */ +trait CommonResponseTrait +{ + /** + * @var callable|null A callback that tells whether we're waiting for response headers + */ + private $initializer; + private $shouldBuffer; + private $content; + private $offset = 0; + private $jsonData; + + /** + * {@inheritdoc} + */ + public function getContent(bool $throw = true): string + { + if ($this->initializer) { + self::initialize($this); + } + + if ($throw) { + $this->checkStatusCode(); + } + + if (null === $this->content) { + $content = null; + + foreach (self::stream([$this]) as $chunk) { + if (!$chunk->isLast()) { + $content .= $chunk->getContent(); + } + } + + if (null !== $content) { + return $content; + } + + if (null === $this->content) { + throw new TransportException('Cannot get the content of the response twice: buffering is disabled.'); + } + } else { + foreach (self::stream([$this]) as $chunk) { + // Chunks are buffered in $this->content already + } + } + + rewind($this->content); + + return stream_get_contents($this->content); + } + + /** + * {@inheritdoc} + */ + public function toArray(bool $throw = true): array + { + if ('' === $content = $this->getContent($throw)) { + throw new JsonException('Response body is empty.'); + } + + if (null !== $this->jsonData) { + return $this->jsonData; + } + + try { + $content = json_decode($content, true, 512, \JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? \JSON_THROW_ON_ERROR : 0)); + } catch (\JsonException $e) { + throw new JsonException($e->getMessage().sprintf(' for "%s".', $this->getInfo('url')), $e->getCode()); + } + + if (\PHP_VERSION_ID < 70300 && \JSON_ERROR_NONE !== json_last_error()) { + throw new JsonException(json_last_error_msg().sprintf(' for "%s".', $this->getInfo('url')), json_last_error()); + } + + if (!\is_array($content)) { + throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned for "%s".', get_debug_type($content), $this->getInfo('url'))); + } + + if (null !== $this->content) { + // Option "buffer" is true + return $this->jsonData = $content; + } + + return $content; + } + + /** + * {@inheritdoc} + */ + public function toStream(bool $throw = true) + { + if ($throw) { + // Ensure headers arrived + $this->getHeaders($throw); + } + + $stream = StreamWrapper::createResource($this); + stream_get_meta_data($stream)['wrapper_data'] + ->bindHandles($this->handle, $this->content); + + return $stream; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + /** + * Closes the response and all its network handles. + */ + abstract protected function close(): void; + + private static function initialize(self $response): void + { + if (null !== $response->getInfo('error')) { + throw new TransportException($response->getInfo('error')); + } + + try { + if (($response->initializer)($response, -0.0)) { + foreach (self::stream([$response], -0.0) as $chunk) { + if ($chunk->isFirst()) { + break; + } + } + } + } catch (\Throwable $e) { + // Persist timeouts thrown during initialization + $response->info['error'] = $e->getMessage(); + $response->close(); + throw $e; + } + + $response->initializer = null; + } + + private function checkStatusCode() + { + $code = $this->getInfo('http_code'); + + if (500 <= $code) { + throw new ServerException($this); + } + + if (400 <= $code) { + throw new ClientException($this); + } + + if (300 <= $code) { + throw new RedirectionException($this); + } + } +} diff --git a/vendor/symfony/http-client/Response/CurlResponse.php b/vendor/symfony/http-client/Response/CurlResponse.php new file mode 100644 index 000000000..241820306 --- /dev/null +++ b/vendor/symfony/http-client/Response/CurlResponse.php @@ -0,0 +1,473 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\InformationalChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\Canary; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Component\HttpClient\Internal\CurlClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class CurlResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait { + getContent as private doGetContent; + } + use TransportResponseTrait; + + private $multi; + private $debugBuffer; + + /** + * @param \CurlHandle|resource|string $ch + * + * @internal + */ + public function __construct(CurlClientState $multi, $ch, array $options = null, LoggerInterface $logger = null, string $method = 'GET', callable $resolveRedirect = null, int $curlVersion = null) + { + $this->multi = $multi; + + if (\is_resource($ch) || $ch instanceof \CurlHandle) { + $this->handle = $ch; + $this->debugBuffer = fopen('php://temp', 'w+'); + if (0x074000 === $curlVersion) { + fwrite($this->debugBuffer, 'Due to a bug in curl 7.64.0, the debug log is disabled; use another version to work around the issue.'); + } else { + curl_setopt($ch, \CURLOPT_VERBOSE, true); + curl_setopt($ch, \CURLOPT_STDERR, $this->debugBuffer); + } + } else { + $this->info['url'] = $ch; + $ch = $this->handle; + } + + $this->id = $id = (int) $ch; + $this->logger = $logger; + $this->shouldBuffer = $options['buffer'] ?? true; + $this->timeout = $options['timeout'] ?? null; + $this->info['http_method'] = $method; + $this->info['user_data'] = $options['user_data'] ?? null; + $this->info['max_duration'] = $options['max_duration'] ?? null; + $this->info['start_time'] = $this->info['start_time'] ?? microtime(true); + $info = &$this->info; + $headers = &$this->headers; + $debugBuffer = $this->debugBuffer; + + if (!$info['response_headers']) { + // Used to keep track of what we're waiting for + curl_setopt($ch, \CURLOPT_PRIVATE, \in_array($method, ['GET', 'HEAD', 'OPTIONS', 'TRACE'], true) && 1.0 < (float) ($options['http_version'] ?? 1.1) ? 'H2' : 'H0'); // H = headers + retry counter + } + + curl_setopt($ch, \CURLOPT_HEADERFUNCTION, static function ($ch, string $data) use (&$info, &$headers, $options, $multi, $id, &$location, $resolveRedirect, $logger): int { + return self::parseHeaderLine($ch, $data, $info, $headers, $options, $multi, $id, $location, $resolveRedirect, $logger); + }); + + if (null === $options) { + // Pushed response: buffer until requested + curl_setopt($ch, \CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int { + $multi->handlesActivity[$id][] = $data; + curl_pause($ch, \CURLPAUSE_RECV); + + return \strlen($data); + }); + + return; + } + + $execCounter = $multi->execCounter; + $this->info['pause_handler'] = static function (float $duration) use ($ch, $multi, $execCounter) { + if (0 < $duration) { + if ($execCounter === $multi->execCounter) { + $multi->execCounter = !\is_float($execCounter) ? 1 + $execCounter : \PHP_INT_MIN; + curl_multi_remove_handle($multi->handle, $ch); + } + + $lastExpiry = end($multi->pauseExpiries); + $multi->pauseExpiries[(int) $ch] = $duration += microtime(true); + if (false !== $lastExpiry && $lastExpiry > $duration) { + asort($multi->pauseExpiries); + } + curl_pause($ch, \CURLPAUSE_ALL); + } else { + unset($multi->pauseExpiries[(int) $ch]); + curl_pause($ch, \CURLPAUSE_CONT); + curl_multi_add_handle($multi->handle, $ch); + } + }; + + $this->inflate = !isset($options['normalized_headers']['accept-encoding']); + curl_pause($ch, \CURLPAUSE_CONT); + + if ($onProgress = $options['on_progress']) { + $url = isset($info['url']) ? ['url' => $info['url']] : []; + curl_setopt($ch, \CURLOPT_NOPROGRESS, false); + curl_setopt($ch, \CURLOPT_PROGRESSFUNCTION, static function ($ch, $dlSize, $dlNow) use ($onProgress, &$info, $url, $multi, $debugBuffer) { + try { + rewind($debugBuffer); + $debug = ['debug' => stream_get_contents($debugBuffer)]; + $onProgress($dlNow, $dlSize, $url + curl_getinfo($ch) + $info + $debug); + } catch (\Throwable $e) { + $multi->handlesActivity[(int) $ch][] = null; + $multi->handlesActivity[(int) $ch][] = $e; + + return 1; // Abort the request + } + + return null; + }); + } + + curl_setopt($ch, \CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int { + if ('H' === (curl_getinfo($ch, \CURLINFO_PRIVATE)[0] ?? null)) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = new TransportException(sprintf('Unsupported protocol for "%s"', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL))); + + return 0; + } + + curl_setopt($ch, \CURLOPT_WRITEFUNCTION, static function ($ch, string $data) use ($multi, $id): int { + $multi->handlesActivity[$id][] = $data; + + return \strlen($data); + }); + + $multi->handlesActivity[$id][] = $data; + + return \strlen($data); + }); + + $this->initializer = static function (self $response) { + $waitFor = curl_getinfo($ch = $response->handle, \CURLINFO_PRIVATE); + + return 'H' === $waitFor[0]; + }; + + // Schedule the request in a non-blocking way + $multi->lastTimeout = null; + $multi->openHandles[$id] = [$ch, $options]; + curl_multi_add_handle($multi->handle, $ch); + + $this->canary = new Canary(static function () use ($ch, $multi, $id) { + unset($multi->pauseExpiries[$id], $multi->openHandles[$id], $multi->handlesActivity[$id]); + curl_setopt($ch, \CURLOPT_PRIVATE, '_0'); + + if ($multi->performing) { + return; + } + + curl_multi_remove_handle($multi->handle, $ch); + curl_setopt_array($ch, [ + \CURLOPT_NOPROGRESS => true, + \CURLOPT_PROGRESSFUNCTION => null, + \CURLOPT_HEADERFUNCTION => null, + \CURLOPT_WRITEFUNCTION => null, + \CURLOPT_READFUNCTION => null, + \CURLOPT_INFILE => null, + ]); + + if (!$multi->openHandles) { + // Schedule DNS cache eviction for the next request + $multi->dnsCache->evictions = $multi->dnsCache->evictions ?: $multi->dnsCache->removals; + $multi->dnsCache->removals = $multi->dnsCache->hostnames = []; + } + }); + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + if (!$info = $this->finalInfo) { + $info = array_merge($this->info, curl_getinfo($this->handle)); + $info['url'] = $this->info['url'] ?? $info['url']; + $info['redirect_url'] = $this->info['redirect_url'] ?? null; + + // workaround curl not subtracting the time offset for pushed responses + if (isset($this->info['url']) && $info['start_time'] / 1000 < $info['total_time']) { + $info['total_time'] -= $info['starttransfer_time'] ?: $info['total_time']; + $info['starttransfer_time'] = 0.0; + } + + rewind($this->debugBuffer); + $info['debug'] = stream_get_contents($this->debugBuffer); + $waitFor = curl_getinfo($this->handle, \CURLINFO_PRIVATE); + + if ('H' !== $waitFor[0] && 'C' !== $waitFor[0]) { + curl_setopt($this->handle, \CURLOPT_VERBOSE, false); + rewind($this->debugBuffer); + ftruncate($this->debugBuffer, 0); + $this->finalInfo = $info; + } + } + + return null !== $type ? $info[$type] ?? null : $info; + } + + /** + * {@inheritdoc} + */ + public function getContent(bool $throw = true): string + { + $performing = $this->multi->performing; + $this->multi->performing = $performing || '_0' === curl_getinfo($this->handle, \CURLINFO_PRIVATE); + + try { + return $this->doGetContent($throw); + } finally { + $this->multi->performing = $performing; + } + } + + public function __destruct() + { + try { + if (null === $this->timeout) { + return; // Unused pushed response + } + + $this->doDestruct(); + } finally { + if (\is_resource($this->handle) || $this->handle instanceof \CurlHandle) { + curl_setopt($this->handle, \CURLOPT_VERBOSE, false); + } + } + } + + /** + * {@inheritdoc} + */ + private static function schedule(self $response, array &$runningResponses): void + { + if (isset($runningResponses[$i = (int) $response->multi->handle])) { + $runningResponses[$i][1][$response->id] = $response; + } else { + $runningResponses[$i] = [$response->multi, [$response->id => $response]]; + } + + if ('_0' === curl_getinfo($ch = $response->handle, \CURLINFO_PRIVATE)) { + // Response already completed + $response->multi->handlesActivity[$response->id][] = null; + $response->multi->handlesActivity[$response->id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } + } + + /** + * {@inheritdoc} + * + * @param CurlClientState $multi + */ + private static function perform(ClientState $multi, array &$responses = null): void + { + if ($multi->performing) { + if ($responses) { + $response = current($responses); + $multi->handlesActivity[(int) $response->handle][] = null; + $multi->handlesActivity[(int) $response->handle][] = new TransportException(sprintf('Userland callback cannot use the client nor the response while processing "%s".', curl_getinfo($response->handle, \CURLINFO_EFFECTIVE_URL))); + } + + return; + } + + try { + $multi->performing = true; + ++$multi->execCounter; + $active = 0; + while (\CURLM_CALL_MULTI_PERFORM === ($err = curl_multi_exec($multi->handle, $active))) { + } + + if (\CURLM_OK !== $err) { + throw new TransportException(curl_multi_strerror($err)); + } + + while ($info = curl_multi_info_read($multi->handle)) { + if (\CURLMSG_DONE !== $info['msg']) { + continue; + } + $result = $info['result']; + $id = (int) $ch = $info['handle']; + $waitFor = @curl_getinfo($ch, \CURLINFO_PRIVATE) ?: '_0'; + + if (\in_array($result, [\CURLE_SEND_ERROR, \CURLE_RECV_ERROR, /* CURLE_HTTP2 */ 16, /* CURLE_HTTP2_STREAM */ 92], true) && $waitFor[1] && 'C' !== $waitFor[0]) { + curl_multi_remove_handle($multi->handle, $ch); + $waitFor[1] = (string) ((int) $waitFor[1] - 1); // decrement the retry counter + curl_setopt($ch, \CURLOPT_PRIVATE, $waitFor); + curl_setopt($ch, \CURLOPT_FORBID_REUSE, true); + + if (0 === curl_multi_add_handle($multi->handle, $ch)) { + continue; + } + } + + if (\CURLE_RECV_ERROR === $result && 'H' === $waitFor[0] && 400 <= ($responses[(int) $ch]->info['http_code'] ?? 0)) { + $multi->handlesActivity[$id][] = new FirstChunk(); + } + + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = \in_array($result, [\CURLE_OK, \CURLE_TOO_MANY_REDIRECTS], true) || '_0' === $waitFor || curl_getinfo($ch, \CURLINFO_SIZE_DOWNLOAD) === curl_getinfo($ch, \CURLINFO_CONTENT_LENGTH_DOWNLOAD) ? null : new TransportException(ucfirst(curl_error($ch) ?: curl_strerror($result)).sprintf(' for "%s".', curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL))); + } + } finally { + $multi->performing = false; + } + } + + /** + * {@inheritdoc} + * + * @param CurlClientState $multi + */ + private static function select(ClientState $multi, float $timeout): int + { + if (\PHP_VERSION_ID < 70211) { + // workaround https://bugs.php.net/76480 + $timeout = min($timeout, 0.01); + } + + if ($multi->pauseExpiries) { + $now = microtime(true); + + foreach ($multi->pauseExpiries as $id => $pauseExpiry) { + if ($now < $pauseExpiry) { + $timeout = min($timeout, $pauseExpiry - $now); + break; + } + + unset($multi->pauseExpiries[$id]); + curl_pause($multi->openHandles[$id][0], \CURLPAUSE_CONT); + curl_multi_add_handle($multi->handle, $multi->openHandles[$id][0]); + } + } + + if (0 !== $selected = curl_multi_select($multi->handle, $timeout)) { + return $selected; + } + + if ($multi->pauseExpiries && 0 < $timeout -= microtime(true) - $now) { + usleep((int) (1E6 * $timeout)); + } + + return 0; + } + + /** + * Parses header lines as curl yields them to us. + */ + private static function parseHeaderLine($ch, string $data, array &$info, array &$headers, ?array $options, CurlClientState $multi, int $id, ?string &$location, ?callable $resolveRedirect, ?LoggerInterface $logger): int + { + if (!str_ends_with($data, "\r\n")) { + return 0; + } + + $waitFor = @curl_getinfo($ch, \CURLINFO_PRIVATE) ?: '_0'; + + if ('H' !== $waitFor[0]) { + return \strlen($data); // Ignore HTTP trailers + } + + $statusCode = curl_getinfo($ch, \CURLINFO_RESPONSE_CODE); + + if ($statusCode !== $info['http_code'] && !preg_match("#^HTTP/\d+(?:\.\d+)? {$statusCode}(?: |\r\n$)#", $data)) { + return \strlen($data); // Ignore headers from responses to CONNECT requests + } + + if ("\r\n" !== $data) { + // Regular header line: add it to the list + self::addResponseHeaders([substr($data, 0, -2)], $info, $headers); + + if (!str_starts_with($data, 'HTTP/')) { + if (0 === stripos($data, 'Location:')) { + $location = trim(substr($data, 9, -2)); + } + + return \strlen($data); + } + + if (\function_exists('openssl_x509_read') && $certinfo = curl_getinfo($ch, \CURLINFO_CERTINFO)) { + $info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert')); + } + + if (300 <= $info['http_code'] && $info['http_code'] < 400) { + if (curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { + curl_setopt($ch, \CURLOPT_FOLLOWLOCATION, false); + } elseif (303 === $info['http_code'] || ('POST' === $info['http_method'] && \in_array($info['http_code'], [301, 302], true))) { + curl_setopt($ch, \CURLOPT_POSTFIELDS, ''); + } + } + + return \strlen($data); + } + + // End of headers: handle informational responses, redirects, etc. + + if (200 > $statusCode) { + $multi->handlesActivity[$id][] = new InformationalChunk($statusCode, $headers); + $location = null; + + return \strlen($data); + } + + $info['redirect_url'] = null; + + if (300 <= $statusCode && $statusCode < 400 && null !== $location) { + if ($noContent = 303 === $statusCode || ('POST' === $info['http_method'] && \in_array($statusCode, [301, 302], true))) { + $info['http_method'] = 'HEAD' === $info['http_method'] ? 'HEAD' : 'GET'; + curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, $info['http_method']); + } + + if (null === $info['redirect_url'] = $resolveRedirect($ch, $location, $noContent)) { + $options['max_redirects'] = curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT); + curl_setopt($ch, \CURLOPT_FOLLOWLOCATION, false); + curl_setopt($ch, \CURLOPT_MAXREDIRS, $options['max_redirects']); + } else { + $url = parse_url($location ?? ':'); + + if (isset($url['host']) && null !== $ip = $multi->dnsCache->hostnames[$url['host'] = strtolower($url['host'])] ?? null) { + // Populate DNS cache for redirects if needed + $port = $url['port'] ?? ('http' === ($url['scheme'] ?? parse_url(curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL), \PHP_URL_SCHEME)) ? 80 : 443); + curl_setopt($ch, \CURLOPT_RESOLVE, ["{$url['host']}:$port:$ip"]); + $multi->dnsCache->removals["-{$url['host']}:$port"] = "-{$url['host']}:$port"; + } + } + } + + if (401 === $statusCode && isset($options['auth_ntlm']) && 0 === strncasecmp($headers['www-authenticate'][0] ?? '', 'NTLM ', 5)) { + // Continue with NTLM auth + } elseif ($statusCode < 300 || 400 <= $statusCode || null === $location || curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) { + // Headers and redirects completed, time to get the response's content + $multi->handlesActivity[$id][] = new FirstChunk(); + + if ('HEAD' === $info['http_method'] || \in_array($statusCode, [204, 304], true)) { + $waitFor = '_0'; // no content expected + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null; + } else { + $waitFor[0] = 'C'; // C = content + } + + curl_setopt($ch, \CURLOPT_PRIVATE, $waitFor); + } elseif (null !== $info['redirect_url'] && $logger) { + $logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url'])); + } + + $location = null; + + return \strlen($data); + } +} diff --git a/vendor/symfony/http-client/Response/HttplugPromise.php b/vendor/symfony/http-client/Response/HttplugPromise.php new file mode 100644 index 000000000..2efacca76 --- /dev/null +++ b/vendor/symfony/http-client/Response/HttplugPromise.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use GuzzleHttp\Promise\Create; +use GuzzleHttp\Promise\PromiseInterface as GuzzlePromiseInterface; +use Http\Promise\Promise as HttplugPromiseInterface; +use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface; + +/** + * @author Tobias Nyholm + * + * @internal + */ +final class HttplugPromise implements HttplugPromiseInterface +{ + private $promise; + + public function __construct(GuzzlePromiseInterface $promise) + { + $this->promise = $promise; + } + + public function then(callable $onFulfilled = null, callable $onRejected = null): self + { + return new self($this->promise->then( + $this->wrapThenCallback($onFulfilled), + $this->wrapThenCallback($onRejected) + )); + } + + public function cancel(): void + { + $this->promise->cancel(); + } + + /** + * {@inheritdoc} + */ + public function getState(): string + { + return $this->promise->getState(); + } + + /** + * {@inheritdoc} + * + * @return Psr7ResponseInterface|mixed + */ + public function wait($unwrap = true) + { + $result = $this->promise->wait($unwrap); + + while ($result instanceof HttplugPromiseInterface || $result instanceof GuzzlePromiseInterface) { + $result = $result->wait($unwrap); + } + + return $result; + } + + private function wrapThenCallback(?callable $callback): ?callable + { + if (null === $callback) { + return null; + } + + return static function ($value) use ($callback) { + return Create::promiseFor($callback($value)); + }; + } +} diff --git a/vendor/symfony/http-client/Response/MockResponse.php b/vendor/symfony/http-client/Response/MockResponse.php new file mode 100644 index 000000000..2c0010875 --- /dev/null +++ b/vendor/symfony/http-client/Response/MockResponse.php @@ -0,0 +1,343 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * A test-friendly response. + * + * @author Nicolas Grekas + */ +class MockResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + use TransportResponseTrait { + doDestruct as public __destruct; + } + + private $body; + private $requestOptions = []; + private $requestUrl; + private $requestMethod; + + private static $mainMulti; + private static $idSequence = 0; + + /** + * @param string|string[]|iterable $body The response body as a string or an iterable of strings, + * yielding an empty string simulates an idle timeout, + * throwing an exception yields an ErrorChunk + * + * @see ResponseInterface::getInfo() for possible info, e.g. "response_headers" + */ + public function __construct($body = '', array $info = []) + { + $this->body = is_iterable($body) ? $body : (string) $body; + $this->info = $info + ['http_code' => 200] + $this->info; + + if (!isset($info['response_headers'])) { + return; + } + + $responseHeaders = []; + + foreach ($info['response_headers'] as $k => $v) { + foreach ((array) $v as $v) { + $responseHeaders[] = (\is_string($k) ? $k.': ' : '').$v; + } + } + + $this->info['response_headers'] = []; + self::addResponseHeaders($responseHeaders, $this->info, $this->headers); + } + + /** + * Returns the options used when doing the request. + */ + public function getRequestOptions(): array + { + return $this->requestOptions; + } + + /** + * Returns the URL used when doing the request. + */ + public function getRequestUrl(): string + { + return $this->requestUrl; + } + + /** + * Returns the method used when doing the request. + */ + public function getRequestMethod(): string + { + return $this->requestMethod; + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + return null !== $type ? $this->info[$type] ?? null : $this->info; + } + + /** + * {@inheritdoc} + */ + public function cancel(): void + { + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + try { + $this->body = null; + } catch (TransportException $e) { + // ignore errors when canceling + } + + $onProgress = $this->requestOptions['on_progress'] ?? static function () {}; + $dlSize = isset($this->headers['content-encoding']) || 'HEAD' === ($this->info['http_method'] ?? null) || \in_array($this->info['http_code'], [204, 304], true) ? 0 : (int) ($this->headers['content-length'][0] ?? 0); + $onProgress($this->offset, $dlSize, $this->info); + } + + /** + * {@inheritdoc} + */ + protected function close(): void + { + $this->inflate = null; + $this->body = []; + } + + /** + * @internal + */ + public static function fromRequest(string $method, string $url, array $options, ResponseInterface $mock): self + { + $response = new self([]); + $response->requestOptions = $options; + $response->id = ++self::$idSequence; + $response->shouldBuffer = $options['buffer'] ?? true; + $response->initializer = static function (self $response) { + return \is_array($response->body[0] ?? null); + }; + + $response->info['redirect_count'] = 0; + $response->info['redirect_url'] = null; + $response->info['start_time'] = microtime(true); + $response->info['http_method'] = $method; + $response->info['http_code'] = 0; + $response->info['user_data'] = $options['user_data'] ?? null; + $response->info['max_duration'] = $options['max_duration'] ?? null; + $response->info['url'] = $url; + + if ($mock instanceof self) { + $mock->requestOptions = $response->requestOptions; + $mock->requestMethod = $method; + $mock->requestUrl = $url; + } + + self::writeRequest($response, $options, $mock); + $response->body[] = [$options, $mock]; + + return $response; + } + + /** + * {@inheritdoc} + */ + protected static function schedule(self $response, array &$runningResponses): void + { + if (!$response->id) { + throw new InvalidArgumentException('MockResponse instances must be issued by MockHttpClient before processing.'); + } + + $multi = self::$mainMulti ?? self::$mainMulti = new ClientState(); + + if (!isset($runningResponses[0])) { + $runningResponses[0] = [$multi, []]; + } + + $runningResponses[0][1][$response->id] = $response; + } + + /** + * {@inheritdoc} + */ + protected static function perform(ClientState $multi, array &$responses): void + { + foreach ($responses as $response) { + $id = $response->id; + + if (null === $response->body) { + // Canceled response + $response->body = []; + } elseif ([] === $response->body) { + // Error chunk + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } elseif (null === $chunk = array_shift($response->body)) { + // Last chunk + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = array_shift($response->body); + } elseif (\is_array($chunk)) { + // First chunk + try { + $offset = 0; + $chunk[1]->getStatusCode(); + $chunk[1]->getHeaders(false); + self::readResponse($response, $chunk[0], $chunk[1], $offset); + $multi->handlesActivity[$id][] = new FirstChunk(); + $buffer = $response->requestOptions['buffer'] ?? null; + + if ($buffer instanceof \Closure && $response->content = $buffer($response->headers) ?: null) { + $response->content = \is_resource($response->content) ? $response->content : fopen('php://temp', 'w+'); + } + } catch (\Throwable $e) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = $e; + } + } elseif ($chunk instanceof \Throwable) { + $multi->handlesActivity[$id][] = null; + $multi->handlesActivity[$id][] = $chunk; + } else { + // Data or timeout chunk + $multi->handlesActivity[$id][] = $chunk; + } + } + } + + /** + * {@inheritdoc} + */ + protected static function select(ClientState $multi, float $timeout): int + { + return 42; + } + + /** + * Simulates sending the request. + */ + private static function writeRequest(self $response, array $options, ResponseInterface $mock) + { + $onProgress = $options['on_progress'] ?? static function () {}; + $response->info += $mock->getInfo() ?: []; + + // simulate "size_upload" if it is set + if (isset($response->info['size_upload'])) { + $response->info['size_upload'] = 0.0; + } + + // simulate "total_time" if it is not set + if (!isset($response->info['total_time'])) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + } + + // "notify" DNS resolution + $onProgress(0, 0, $response->info); + + // consume the request body + if (\is_resource($body = $options['body'] ?? '')) { + $data = stream_get_contents($body); + if (isset($response->info['size_upload'])) { + $response->info['size_upload'] += \strlen($data); + } + } elseif ($body instanceof \Closure) { + while ('' !== $data = $body(16372)) { + if (!\is_string($data)) { + throw new TransportException(sprintf('Return value of the "body" option callback must be string, "%s" returned.', get_debug_type($data))); + } + + // "notify" upload progress + if (isset($response->info['size_upload'])) { + $response->info['size_upload'] += \strlen($data); + } + + $onProgress(0, 0, $response->info); + } + } + } + + /** + * Simulates reading the response. + */ + private static function readResponse(self $response, array $options, ResponseInterface $mock, int &$offset) + { + $onProgress = $options['on_progress'] ?? static function () {}; + + // populate info related to headers + $info = $mock->getInfo() ?: []; + $response->info['http_code'] = ($info['http_code'] ?? 0) ?: $mock->getStatusCode() ?: 200; + $response->addResponseHeaders($info['response_headers'] ?? [], $response->info, $response->headers); + $dlSize = isset($response->headers['content-encoding']) || 'HEAD' === $response->info['http_method'] || \in_array($response->info['http_code'], [204, 304], true) ? 0 : (int) ($response->headers['content-length'][0] ?? 0); + + $response->info = [ + 'start_time' => $response->info['start_time'], + 'user_data' => $response->info['user_data'], + 'max_duration' => $response->info['max_duration'], + 'http_code' => $response->info['http_code'], + ] + $info + $response->info; + + if (null !== $response->info['error']) { + throw new TransportException($response->info['error']); + } + + if (!isset($response->info['total_time'])) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + } + + // "notify" headers arrival + $onProgress(0, $dlSize, $response->info); + + // cast response body to activity list + $body = $mock instanceof self ? $mock->body : $mock->getContent(false); + + if (!\is_string($body)) { + try { + foreach ($body as $chunk) { + if ('' === $chunk = (string) $chunk) { + // simulate an idle timeout + $response->body[] = new ErrorChunk($offset, sprintf('Idle timeout reached for "%s".', $response->info['url'])); + } else { + $response->body[] = $chunk; + $offset += \strlen($chunk); + // "notify" download progress + $onProgress($offset, $dlSize, $response->info); + } + } + } catch (\Throwable $e) { + $response->body[] = $e; + } + } elseif ('' !== $body) { + $response->body[] = $body; + $offset = \strlen($body); + } + + if (!isset($response->info['total_time'])) { + $response->info['total_time'] = microtime(true) - $response->info['start_time']; + } + + // "notify" completion + $onProgress($offset, $dlSize, $response->info); + + if ($dlSize && $offset !== $dlSize) { + throw new TransportException(sprintf('Transfer closed with %d bytes remaining to read.', $dlSize - $offset)); + } + } +} diff --git a/vendor/symfony/http-client/Response/NativeResponse.php b/vendor/symfony/http-client/Response/NativeResponse.php new file mode 100644 index 000000000..c00e946f6 --- /dev/null +++ b/vendor/symfony/http-client/Response/NativeResponse.php @@ -0,0 +1,376 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\Canary; +use Symfony\Component\HttpClient\Internal\ClientState; +use Symfony\Component\HttpClient\Internal\NativeClientState; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class NativeResponse implements ResponseInterface, StreamableInterface +{ + use CommonResponseTrait; + use TransportResponseTrait; + + private $context; + private $url; + private $resolver; + private $onProgress; + private $remaining; + private $buffer; + private $multi; + private $pauseExpiry = 0; + + /** + * @internal + */ + public function __construct(NativeClientState $multi, $context, string $url, array $options, array &$info, callable $resolver, ?callable $onProgress, ?LoggerInterface $logger) + { + $this->multi = $multi; + $this->id = $id = (int) $context; + $this->context = $context; + $this->url = $url; + $this->logger = $logger; + $this->timeout = $options['timeout']; + $this->info = &$info; + $this->resolver = $resolver; + $this->onProgress = $onProgress; + $this->inflate = !isset($options['normalized_headers']['accept-encoding']); + $this->shouldBuffer = $options['buffer'] ?? true; + + // Temporary resource to dechunk the response stream + $this->buffer = fopen('php://temp', 'w+'); + + $info['user_data'] = $options['user_data']; + $info['max_duration'] = $options['max_duration']; + ++$multi->responseCount; + + $this->initializer = static function (self $response) { + return null === $response->remaining; + }; + + $pauseExpiry = &$this->pauseExpiry; + $info['pause_handler'] = static function (float $duration) use (&$pauseExpiry) { + $pauseExpiry = 0 < $duration ? microtime(true) + $duration : 0; + }; + + $this->canary = new Canary(static function () use ($multi, $id) { + if (null !== ($host = $multi->openHandles[$id][6] ?? null) && 0 >= --$multi->hosts[$host]) { + unset($multi->hosts[$host]); + } + unset($multi->openHandles[$id], $multi->handlesActivity[$id]); + }); + } + + /** + * {@inheritdoc} + */ + public function getInfo(string $type = null) + { + if (!$info = $this->finalInfo) { + $info = $this->info; + $info['url'] = implode('', $info['url']); + unset($info['size_body'], $info['request_header']); + + if (null === $this->buffer) { + $this->finalInfo = $info; + } + } + + return null !== $type ? $info[$type] ?? null : $info; + } + + public function __destruct() + { + try { + $this->doDestruct(); + } finally { + // Clear the DNS cache when all requests completed + if (0 >= --$this->multi->responseCount) { + $this->multi->responseCount = 0; + $this->multi->dnsCache = []; + } + } + } + + private function open(): void + { + $url = $this->url; + + set_error_handler(function ($type, $msg) use (&$url) { + if (\E_NOTICE !== $type || 'fopen(): Content-type not specified assuming application/x-www-form-urlencoded' !== $msg) { + throw new TransportException($msg); + } + + $this->logger && $this->logger->info(sprintf('%s for "%s".', $msg, $url ?? $this->url)); + }); + + try { + $this->info['start_time'] = microtime(true); + + [$resolver, $url] = ($this->resolver)($this->multi); + + while (true) { + $context = stream_context_get_options($this->context); + + if ($proxy = $context['http']['proxy'] ?? null) { + $this->info['debug'] .= "* Establish HTTP proxy tunnel to {$proxy}\n"; + $this->info['request_header'] = $url; + } else { + $this->info['debug'] .= "* Trying {$this->info['primary_ip']}...\n"; + $this->info['request_header'] = $this->info['url']['path'].$this->info['url']['query']; + } + + $this->info['request_header'] = sprintf("> %s %s HTTP/%s \r\n", $context['http']['method'], $this->info['request_header'], $context['http']['protocol_version']); + $this->info['request_header'] .= implode("\r\n", $context['http']['header'])."\r\n\r\n"; + + if (\array_key_exists('peer_name', $context['ssl']) && null === $context['ssl']['peer_name']) { + unset($context['ssl']['peer_name']); + $this->context = stream_context_create([], ['options' => $context] + stream_context_get_params($this->context)); + } + + // Send request and follow redirects when needed + $this->handle = $h = fopen($url, 'r', false, $this->context); + self::addResponseHeaders(stream_get_meta_data($h)['wrapper_data'], $this->info, $this->headers, $this->info['debug']); + $url = $resolver($this->multi, $this->headers['location'][0] ?? null, $this->context); + + if (null === $url) { + break; + } + + $this->logger && $this->logger->info(sprintf('Redirecting: "%s %s"', $this->info['http_code'], $url ?? $this->url)); + } + } catch (\Throwable $e) { + $this->close(); + $this->multi->handlesActivity[$this->id][] = null; + $this->multi->handlesActivity[$this->id][] = $e; + + return; + } finally { + $this->info['pretransfer_time'] = $this->info['total_time'] = microtime(true) - $this->info['start_time']; + restore_error_handler(); + } + + if (isset($context['ssl']['capture_peer_cert_chain']) && isset(($context = stream_context_get_options($this->context))['ssl']['peer_certificate_chain'])) { + $this->info['peer_certificate_chain'] = $context['ssl']['peer_certificate_chain']; + } + + stream_set_blocking($h, false); + $this->context = $this->resolver = null; + + // Create dechunk buffers + if (isset($this->headers['content-length'])) { + $this->remaining = (int) $this->headers['content-length'][0]; + } elseif ('chunked' === ($this->headers['transfer-encoding'][0] ?? null)) { + stream_filter_append($this->buffer, 'dechunk', \STREAM_FILTER_WRITE); + $this->remaining = -1; + } else { + $this->remaining = -2; + } + + $this->multi->handlesActivity[$this->id] = [new FirstChunk()]; + + if ('HEAD' === $context['http']['method'] || \in_array($this->info['http_code'], [204, 304], true)) { + $this->multi->handlesActivity[$this->id][] = null; + $this->multi->handlesActivity[$this->id][] = null; + + return; + } + + $host = parse_url($this->info['redirect_url'] ?? $this->url, \PHP_URL_HOST); + $this->multi->lastTimeout = null; + $this->multi->openHandles[$this->id] = [&$this->pauseExpiry, $h, $this->buffer, $this->onProgress, &$this->remaining, &$this->info, $host]; + $this->multi->hosts[$host] = 1 + ($this->multi->hosts[$host] ?? 0); + } + + /** + * {@inheritdoc} + */ + private function close(): void + { + $this->canary->cancel(); + $this->handle = $this->buffer = $this->inflate = $this->onProgress = null; + } + + /** + * {@inheritdoc} + */ + private static function schedule(self $response, array &$runningResponses): void + { + if (!isset($runningResponses[$i = $response->multi->id])) { + $runningResponses[$i] = [$response->multi, []]; + } + + $runningResponses[$i][1][$response->id] = $response; + + if (null === $response->buffer) { + // Response already completed + $response->multi->handlesActivity[$response->id][] = null; + $response->multi->handlesActivity[$response->id][] = null !== $response->info['error'] ? new TransportException($response->info['error']) : null; + } + } + + /** + * {@inheritdoc} + * + * @param NativeClientState $multi + */ + private static function perform(ClientState $multi, array &$responses = null): void + { + foreach ($multi->openHandles as $i => [$pauseExpiry, $h, $buffer, $onProgress]) { + if ($pauseExpiry) { + if (microtime(true) < $pauseExpiry) { + continue; + } + + $multi->openHandles[$i][0] = 0; + } + + $hasActivity = false; + $remaining = &$multi->openHandles[$i][4]; + $info = &$multi->openHandles[$i][5]; + $e = null; + + // Read incoming buffer and write it to the dechunk one + try { + if ($remaining && '' !== $data = (string) fread($h, 0 > $remaining ? 16372 : $remaining)) { + fwrite($buffer, $data); + $hasActivity = true; + $multi->sleep = false; + + if (-1 !== $remaining) { + $remaining -= \strlen($data); + } + } + } catch (\Throwable $e) { + $hasActivity = $onProgress = false; + } + + if (!$hasActivity) { + if ($onProgress) { + try { + // Notify the progress callback so that it can e.g. cancel + // the request if the stream is inactive for too long + $info['total_time'] = microtime(true) - $info['start_time']; + $onProgress(); + } catch (\Throwable $e) { + // no-op + } + } + } elseif ('' !== $data = stream_get_contents($buffer, -1, 0)) { + rewind($buffer); + ftruncate($buffer, 0); + + if (null === $e) { + $multi->handlesActivity[$i][] = $data; + } + } + + if (null !== $e || !$remaining || feof($h)) { + // Stream completed + $info['total_time'] = microtime(true) - $info['start_time']; + $info['starttransfer_time'] = $info['starttransfer_time'] ?: $info['total_time']; + + if ($onProgress) { + try { + $onProgress(-1); + } catch (\Throwable $e) { + // no-op + } + } + + if (null === $e) { + if (0 < $remaining) { + $e = new TransportException(sprintf('Transfer closed with %s bytes remaining to read.', $remaining)); + } elseif (-1 === $remaining && fwrite($buffer, '-') && '' !== stream_get_contents($buffer, -1, 0)) { + $e = new TransportException('Transfer closed with outstanding data remaining from chunked response.'); + } + } + + $multi->handlesActivity[$i][] = null; + $multi->handlesActivity[$i][] = $e; + if (null !== ($host = $multi->openHandles[$i][6] ?? null) && 0 >= --$multi->hosts[$host]) { + unset($multi->hosts[$host]); + } + unset($multi->openHandles[$i]); + $multi->sleep = false; + } + } + + if (null === $responses) { + return; + } + + $maxHosts = $multi->maxHostConnections; + + foreach ($responses as $i => $response) { + if (null !== $response->remaining || null === $response->buffer) { + continue; + } + + if ($response->pauseExpiry && microtime(true) < $response->pauseExpiry) { + // Create empty open handles to tell we still have pending requests + $multi->openHandles[$i] = [\INF, null, null, null]; + } elseif ($maxHosts && $maxHosts > ($multi->hosts[parse_url($response->url, \PHP_URL_HOST)] ?? 0)) { + // Open the next pending request - this is a blocking operation so we do only one of them + $response->open(); + $multi->sleep = false; + self::perform($multi); + $maxHosts = 0; + } + } + } + + /** + * {@inheritdoc} + * + * @param NativeClientState $multi + */ + private static function select(ClientState $multi, float $timeout): int + { + if (!$multi->sleep = !$multi->sleep) { + return -1; + } + + $_ = $handles = []; + $now = null; + + foreach ($multi->openHandles as [$pauseExpiry, $h]) { + if (null === $h) { + continue; + } + + if ($pauseExpiry && ($now ?? $now = microtime(true)) < $pauseExpiry) { + $timeout = min($timeout, $pauseExpiry - $now); + continue; + } + + $handles[] = $h; + } + + if (!$handles) { + usleep((int) (1E6 * $timeout)); + + return 0; + } + + return stream_select($handles, $_, $_, (int) $timeout, (int) (1E6 * ($timeout - (int) $timeout))); + } +} diff --git a/vendor/symfony/http-client/Response/ResponseStream.php b/vendor/symfony/http-client/Response/ResponseStream.php new file mode 100644 index 000000000..f86d2d407 --- /dev/null +++ b/vendor/symfony/http-client/Response/ResponseStream.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; + +/** + * @author Nicolas Grekas + */ +final class ResponseStream implements ResponseStreamInterface +{ + private $generator; + + public function __construct(\Generator $generator) + { + $this->generator = $generator; + } + + public function key(): ResponseInterface + { + return $this->generator->key(); + } + + public function current(): ChunkInterface + { + return $this->generator->current(); + } + + public function next(): void + { + $this->generator->next(); + } + + public function rewind(): void + { + $this->generator->rewind(); + } + + public function valid(): bool + { + return $this->generator->valid(); + } +} diff --git a/vendor/symfony/http-client/Response/StreamWrapper.php b/vendor/symfony/http-client/Response/StreamWrapper.php new file mode 100644 index 000000000..50a7c3662 --- /dev/null +++ b/vendor/symfony/http-client/Response/StreamWrapper.php @@ -0,0 +1,313 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * Allows turning ResponseInterface instances to PHP streams. + * + * @author Nicolas Grekas + */ +class StreamWrapper +{ + /** @var resource|null */ + public $context; + + /** @var HttpClientInterface */ + private $client; + + /** @var ResponseInterface */ + private $response; + + /** @var resource|string|null */ + private $content; + + /** @var resource|null */ + private $handle; + + private $blocking = true; + private $timeout; + private $eof = false; + private $offset = 0; + + /** + * Creates a PHP stream resource from a ResponseInterface. + * + * @return resource + */ + public static function createResource(ResponseInterface $response, HttpClientInterface $client = null) + { + if ($response instanceof StreamableInterface) { + $stack = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 2); + + if ($response !== ($stack[1]['object'] ?? null)) { + return $response->toStream(false); + } + } + + if (null === $client && !method_exists($response, 'stream')) { + throw new \InvalidArgumentException(sprintf('Providing a client to "%s()" is required when the response doesn\'t have any "stream()" method.', __CLASS__)); + } + + static $registered = false; + + if (!$registered = $registered || stream_wrapper_register(strtr(__CLASS__, '\\', '-'), __CLASS__)) { + throw new \RuntimeException(error_get_last()['message'] ?? 'Registering the "symfony" stream wrapper failed.'); + } + + $context = [ + 'client' => $client ?? $response, + 'response' => $response, + ]; + + return fopen(strtr(__CLASS__, '\\', '-').'://'.$response->getInfo('url'), 'r', false, stream_context_create(['symfony' => $context])); + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } + + /** + * @param resource|callable|null $handle The resource handle that should be monitored when + * stream_select() is used on the created stream + * @param resource|null $content The seekable resource where the response body is buffered + */ + public function bindHandles(&$handle, &$content): void + { + $this->handle = &$handle; + $this->content = &$content; + $this->offset = null; + } + + public function stream_open(string $path, string $mode, int $options): bool + { + if ('r' !== $mode) { + if ($options & \STREAM_REPORT_ERRORS) { + trigger_error(sprintf('Invalid mode "%s": only "r" is supported.', $mode), \E_USER_WARNING); + } + + return false; + } + + $context = stream_context_get_options($this->context)['symfony'] ?? null; + $this->client = $context['client'] ?? null; + $this->response = $context['response'] ?? null; + $this->context = null; + + if (null !== $this->client && null !== $this->response) { + return true; + } + + if ($options & \STREAM_REPORT_ERRORS) { + trigger_error('Missing options "client" or "response" in "symfony" stream context.', \E_USER_WARNING); + } + + return false; + } + + public function stream_read(int $count) + { + if (\is_resource($this->content)) { + // Empty the internal activity list + foreach ($this->client->stream([$this->response], 0) as $chunk) { + try { + if (!$chunk->isTimeout() && $chunk->isFirst()) { + $this->response->getStatusCode(); // ignore 3/4/5xx + } + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + + return false; + } + } + + if (0 !== fseek($this->content, $this->offset ?? 0)) { + return false; + } + + if ('' !== $data = fread($this->content, $count)) { + fseek($this->content, 0, \SEEK_END); + $this->offset += \strlen($data); + + return $data; + } + } + + if (\is_string($this->content)) { + if (\strlen($this->content) <= $count) { + $data = $this->content; + $this->content = null; + } else { + $data = substr($this->content, 0, $count); + $this->content = substr($this->content, $count); + } + $this->offset += \strlen($data); + + return $data; + } + + foreach ($this->client->stream([$this->response], $this->blocking ? $this->timeout : 0) as $chunk) { + try { + $this->eof = true; + $this->eof = !$chunk->isTimeout(); + + if (!$this->eof && !$this->blocking) { + return ''; + } + + $this->eof = $chunk->isLast(); + + if ($chunk->isFirst()) { + $this->response->getStatusCode(); // ignore 3/4/5xx + } + + if ('' !== $data = $chunk->getContent()) { + if (\strlen($data) > $count) { + if (null === $this->content) { + $this->content = substr($data, $count); + } + $data = substr($data, 0, $count); + } + $this->offset += \strlen($data); + + return $data; + } + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + + return false; + } + } + + return ''; + } + + public function stream_set_option(int $option, int $arg1, ?int $arg2): bool + { + if (\STREAM_OPTION_BLOCKING === $option) { + $this->blocking = (bool) $arg1; + } elseif (\STREAM_OPTION_READ_TIMEOUT === $option) { + $this->timeout = $arg1 + $arg2 / 1e6; + } else { + return false; + } + + return true; + } + + public function stream_tell(): int + { + return $this->offset ?? 0; + } + + public function stream_eof(): bool + { + return $this->eof && !\is_string($this->content); + } + + public function stream_seek(int $offset, int $whence = \SEEK_SET): bool + { + if (null === $this->content && null === $this->offset) { + $this->response->getStatusCode(); + $this->offset = 0; + } + + if (!\is_resource($this->content) || 0 !== fseek($this->content, 0, \SEEK_END)) { + return false; + } + + $size = ftell($this->content); + + if (\SEEK_CUR === $whence) { + $offset += $this->offset ?? 0; + } + + if (\SEEK_END === $whence || $size < $offset) { + foreach ($this->client->stream([$this->response]) as $chunk) { + try { + if ($chunk->isFirst()) { + $this->response->getStatusCode(); // ignore 3/4/5xx + } + + // Chunks are buffered in $this->content already + $size += \strlen($chunk->getContent()); + + if (\SEEK_END !== $whence && $offset <= $size) { + break; + } + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + + return false; + } + } + + if (\SEEK_END === $whence) { + $offset += $size; + } + } + + if (0 <= $offset && $offset <= $size) { + $this->eof = false; + $this->offset = $offset; + + return true; + } + + return false; + } + + public function stream_cast(int $castAs) + { + if (\STREAM_CAST_FOR_SELECT === $castAs) { + $this->response->getHeaders(false); + + return (\is_callable($this->handle) ? ($this->handle)() : $this->handle) ?? false; + } + + return false; + } + + public function stream_stat(): array + { + try { + $headers = $this->response->getHeaders(false); + } catch (ExceptionInterface $e) { + trigger_error($e->getMessage(), \E_USER_WARNING); + $headers = []; + } + + return [ + 'dev' => 0, + 'ino' => 0, + 'mode' => 33060, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => (int) ($headers['content-length'][0] ?? -1), + 'atime' => 0, + 'mtime' => strtotime($headers['last-modified'][0] ?? '') ?: 0, + 'ctime' => 0, + 'blksize' => 0, + 'blocks' => 0, + ]; + } + + private function __construct() + { + } +} diff --git a/vendor/symfony/http-client/Response/StreamableInterface.php b/vendor/symfony/http-client/Response/StreamableInterface.php new file mode 100644 index 000000000..eb1f9335c --- /dev/null +++ b/vendor/symfony/http-client/Response/StreamableInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Nicolas Grekas + */ +interface StreamableInterface +{ + /** + * Casts the response to a PHP stream resource. + * + * @return resource + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function toStream(bool $throw = true); +} diff --git a/vendor/symfony/http-client/Response/TraceableResponse.php b/vendor/symfony/http-client/Response/TraceableResponse.php new file mode 100644 index 000000000..d656c0a5f --- /dev/null +++ b/vendor/symfony/http-client/Response/TraceableResponse.php @@ -0,0 +1,219 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Exception\ClientException; +use Symfony\Component\HttpClient\Exception\RedirectionException; +use Symfony\Component\HttpClient\Exception\ServerException; +use Symfony\Component\HttpClient\TraceableHttpClient; +use Symfony\Component\Stopwatch\StopwatchEvent; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class TraceableResponse implements ResponseInterface, StreamableInterface +{ + private $client; + private $response; + private $content; + private $event; + + public function __construct(HttpClientInterface $client, ResponseInterface $response, &$content, StopwatchEvent $event = null) + { + $this->client = $client; + $this->response = $response; + $this->content = &$content; + $this->event = $event; + } + + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + try { + $this->response->__destruct(); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + } + } + + public function getStatusCode(): int + { + try { + return $this->response->getStatusCode(); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->lap(); + } + } + } + + public function getHeaders(bool $throw = true): array + { + try { + return $this->response->getHeaders($throw); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->lap(); + } + } + } + + public function getContent(bool $throw = true): string + { + try { + if (false === $this->content) { + return $this->response->getContent($throw); + } + + return $this->content = $this->response->getContent(false); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + if ($throw) { + $this->checkStatusCode($this->response->getStatusCode()); + } + } + } + + public function toArray(bool $throw = true): array + { + try { + if (false === $this->content) { + return $this->response->toArray($throw); + } + + return $this->content = $this->response->toArray(false); + } finally { + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + if ($throw) { + $this->checkStatusCode($this->response->getStatusCode()); + } + } + } + + public function cancel(): void + { + $this->response->cancel(); + + if ($this->event && $this->event->isStarted()) { + $this->event->stop(); + } + } + + public function getInfo(string $type = null) + { + return $this->response->getInfo($type); + } + + /** + * Casts the response to a PHP stream resource. + * + * @return resource + * + * @throws TransportExceptionInterface When a network error occurs + * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached + * @throws ClientExceptionInterface On a 4xx when $throw is true + * @throws ServerExceptionInterface On a 5xx when $throw is true + */ + public function toStream(bool $throw = true) + { + if ($throw) { + // Ensure headers arrived + $this->response->getHeaders(true); + } + + if ($this->response instanceof StreamableInterface) { + return $this->response->toStream(false); + } + + return StreamWrapper::createResource($this->response, $this->client); + } + + /** + * @internal + */ + public static function stream(HttpClientInterface $client, iterable $responses, ?float $timeout): \Generator + { + $wrappedResponses = []; + $traceableMap = new \SplObjectStorage(); + + foreach ($responses as $r) { + if (!$r instanceof self) { + throw new \TypeError(sprintf('"%s::stream()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', TraceableHttpClient::class, get_debug_type($r))); + } + + $traceableMap[$r->response] = $r; + $wrappedResponses[] = $r->response; + if ($r->event && !$r->event->isStarted()) { + $r->event->start(); + } + } + + foreach ($client->stream($wrappedResponses, $timeout) as $r => $chunk) { + if ($traceableMap[$r]->event && $traceableMap[$r]->event->isStarted()) { + try { + if ($chunk->isTimeout() || !$chunk->isLast()) { + $traceableMap[$r]->event->lap(); + } else { + $traceableMap[$r]->event->stop(); + } + } catch (TransportExceptionInterface $e) { + $traceableMap[$r]->event->stop(); + if ($chunk instanceof ErrorChunk) { + $chunk->didThrow(false); + } else { + $chunk = new ErrorChunk($chunk->getOffset(), $e); + } + } + } + yield $traceableMap[$r] => $chunk; + } + } + + private function checkStatusCode(int $code) + { + if (500 <= $code) { + throw new ServerException($this); + } + + if (400 <= $code) { + throw new ClientException($this); + } + + if (300 <= $code) { + throw new RedirectionException($this); + } + } +} diff --git a/vendor/symfony/http-client/Response/TransportResponseTrait.php b/vendor/symfony/http-client/Response/TransportResponseTrait.php new file mode 100644 index 000000000..566d61e17 --- /dev/null +++ b/vendor/symfony/http-client/Response/TransportResponseTrait.php @@ -0,0 +1,312 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Response; + +use Symfony\Component\HttpClient\Chunk\DataChunk; +use Symfony\Component\HttpClient\Chunk\ErrorChunk; +use Symfony\Component\HttpClient\Chunk\FirstChunk; +use Symfony\Component\HttpClient\Chunk\LastChunk; +use Symfony\Component\HttpClient\Exception\TransportException; +use Symfony\Component\HttpClient\Internal\ClientState; + +/** + * Implements common logic for transport-level response classes. + * + * @author Nicolas Grekas + * + * @internal + */ +trait TransportResponseTrait +{ + private $canary; + private $headers = []; + private $info = [ + 'response_headers' => [], + 'http_code' => 0, + 'error' => null, + 'canceled' => false, + ]; + + /** @var object|resource */ + private $handle; + private $id; + private $timeout = 0; + private $inflate; + private $finalInfo; + private $logger; + + /** + * {@inheritdoc} + */ + public function getStatusCode(): int + { + if ($this->initializer) { + self::initialize($this); + } + + return $this->info['http_code']; + } + + /** + * {@inheritdoc} + */ + public function getHeaders(bool $throw = true): array + { + if ($this->initializer) { + self::initialize($this); + } + + if ($throw) { + $this->checkStatusCode(); + } + + return $this->headers; + } + + /** + * {@inheritdoc} + */ + public function cancel(): void + { + $this->info['canceled'] = true; + $this->info['error'] = 'Response has been canceled.'; + $this->close(); + } + + /** + * Closes the response and all its network handles. + */ + protected function close(): void + { + $this->canary->cancel(); + $this->inflate = null; + } + + /** + * Adds pending responses to the activity list. + */ + abstract protected static function schedule(self $response, array &$runningResponses): void; + + /** + * Performs all pending non-blocking operations. + */ + abstract protected static function perform(ClientState $multi, array &$responses): void; + + /** + * Waits for network activity. + */ + abstract protected static function select(ClientState $multi, float $timeout): int; + + private static function addResponseHeaders(array $responseHeaders, array &$info, array &$headers, string &$debug = ''): void + { + foreach ($responseHeaders as $h) { + if (11 <= \strlen($h) && '/' === $h[4] && preg_match('#^HTTP/\d+(?:\.\d+)? (\d\d\d)(?: |$)#', $h, $m)) { + if ($headers) { + $debug .= "< \r\n"; + $headers = []; + } + $info['http_code'] = (int) $m[1]; + } elseif (2 === \count($m = explode(':', $h, 2))) { + $headers[strtolower($m[0])][] = ltrim($m[1]); + } + + $debug .= "< {$h}\r\n"; + $info['response_headers'][] = $h; + } + + $debug .= "< \r\n"; + } + + /** + * Ensures the request is always sent and that the response code was checked. + */ + private function doDestruct() + { + $this->shouldBuffer = true; + + if ($this->initializer && null === $this->info['error']) { + self::initialize($this); + $this->checkStatusCode(); + } + } + + /** + * Implements an event loop based on a buffer activity queue. + * + * @param iterable $responses + * + * @internal + */ + public static function stream(iterable $responses, float $timeout = null): \Generator + { + $runningResponses = []; + + foreach ($responses as $response) { + self::schedule($response, $runningResponses); + } + + $lastActivity = microtime(true); + $elapsedTimeout = 0; + + if ($fromLastTimeout = 0.0 === $timeout && '-0' === (string) $timeout) { + $timeout = null; + } elseif ($fromLastTimeout = 0 > $timeout) { + $timeout = -$timeout; + } + + while (true) { + $hasActivity = false; + $timeoutMax = 0; + $timeoutMin = $timeout ?? \INF; + + /** @var ClientState $multi */ + foreach ($runningResponses as $i => [$multi]) { + $responses = &$runningResponses[$i][1]; + self::perform($multi, $responses); + + foreach ($responses as $j => $response) { + $timeoutMax = $timeout ?? max($timeoutMax, $response->timeout); + $timeoutMin = min($timeoutMin, $response->timeout, 1); + $chunk = false; + + if ($fromLastTimeout && null !== $multi->lastTimeout) { + $elapsedTimeout = microtime(true) - $multi->lastTimeout; + } + + if (isset($multi->handlesActivity[$j])) { + $multi->lastTimeout = null; + } elseif (!isset($multi->openHandles[$j])) { + unset($responses[$j]); + continue; + } elseif ($elapsedTimeout >= $timeoutMax) { + $multi->handlesActivity[$j] = [new ErrorChunk($response->offset, sprintf('Idle timeout reached for "%s".', $response->getInfo('url')))]; + $multi->lastTimeout ?? $multi->lastTimeout = $lastActivity; + } else { + continue; + } + + while ($multi->handlesActivity[$j] ?? false) { + $hasActivity = true; + $elapsedTimeout = 0; + + if (\is_string($chunk = array_shift($multi->handlesActivity[$j]))) { + if (null !== $response->inflate && false === $chunk = @inflate_add($response->inflate, $chunk)) { + $multi->handlesActivity[$j] = [null, new TransportException(sprintf('Error while processing content unencoding for "%s".', $response->getInfo('url')))]; + continue; + } + + if ('' !== $chunk && null !== $response->content && \strlen($chunk) !== fwrite($response->content, $chunk)) { + $multi->handlesActivity[$j] = [null, new TransportException(sprintf('Failed writing %d bytes to the response buffer.', \strlen($chunk)))]; + continue; + } + + $chunkLen = \strlen($chunk); + $chunk = new DataChunk($response->offset, $chunk); + $response->offset += $chunkLen; + } elseif (null === $chunk) { + $e = $multi->handlesActivity[$j][0]; + unset($responses[$j], $multi->handlesActivity[$j]); + $response->close(); + + if (null !== $e) { + $response->info['error'] = $e->getMessage(); + + if ($e instanceof \Error) { + throw $e; + } + + $chunk = new ErrorChunk($response->offset, $e); + } else { + if (0 === $response->offset && null === $response->content) { + $response->content = fopen('php://memory', 'w+'); + } + + $chunk = new LastChunk($response->offset); + } + } elseif ($chunk instanceof ErrorChunk) { + unset($responses[$j]); + $elapsedTimeout = $timeoutMax; + } elseif ($chunk instanceof FirstChunk) { + if ($response->logger) { + $info = $response->getInfo(); + $response->logger->info(sprintf('Response: "%s %s"', $info['http_code'], $info['url'])); + } + + $response->inflate = \extension_loaded('zlib') && $response->inflate && 'gzip' === ($response->headers['content-encoding'][0] ?? null) ? inflate_init(\ZLIB_ENCODING_GZIP) : null; + + if ($response->shouldBuffer instanceof \Closure) { + try { + $response->shouldBuffer = ($response->shouldBuffer)($response->headers); + + if (null !== $response->info['error']) { + throw new TransportException($response->info['error']); + } + } catch (\Throwable $e) { + $response->close(); + $multi->handlesActivity[$j] = [null, $e]; + } + } + + if (true === $response->shouldBuffer) { + $response->content = fopen('php://temp', 'w+'); + } elseif (\is_resource($response->shouldBuffer)) { + $response->content = $response->shouldBuffer; + } + $response->shouldBuffer = null; + + yield $response => $chunk; + + if ($response->initializer && null === $response->info['error']) { + // Ensure the HTTP status code is always checked + $response->getHeaders(true); + } + + continue; + } + + yield $response => $chunk; + } + + unset($multi->handlesActivity[$j]); + + if ($chunk instanceof ErrorChunk && !$chunk->didThrow()) { + // Ensure transport exceptions are always thrown + $chunk->getContent(); + } + } + + if (!$responses) { + unset($runningResponses[$i]); + } + + // Prevent memory leaks + $multi->handlesActivity = $multi->handlesActivity ?: []; + $multi->openHandles = $multi->openHandles ?: []; + } + + if (!$runningResponses) { + break; + } + + if ($hasActivity) { + $lastActivity = microtime(true); + continue; + } + + if (-1 === self::select($multi, min($timeoutMin, $timeoutMax - $elapsedTimeout))) { + usleep(min(500, 1E6 * $timeoutMin)); + } + + $elapsedTimeout = microtime(true) - $lastActivity; + } + } +} diff --git a/vendor/symfony/http-client/Retry/GenericRetryStrategy.php b/vendor/symfony/http-client/Retry/GenericRetryStrategy.php new file mode 100644 index 000000000..3241a5eb2 --- /dev/null +++ b/vendor/symfony/http-client/Retry/GenericRetryStrategy.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Retry; + +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * Decides to retry the request when HTTP status codes belong to the given list of codes. + * + * @author Jérémy Derussé + */ +class GenericRetryStrategy implements RetryStrategyInterface +{ + public const IDEMPOTENT_METHODS = ['GET', 'HEAD', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']; + public const DEFAULT_RETRY_STATUS_CODES = [ + 0 => self::IDEMPOTENT_METHODS, // for transport exceptions + 423, + 425, + 429, + 500 => self::IDEMPOTENT_METHODS, + 502, + 503, + 504 => self::IDEMPOTENT_METHODS, + 507 => self::IDEMPOTENT_METHODS, + 510 => self::IDEMPOTENT_METHODS, + ]; + + private $statusCodes; + private $delayMs; + private $multiplier; + private $maxDelayMs; + private $jitter; + + /** + * @param array $statusCodes List of HTTP status codes that trigger a retry + * @param int $delayMs Amount of time to delay (or the initial value when multiplier is used) + * @param float $multiplier Multiplier to apply to the delay each time a retry occurs + * @param int $maxDelayMs Maximum delay to allow (0 means no maximum) + * @param float $jitter Probability of randomness int delay (0 = none, 1 = 100% random) + */ + public function __construct(array $statusCodes = self::DEFAULT_RETRY_STATUS_CODES, int $delayMs = 1000, float $multiplier = 2.0, int $maxDelayMs = 0, float $jitter = 0.1) + { + $this->statusCodes = $statusCodes; + + if ($delayMs < 0) { + throw new InvalidArgumentException(sprintf('Delay must be greater than or equal to zero: "%s" given.', $delayMs)); + } + $this->delayMs = $delayMs; + + if ($multiplier < 1) { + throw new InvalidArgumentException(sprintf('Multiplier must be greater than or equal to one: "%s" given.', $multiplier)); + } + $this->multiplier = $multiplier; + + if ($maxDelayMs < 0) { + throw new InvalidArgumentException(sprintf('Max delay must be greater than or equal to zero: "%s" given.', $maxDelayMs)); + } + $this->maxDelayMs = $maxDelayMs; + + if ($jitter < 0 || $jitter > 1) { + throw new InvalidArgumentException(sprintf('Jitter must be between 0 and 1: "%s" given.', $jitter)); + } + $this->jitter = $jitter; + } + + public function shouldRetry(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): ?bool + { + $statusCode = $context->getStatusCode(); + if (\in_array($statusCode, $this->statusCodes, true)) { + return true; + } + if (isset($this->statusCodes[$statusCode]) && \is_array($this->statusCodes[$statusCode])) { + return \in_array($context->getInfo('http_method'), $this->statusCodes[$statusCode], true); + } + if (null === $exception) { + return false; + } + + if (\in_array(0, $this->statusCodes, true)) { + return true; + } + if (isset($this->statusCodes[0]) && \is_array($this->statusCodes[0])) { + return \in_array($context->getInfo('http_method'), $this->statusCodes[0], true); + } + + return false; + } + + public function getDelay(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): int + { + $delay = $this->delayMs * $this->multiplier ** $context->getInfo('retry_count'); + + if ($this->jitter > 0) { + $randomness = (int) ($delay * $this->jitter); + $delay = $delay + random_int(-$randomness, +$randomness); + } + + if ($delay > $this->maxDelayMs && 0 !== $this->maxDelayMs) { + return $this->maxDelayMs; + } + + return (int) $delay; + } +} diff --git a/vendor/symfony/http-client/Retry/RetryStrategyInterface.php b/vendor/symfony/http-client/Retry/RetryStrategyInterface.php new file mode 100644 index 000000000..25764336e --- /dev/null +++ b/vendor/symfony/http-client/Retry/RetryStrategyInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient\Retry; + +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; + +/** + * @author Jérémy Derussé + * @author Nicolas Grekas + */ +interface RetryStrategyInterface +{ + /** + * Returns whether the request should be retried. + * + * @param ?string $responseContent Null is passed when the body did not arrive yet + * + * @return bool|null Returns null to signal that the body is required to take a decision + */ + public function shouldRetry(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): ?bool; + + /** + * Returns the time to wait in milliseconds. + */ + public function getDelay(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): int; +} diff --git a/vendor/symfony/http-client/RetryableHttpClient.php b/vendor/symfony/http-client/RetryableHttpClient.php new file mode 100644 index 000000000..bec13784b --- /dev/null +++ b/vendor/symfony/http-client/RetryableHttpClient.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; +use Symfony\Component\HttpClient\Response\AsyncContext; +use Symfony\Component\HttpClient\Response\AsyncResponse; +use Symfony\Component\HttpClient\Retry\GenericRetryStrategy; +use Symfony\Component\HttpClient\Retry\RetryStrategyInterface; +use Symfony\Contracts\HttpClient\ChunkInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Automatically retries failing HTTP requests. + * + * @author Jérémy Derussé + */ +class RetryableHttpClient implements HttpClientInterface, ResetInterface +{ + use AsyncDecoratorTrait; + + private $strategy; + private $maxRetries; + private $logger; + + /** + * @param int $maxRetries The maximum number of times to retry + */ + public function __construct(HttpClientInterface $client, RetryStrategyInterface $strategy = null, int $maxRetries = 3, LoggerInterface $logger = null) + { + $this->client = $client; + $this->strategy = $strategy ?? new GenericRetryStrategy(); + $this->maxRetries = $maxRetries; + $this->logger = $logger ?? new NullLogger(); + } + + public function request(string $method, string $url, array $options = []): ResponseInterface + { + if ($this->maxRetries <= 0) { + return new AsyncResponse($this->client, $method, $url, $options); + } + + $retryCount = 0; + $content = ''; + $firstChunk = null; + + return new AsyncResponse($this->client, $method, $url, $options, function (ChunkInterface $chunk, AsyncContext $context) use ($method, $url, $options, &$retryCount, &$content, &$firstChunk) { + $exception = null; + try { + if ($context->getInfo('canceled') || $chunk->isTimeout() || null !== $chunk->getInformationalStatus()) { + yield $chunk; + + return; + } + } catch (TransportExceptionInterface $exception) { + // catch TransportExceptionInterface to send it to the strategy + } + if (null !== $exception) { + // always retry request that fail to resolve DNS + if ('' !== $context->getInfo('primary_ip')) { + $shouldRetry = $this->strategy->shouldRetry($context, null, $exception); + if (null === $shouldRetry) { + throw new \LogicException(sprintf('The "%s::shouldRetry()" method must not return null when called with an exception.', \get_class($this->strategy))); + } + + if (false === $shouldRetry) { + yield from $this->passthru($context, $firstChunk, $content, $chunk); + + return; + } + } + } elseif ($chunk->isFirst()) { + if (false === $shouldRetry = $this->strategy->shouldRetry($context, null, null)) { + yield from $this->passthru($context, $firstChunk, $content, $chunk); + + return; + } + + // Body is needed to decide + if (null === $shouldRetry) { + $firstChunk = $chunk; + $content = ''; + + return; + } + } else { + if (!$chunk->isLast()) { + $content .= $chunk->getContent(); + + return; + } + + if (null === $shouldRetry = $this->strategy->shouldRetry($context, $content, null)) { + throw new \LogicException(sprintf('The "%s::shouldRetry()" method must not return null when called with a body.', \get_class($this->strategy))); + } + + if (false === $shouldRetry) { + yield from $this->passthru($context, $firstChunk, $content, $chunk); + + return; + } + } + + $context->getResponse()->cancel(); + + $delay = $this->getDelayFromHeader($context->getHeaders()) ?? $this->strategy->getDelay($context, !$exception && $chunk->isLast() ? $content : null, $exception); + ++$retryCount; + $content = ''; + $firstChunk = null; + + $this->logger->info('Try #{count} after {delay}ms'.($exception ? ': '.$exception->getMessage() : ', status code: '.$context->getStatusCode()), [ + 'count' => $retryCount, + 'delay' => $delay, + ]); + + $context->setInfo('retry_count', $retryCount); + $context->replaceRequest($method, $url, $options); + $context->pause($delay / 1000); + + if ($retryCount >= $this->maxRetries) { + $context->passthru(); + } + }); + } + + private function getDelayFromHeader(array $headers): ?int + { + if (null !== $after = $headers['retry-after'][0] ?? null) { + if (is_numeric($after)) { + return (int) ($after * 1000); + } + + if (false !== $time = strtotime($after)) { + return max(0, $time - time()) * 1000; + } + } + + return null; + } + + private function passthru(AsyncContext $context, ?ChunkInterface $firstChunk, string &$content, ChunkInterface $lastChunk): \Generator + { + $context->passthru(); + + if (null !== $firstChunk) { + yield $firstChunk; + } + + if ('' !== $content) { + $chunk = $context->createChunk($content); + $content = ''; + + yield $chunk; + } + + yield $lastChunk; + } +} diff --git a/vendor/symfony/http-client/ScopingHttpClient.php b/vendor/symfony/http-client/ScopingHttpClient.php new file mode 100644 index 000000000..85fa26acd --- /dev/null +++ b/vendor/symfony/http-client/ScopingHttpClient.php @@ -0,0 +1,131 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * Auto-configure the default options based on the requested URL. + * + * @author Anthony Martin + */ +class ScopingHttpClient implements HttpClientInterface, ResetInterface, LoggerAwareInterface +{ + use HttpClientTrait; + + private $client; + private $defaultOptionsByRegexp; + private $defaultRegexp; + + public function __construct(HttpClientInterface $client, array $defaultOptionsByRegexp, string $defaultRegexp = null) + { + $this->client = $client; + $this->defaultOptionsByRegexp = $defaultOptionsByRegexp; + $this->defaultRegexp = $defaultRegexp; + + if (null !== $defaultRegexp && !isset($defaultOptionsByRegexp[$defaultRegexp])) { + throw new InvalidArgumentException(sprintf('No options are mapped to the provided "%s" default regexp.', $defaultRegexp)); + } + } + + public static function forBaseUri(HttpClientInterface $client, string $baseUri, array $defaultOptions = [], string $regexp = null): self + { + if (null === $regexp) { + $regexp = preg_quote(implode('', self::resolveUrl(self::parseUrl('.'), self::parseUrl($baseUri)))); + } + + $defaultOptions['base_uri'] = $baseUri; + + return new self($client, [$regexp => $defaultOptions], $regexp); + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $e = null; + $url = self::parseUrl($url, $options['query'] ?? []); + + if (\is_string($options['base_uri'] ?? null)) { + $options['base_uri'] = self::parseUrl($options['base_uri']); + } + + try { + $url = implode('', self::resolveUrl($url, $options['base_uri'] ?? null)); + } catch (InvalidArgumentException $e) { + if (null === $this->defaultRegexp) { + throw $e; + } + + $defaultOptions = $this->defaultOptionsByRegexp[$this->defaultRegexp]; + $options = self::mergeDefaultOptions($options, $defaultOptions, true); + if (\is_string($options['base_uri'] ?? null)) { + $options['base_uri'] = self::parseUrl($options['base_uri']); + } + $url = implode('', self::resolveUrl($url, $options['base_uri'] ?? null, $defaultOptions['query'] ?? [])); + } + + foreach ($this->defaultOptionsByRegexp as $regexp => $defaultOptions) { + if (preg_match("{{$regexp}}A", $url)) { + if (null === $e || $regexp !== $this->defaultRegexp) { + $options = self::mergeDefaultOptions($options, $defaultOptions, true); + } + break; + } + } + + return $this->client->request($method, $url, $options); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->client->stream($responses, $timeout); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + } + + /** + * {@inheritdoc} + */ + public function setLogger(LoggerInterface $logger): void + { + if ($this->client instanceof LoggerAwareInterface) { + $this->client->setLogger($logger); + } + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } +} diff --git a/vendor/symfony/http-client/TraceableHttpClient.php b/vendor/symfony/http-client/TraceableHttpClient.php new file mode 100644 index 000000000..76c928224 --- /dev/null +++ b/vendor/symfony/http-client/TraceableHttpClient.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpClient; + +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\HttpClient\Response\ResponseStream; +use Symfony\Component\HttpClient\Response\TraceableResponse; +use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; +use Symfony\Contracts\HttpClient\ResponseStreamInterface; +use Symfony\Contracts\Service\ResetInterface; + +/** + * @author Jérémy Romey + */ +final class TraceableHttpClient implements HttpClientInterface, ResetInterface, LoggerAwareInterface +{ + private $client; + private $stopwatch; + private $tracedRequests; + + public function __construct(HttpClientInterface $client, Stopwatch $stopwatch = null) + { + $this->client = $client; + $this->stopwatch = $stopwatch; + $this->tracedRequests = new \ArrayObject(); + } + + /** + * {@inheritdoc} + */ + public function request(string $method, string $url, array $options = []): ResponseInterface + { + $content = null; + $traceInfo = []; + $this->tracedRequests[] = [ + 'method' => $method, + 'url' => $url, + 'options' => $options, + 'info' => &$traceInfo, + 'content' => &$content, + ]; + $onProgress = $options['on_progress'] ?? null; + + if (false === ($options['extra']['trace_content'] ?? true)) { + unset($content); + $content = false; + } + + $options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use (&$traceInfo, $onProgress) { + $traceInfo = $info; + + if (null !== $onProgress) { + $onProgress($dlNow, $dlSize, $info); + } + }; + + return new TraceableResponse($this->client, $this->client->request($method, $url, $options), $content, null === $this->stopwatch ? null : $this->stopwatch->start("$method $url", 'http_client')); + } + + /** + * {@inheritdoc} + */ + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + if ($responses instanceof TraceableResponse) { + $responses = [$responses]; + } elseif (!is_iterable($responses)) { + throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + } + + return new ResponseStream(TraceableResponse::stream($this->client, $responses, $timeout)); + } + + public function getTracedRequests(): array + { + return $this->tracedRequests->getArrayCopy(); + } + + public function reset() + { + if ($this->client instanceof ResetInterface) { + $this->client->reset(); + } + + $this->tracedRequests->exchangeArray([]); + } + + /** + * {@inheritdoc} + */ + public function setLogger(LoggerInterface $logger): void + { + if ($this->client instanceof LoggerAwareInterface) { + $this->client->setLogger($logger); + } + } + + /** + * {@inheritdoc} + */ + public function withOptions(array $options): self + { + $clone = clone $this; + $clone->client = $this->client->withOptions($options); + + return $clone; + } +} diff --git a/vendor/symfony/http-client/composer.json b/vendor/symfony/http-client/composer.json new file mode 100644 index 000000000..7f546b3a2 --- /dev/null +++ b/vendor/symfony/http-client/composer.json @@ -0,0 +1,55 @@ +{ + "name": "symfony/http-client", + "type": "library", + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "keywords": ["http"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "2.4" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.4", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2|^3" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\HttpClient\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/vendor/symfony/polyfill-php73/LICENSE b/vendor/symfony/polyfill-php73/LICENSE new file mode 100644 index 000000000..7536caeae --- /dev/null +++ b/vendor/symfony/polyfill-php73/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-php73/Php73.php b/vendor/symfony/polyfill-php73/Php73.php new file mode 100644 index 000000000..65c35a6a1 --- /dev/null +++ b/vendor/symfony/polyfill-php73/Php73.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php73; + +/** + * @author Gabriel Caruso + * @author Ion Bazan + * + * @internal + */ +final class Php73 +{ + public static $startAt = 1533462603; + + /** + * @param bool $asNum + * + * @return array|float|int + */ + public static function hrtime($asNum = false) + { + $ns = microtime(false); + $s = substr($ns, 11) - self::$startAt; + $ns = 1E9 * (float) $ns; + + if ($asNum) { + $ns += $s * 1E9; + + return \PHP_INT_SIZE === 4 ? $ns : (int) $ns; + } + + return [$s, (int) $ns]; + } +} diff --git a/vendor/symfony/polyfill-php73/README.md b/vendor/symfony/polyfill-php73/README.md new file mode 100644 index 000000000..032fafbda --- /dev/null +++ b/vendor/symfony/polyfill-php73/README.md @@ -0,0 +1,18 @@ +Symfony Polyfill / Php73 +======================== + +This component provides functions added to PHP 7.3 core: + +- [`array_key_first`](https://php.net/array_key_first) +- [`array_key_last`](https://php.net/array_key_last) +- [`hrtime`](https://php.net/function.hrtime) +- [`is_countable`](https://php.net/is_countable) +- [`JsonException`](https://php.net/JsonException) + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php b/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php new file mode 100644 index 000000000..f06d6c269 --- /dev/null +++ b/vendor/symfony/polyfill-php73/Resources/stubs/JsonException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 70300) { + class JsonException extends Exception + { + } +} diff --git a/vendor/symfony/polyfill-php73/bootstrap.php b/vendor/symfony/polyfill-php73/bootstrap.php new file mode 100644 index 000000000..d6b215382 --- /dev/null +++ b/vendor/symfony/polyfill-php73/bootstrap.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php73 as p; + +if (\PHP_VERSION_ID >= 70300) { + return; +} + +if (!function_exists('is_countable')) { + function is_countable($value) { return is_array($value) || $value instanceof Countable || $value instanceof ResourceBundle || $value instanceof SimpleXmlElement; } +} +if (!function_exists('hrtime')) { + require_once __DIR__.'/Php73.php'; + p\Php73::$startAt = (int) microtime(true); + function hrtime($as_number = false) { return p\Php73::hrtime($as_number); } +} +if (!function_exists('array_key_first')) { + function array_key_first(array $array) { foreach ($array as $key => $value) { return $key; } } +} +if (!function_exists('array_key_last')) { + function array_key_last(array $array) { return key(array_slice($array, -1, 1, true)); } +} diff --git a/vendor/symfony/polyfill-php73/composer.json b/vendor/symfony/polyfill-php73/composer.json new file mode 100644 index 000000000..48295ef97 --- /dev/null +++ b/vendor/symfony/polyfill-php73/composer.json @@ -0,0 +1,36 @@ +{ + "name": "symfony/polyfill-php73", + "type": "library", + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php73\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/vendor/symfony/polyfill-php80/LICENSE b/vendor/symfony/polyfill-php80/LICENSE new file mode 100644 index 000000000..0ed3a2465 --- /dev/null +++ b/vendor/symfony/polyfill-php80/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/polyfill-php80/Php80.php b/vendor/symfony/polyfill-php80/Php80.php new file mode 100644 index 000000000..362dd1a95 --- /dev/null +++ b/vendor/symfony/polyfill-php80/Php80.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php80; + +/** + * @author Ion Bazan + * @author Nico Oelgart + * @author Nicolas Grekas + * + * @internal + */ +final class Php80 +{ + public static function fdiv(float $dividend, float $divisor): float + { + return @($dividend / $divisor); + } + + public static function get_debug_type($value): string + { + switch (true) { + case null === $value: return 'null'; + case \is_bool($value): return 'bool'; + case \is_string($value): return 'string'; + case \is_array($value): return 'array'; + case \is_int($value): return 'int'; + case \is_float($value): return 'float'; + case \is_object($value): break; + case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class'; + default: + if (null === $type = @get_resource_type($value)) { + return 'unknown'; + } + + if ('Unknown' === $type) { + $type = 'closed'; + } + + return "resource ($type)"; + } + + $class = \get_class($value); + + if (false === strpos($class, '@')) { + return $class; + } + + return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous'; + } + + public static function get_resource_id($res): int + { + if (!\is_resource($res) && null === @get_resource_type($res)) { + throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res))); + } + + return (int) $res; + } + + public static function preg_last_error_msg(): string + { + switch (preg_last_error()) { + case \PREG_INTERNAL_ERROR: + return 'Internal error'; + case \PREG_BAD_UTF8_ERROR: + return 'Malformed UTF-8 characters, possibly incorrectly encoded'; + case \PREG_BAD_UTF8_OFFSET_ERROR: + return 'The offset did not correspond to the beginning of a valid UTF-8 code point'; + case \PREG_BACKTRACK_LIMIT_ERROR: + return 'Backtrack limit exhausted'; + case \PREG_RECURSION_LIMIT_ERROR: + return 'Recursion limit exhausted'; + case \PREG_JIT_STACKLIMIT_ERROR: + return 'JIT stack limit exhausted'; + case \PREG_NO_ERROR: + return 'No error'; + default: + return 'Unknown error'; + } + } + + public static function str_contains(string $haystack, string $needle): bool + { + return '' === $needle || false !== strpos($haystack, $needle); + } + + public static function str_starts_with(string $haystack, string $needle): bool + { + return 0 === strncmp($haystack, $needle, \strlen($needle)); + } + + public static function str_ends_with(string $haystack, string $needle): bool + { + if ('' === $needle || $needle === $haystack) { + return true; + } + + if ('' === $haystack) { + return false; + } + + $needleLength = \strlen($needle); + + return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength); + } +} diff --git a/vendor/symfony/polyfill-php80/PhpToken.php b/vendor/symfony/polyfill-php80/PhpToken.php new file mode 100644 index 000000000..fe6e69105 --- /dev/null +++ b/vendor/symfony/polyfill-php80/PhpToken.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php80; + +/** + * @author Fedonyuk Anton + * + * @internal + */ +class PhpToken implements \Stringable +{ + /** + * @var int + */ + public $id; + + /** + * @var string + */ + public $text; + + /** + * @var int + */ + public $line; + + /** + * @var int + */ + public $pos; + + public function __construct(int $id, string $text, int $line = -1, int $position = -1) + { + $this->id = $id; + $this->text = $text; + $this->line = $line; + $this->pos = $position; + } + + public function getTokenName(): ?string + { + if ('UNKNOWN' === $name = token_name($this->id)) { + $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text; + } + + return $name; + } + + /** + * @param int|string|array $kind + */ + public function is($kind): bool + { + foreach ((array) $kind as $value) { + if (\in_array($value, [$this->id, $this->text], true)) { + return true; + } + } + + return false; + } + + public function isIgnorable(): bool + { + return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true); + } + + public function __toString(): string + { + return (string) $this->text; + } + + /** + * @return static[] + */ + public static function tokenize(string $code, int $flags = 0): array + { + $line = 1; + $position = 0; + $tokens = token_get_all($code, $flags); + foreach ($tokens as $index => $token) { + if (\is_string($token)) { + $id = \ord($token); + $text = $token; + } else { + [$id, $text, $line] = $token; + } + $tokens[$index] = new static($id, $text, $line, $position); + $position += \strlen($text); + } + + return $tokens; + } +} diff --git a/vendor/symfony/polyfill-php80/README.md b/vendor/symfony/polyfill-php80/README.md new file mode 100644 index 000000000..3816c559d --- /dev/null +++ b/vendor/symfony/polyfill-php80/README.md @@ -0,0 +1,25 @@ +Symfony Polyfill / Php80 +======================== + +This component provides features added to PHP 8.0 core: + +- [`Stringable`](https://php.net/stringable) interface +- [`fdiv`](https://php.net/fdiv) +- [`ValueError`](https://php.net/valueerror) class +- [`UnhandledMatchError`](https://php.net/unhandledmatcherror) class +- `FILTER_VALIDATE_BOOL` constant +- [`get_debug_type`](https://php.net/get_debug_type) +- [`PhpToken`](https://php.net/phptoken) class +- [`preg_last_error_msg`](https://php.net/preg_last_error_msg) +- [`str_contains`](https://php.net/str_contains) +- [`str_starts_with`](https://php.net/str_starts_with) +- [`str_ends_with`](https://php.net/str_ends_with) +- [`get_resource_id`](https://php.net/get_resource_id) + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php new file mode 100644 index 000000000..2b955423f --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#[Attribute(Attribute::TARGET_CLASS)] +final class Attribute +{ + public const TARGET_CLASS = 1; + public const TARGET_FUNCTION = 2; + public const TARGET_METHOD = 4; + public const TARGET_PROPERTY = 8; + public const TARGET_CLASS_CONSTANT = 16; + public const TARGET_PARAMETER = 32; + public const TARGET_ALL = 63; + public const IS_REPEATABLE = 64; + + /** @var int */ + public $flags; + + public function __construct(int $flags = self::TARGET_ALL) + { + $this->flags = $flags; + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php new file mode 100644 index 000000000..bd1212f6e --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) { + class PhpToken extends Symfony\Polyfill\Php80\PhpToken + { + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php new file mode 100644 index 000000000..7c62d7508 --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + interface Stringable + { + /** + * @return string + */ + public function __toString(); + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php new file mode 100644 index 000000000..01c6c6c8a --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + class UnhandledMatchError extends Error + { + } +} diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php new file mode 100644 index 000000000..783dbc28c --- /dev/null +++ b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + class ValueError extends Error + { + } +} diff --git a/vendor/symfony/polyfill-php80/bootstrap.php b/vendor/symfony/polyfill-php80/bootstrap.php new file mode 100644 index 000000000..e5f7dbc1a --- /dev/null +++ b/vendor/symfony/polyfill-php80/bootstrap.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php80 as p; + +if (\PHP_VERSION_ID >= 80000) { + return; +} + +if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) { + define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN); +} + +if (!function_exists('fdiv')) { + function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); } +} +if (!function_exists('preg_last_error_msg')) { + function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); } +} +if (!function_exists('str_contains')) { + function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('str_starts_with')) { + function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('str_ends_with')) { + function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('get_debug_type')) { + function get_debug_type($value): string { return p\Php80::get_debug_type($value); } +} +if (!function_exists('get_resource_id')) { + function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); } +} diff --git a/vendor/symfony/polyfill-php80/composer.json b/vendor/symfony/polyfill-php80/composer.json new file mode 100644 index 000000000..f1801f403 --- /dev/null +++ b/vendor/symfony/polyfill-php80/composer.json @@ -0,0 +1,40 @@ +{ + "name": "symfony/polyfill-php80", + "type": "library", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/vendor/symfony/service-contracts/.gitignore b/vendor/symfony/service-contracts/.gitignore new file mode 100644 index 000000000..c49a5d8df --- /dev/null +++ b/vendor/symfony/service-contracts/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/vendor/symfony/service-contracts/Attribute/Required.php b/vendor/symfony/service-contracts/Attribute/Required.php new file mode 100644 index 000000000..9df851189 --- /dev/null +++ b/vendor/symfony/service-contracts/Attribute/Required.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Attribute; + +/** + * A required dependency. + * + * This attribute indicates that a property holds a required dependency. The annotated property or method should be + * considered during the instantiation process of the containing class. + * + * @author Alexander M. Turek + */ +#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)] +final class Required +{ +} diff --git a/vendor/symfony/service-contracts/Attribute/SubscribedService.php b/vendor/symfony/service-contracts/Attribute/SubscribedService.php new file mode 100644 index 000000000..10d1bc38e --- /dev/null +++ b/vendor/symfony/service-contracts/Attribute/SubscribedService.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Attribute; + +use Symfony\Contracts\Service\ServiceSubscriberTrait; + +/** + * Use with {@see ServiceSubscriberTrait} to mark a method's return type + * as a subscribed service. + * + * @author Kevin Bond + */ +#[\Attribute(\Attribute::TARGET_METHOD)] +final class SubscribedService +{ + /** + * @param string|null $key The key to use for the service + * If null, use "ClassName::methodName" + */ + public function __construct( + public ?string $key = null + ) { + } +} diff --git a/vendor/symfony/service-contracts/CHANGELOG.md b/vendor/symfony/service-contracts/CHANGELOG.md new file mode 100644 index 000000000..7932e2613 --- /dev/null +++ b/vendor/symfony/service-contracts/CHANGELOG.md @@ -0,0 +1,5 @@ +CHANGELOG +========= + +The changelog is maintained for all Symfony contracts at the following URL: +https://github.com/symfony/contracts/blob/main/CHANGELOG.md diff --git a/vendor/symfony/service-contracts/LICENSE b/vendor/symfony/service-contracts/LICENSE new file mode 100644 index 000000000..74cdc2dbf --- /dev/null +++ b/vendor/symfony/service-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/service-contracts/README.md b/vendor/symfony/service-contracts/README.md new file mode 100644 index 000000000..41e054a10 --- /dev/null +++ b/vendor/symfony/service-contracts/README.md @@ -0,0 +1,9 @@ +Symfony Service Contracts +========================= + +A set of abstractions extracted out of the Symfony components. + +Can be used to build on semantics that the Symfony components proved useful - and +that already have battle tested implementations. + +See https://github.com/symfony/contracts/blob/main/README.md for more information. diff --git a/vendor/symfony/service-contracts/ResetInterface.php b/vendor/symfony/service-contracts/ResetInterface.php new file mode 100644 index 000000000..1af1075ee --- /dev/null +++ b/vendor/symfony/service-contracts/ResetInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * Provides a way to reset an object to its initial state. + * + * When calling the "reset()" method on an object, it should be put back to its + * initial state. This usually means clearing any internal buffers and forwarding + * the call to internal dependencies. All properties of the object should be put + * back to the same state it had when it was first ready to use. + * + * This method could be called, for example, to recycle objects that are used as + * services, so that they can be used to handle several requests in the same + * process loop (note that we advise making your services stateless instead of + * implementing this interface when possible.) + */ +interface ResetInterface +{ + public function reset(); +} diff --git a/vendor/symfony/service-contracts/ServiceLocatorTrait.php b/vendor/symfony/service-contracts/ServiceLocatorTrait.php new file mode 100644 index 000000000..74dfa4362 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceLocatorTrait.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; + +// Help opcache.preload discover always-needed symbols +class_exists(ContainerExceptionInterface::class); +class_exists(NotFoundExceptionInterface::class); + +/** + * A trait to help implement ServiceProviderInterface. + * + * @author Robin Chalas + * @author Nicolas Grekas + */ +trait ServiceLocatorTrait +{ + private $factories; + private $loading = []; + private $providedTypes; + + /** + * @param callable[] $factories + */ + public function __construct(array $factories) + { + $this->factories = $factories; + } + + /** + * {@inheritdoc} + * + * @return bool + */ + public function has(string $id) + { + return isset($this->factories[$id]); + } + + /** + * {@inheritdoc} + * + * @return mixed + */ + public function get(string $id) + { + if (!isset($this->factories[$id])) { + throw $this->createNotFoundException($id); + } + + if (isset($this->loading[$id])) { + $ids = array_values($this->loading); + $ids = \array_slice($this->loading, array_search($id, $ids)); + $ids[] = $id; + + throw $this->createCircularReferenceException($id, $ids); + } + + $this->loading[$id] = $id; + try { + return $this->factories[$id]($this); + } finally { + unset($this->loading[$id]); + } + } + + /** + * {@inheritdoc} + */ + public function getProvidedServices(): array + { + if (null === $this->providedTypes) { + $this->providedTypes = []; + + foreach ($this->factories as $name => $factory) { + if (!\is_callable($factory)) { + $this->providedTypes[$name] = '?'; + } else { + $type = (new \ReflectionFunction($factory))->getReturnType(); + + $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '').($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?'; + } + } + } + + return $this->providedTypes; + } + + private function createNotFoundException(string $id): NotFoundExceptionInterface + { + if (!$alternatives = array_keys($this->factories)) { + $message = 'is empty...'; + } else { + $last = array_pop($alternatives); + if ($alternatives) { + $message = sprintf('only knows about the "%s" and "%s" services.', implode('", "', $alternatives), $last); + } else { + $message = sprintf('only knows about the "%s" service.', $last); + } + } + + if ($this->loading) { + $message = sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $message); + } else { + $message = sprintf('Service "%s" not found: the current service locator %s', $id, $message); + } + + return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface { + }; + } + + private function createCircularReferenceException(string $id, array $path): ContainerExceptionInterface + { + return new class(sprintf('Circular reference detected for service "%s", path: "%s".', $id, implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface { + }; + } +} diff --git a/vendor/symfony/service-contracts/ServiceProviderInterface.php b/vendor/symfony/service-contracts/ServiceProviderInterface.php new file mode 100644 index 000000000..c60ad0bd4 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceProviderInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; + +/** + * A ServiceProviderInterface exposes the identifiers and the types of services provided by a container. + * + * @author Nicolas Grekas + * @author Mateusz Sip + */ +interface ServiceProviderInterface extends ContainerInterface +{ + /** + * Returns an associative array of service types keyed by the identifiers provided by the current container. + * + * Examples: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface + * * ['foo' => '?'] means the container provides service name "foo" of unspecified type + * * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null + * + * @return string[] The provided service types, keyed by service names + */ + public function getProvidedServices(): array; +} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberInterface.php b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php new file mode 100644 index 000000000..098ab908c --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceSubscriberInterface.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +/** + * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method. + * + * The getSubscribedServices method returns an array of service types required by such instances, + * optionally keyed by the service names used internally. Service types that start with an interrogation + * mark "?" are optional, while the other ones are mandatory service dependencies. + * + * The injected service locators SHOULD NOT allow access to any other services not specified by the method. + * + * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally. + * This interface does not dictate any injection method for these service locators, although constructor + * injection is recommended. + * + * @author Nicolas Grekas + */ +interface ServiceSubscriberInterface +{ + /** + * Returns an array of service types required by such instances, optionally keyed by the service names used internally. + * + * For mandatory dependencies: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name + * internally to fetch a service which must implement Psr\Log\LoggerInterface. + * * ['loggers' => 'Psr\Log\LoggerInterface[]'] means the objects use the "loggers" name + * internally to fetch an iterable of Psr\Log\LoggerInterface instances. + * * ['Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface'] + * + * otherwise: + * + * * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency + * * ['loggers' => '?Psr\Log\LoggerInterface[]'] denotes an optional iterable dependency + * * ['?Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface'] + * + * @return string[] The required service types, optionally keyed by service names + */ + public static function getSubscribedServices(); +} diff --git a/vendor/symfony/service-contracts/ServiceSubscriberTrait.php b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php new file mode 100644 index 000000000..16e3eb2c1 --- /dev/null +++ b/vendor/symfony/service-contracts/ServiceSubscriberTrait.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service; + +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\Attribute\SubscribedService; + +/** + * Implementation of ServiceSubscriberInterface that determines subscribed services from + * method return types. Service ids are available as "ClassName::methodName". + * + * @author Kevin Bond + */ +trait ServiceSubscriberTrait +{ + /** @var ContainerInterface */ + protected $container; + + /** + * {@inheritdoc} + */ + public static function getSubscribedServices(): array + { + $services = method_exists(get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : []; + $attributeOptIn = false; + + if (\PHP_VERSION_ID >= 80000) { + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + + if (!$attribute = $method->getAttributes(SubscribedService::class)[0] ?? null) { + continue; + } + + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + throw new \LogicException(sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name)); + } + + if (!$returnType = $method->getReturnType()) { + throw new \LogicException(sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class)); + } + + $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; + + if ($returnType->allowsNull()) { + $serviceId = '?'.$serviceId; + } + + $services[$attribute->newInstance()->key ?? self::class.'::'.$method->name] = $serviceId; + $attributeOptIn = true; + } + } + + if (!$attributeOptIn) { + foreach ((new \ReflectionClass(self::class))->getMethods() as $method) { + if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) { + continue; + } + + if (self::class !== $method->getDeclaringClass()->name) { + continue; + } + + if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) { + continue; + } + + if ($returnType->isBuiltin()) { + continue; + } + + if (\PHP_VERSION_ID >= 80000) { + trigger_deprecation('symfony/service-contracts', '2.5', 'Using "%s" in "%s" without using the "%s" attribute on any method is deprecated.', ServiceSubscriberTrait::class, self::class, SubscribedService::class); + } + + $services[self::class.'::'.$method->name] = '?'.($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType); + } + } + + return $services; + } + + /** + * @required + * + * @return ContainerInterface|null + */ + public function setContainer(ContainerInterface $container) + { + $this->container = $container; + + if (method_exists(get_parent_class(self::class) ?: '', __FUNCTION__)) { + return parent::setContainer($container); + } + + return null; + } +} diff --git a/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php new file mode 100644 index 000000000..2a1b565f5 --- /dev/null +++ b/vendor/symfony/service-contracts/Test/ServiceLocatorTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Contracts\Service\Test; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceLocatorTrait; + +abstract class ServiceLocatorTest extends TestCase +{ + /** + * @return ContainerInterface + */ + protected function getServiceLocator(array $factories) + { + return new class($factories) implements ContainerInterface { + use ServiceLocatorTrait; + }; + } + + public function testHas() + { + $locator = $this->getServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + function () { return 'dummy'; }, + ]); + + $this->assertTrue($locator->has('foo')); + $this->assertTrue($locator->has('bar')); + $this->assertFalse($locator->has('dummy')); + } + + public function testGet() + { + $locator = $this->getServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('baz', $locator->get('bar')); + } + + public function testGetDoesNotMemoize() + { + $i = 0; + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$i) { + ++$i; + + return 'bar'; + }, + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame(2, $i); + } + + public function testThrowsOnUndefinedInternalService() + { + if (!$this->getExpectedException()) { + $this->expectException(\Psr\Container\NotFoundExceptionInterface::class); + $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.'); + } + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $locator->get('foo'); + } + + public function testThrowsOnCircularReference() + { + $this->expectException(\Psr\Container\ContainerExceptionInterface::class); + $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".'); + $locator = $this->getServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + 'bar' => function () use (&$locator) { return $locator->get('baz'); }, + 'baz' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $locator->get('foo'); + } +} diff --git a/vendor/symfony/service-contracts/composer.json b/vendor/symfony/service-contracts/composer.json new file mode 100644 index 000000000..f05863701 --- /dev/null +++ b/vendor/symfony/service-contracts/composer.json @@ -0,0 +1,42 @@ +{ + "name": "symfony/service-contracts", + "type": "library", + "description": "Generic abstractions related to writing services", + "keywords": ["abstractions", "contracts", "decoupling", "interfaces", "interoperability", "standards"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "autoload": { + "psr-4": { "Symfony\\Contracts\\Service\\": "" } + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + } +} From 2218a7c93359bb2d49b1fb6e91db50e915f73f46 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 11:26:49 +0200 Subject: [PATCH 3/9] spaces: create link --- models/digitalocean-spaces-browser.class.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index 9efe9d866..344d35935 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -26,11 +26,19 @@ function get_custom_domain_url( $link, $bucket, $custom_domain ) { // Legacy function init_for_gutenberg() {} + function get_endpoint() { + global $FV_Player_DigitalOcean_Spaces; + + $endpoint = 'https://' . $FV_Player_DigitalOcean_Spaces->get_endpoint(); + + return $endpoint; + } + function get_s3_client() { global $fv_fp, $FV_Player_DigitalOcean_Spaces; // instantiate the S3 client with AWS credentials - $endpoint = 'https://' . $FV_Player_DigitalOcean_Spaces->get_endpoint(); + $endpoint = $this->get_endpoint(); $region = $FV_Player_DigitalOcean_Spaces->get_region(); @@ -99,7 +107,9 @@ function get_formatted_assets_data() { $item['size'] = $object->getSize(); $item['type'] = 'file'; - $item['link'] = ''; + $link = $this->get_endpoint() . '/' . $bucket . '/' . $path; + + $item['link'] = $link; } else { $item['type'] = 'folder'; From 8ed1cce78d1f0f76bfb15de4e22fba4027ecd07a Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 11:36:46 +0200 Subject: [PATCH 4/9] spaces: folders, use get_s3_async_aws_client for async aws --- models/digitalocean-spaces-browser.class.php | 57 +++++++++++++++----- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index 344d35935..ca875593c 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -37,6 +37,27 @@ function get_endpoint() { function get_s3_client() { global $fv_fp, $FV_Player_DigitalOcean_Spaces; + // instantiate the S3 client with AWS credentials + $endpoint = 'https://' . $FV_Player_DigitalOcean_Spaces->get_endpoint(); + + $region = $FV_Player_DigitalOcean_Spaces->get_region(); + + $secret = $fv_fp->_get_option(array('digitalocean_spaces','secret')); + $key = $fv_fp->_get_option(array('digitalocean_spaces','key')); + + $credentials = new Aws\Credentials\Credentials( $key, $secret ); + + return Aws\S3\S3Client::factory( array( + 'credentials' => $credentials, + 'region' => $region, + 'version' => 'latest', + 'endpoint' => $endpoint + ) ); + } + + function get_s3_async_aws_client() { + global $fv_fp, $FV_Player_DigitalOcean_Spaces; + // instantiate the S3 client with AWS credentials $endpoint = $this->get_endpoint(); @@ -70,8 +91,7 @@ function get_formatted_assets_data() { $output = $this->get_output(); // instantiate the S3 client with AWS credentials - $s3Client = $this->get_s3_client(); - + $s3Client = $this->get_s3_async_aws_client(); try { $args = array( @@ -89,6 +109,7 @@ function get_formatted_assets_data() { $paged = $s3Client->listObjectsV2($args); + // files foreach ($paged->getContents() as $object) { $path = $object->getKey(); @@ -99,23 +120,35 @@ function get_formatted_assets_data() { } else { $item['name'] = $path; } + $dateString = $object->getLastModified()->format('Y-m-d H:i:s'); + $timetamp = strtotime($dateString); + $item['modified'] = date($date_format, $timetamp); + $item['size'] = $object->getSize(); + $item['type'] = 'file'; + + $link = $this->get_endpoint() . '/' . $bucket . '/' . $path; - if( $object->getSize() ) { - $dateString = $object->getLastModified()->format('Y-m-d H:i:s'); - $timetamp = strtotime($dateString); - $item['modified'] = date($date_format, $timetamp); - $item['size'] = $object->getSize(); - $item['type'] = 'file'; + $item['link'] = $link; - $link = $this->get_endpoint() . '/' . $bucket . '/' . $path; + + $output['items'][] = $item; + } - $item['link'] = $link; + // folders + foreach( $paged->getCommonPrefixes() as $object ) { + $path = $object->getPrefix(); + $item['path'] = 'Home/' . $path; + + if( $request_path ) { + $item['name'] = str_replace( $request_path, '', $path ); } else { - $item['type'] = 'folder'; - $item['items'] = array(); + $item['name'] = $path; } + $item['type'] = 'folder'; + $item['items'] = array(); + $output['items'][] = $item; } From 2d07e940eaaef479481962e46d227a1c96a7c84a Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 11:42:43 +0200 Subject: [PATCH 5/9] spaces: add LastModified --- models/digitalocean-spaces-browser.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index ca875593c..12e791d31 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -123,6 +123,7 @@ function get_formatted_assets_data() { $dateString = $object->getLastModified()->format('Y-m-d H:i:s'); $timetamp = strtotime($dateString); $item['modified'] = date($date_format, $timetamp); + $item['LastModified'] = $timetamp; $item['size'] = $object->getSize(); $item['type'] = 'file'; From 3177e2a6e11958b0a45b275749f7d544de470568 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 11:51:19 +0200 Subject: [PATCH 6/9] spaces: LastModified for folders --- models/digitalocean-spaces-browser.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index 12e791d31..896c3957f 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -147,6 +147,8 @@ function get_formatted_assets_data() { $item['name'] = $path; } + $item['LastModified'] = 0; + $item['type'] = 'folder'; $item['items'] = array(); From 97f69c0aba5554231c47a98454758884339f346e Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 11:52:21 +0200 Subject: [PATCH 7/9] spaces: sorting fix --- models/digitalocean-spaces-browser.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index 896c3957f..ed2e91b18 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -169,8 +169,8 @@ function get_formatted_assets_data() { // sorting by date, descending // TODO: Make this an interface option? How to handle it for paged listings, like on Vimeo? function date_compare($a, $b) { - $t1 = strtotime($a['LastModified']); - $t2 = strtotime($b['LastModified']); + $t1 = $a['LastModified']; + $t2 = $b['LastModified']; return $t1 - $t2; } usort($output['items'], 'date_compare'); From c6dc732a55040d53ae0e7108fbf50dcee78889a5 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 12:21:12 +0200 Subject: [PATCH 8/9] spaces: link --- models/digitalocean-spaces-browser.class.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index ed2e91b18..9979901bc 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -29,9 +29,7 @@ function init_for_gutenberg() {} function get_endpoint() { global $FV_Player_DigitalOcean_Spaces; - $endpoint = 'https://' . $FV_Player_DigitalOcean_Spaces->get_endpoint(); - - return $endpoint; + return $FV_Player_DigitalOcean_Spaces->get_endpoint(); } function get_s3_client() { @@ -59,7 +57,7 @@ function get_s3_async_aws_client() { global $fv_fp, $FV_Player_DigitalOcean_Spaces; // instantiate the S3 client with AWS credentials - $endpoint = $this->get_endpoint(); + $endpoint = 'https://' . $this->get_endpoint(); $region = $FV_Player_DigitalOcean_Spaces->get_region(); @@ -127,11 +125,12 @@ function get_formatted_assets_data() { $item['size'] = $object->getSize(); $item['type'] = 'file'; - $link = $this->get_endpoint() . '/' . $bucket . '/' . $path; + $endpoint = $this->get_endpoint(); + + $link = 'https://' . $bucket . '.' . $endpoint . '/' . $path; $item['link'] = $link; - $output['items'][] = $item; } From 3030dfdd8842028df696d0161a727f42fe51f8d8 Mon Sep 17 00:00:00 2001 From: Michal Date: Tue, 5 Sep 2023 14:32:22 +0200 Subject: [PATCH 9/9] spaces: use getIterator --- models/digitalocean-spaces-browser.class.php | 55 +++++++++----------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/models/digitalocean-spaces-browser.class.php b/models/digitalocean-spaces-browser.class.php index 9979901bc..9afe61ca3 100644 --- a/models/digitalocean-spaces-browser.class.php +++ b/models/digitalocean-spaces-browser.class.php @@ -95,6 +95,7 @@ function get_formatted_assets_data() { $args = array( 'Bucket' => $bucket, 'Delimiter' => '/', + 'MaxKeys' => 1000, ); $date_format = get_option( 'date_format' ); @@ -107,36 +108,14 @@ function get_formatted_assets_data() { $paged = $s3Client->listObjectsV2($args); - // files - foreach ($paged->getContents() as $object) { - $path = $object->getKey(); - - $item['path'] = 'Home/' . $path; - - if( $request_path ) { - $item['name'] = str_replace( $request_path, '', $path ); + foreach($paged->getIterator() as $object) { + if( $object instanceof \AsyncAws\S3\ValueObject\AwsObject ) { + $path = $object->getKey(); } else { - $item['name'] = $path; + $path = $object->getPrefix(); } - $dateString = $object->getLastModified()->format('Y-m-d H:i:s'); - $timetamp = strtotime($dateString); - $item['modified'] = date($date_format, $timetamp); - $item['LastModified'] = $timetamp; - $item['size'] = $object->getSize(); - $item['type'] = 'file'; - - $endpoint = $this->get_endpoint(); - - $link = 'https://' . $bucket . '.' . $endpoint . '/' . $path; - $item['link'] = $link; - - $output['items'][] = $item; - } - - // folders - foreach( $paged->getCommonPrefixes() as $object ) { - $path = $object->getPrefix(); + $item = array(); $item['path'] = 'Home/' . $path; @@ -146,10 +125,24 @@ function get_formatted_assets_data() { $item['name'] = $path; } - $item['LastModified'] = 0; - - $item['type'] = 'folder'; - $item['items'] = array(); + if( $object instanceof \AsyncAws\S3\ValueObject\AwsObject ) { + $dateString = $object->getLastModified()->format('Y-m-d H:i:s'); + $timetamp = strtotime($dateString); + $item['modified'] = date($date_format, $timetamp); + $item['LastModified'] = $timetamp; + $item['size'] = $object->getSize(); + $item['type'] = 'file'; + + $endpoint = $this->get_endpoint(); + + $link = 'https://' . $bucket . '.' . $endpoint . '/' . $path; + + $item['link'] = $link; + } else { + $item['LastModified'] = 0; + $item['type'] = 'folder'; + $item['items'] = array(); + } $output['items'][] = $item; }