Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
ericsizemore committed Dec 24, 2023
1 parent fd74833 commit 4e01724
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 56 deletions.
56 changes: 32 additions & 24 deletions src/AbstractBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

// Functions and constants
use function is_dir, is_writable, json_decode, preg_match;
use function str_contains;
use const JSON_THROW_ON_ERROR;

/**
Expand Down Expand Up @@ -78,41 +79,37 @@ abstract class AbstractBase
*
* @var Client
*/
public Client $client;
protected Client $client;

/**
* Base API endpoint.
*
* @var string
*/
public const API_URL = 'https://libraries.io/api/';
final protected const API_URL = 'https://libraries.io/api/';

/**
* Libraries.io API key.
*
* @see https://libraries.io/account
* @var ?string
*/
public ?string $apiKey = null;
protected ?string $apiKey = null;

/**
* Path to your cache folder on the file system.
*
* @var ?string
*/
public ?string $cachePath = null;
protected ?string $cachePath = null;

/**
* Constructor.
*
* @param string $apiKey Your Libraries.io API Key
* @param ?string $cachePath The path to your cache on the filesystem
*/
public function __construct(
#[SensitiveParameter]
string $apiKey,
?string $cachePath = null
)
protected function __construct(#[SensitiveParameter] string $apiKey, ?string $cachePath = null)
{
if (preg_match('/^[0-9a-fA-F]{32}$/', $apiKey) === 0) {
throw new InvalidArgumentException('API key appears to be invalid, keys are typically alpha numeric and 32 chars in length');
Expand All @@ -132,7 +129,7 @@ public function __construct(
* @param array<string, int|string> $query
* @return Client
*/
public function makeClient(?array $query = null): Client
final protected function makeClient(?array $query = null): Client
{
// Some endpoints do not require any query parameters
if ($query === null) {
Expand All @@ -158,13 +155,9 @@ public function makeClient(?array $query = null): Client
$stack = HandlerStack::create();

// Add this middleware to the top with `push`
$stack->push(new CacheMiddleware(
new PrivateCacheStrategy(
new Psr6CacheStorage(
new FilesystemAdapter('libio', 60, $this->cachePath)
)
)
), 'cache');
$stack->push(new CacheMiddleware(new PrivateCacheStrategy(
new Psr6CacheStorage(new FilesystemAdapter('', 300, $this->cachePath))
)), 'cache');

// Add handler to $options
$options += ['handler' => $stack];
Expand All @@ -184,15 +177,15 @@ public function makeClient(?array $query = null): Client
* @return ResponseInterface
* @throws ClientException|GuzzleException
*/
public abstract function makeRequest(string $endpoint, array $options): ResponseInterface;
protected abstract function makeRequest(string $endpoint, array $options): ResponseInterface;

/**
* Processes the available parameters for a given endpoint.
*
* @param string $endpoint
* @return array<string, array<string>|string>
*/
public abstract function endpointParameters(string $endpoint): array;
protected abstract function endpointParameters(string $endpoint): array;

/**
* Each endpoint class will have a 'subset' of endpoints that fall under it. This
Expand All @@ -202,9 +195,9 @@ public abstract function endpointParameters(string $endpoint): array;
* @param array<string, int|string> $options
* @return string
*/
public function processEndpointFormat(string $format, array $options): string
final protected function processEndpointFormat(string $format, array $options): string
{
if (\str_contains($format, ':') === false) {
if (str_contains($format, ':') === false) {
return $format;
}

Expand All @@ -226,7 +219,7 @@ public function processEndpointFormat(string $format, array $options): string
* @param array<string, int|string> $options
* @return bool
*/
public function verifyEndpointOptions(array $endpointOptions, array $options): bool
final protected function verifyEndpointOptions(array $endpointOptions, array $options): bool
{
if ($endpointOptions === []) {
return true;
Expand All @@ -243,6 +236,19 @@ public function verifyEndpointOptions(array $endpointOptions, array $options): b
return $noError;
}

/**
* Returns the jSON data as-is from the API.
*
* @param ResponseInterface $response The response object from makeRequest()
* @return string
*/
public function raw(ResponseInterface $response): string
{
$json = $response->getBody()->getContents();

return $json;
}

/**
* Decodes the jSON returned from the API. Returns as an associative array.
*
Expand All @@ -252,8 +258,9 @@ public function verifyEndpointOptions(array $endpointOptions, array $options): b
*/
public function toArray(ResponseInterface $response): array
{
$json = $this->raw($response);
/** @var array<mixed> $json **/
$json = json_decode($response->getBody()->getContents(), true, flags: JSON_THROW_ON_ERROR);
$json = json_decode($json, true, flags: JSON_THROW_ON_ERROR);

return $json;
}
Expand All @@ -267,8 +274,9 @@ public function toArray(ResponseInterface $response): array
*/
public function toObject(ResponseInterface $response): array
{
$json = $this->raw($response);
/** @var array<mixed> $json **/
$json = json_decode($response->getBody()->getContents(), false, flags: JSON_THROW_ON_ERROR);
$json = json_decode($json, false, flags: JSON_THROW_ON_ERROR);

return $json;
}
Expand Down
4 changes: 0 additions & 4 deletions src/Exception/RateLimitExceededException.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/**
* @psalm-api
*/
final class RateLimitExceededException extends InvalidArgumentException
{
//
Expand Down
14 changes: 10 additions & 4 deletions src/Platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@

use InvalidArgumentException;

use Esi\LibrariesIO\{
Exception\RateLimitExceededException,
AbstractBase
};
use Esi\LibrariesIO\Exception\RateLimitExceededException;
use SensitiveParameter;

use GuzzleHttp\Exception\ClientException;
use Psr\Http\Message\ResponseInterface;
Expand Down Expand Up @@ -56,6 +54,14 @@
*/
final class Platform extends AbstractBase
{
/**
* {@inheritdoc}
*/
public function __construct(#[SensitiveParameter] string $apiKey, ?string $cachePath = null)
{
parent::__construct($apiKey, $cachePath);
}

/**
* {@inheritdoc}
*/
Expand Down
18 changes: 12 additions & 6 deletions src/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@

use InvalidArgumentException;

use Esi\LibrariesIO\{
Exception\RateLimitExceededException,
AbstractBase
};
use Esi\LibrariesIO\Exception\RateLimitExceededException;
use SensitiveParameter;

use GuzzleHttp\Exception\ClientException;
use Psr\Http\Message\ResponseInterface;
Expand Down Expand Up @@ -58,6 +56,14 @@
*/
final class Project extends AbstractBase
{
/**
* {@inheritdoc}
*/
public function __construct(#[SensitiveParameter] string $apiKey, ?string $cachePath = null)
{
parent::__construct($apiKey, $cachePath);
}

/**
* {@inheritdoc}
*/
Expand All @@ -77,7 +83,7 @@ public function makeRequest(string $endpoint, array $options): ResponseInterface

if (!parent::verifyEndpointOptions($endpointOptions, $options)) {
throw new InvalidArgumentException(
'$options has not specified all required parameters. Paremeters needed: ' . implode(', ', $endpointOptions)
'$options has not specified all required parameters. Parameters needed: ' . implode(', ', $endpointOptions)
);
}

Expand All @@ -94,7 +100,7 @@ public function makeRequest(string $endpoint, array $options): ResponseInterface
'sort' => $this->searchVerifySortOption(/** @phpstan-ignore-line **/$options['sort']),
];

// Search can also have: 'languages', 'licenses', 'keywords', 'platforms' as additional paremeters
// Search can also have: 'languages', 'licenses', 'keywords', 'platforms' as additional parameters
$additionalParams = $this->searchAdditionalParams($options);

if ($additionalParams !== []) {
Expand Down
20 changes: 12 additions & 8 deletions src/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
namespace Esi\LibrariesIO;

use InvalidArgumentException;
use Esi\LibrariesIO\{
Exception\RateLimitExceededException,
AbstractBase
};
use Esi\LibrariesIO\Exception\RateLimitExceededException;
use SensitiveParameter;

use GuzzleHttp\Exception\ClientException;
use Psr\Http\Message\ResponseInterface;

Expand Down Expand Up @@ -54,11 +53,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @psalm-api
*/
final class Repository extends AbstractBase
{
/**
* {@inheritdoc}
*/
public function __construct(#[SensitiveParameter] string $apiKey, ?string $cachePath = null)
{
parent::__construct($apiKey, $cachePath);
}

/**
* {@inheritdoc}
*/
Expand All @@ -78,7 +82,7 @@ public function makeRequest(string $endpoint, array $options): ResponseInterface

if (!parent::verifyEndpointOptions($endpointOptions, $options)) {
throw new InvalidArgumentException(
'$options has not specified all required parameters. Paremeters needed: ' . implode(', ', $endpointOptions)
'$options has not specified all required parameters. Parameters needed: ' . implode(', ', $endpointOptions)
);
}

Expand Down
23 changes: 13 additions & 10 deletions src/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@

use InvalidArgumentException;

use Esi\LibrariesIO\{
Exception\RateLimitExceededException,
AbstractBase
};
use Esi\LibrariesIO\Exception\RateLimitExceededException;
use SensitiveParameter;

use GuzzleHttp\Exception\ClientException;
use Psr\Http\Message\ResponseInterface;
Expand Down Expand Up @@ -56,11 +54,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @psalm-api
*/
final class User extends AbstractBase
{
/**
* {@inheritdoc}
*/
public function __construct(#[SensitiveParameter] string $apiKey, ?string $cachePath = null)
{
parent::__construct($apiKey, $cachePath);
}

/**
* {@inheritdoc}
*/
Expand All @@ -71,7 +74,7 @@ public function makeRequest(string $endpoint, array $options): ResponseInterface

if ($endpointParameters === []) {
throw new InvalidArgumentException(
'Invalid endpoint specified. Must be one of: dependencies, package_contributions, packages, repositories, repository_constributions, or subscriptions'
'Invalid endpoint specified. Must be one of: dependencies, package_contributions, packages, repositories, repository_contributions, or subscriptions'
);
}

Expand All @@ -80,7 +83,7 @@ public function makeRequest(string $endpoint, array $options): ResponseInterface

if (!parent::verifyEndpointOptions($endpointOptions, $options)) {
throw new InvalidArgumentException(
'$options has not specified all required parameters. Paremeters needed: ' . implode(', ', $endpointOptions)
'$options has not specified all required parameters. Parameters needed: ' . implode(', ', $endpointOptions)
. '. (login can be: username or username/repo) depending on the endpoint)'
);
}
Expand All @@ -96,7 +99,7 @@ public function makeRequest(string $endpoint, array $options): ResponseInterface

// Attempt the request
try {
return $this->client->get($endpointParameters['format']);
return $this->client->request('GET', $endpointParameters['format']);
} catch (ClientException $e) {
if ($e->getResponse()->getStatusCode() === 429) {
throw new RateLimitExceededException('Libraries.io API rate limit exceeded.', previous: $e);
Expand Down

0 comments on commit 4e01724

Please sign in to comment.