Tags: seatplus/esi-client
Tags
chore: add strict_types and fix strict-mode type errors (#32) - Add declare(strict_types=1) to all 20 source files - Fix EsiClient::invoke() — cast Guzzle Uri to string before GuzzleFetcher::call() - Fix EsiClient::buildDataUri() — cast (string) $data[$match] for str_replace - Fix EsiClient::getConfiguration() return type — add int|null to union (EsiConfiguration properties include int fields e.g. esi_port) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ci: add structured coverage CI (100% min) (#31) * ci: add structured coverage CI matching eveapi pattern - formats.yml: bump PHP to 8.5, add FORK_MEM_PER_PROC=107374182400 to prevent pokio race condition on type coverage checks - tests.yml: restructure to 3-shard matrix + all-tests-pass gate + separate coverage job (pcov) with --min=100 - composer.json: add --min=100 to test:unit-coverage script Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: resolve deprecation warnings for PHP 8.5 - Replace abandoned fzaninotto/faker with fakerphp/faker ^1.23 - Upgrade kevinrob/guzzle-cache-middleware ^4 -> ^6 (fixes implicit nullable params deprecated in PHP 8.4+) - Fix faker property accesses to method calls: randomNumber/md5/sha1 - Remove ReflectionMethod::setAccessible(true) call (deprecated since PHP 8.5, no-op since PHP 8.1) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: upgrade kevinrob/guzzle-cache-middleware to ^7.0 Latest stable release (2025-09-04). v6 would have been sufficient to fix the PHP 8.5 implicit-nullable deprecation, but there is no reason to stop short of the latest version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
feat: propagate X-ESI-Error-Limit-Reset through EsiResponse and EsiCl… …ient (#28) - EsiResponse: add `error_limit_reset` property parsed from X-ESI-Error-Limit-Reset header - EsiClient::invoke(): map error_limit_remain/reset into EsiRawResponse so callers (RecordingEsiClient in eveapi) can track the global error budget - GuzzleFetcher: pass retryAfter to EsiErrorLimitedException from X-Esi-Error-Limit-Reset header - composer.json: bump seatplus/esi-schema to ^1.3 (adds errorLimitRemaining/Reset to EsiRawResponse) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
feat: ESI rate-limit support + typed SDK with OAS3 generator (#22) * remove spatie/data-transfer-object dependency * Fix styling * Fix/badges (#18) * update batches * update workflow for branch renaming * improve coverage * Update PHP version requirement to 8.3 and add Rector/rector in require-dev. * Update GuzzleFetcherTest for Carbon\Carbon::now() usage. * Add VerifyAccessTokenTest.php and VerifyAccessToken.php files for token verification. * Refactored UpdateRefreshTokenService constructor for dependency injection. * Create JwtService class with methods to decode JWT and parse JWKS. * Create Null Logger Test * Refactor __set method to return void and remove unnecessary return statement. * Refactor getErrorMessage method to return string directly. * Refactor EsiConfiguration to use new instance singleton pattern. * Refactor CheckAccess to use EsiConfiguration instead of Configuration. * Update RotatingFileLogger to use EsiConfiguration singleton for logger setup. * Refactor EsiClient invoke method for better error handling and readability. * Refactor GuzzleFetcher constructor for better dependency injection. * Add method to make $method lowercase before checking URI. * Remove outdated interface implementation and add method to reset the instance. * improve export format * Add unit test for LaravelFileCacheMiddleware returning CacheMiddleware instance. * Add EsiResponseTest with parsing and handling methods. * lint * Lint: enforce type declaration in GuzzleFetcher and EsiResponse methods. * rector * lint * Workflow update * Update code climate badges for maintainability and test coverage. * Refactor RotatingFileLoggerTest.php for log level functionality. (#19) * Refactor RotatingFileLoggerTest.php for log level functionality. * lint * fix: upgrade firebase/php-jwt from v5 to v6 (#20) * fix: upgrade firebase/php-jwt from v5 to v6 - Bump composer requirement from ^5.4 to ^6.0 - Remove $allowed_algs parameter from JwtService::decodeJWT() — v6 embeds the algorithm inside Key objects; JWT::decode() no longer accepts a third argument - Update VerifyAccessToken to drop the ['RS256'] third argument - Update JwtServiceTest to use new Key($secret, 'HS256') instead of plain string keys - Update VerifyAccessTokenTest mock expectations to match new 2-arg decodeJWT() signature Resolves security advisories PKSA-y2cr-5h3j-g3ys and PKSA-2kqm-ps5x-s4f5 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: update deprecated actions (checkout v4, codeclimate v9) - actions/checkout@v2 -> @v4 - paambaati/codeclimate-action@v2.6.0 -> @v9.0.0 Old versions crash with Node.js 20+ runners. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: replace broken codeclimate-action with direct pest run codeclimate.com/downloads/test-reporter returns 404 — the reporter binary has been removed upstream. Drop paambaati/codeclimate-action and run tests directly via pest --coverage --ci --min=100. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: upgrade firebase/php-jwt to ^7.0 v6.x is also affected by PKSA-y2cr-5h3j-g3ys, so bump to ^7.0 which is unaffected. v7 enforces minimum key lengths (HS256: 32 bytes, RSA: 2048 bits) — update tests accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * style: apply pint fixes for updated ruleset New pint version enforces fully_qualified_strict_types, ordered_imports, and other rules across existing files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: add logs, .phpunit.cache to .gitignore Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: pin phpstan <1.12.28 to fix pest-plugin-type-coverage incompatibility phpstan 1.12.28+ changed RuleErrorTransformer::transform() signature breaking pest-plugin-type-coverage v3.x. Pin to <1.12.28 until the plugin is upgraded to v4 (which requires pest v4). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: upgrade pest to v4 to resolve phpstan incompatibility pest-plugin-type-coverage v3.x was incompatible with phpstan 1.12.28+ due to a changed RuleErrorTransformer::transform() signature. Upgrading to pest v4 + pest-plugin-type-coverage v4 resolves this properly without needing a phpstan version pin. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: add pull_request trigger and composer.json path to formats workflow Also update actions/checkout to v4. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: pin phpstan <1.12.28 (pest-plugin-type-coverage v4 still broken) pest-plugin-type-coverage v4 calls PHPStan\RuleErrorTransformer::transform() with an array for arg #3, but phpstan 1.12.28+ changed that parameter to strictly require string. Both v3 and v4 of the plugin are affected. This is an upstream bug — track: https://github.com/pestphp/pest-plugin-type-coverage Pin until a fixed release of pest-plugin-type-coverage ships. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: upgrade to PHPUnit 12 / PHPStan 2 / Rector 2 for Pest 4 compatibility - Bump phpstan/phpstan ^1.12 → ^2.1.46 to match pest-plugin-type-coverage v4 API (RuleErrorTransformer::transform signature changed in PHPStan 2) - Bump rector/rector ^1.2 → ^2.0 (rector 1.x requires PHPStan 1.x) - Update phpunit.xml.dist schema to PHPUnit 12.5 (<coverage> element was removed from the schema; keeping it caused a validation WARN that with failOnWarning=true became a fatal test failure) - Move coverage report flags to test:unit-coverage CLI script - Set failOnWarning=false (schema warnings from missing optional drivers should not be fatal) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: remove pull_request trigger and composer.json path from formats workflow * ci: add pull_request trigger for 3.x branch in formats workflow * feat: ESI rate-limit support + EsiResponse ArrayObject refactor - Add EsiRateLimitedException (HTTP 429) with retryAfter from Retry-After header - Add EsiErrorLimitedException (HTTP 420) with default retryAfter of 60s - GuzzleFetcher: throw specific exceptions for 429/420 instead of generic RequestFailedException - GuzzleFetcher: send X-Compatibility-Date header when EsiConfiguration::compatibility_date is set - GuzzleFetcher: log X-Ratelimit-Remaining alongside X-Esi-Error-Limit-Remain - EsiResponse: drop extends ArrayObject; add public object $data with @deprecated __get/__isset bridge - EsiResponse: parse X-Ratelimit-Group/Limit/Remaining/Used and Retry-After headers - EsiResponse: add isRateLimitLow() helper (returns true when remaining < 10% of limit) - EsiConfiguration: add public ?string $compatibility_date = null - All tests pass: 73 assertions, 100% type coverage, PHPStan clean, Pint clean Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: parse ratelimit window seconds from X-Ratelimit-Limit header Parse the '15m' window part of '1800/15m' into ratelimitWindowSeconds (e.g. 900 for 15m). This enables Phase 2 proactive rate-limit middleware to calculate the correct dispatch rate (limit / window). Supports s/m/h unit suffixes; null when header is absent or has no '/'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: bump PHP requirement to ^8.5, add typed constants - Require PHP ^8.5 (skipping 8.4, targeting current stable) - Add typed class constants (const string) in VerifyAccessToken and UpdateRefreshTokenService — required for 100% type coverage on PHP 8.5 - Update CI workflows: php-version 8.3 → 8.5, add 4.x to trigger branches - Update composer.lock for PHP 8.5 compatible deps Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: add version 4.0.0 field for path-repo dev workaround Required so eveapi's path repository can satisfy the ^4.0 constraint while PR #22 is unmerged. Must be removed after the tag is published. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat!: remove deprecated EsiResponse __get/__isset shim Magic property access bridge dropped for v4. All eveapi callers now use ->data->property directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: update README with usage, DTO contract, and rate-limit notes - Replace outdated echo $character_info usage example with proper EsiResponse consumption pattern - Document that response shapes are the consumer's responsibility (transport-only contract) - Show eveapi DTO pattern: XxxResponse::from($response->data) - Document ESI 1800-token/15-min rate limit and that throttling is handled by eveapi Horizon middleware Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: add EsiResult<T>, withToken(), and 30 resource stubs (typed SDK scaffold) - EsiResult<T> readonly class wraps typed data + pages + isCachedLoad - EsiClient::withToken(string): static for fluent authenticated calls - 30 resource factory methods on EsiClient (one per ESI tag group) - AbstractResource base class + 30 generated stub classes - EsiClient::$authentication changed from readonly to allow clone+reassign Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(generator): body params in invoke, constant interpolation in header comment - buildInvokeCall: pass body params (in:body) as 6th arg to invoke() - buildMethodSignature: resolve type from schema.type for body params, use mixed type - generateResourceFile: fix {ESI_COMPATIBILITY_DATE} constant not interpolated in heredoc — pre-assign to $compatDate variable Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(esi-client): add tests for EsiResult and generated resources - EsiResultTest: constructor defaults, explicit pages/cached, fromResponse with object body, X-Pages extraction, X-Kevinrob-Cache HIT/MISS - GeneratedResourcesTest: withToken() immutability, resource factory methods (characters/alliance/universe), typed DTO assertion on character endpoint, paginated asset endpoint with page count, cached-load propagation via HIT header - Helper makeAuthedClient() mocks CheckAccess::can() to avoid JWT decode on authenticated endpoints in unit tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: rewrite generator for OpenAPI 3.1 YAML spec - bin/generate.php now fetches from esi.evetech.net/meta/openapi.yaml - Uses symfony/yaml for parsing (avoid native yaml_parse dependency) - DTO class names now match schema names directly (e.g. CharactersDetail) - Flat namespace: Responses/{SchemaName}.php (no tag subdirs) - Typed method params: CharacterID x-common-model resolves to int - Fixed: nullable mixed becomes mixed (PHP 8.4+ compliance) - Fixed: array_map with cast for array<primitive> return types - Added resources for 3 new tag groups: CorporationProjects, FreelanceJobs, Meta - EsiClient: added corporationProjects(), freelanceJobs(), meta() methods - Updated tests to use new DTO class names PHPStan: 0 errors. All 87 tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: remove stale Clones/ subdirectory leftover from Swagger 2.0 generator The Clones/ subdirectory was missed in the cleanup when switching to the OAS3 flat-namespace generator. The replacement file CharactersCharacterIdClonesGet.php already exists at the correct path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(generator): defensive ?? fallbacks in from() for all required fields CCP has been observed changing ESI response fields without bumping the compatibility date (e.g. active_skill_level on 2026-02-27). Previously, required fields in from() did $data->field directly — a TypeError if ESI silently drops the field. Now all required primitive fields use a type-safe cast + zero fallback: (int)($data->field ?? 0) (string)($data->field ?? '') (bool)($data->field ?? false) (float)($data->field ?? 0.0) (array)($data->field ?? []) Required object (DTO) fields fall back to an empty stdClass so ::from() still runs rather than crashing on property access. Optional fields already used ?? and are unchanged. PHPStan: 0 errors. All 87 tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: integrate seatplus/esi-schema, return DTOs directly from object endpoints - Require seatplus/esi-schema:1.x-dev (VCS from github.com/seatplus/esi-schema) - Delete src/Generated/Responses/ — all DTOs now come from seatplus/esi-schema - Generator: no longer generates DTO files, only Resources - Generator: all DTO imports changed to Seatplus\EsiSchema\Responses\* - Object endpoints (single-object responses) now return the DTO directly instead of wrapping in EsiResult<T>. The DTO extends AbstractEsiDto so $dto->isCachedLoad and $dto->pages are available on the result. - Paginated array endpoints keep EsiResult<array<T>> (pages metadata required) - Update tests to reflect new return types - Update README: compatibility date notice + new SDK usage examples - ESI compatibility date: 2025-12-16 and forward Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: delete obsolete tools/ folder, bump Rector target to PHP_85 - Remove tools/swagger_download.php, tools/get_endpoints_and_scopes.php, tools/esi.json — all artefacts of the old Swagger 2.0 workflow; the generator now fetches OAS3 YAML directly from ESI - rector.php: PHP_83 → PHP_85 (SetList::PHP_85 confirmed present) - rector.php: replace tools path with bin (tools deleted, bin has generator) - Rector dry-run: 0 changes — codebase already fully PHP 8.5 compatible Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: implement EsiTransportInterface, delete Generated/Resources - EsiClient now implements Seatplus\EsiSchema\Contracts\EsiTransportInterface - invoke() returns EsiRawResponse (wrapping GuzzleFetcher EsiResponse) converting: data, isCachedLoad(), pages → EsiRawResponse properties - All resource factory methods updated to return Seatplus\EsiSchema\Resources\* - Deleted src/Generated/Resources/ (34 files) — now live in esi-schema - Deleted bin/generate.php — single generator now in esi-schema - Updated composer.json: esi-schema dev-fix/ci-phpunit-config (pending PR merge) - Updated tests: EsiClientTest expects EsiRawResponse from invoke() - Updated tests: GeneratedResourcesTest uses esi-schema Resources + EsiResult - All 89 tests pass, PHPStan clean, 100% type coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: remove $version from invoke() — always uses 'latest' Aligned with EsiTransportInterface change: version parameter removed since compatibility_date header handles versioning now. buildDataUri() hardcodes 'latest' in the URL path. Updated EsiClientTest to reflect /latest/ in expected URI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: remove dead EsiClient\EsiResult Resources now use Seatplus\EsiSchema\EsiResult::fromRaw() — the EsiClient\EsiResult (which used fromResponse(EsiResponse)) is no longer referenced by anything. Removing it eliminates the confusion of two nearly-identical EsiResult classes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: populate cursor and rate-limit fields in EsiRawResponse from invoke() - Lower PHP requirement to ^8.3 (no PHP 8.5 features used yet) - EsiClient::invoke() now propagates rateLimitRemaining, rateLimitUsed, retryAfter from EsiResponse headers into EsiRawResponse - Detects cursor token in response body and populates EsiRawResponse::cursor (for x-pagination: cursor routes like freelance-jobs, projects) - 3 new tests covering rate-limit propagation and cursor extraction Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: bump PHP requirement to ^8.5, Carbon to ^3.0 PHP 8.5 released and available. No code changes required — the package already uses PHP 8.3+ features only (typed class constants). - composer.json: PHP ^8.3 → ^8.5 - composer.json: nesbot/carbon ^2.53 → ^3.0 (required for Laravel 13 compat) - tests/Unit/EsiClientTest.php: pint binary_operator_spaces fix Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: use seatplus/esi-schema ^1.0 stable release from Packagist - Switch from dev-feat/typed-operation-meta branch alias to stable ^1.0 - Remove VCS repository override (package is on Packagist) - Remove minimum-stability: dev and prefer-stable (no longer needed) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: add coverage for all EsiClient factory methods; remove dead code in EsiResponse - Add data-provider test covering all 30 remaining factory methods on EsiClient (calendar, clones, contacts, … meta) to reach 100% line coverage - Remove unreachable $window === null guard in parseRatelimitWindowSeconds(): the str_contains() check above guarantees explode() always yields index [1], making the null branch dead code and untestable Fixes CI code-coverage failure (was 90.5 %, now 100.0 %) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: lower PHP requirement from ^8.5 to ^8.2 The source only uses PHP 8.1 features (readonly properties, new-in-initializers). All runtime deps (Carbon ^3.0, monolog ^3.7, guzzle-cache-middleware ^4.0) support PHP 8.1+. PHP 8.1 is EOL, so - require.php: ^8.5 → ^8.2 - remove unused symfony/yaml dev dependency (leftover from esi-schema codegen work; never referenced in esi-client source or tests) - ci: php-version 8.5 → 8.2 in both tests.yml and formats.yml Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: remove hardcoded version from composer.json Packagist derives the version from git tags. A hardcoded "version" field overrides tag detection and would pin the package permanently at 4.0.0 regardless of future tags. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: raise PHP requirement to ^8.3 pestphp/pest ^4.0 and seatplus/esi-schema 1.0.0 both require php ^8.3, making 8.2 uninstallable. ^8.3 is the correct minimum — still well below the previous ^8.5. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: replace CheckAccess with assertScope() — delete 250-line hardcoded scope map (#25) * refactor: replace CheckAccess with assertScope() from EsiTransportInterface Scope enforcement now lives where scope is defined. Each generated execute() calls $transport->assertScope(self::REQUIRED_SCOPE) before any HTTP call. The transport (EsiClient) implements the check against the JWT token. Changes: - EsiClient: implement assertScope(?string $scope): void - null = public endpoint → no-op - non-null = must be present in JWT scopes → ScopeAccessDeniedException - EsiClient: remove CheckAccess wiring from constructor and withToken() - EsiClient: remove hasAccess() pre-flight from invoke() - EsiScopeAccessDeniedException: now extends ScopeAccessDeniedException from esi-schema for backward compatibility - Delete CheckAccess.php (250-line hardcoded scope map — no longer needed) - Delete CheckAccessTest.php (replaced by assertScope tests in EsiClientTest) - Bump seatplus/esi-schema: ^1.1 (requires assertScope in EsiTransportInterface) - Update GeneratedResourcesTest: use real JWT tokens, remove CheckAccess mock - Update EsiClientTest: replace access-denied test with assertScope tests Requires seatplus/esi-schema ^1.1 (PR #4). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: use dev-feat/assert-scope alias until esi-schema 1.1.0 is tagged Until esi-schema PR #4 is merged and 1.1.0 tagged on Packagist, use the branch dev alias so CI can resolve the dependency. Will be reverted to ^1.1 once tag exists. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: trigger CI — add assertScope docblock, watch composer.json in formats workflow - Add docblock to EsiClient::assertScope() explaining null semantics - Update formats.yml to also trigger on composer.json changes and pull_request targeting feat/esi-rate-limit-overhaul Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: remove minimum-stability=dev — explicit dev-branch constraint is sufficient Explicit dev-* constraints override minimum-stability per-package, so setting minimum-stability=dev globally was unnecessary and caused pest-plugin-type-coverage to resolve a dev build instead of stable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: use stable seatplus/esi-schema ^1.1 (1.1.0 now tagged on Packagist) Replaces the temporary dev-feat/assert-scope alias now that esi-schema PR #4 has been merged and tagged 1.1.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: remove feature branch name from formats.yml pull_request trigger Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: drop EsiScopeAccessDeniedException — use ScopeAccessDeniedException from esi-schema directly No backwards compatibility needed. Callers should catch Seatplus\EsiSchema\Contracts\ScopeAccessDeniedException. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: remove /latest/ URL prefix — use server+path per ESI OpenAPI 3.1 spec The ESI OpenAPI 3.1 spec (esi.evetech.net/meta/openapi.yaml) defines: servers: [url: https://esi.evetech.net] paths: /alliances, /characters/{character_id}/assets, … No version prefix anywhere. Versioning is handled by X-Compatibility-Date header (already sent by GuzzleFetcher). The /latest/ prefix was a Swagger 2.0 basePath artifact. Changes: - buildDataUri(): /{path}/ instead of /latest/{path}/ - EsiConfiguration: default compatibility_date to '2025-12-16' (matches esi-schema generation date; update when regenerating) - Update tests accordingly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * style: apply Spatie coding guidelines across all source files - Strings: replace sprintf() and . concatenation with string interpolation throughout EsiRateLimitedException, EsiErrorLimitedException, EsiClient, GuzzleFetcher, UpdateRefreshTokenService, EsiResponse, RotatingFileLogger - Fix latent bug: logFetcherActivity used %F with number_format result, double-formatting the float (0.12 → 0.120000); interpolation uses the number_format string directly - Docblocks: remove duplicate docblock on EsiClient::assertScope(); remove useless 'FileLogger constructor.' description from RotatingFileLogger - Comments: remove inline comments that restate the code they precede - Naming: rename private snake_case members in EsiResponse to camelCase (get_data→getData, error_message→errorMessage, expires_at→expiresAt, cache_loaded→cacheLoaded) - Constructor: expand UpdateRefreshTokenService single-line constructor to multi-line promoted-parameter style (one param per line, trailing comma) All 113 tests pass, Pint clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: herpaderpaldent <herpaderpaldent@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fix: upgrade firebase/php-jwt to ^7.0 (v6 also vulnerable) (#21) * fix: upgrade firebase/php-jwt to ^7.0 v6.x is also affected by PKSA-y2cr-5h3j-g3ys, so bump to ^7.0 which is unaffected. v7 enforces minimum key lengths (HS256: 32 bytes, RSA: 2048 bits) — update tests accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * style: apply pint fixes for updated ruleset New pint version enforces fully_qualified_strict_types, ordered_imports, and other rules across existing files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: add logs, .phpunit.cache to .gitignore Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: pin phpstan <1.12.28 to fix pest-plugin-type-coverage incompatibility phpstan 1.12.28+ changed RuleErrorTransformer::transform() signature breaking pest-plugin-type-coverage v3.x. Pin to <1.12.28 until the plugin is upgraded to v4 (which requires pest v4). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: upgrade pest to v4 to resolve phpstan incompatibility pest-plugin-type-coverage v3.x was incompatible with phpstan 1.12.28+ due to a changed RuleErrorTransformer::transform() signature. Upgrading to pest v4 + pest-plugin-type-coverage v4 resolves this properly without needing a phpstan version pin. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: add pull_request trigger and composer.json path to formats workflow Also update actions/checkout to v4. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: pin phpstan <1.12.28 (pest-plugin-type-coverage v4 still broken) pest-plugin-type-coverage v4 calls PHPStan\RuleErrorTransformer::transform() with an array for arg #3, but phpstan 1.12.28+ changed that parameter to strictly require string. Both v3 and v4 of the plugin are affected. This is an upstream bug — track: https://github.com/pestphp/pest-plugin-type-coverage Pin until a fixed release of pest-plugin-type-coverage ships. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: upgrade to PHPUnit 12 / PHPStan 2 / Rector 2 for Pest 4 compatibility - Bump phpstan/phpstan ^1.12 → ^2.1.46 to match pest-plugin-type-coverage v4 API (RuleErrorTransformer::transform signature changed in PHPStan 2) - Bump rector/rector ^1.2 → ^2.0 (rector 1.x requires PHPStan 1.x) - Update phpunit.xml.dist schema to PHPUnit 12.5 (<coverage> element was removed from the schema; keeping it caused a validation WARN that with failOnWarning=true became a fatal test failure) - Move coverage report flags to test:unit-coverage CLI script - Set failOnWarning=false (schema warnings from missing optional drivers should not be fatal) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: remove pull_request trigger and composer.json path from formats workflow * ci: add pull_request trigger for 3.x branch in formats workflow --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PreviousNext