From e8684893f2f7c4ab6d75c2be56fc9f2d7c6a5323 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 05:23:01 +0000 Subject: [PATCH 1/8] chore(internal): remove mock server code --- scripts/mock | 41 ----------------------------------------- scripts/test | 46 ---------------------------------------------- 2 files changed, 87 deletions(-) delete mode 100755 scripts/mock diff --git a/scripts/mock b/scripts/mock deleted file mode 100755 index 0b28f6e..0000000 --- a/scripts/mock +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "$(dirname "$0")/.." - -if [[ -n "$1" && "$1" != '--'* ]]; then - URL="$1" - shift -else - URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)" -fi - -# Check if the URL is empty -if [ -z "$URL" ]; then - echo "Error: No OpenAPI spec path/url provided or found in .stats.yml" - exit 1 -fi - -echo "==> Starting mock server with URL ${URL}" - -# Run prism mock on the given spec -if [ "$1" == "--daemon" ]; then - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log & - - # Wait for server to come online - echo -n "Waiting for server" - while ! grep -q "✖ fatal\|Prism is listening" ".prism.log" ; do - echo -n "." - sleep 0.1 - done - - if grep -q "✖ fatal" ".prism.log"; then - cat .prism.log - exit 1 - fi - - echo -else - npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" -fi diff --git a/scripts/test b/scripts/test index 4b777e0..63df137 100755 --- a/scripts/test +++ b/scripts/test @@ -4,52 +4,6 @@ set -e cd "$(dirname "$0")/.." -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -NC='\033[0m' # No Color -function prism_is_running() { - curl --silent "http://localhost:4010" >/dev/null 2>&1 -} - -kill_server_on_port() { - pids=$(lsof -t -i tcp:"$1" || echo "") - if [ "$pids" != "" ]; then - kill "$pids" - echo "Stopped $pids." - fi -} - -function is_overriding_api_base_url() { - [ -n "$TEST_API_BASE_URL" ] -} - -if ! is_overriding_api_base_url && ! prism_is_running ; then - # When we exit this script, make sure to kill the background mock server process - trap 'kill_server_on_port 4010' EXIT - - # Start the dev server - ./scripts/mock --daemon -fi - -if is_overriding_api_base_url ; then - echo -e "${GREEN}✔ Running tests against ${TEST_API_BASE_URL}${NC}" - echo -elif ! prism_is_running ; then - echo -e "${RED}ERROR:${NC} The test suite will not run without a mock Prism server" - echo -e "running against your OpenAPI spec." - echo - echo -e "To run the server, pass in the path or url of your OpenAPI" - echo -e "spec to the prism command:" - echo - echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}" - echo - - exit 1 -else - echo -e "${GREEN}✔ Mock prism server is running with your OpenAPI spec${NC}" - echo -fi exec -- ./vendor/bin/pest --colors=always From 8a17bdee09cb200c74522cdf7ed35f8934ba4ecd Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 05:23:57 +0000 Subject: [PATCH 2/8] chore: update mock server docs --- tests/Services/AccessTokenTest.php | 2 +- tests/Services/CamsKfintechTest.php | 2 +- tests/Services/Cdsl/FetchTest.php | 8 ++++---- tests/Services/CdslTest.php | 2 +- tests/Services/ContractNoteTest.php | 2 +- tests/Services/CreditsTest.php | 2 +- tests/Services/InboxTest.php | 16 ++++++++-------- tests/Services/KfintechTest.php | 4 ++-- tests/Services/LogsTest.php | 4 ++-- tests/Services/NsdlTest.php | 2 +- tests/Services/SmartTest.php | 2 +- tests/Services/VerifyTokenTest.php | 2 +- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/Services/AccessTokenTest.php b/tests/Services/AccessTokenTest.php index d46346f..bb5ae62 100644 --- a/tests/Services/AccessTokenTest.php +++ b/tests/Services/AccessTokenTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testCreate(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->accessToken->create(); diff --git a/tests/Services/CamsKfintechTest.php b/tests/Services/CamsKfintechTest.php index bd5095b..7febae0 100644 --- a/tests/Services/CamsKfintechTest.php +++ b/tests/Services/CamsKfintechTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testParse(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->camsKfintech->parse(); diff --git a/tests/Services/Cdsl/FetchTest.php b/tests/Services/Cdsl/FetchTest.php index 64a2678..5b044ff 100644 --- a/tests/Services/Cdsl/FetchTest.php +++ b/tests/Services/Cdsl/FetchTest.php @@ -33,7 +33,7 @@ protected function setUp(): void public function testRequestOtp(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->cdsl->fetch->requestOtp( @@ -50,7 +50,7 @@ public function testRequestOtp(): void public function testRequestOtpWithOptionalParams(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->cdsl->fetch->requestOtp( @@ -67,7 +67,7 @@ public function testRequestOtpWithOptionalParams(): void public function testVerifyOtp(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->cdsl->fetch->verifyOtp( @@ -83,7 +83,7 @@ public function testVerifyOtp(): void public function testVerifyOtpWithOptionalParams(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->cdsl->fetch->verifyOtp( diff --git a/tests/Services/CdslTest.php b/tests/Services/CdslTest.php index ba35fd5..de3b3ad 100644 --- a/tests/Services/CdslTest.php +++ b/tests/Services/CdslTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testParsePdf(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->cdsl->parsePdf(); diff --git a/tests/Services/ContractNoteTest.php b/tests/Services/ContractNoteTest.php index 57f171b..37b12c7 100644 --- a/tests/Services/ContractNoteTest.php +++ b/tests/Services/ContractNoteTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testParse(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->contractNote->parse(); diff --git a/tests/Services/CreditsTest.php b/tests/Services/CreditsTest.php index c658279..70e7b80 100644 --- a/tests/Services/CreditsTest.php +++ b/tests/Services/CreditsTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testCheck(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->credits->check(); diff --git a/tests/Services/InboxTest.php b/tests/Services/InboxTest.php index 236a1aa..f7d2e8e 100644 --- a/tests/Services/InboxTest.php +++ b/tests/Services/InboxTest.php @@ -35,7 +35,7 @@ protected function setUp(): void public function testCheckConnectionStatus(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->checkConnectionStatus( @@ -50,7 +50,7 @@ public function testCheckConnectionStatus(): void public function testCheckConnectionStatusWithOptionalParams(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->checkConnectionStatus( @@ -65,7 +65,7 @@ public function testCheckConnectionStatusWithOptionalParams(): void public function testConnectEmail(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->connectEmail( @@ -80,7 +80,7 @@ public function testConnectEmail(): void public function testConnectEmailWithOptionalParams(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->connectEmail( @@ -96,7 +96,7 @@ public function testConnectEmailWithOptionalParams(): void public function testDisconnectEmail(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->disconnectEmail( @@ -111,7 +111,7 @@ public function testDisconnectEmail(): void public function testDisconnectEmailWithOptionalParams(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->disconnectEmail( @@ -126,7 +126,7 @@ public function testDisconnectEmailWithOptionalParams(): void public function testListCasFiles(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->listCasFiles(xInboxToken: 'x-inbox-token'); @@ -139,7 +139,7 @@ public function testListCasFiles(): void public function testListCasFilesWithOptionalParams(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->inbox->listCasFiles( diff --git a/tests/Services/KfintechTest.php b/tests/Services/KfintechTest.php index d181b1d..934dd0d 100644 --- a/tests/Services/KfintechTest.php +++ b/tests/Services/KfintechTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testGenerateCas(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->kfintech->generateCas( @@ -50,7 +50,7 @@ public function testGenerateCas(): void public function testGenerateCasWithOptionalParams(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->kfintech->generateCas( diff --git a/tests/Services/LogsTest.php b/tests/Services/LogsTest.php index fefa01f..1f4c4da 100644 --- a/tests/Services/LogsTest.php +++ b/tests/Services/LogsTest.php @@ -33,7 +33,7 @@ protected function setUp(): void public function testCreate(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->logs->create(); @@ -46,7 +46,7 @@ public function testCreate(): void public function testGetSummary(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->logs->getSummary(); diff --git a/tests/Services/NsdlTest.php b/tests/Services/NsdlTest.php index ba72197..e41f048 100644 --- a/tests/Services/NsdlTest.php +++ b/tests/Services/NsdlTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testParse(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->nsdl->parse(); diff --git a/tests/Services/SmartTest.php b/tests/Services/SmartTest.php index 95305b4..ab62d05 100644 --- a/tests/Services/SmartTest.php +++ b/tests/Services/SmartTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testParseCasPdf(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->smart->parseCasPdf(); diff --git a/tests/Services/VerifyTokenTest.php b/tests/Services/VerifyTokenTest.php index 16b7649..36549b1 100644 --- a/tests/Services/VerifyTokenTest.php +++ b/tests/Services/VerifyTokenTest.php @@ -32,7 +32,7 @@ protected function setUp(): void public function testVerify(): void { if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Prism tests are disabled'); + $this->markTestSkipped('Mock server tests are disabled'); } $result = $this->client->verifyToken->verify(); From c0fc7b8b4284930ca1d6eec4c58e88b026cf2da5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:17:44 +0000 Subject: [PATCH 3/8] feat(api): api update --- .stats.yml | 6 +- README.md | 10 +- src/AccessToken/AccessTokenCreateParams.php | 68 -------- src/AccessToken/AccessTokenNewResponse.php | 95 ---------- src/Credits/CreditCheckResponse.php | 163 ------------------ src/Logs/LogCreateParams.php | 106 ------------ src/Logs/LogGetSummaryParams.php | 84 --------- src/Logs/LogGetSummaryResponse.php | 72 -------- src/Logs/LogGetSummaryResponse/Summary.php | 106 ------------ .../Summary/ByFeature.php | 95 ---------- src/Logs/LogNewResponse.php | 92 ---------- src/Logs/LogNewResponse/Log.php | 157 ----------------- src/ServiceContracts/AccessTokenContract.php | 23 +-- .../AccessTokenRawContract.php | 27 +-- src/ServiceContracts/CreditsContract.php | 21 +-- src/ServiceContracts/CreditsRawContract.php | 24 +-- src/ServiceContracts/LogsContract.php | 43 +---- src/ServiceContracts/LogsRawContract.php | 44 +---- src/ServiceContracts/VerifyTokenContract.php | 21 +-- .../VerifyTokenRawContract.php | 24 +-- src/Services/AccessTokenRawService.php | 47 ----- src/Services/AccessTokenService.php | 38 +--- src/Services/CreditsRawService.php | 37 ---- src/Services/CreditsService.php | 32 +--- src/Services/LogsRawService.php | 81 --------- src/Services/LogsService.php | 68 +------- src/Services/VerifyTokenRawService.php | 31 ---- src/Services/VerifyTokenService.php | 26 +-- src/VerifyToken/VerifyTokenVerifyResponse.php | 95 ---------- tests/ClientTest.php | 2 +- tests/Services/AccessTokenTest.php | 43 ----- tests/Services/CreditsTest.php | 43 ----- tests/Services/LogsTest.php | 57 ------ tests/Services/VerifyTokenTest.php | 43 ----- 34 files changed, 21 insertions(+), 1903 deletions(-) delete mode 100644 src/AccessToken/AccessTokenCreateParams.php delete mode 100644 src/AccessToken/AccessTokenNewResponse.php delete mode 100644 src/Credits/CreditCheckResponse.php delete mode 100644 src/Logs/LogCreateParams.php delete mode 100644 src/Logs/LogGetSummaryParams.php delete mode 100644 src/Logs/LogGetSummaryResponse.php delete mode 100644 src/Logs/LogGetSummaryResponse/Summary.php delete mode 100644 src/Logs/LogGetSummaryResponse/Summary/ByFeature.php delete mode 100644 src/Logs/LogNewResponse.php delete mode 100644 src/Logs/LogNewResponse/Log.php delete mode 100644 src/VerifyToken/VerifyTokenVerifyResponse.php delete mode 100644 tests/Services/AccessTokenTest.php delete mode 100644 tests/Services/CreditsTest.php delete mode 100644 tests/Services/LogsTest.php delete mode 100644 tests/Services/VerifyTokenTest.php diff --git a/.stats.yml b/.stats.yml index 56f5a81..80a6900 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 17 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-56b0f699c5437d9e5326626d35dfc972c17d01f12cb416c7f4854c8ea6d0e95e.yml -openapi_spec_hash: 158f405c1880706266d83e6ff16b9d2f +configured_endpoints: 12 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-6a9d3b677dcfb856dc571865c34b3fe401e4d7f0d799edfc743acb9a55800bd0.yml +openapi_spec_hash: 037703a6c741e4310fda3f57c22fa51e config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/README.md b/README.md index e37f9da..17ea850 100644 --- a/README.md +++ b/README.md @@ -45,9 +45,9 @@ $client = new Client( environment: 'environment_1', ); -$response = $client->credits->check(); +$unifiedResponse = $client->camsKfintech->parse(); -var_dump($response->enabled_features); +var_dump($unifiedResponse->demat_accounts); ``` ### Value Objects @@ -69,7 +69,7 @@ use CasParser\Core\Exceptions\RateLimitException; use CasParser\Core\Exceptions\APIStatusException; try { - $response = $client->credits->check(); + $unifiedResponse = $client->camsKfintech->parse(); } catch (APIConnectionException $e) { echo "The server could not be reached", PHP_EOL; var_dump($e->getPrevious()); @@ -114,7 +114,7 @@ use CasParser\Client; $client = new Client(requestOptions: ['maxRetries' => 0]); // Or, configure per-request: -$result = $client->credits->check(requestOptions: ['maxRetries' => 5]); +$result = $client->camsKfintech->parse(requestOptions: ['maxRetries' => 5]); ``` ## Advanced concepts @@ -130,7 +130,7 @@ Note: the `extra*` parameters of the same name overrides the documented paramete ```php credits->check( +$unifiedResponse = $client->camsKfintech->parse( requestOptions: [ 'extraQueryParams' => ['my_query_parameter' => 'value'], 'extraBodyParams' => ['my_body_parameter' => 'value'], diff --git a/src/AccessToken/AccessTokenCreateParams.php b/src/AccessToken/AccessTokenCreateParams.php deleted file mode 100644 index f433ba8..0000000 --- a/src/AccessToken/AccessTokenCreateParams.php +++ /dev/null @@ -1,68 +0,0 @@ - */ - use SdkModel; - use SdkParams; - - /** - * Token validity in minutes (max 60). - */ - #[Optional('expiry_minutes')] - public ?int $expiryMinutes; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - */ - public static function with(?int $expiryMinutes = null): self - { - $self = new self; - - null !== $expiryMinutes && $self['expiryMinutes'] = $expiryMinutes; - - return $self; - } - - /** - * Token validity in minutes (max 60). - */ - public function withExpiryMinutes(int $expiryMinutes): self - { - $self = clone $this; - $self['expiryMinutes'] = $expiryMinutes; - - return $self; - } -} diff --git a/src/AccessToken/AccessTokenNewResponse.php b/src/AccessToken/AccessTokenNewResponse.php deleted file mode 100644 index 9dace1d..0000000 --- a/src/AccessToken/AccessTokenNewResponse.php +++ /dev/null @@ -1,95 +0,0 @@ - */ - use SdkModel; - - /** - * The at_ prefixed access token. - */ - #[Optional('access_token')] - public ?string $accessToken; - - /** - * Token validity in seconds. - */ - #[Optional('expires_in')] - public ?int $expiresIn; - - /** - * Always "api_key" - token is a drop-in replacement for x-api-key header. - */ - #[Optional('token_type')] - public ?string $tokenType; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - */ - public static function with( - ?string $accessToken = null, - ?int $expiresIn = null, - ?string $tokenType = null - ): self { - $self = new self; - - null !== $accessToken && $self['accessToken'] = $accessToken; - null !== $expiresIn && $self['expiresIn'] = $expiresIn; - null !== $tokenType && $self['tokenType'] = $tokenType; - - return $self; - } - - /** - * The at_ prefixed access token. - */ - public function withAccessToken(string $accessToken): self - { - $self = clone $this; - $self['accessToken'] = $accessToken; - - return $self; - } - - /** - * Token validity in seconds. - */ - public function withExpiresIn(int $expiresIn): self - { - $self = clone $this; - $self['expiresIn'] = $expiresIn; - - return $self; - } - - /** - * Always "api_key" - token is a drop-in replacement for x-api-key header. - */ - public function withTokenType(string $tokenType): self - { - $self = clone $this; - $self['tokenType'] = $tokenType; - - return $self; - } -} diff --git a/src/Credits/CreditCheckResponse.php b/src/Credits/CreditCheckResponse.php deleted file mode 100644 index c0983a6..0000000 --- a/src/Credits/CreditCheckResponse.php +++ /dev/null @@ -1,163 +0,0 @@ -|null, - * isUnlimited?: bool|null, - * limit?: int|null, - * remaining?: float|null, - * resetsAt?: \DateTimeInterface|null, - * used?: float|null, - * } - */ -final class CreditCheckResponse implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * List of API features enabled for your plan. - * - * @var list|null $enabledFeatures - */ - #[Optional('enabled_features', list: 'string')] - public ?array $enabledFeatures; - - /** - * Whether the account has unlimited credits. - */ - #[Optional('is_unlimited')] - public ?bool $isUnlimited; - - /** - * Total credit limit for billing period. - */ - #[Optional] - public ?int $limit; - - /** - * Remaining credits (null if unlimited). - */ - #[Optional(nullable: true)] - public ?float $remaining; - - /** - * When credits reset (ISO 8601). - */ - #[Optional('resets_at', nullable: true)] - public ?\DateTimeInterface $resetsAt; - - /** - * Number of credits used this billing period. - */ - #[Optional] - public ?float $used; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - * - * @param list|null $enabledFeatures - */ - public static function with( - ?array $enabledFeatures = null, - ?bool $isUnlimited = null, - ?int $limit = null, - ?float $remaining = null, - ?\DateTimeInterface $resetsAt = null, - ?float $used = null, - ): self { - $self = new self; - - null !== $enabledFeatures && $self['enabledFeatures'] = $enabledFeatures; - null !== $isUnlimited && $self['isUnlimited'] = $isUnlimited; - null !== $limit && $self['limit'] = $limit; - null !== $remaining && $self['remaining'] = $remaining; - null !== $resetsAt && $self['resetsAt'] = $resetsAt; - null !== $used && $self['used'] = $used; - - return $self; - } - - /** - * List of API features enabled for your plan. - * - * @param list $enabledFeatures - */ - public function withEnabledFeatures(array $enabledFeatures): self - { - $self = clone $this; - $self['enabledFeatures'] = $enabledFeatures; - - return $self; - } - - /** - * Whether the account has unlimited credits. - */ - public function withIsUnlimited(bool $isUnlimited): self - { - $self = clone $this; - $self['isUnlimited'] = $isUnlimited; - - return $self; - } - - /** - * Total credit limit for billing period. - */ - public function withLimit(int $limit): self - { - $self = clone $this; - $self['limit'] = $limit; - - return $self; - } - - /** - * Remaining credits (null if unlimited). - */ - public function withRemaining(?float $remaining): self - { - $self = clone $this; - $self['remaining'] = $remaining; - - return $self; - } - - /** - * When credits reset (ISO 8601). - */ - public function withResetsAt(?\DateTimeInterface $resetsAt): self - { - $self = clone $this; - $self['resetsAt'] = $resetsAt; - - return $self; - } - - /** - * Number of credits used this billing period. - */ - public function withUsed(float $used): self - { - $self = clone $this; - $self['used'] = $used; - - return $self; - } -} diff --git a/src/Logs/LogCreateParams.php b/src/Logs/LogCreateParams.php deleted file mode 100644 index e1e5df7..0000000 --- a/src/Logs/LogCreateParams.php +++ /dev/null @@ -1,106 +0,0 @@ - */ - use SdkModel; - use SdkParams; - - /** - * End time filter (ISO 8601). Defaults to now. - */ - #[Optional('end_time')] - public ?\DateTimeInterface $endTime; - - /** - * Maximum number of logs to return. - */ - #[Optional] - public ?int $limit; - - /** - * Start time filter (ISO 8601). Defaults to 30 days ago. - */ - #[Optional('start_time')] - public ?\DateTimeInterface $startTime; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - */ - public static function with( - ?\DateTimeInterface $endTime = null, - ?int $limit = null, - ?\DateTimeInterface $startTime = null, - ): self { - $self = new self; - - null !== $endTime && $self['endTime'] = $endTime; - null !== $limit && $self['limit'] = $limit; - null !== $startTime && $self['startTime'] = $startTime; - - return $self; - } - - /** - * End time filter (ISO 8601). Defaults to now. - */ - public function withEndTime(\DateTimeInterface $endTime): self - { - $self = clone $this; - $self['endTime'] = $endTime; - - return $self; - } - - /** - * Maximum number of logs to return. - */ - public function withLimit(int $limit): self - { - $self = clone $this; - $self['limit'] = $limit; - - return $self; - } - - /** - * Start time filter (ISO 8601). Defaults to 30 days ago. - */ - public function withStartTime(\DateTimeInterface $startTime): self - { - $self = clone $this; - $self['startTime'] = $startTime; - - return $self; - } -} diff --git a/src/Logs/LogGetSummaryParams.php b/src/Logs/LogGetSummaryParams.php deleted file mode 100644 index 6448a9d..0000000 --- a/src/Logs/LogGetSummaryParams.php +++ /dev/null @@ -1,84 +0,0 @@ - */ - use SdkModel; - use SdkParams; - - /** - * End time filter (ISO 8601). Defaults to now. - */ - #[Optional('end_time')] - public ?\DateTimeInterface $endTime; - - /** - * Start time filter (ISO 8601). Defaults to start of current month. - */ - #[Optional('start_time')] - public ?\DateTimeInterface $startTime; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - */ - public static function with( - ?\DateTimeInterface $endTime = null, - ?\DateTimeInterface $startTime = null - ): self { - $self = new self; - - null !== $endTime && $self['endTime'] = $endTime; - null !== $startTime && $self['startTime'] = $startTime; - - return $self; - } - - /** - * End time filter (ISO 8601). Defaults to now. - */ - public function withEndTime(\DateTimeInterface $endTime): self - { - $self = clone $this; - $self['endTime'] = $endTime; - - return $self; - } - - /** - * Start time filter (ISO 8601). Defaults to start of current month. - */ - public function withStartTime(\DateTimeInterface $startTime): self - { - $self = clone $this; - $self['startTime'] = $startTime; - - return $self; - } -} diff --git a/src/Logs/LogGetSummaryResponse.php b/src/Logs/LogGetSummaryResponse.php deleted file mode 100644 index c322ffc..0000000 --- a/src/Logs/LogGetSummaryResponse.php +++ /dev/null @@ -1,72 +0,0 @@ - */ - use SdkModel; - - #[Optional] - public ?string $status; - - #[Optional] - public ?Summary $summary; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - * - * @param Summary|SummaryShape|null $summary - */ - public static function with( - ?string $status = null, - Summary|array|null $summary = null - ): self { - $self = new self; - - null !== $status && $self['status'] = $status; - null !== $summary && $self['summary'] = $summary; - - return $self; - } - - public function withStatus(string $status): self - { - $self = clone $this; - $self['status'] = $status; - - return $self; - } - - /** - * @param Summary|SummaryShape $summary - */ - public function withSummary(Summary|array $summary): self - { - $self = clone $this; - $self['summary'] = $summary; - - return $self; - } -} diff --git a/src/Logs/LogGetSummaryResponse/Summary.php b/src/Logs/LogGetSummaryResponse/Summary.php deleted file mode 100644 index 852e652..0000000 --- a/src/Logs/LogGetSummaryResponse/Summary.php +++ /dev/null @@ -1,106 +0,0 @@ -|null, - * totalCredits?: float|null, - * totalRequests?: int|null, - * } - */ -final class Summary implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * Usage breakdown by feature. - * - * @var list|null $byFeature - */ - #[Optional('by_feature', list: ByFeature::class)] - public ?array $byFeature; - - /** - * Total credits consumed in the period. - */ - #[Optional('total_credits')] - public ?float $totalCredits; - - /** - * Total API requests made in the period. - */ - #[Optional('total_requests')] - public ?int $totalRequests; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - * - * @param list|null $byFeature - */ - public static function with( - ?array $byFeature = null, - ?float $totalCredits = null, - ?int $totalRequests = null, - ): self { - $self = new self; - - null !== $byFeature && $self['byFeature'] = $byFeature; - null !== $totalCredits && $self['totalCredits'] = $totalCredits; - null !== $totalRequests && $self['totalRequests'] = $totalRequests; - - return $self; - } - - /** - * Usage breakdown by feature. - * - * @param list $byFeature - */ - public function withByFeature(array $byFeature): self - { - $self = clone $this; - $self['byFeature'] = $byFeature; - - return $self; - } - - /** - * Total credits consumed in the period. - */ - public function withTotalCredits(float $totalCredits): self - { - $self = clone $this; - $self['totalCredits'] = $totalCredits; - - return $self; - } - - /** - * Total API requests made in the period. - */ - public function withTotalRequests(int $totalRequests): self - { - $self = clone $this; - $self['totalRequests'] = $totalRequests; - - return $self; - } -} diff --git a/src/Logs/LogGetSummaryResponse/Summary/ByFeature.php b/src/Logs/LogGetSummaryResponse/Summary/ByFeature.php deleted file mode 100644 index 8d15ea0..0000000 --- a/src/Logs/LogGetSummaryResponse/Summary/ByFeature.php +++ /dev/null @@ -1,95 +0,0 @@ - */ - use SdkModel; - - /** - * Credits consumed by this feature. - */ - #[Optional] - public ?float $credits; - - /** - * API feature name. - */ - #[Optional] - public ?string $feature; - - /** - * Number of requests for this feature. - */ - #[Optional] - public ?int $requests; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - */ - public static function with( - ?float $credits = null, - ?string $feature = null, - ?int $requests = null - ): self { - $self = new self; - - null !== $credits && $self['credits'] = $credits; - null !== $feature && $self['feature'] = $feature; - null !== $requests && $self['requests'] = $requests; - - return $self; - } - - /** - * Credits consumed by this feature. - */ - public function withCredits(float $credits): self - { - $self = clone $this; - $self['credits'] = $credits; - - return $self; - } - - /** - * API feature name. - */ - public function withFeature(string $feature): self - { - $self = clone $this; - $self['feature'] = $feature; - - return $self; - } - - /** - * Number of requests for this feature. - */ - public function withRequests(int $requests): self - { - $self = clone $this; - $self['requests'] = $requests; - - return $self; - } -} diff --git a/src/Logs/LogNewResponse.php b/src/Logs/LogNewResponse.php deleted file mode 100644 index 45adea4..0000000 --- a/src/Logs/LogNewResponse.php +++ /dev/null @@ -1,92 +0,0 @@ -|null, status?: string|null - * } - */ -final class LogNewResponse implements BaseModel -{ - /** @use SdkModel */ - use SdkModel; - - /** - * Number of logs returned. - */ - #[Optional] - public ?int $count; - - /** @var list|null $logs */ - #[Optional(list: Log::class)] - public ?array $logs; - - #[Optional] - public ?string $status; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - * - * @param list|null $logs - */ - public static function with( - ?int $count = null, - ?array $logs = null, - ?string $status = null - ): self { - $self = new self; - - null !== $count && $self['count'] = $count; - null !== $logs && $self['logs'] = $logs; - null !== $status && $self['status'] = $status; - - return $self; - } - - /** - * Number of logs returned. - */ - public function withCount(int $count): self - { - $self = clone $this; - $self['count'] = $count; - - return $self; - } - - /** - * @param list $logs - */ - public function withLogs(array $logs): self - { - $self = clone $this; - $self['logs'] = $logs; - - return $self; - } - - public function withStatus(string $status): self - { - $self = clone $this; - $self['status'] = $status; - - return $self; - } -} diff --git a/src/Logs/LogNewResponse/Log.php b/src/Logs/LogNewResponse/Log.php deleted file mode 100644 index 2df24ca..0000000 --- a/src/Logs/LogNewResponse/Log.php +++ /dev/null @@ -1,157 +0,0 @@ - */ - use SdkModel; - - /** - * Credits consumed for this request. - */ - #[Optional] - public ?float $credits; - - /** - * API feature used. - */ - #[Optional] - public ?string $feature; - - /** - * API endpoint path. - */ - #[Optional] - public ?string $path; - - /** - * Unique request identifier. - */ - #[Optional('request_id')] - public ?string $requestID; - - /** - * HTTP response status code. - */ - #[Optional('status_code')] - public ?int $statusCode; - - /** - * When the request was made. - */ - #[Optional] - public ?\DateTimeInterface $timestamp; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - */ - public static function with( - ?float $credits = null, - ?string $feature = null, - ?string $path = null, - ?string $requestID = null, - ?int $statusCode = null, - ?\DateTimeInterface $timestamp = null, - ): self { - $self = new self; - - null !== $credits && $self['credits'] = $credits; - null !== $feature && $self['feature'] = $feature; - null !== $path && $self['path'] = $path; - null !== $requestID && $self['requestID'] = $requestID; - null !== $statusCode && $self['statusCode'] = $statusCode; - null !== $timestamp && $self['timestamp'] = $timestamp; - - return $self; - } - - /** - * Credits consumed for this request. - */ - public function withCredits(float $credits): self - { - $self = clone $this; - $self['credits'] = $credits; - - return $self; - } - - /** - * API feature used. - */ - public function withFeature(string $feature): self - { - $self = clone $this; - $self['feature'] = $feature; - - return $self; - } - - /** - * API endpoint path. - */ - public function withPath(string $path): self - { - $self = clone $this; - $self['path'] = $path; - - return $self; - } - - /** - * Unique request identifier. - */ - public function withRequestID(string $requestID): self - { - $self = clone $this; - $self['requestID'] = $requestID; - - return $self; - } - - /** - * HTTP response status code. - */ - public function withStatusCode(int $statusCode): self - { - $self = clone $this; - $self['statusCode'] = $statusCode; - - return $self; - } - - /** - * When the request was made. - */ - public function withTimestamp(\DateTimeInterface $timestamp): self - { - $self = clone $this; - $self['timestamp'] = $timestamp; - - return $self; - } -} diff --git a/src/ServiceContracts/AccessTokenContract.php b/src/ServiceContracts/AccessTokenContract.php index c5a0c9e..fece3c7 100644 --- a/src/ServiceContracts/AccessTokenContract.php +++ b/src/ServiceContracts/AccessTokenContract.php @@ -4,25 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\AccessToken\AccessTokenNewResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\RequestOptions; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface AccessTokenContract -{ - /** - * @api - * - * @param int $expiryMinutes Token validity in minutes (max 60) - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function create( - int $expiryMinutes = 60, - RequestOptions|array|null $requestOptions = null - ): AccessTokenNewResponse; -} +interface AccessTokenContract {} diff --git a/src/ServiceContracts/AccessTokenRawContract.php b/src/ServiceContracts/AccessTokenRawContract.php index 326e148..b52767b 100644 --- a/src/ServiceContracts/AccessTokenRawContract.php +++ b/src/ServiceContracts/AccessTokenRawContract.php @@ -4,29 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\AccessToken\AccessTokenCreateParams; -use CasParser\AccessToken\AccessTokenNewResponse; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\RequestOptions; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface AccessTokenRawContract -{ - /** - * @api - * - * @param array|AccessTokenCreateParams $params - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function create( - array|AccessTokenCreateParams $params, - RequestOptions|array|null $requestOptions = null, - ): BaseResponse; -} +interface AccessTokenRawContract {} diff --git a/src/ServiceContracts/CreditsContract.php b/src/ServiceContracts/CreditsContract.php index 1bb58a2..678b37f 100644 --- a/src/ServiceContracts/CreditsContract.php +++ b/src/ServiceContracts/CreditsContract.php @@ -4,23 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\Core\Exceptions\APIException; -use CasParser\Credits\CreditCheckResponse; -use CasParser\RequestOptions; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface CreditsContract -{ - /** - * @api - * - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function check( - RequestOptions|array|null $requestOptions = null - ): CreditCheckResponse; -} +interface CreditsContract {} diff --git a/src/ServiceContracts/CreditsRawContract.php b/src/ServiceContracts/CreditsRawContract.php index 396184b..436209b 100644 --- a/src/ServiceContracts/CreditsRawContract.php +++ b/src/ServiceContracts/CreditsRawContract.php @@ -4,26 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\Credits\CreditCheckResponse; -use CasParser\RequestOptions; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface CreditsRawContract -{ - /** - * @api - * - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function check( - RequestOptions|array|null $requestOptions = null - ): BaseResponse; -} +interface CreditsRawContract {} diff --git a/src/ServiceContracts/LogsContract.php b/src/ServiceContracts/LogsContract.php index d7b2de0..4c7175c 100644 --- a/src/ServiceContracts/LogsContract.php +++ b/src/ServiceContracts/LogsContract.php @@ -4,45 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\Core\Exceptions\APIException; -use CasParser\Logs\LogGetSummaryResponse; -use CasParser\Logs\LogNewResponse; -use CasParser\RequestOptions; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface LogsContract -{ - /** - * @api - * - * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. - * @param int $limit Maximum number of logs to return - * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to 30 days ago. - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function create( - ?\DateTimeInterface $endTime = null, - int $limit = 100, - ?\DateTimeInterface $startTime = null, - RequestOptions|array|null $requestOptions = null, - ): LogNewResponse; - - /** - * @api - * - * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. - * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to start of current month. - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function getSummary( - ?\DateTimeInterface $endTime = null, - ?\DateTimeInterface $startTime = null, - RequestOptions|array|null $requestOptions = null, - ): LogGetSummaryResponse; -} +interface LogsContract {} diff --git a/src/ServiceContracts/LogsRawContract.php b/src/ServiceContracts/LogsRawContract.php index 5a6a6da..43678fd 100644 --- a/src/ServiceContracts/LogsRawContract.php +++ b/src/ServiceContracts/LogsRawContract.php @@ -4,46 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\Logs\LogCreateParams; -use CasParser\Logs\LogGetSummaryParams; -use CasParser\Logs\LogGetSummaryResponse; -use CasParser\Logs\LogNewResponse; -use CasParser\RequestOptions; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface LogsRawContract -{ - /** - * @api - * - * @param array|LogCreateParams $params - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function create( - array|LogCreateParams $params, - RequestOptions|array|null $requestOptions = null, - ): BaseResponse; - - /** - * @api - * - * @param array|LogGetSummaryParams $params - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function getSummary( - array|LogGetSummaryParams $params, - RequestOptions|array|null $requestOptions = null, - ): BaseResponse; -} +interface LogsRawContract {} diff --git a/src/ServiceContracts/VerifyTokenContract.php b/src/ServiceContracts/VerifyTokenContract.php index d9073a8..77ed08e 100644 --- a/src/ServiceContracts/VerifyTokenContract.php +++ b/src/ServiceContracts/VerifyTokenContract.php @@ -4,23 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\Core\Exceptions\APIException; -use CasParser\RequestOptions; -use CasParser\VerifyToken\VerifyTokenVerifyResponse; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface VerifyTokenContract -{ - /** - * @api - * - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function verify( - RequestOptions|array|null $requestOptions = null - ): VerifyTokenVerifyResponse; -} +interface VerifyTokenContract {} diff --git a/src/ServiceContracts/VerifyTokenRawContract.php b/src/ServiceContracts/VerifyTokenRawContract.php index 69d807d..aed9c6c 100644 --- a/src/ServiceContracts/VerifyTokenRawContract.php +++ b/src/ServiceContracts/VerifyTokenRawContract.php @@ -4,26 +4,4 @@ namespace CasParser\ServiceContracts; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\RequestOptions; -use CasParser\VerifyToken\VerifyTokenVerifyResponse; - -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ -interface VerifyTokenRawContract -{ - /** - * @api - * - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function verify( - RequestOptions|array|null $requestOptions = null - ): BaseResponse; -} +interface VerifyTokenRawContract {} diff --git a/src/Services/AccessTokenRawService.php b/src/Services/AccessTokenRawService.php index a2a3bb0..f595a6e 100644 --- a/src/Services/AccessTokenRawService.php +++ b/src/Services/AccessTokenRawService.php @@ -4,17 +4,9 @@ namespace CasParser\Services; -use CasParser\AccessToken\AccessTokenCreateParams; -use CasParser\AccessToken\AccessTokenNewResponse; use CasParser\Client; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\RequestOptions; use CasParser\ServiceContracts\AccessTokenRawContract; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class AccessTokenRawService implements AccessTokenRawContract { // @phpstan-ignore-next-line @@ -22,43 +14,4 @@ final class AccessTokenRawService implements AccessTokenRawContract * @internal */ public function __construct(private Client $client) {} - - /** - * @api - * - * Generate a short-lived access token from your API key. - * - * **Use this endpoint from your backend** to create tokens that can be safely passed to frontend/SDK. - * - * Access tokens: - * - Are prefixed with `at_` for easy identification - * - Valid for up to 60 minutes - * - Can be used in place of API keys on all v4 endpoints - * - Cannot be used to generate other access tokens - * - * @param array{expiryMinutes?: int}|AccessTokenCreateParams $params - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function create( - array|AccessTokenCreateParams $params, - RequestOptions|array|null $requestOptions = null, - ): BaseResponse { - [$parsed, $options] = AccessTokenCreateParams::parseRequest( - $params, - $requestOptions, - ); - - // @phpstan-ignore-next-line return.type - return $this->client->request( - method: 'post', - path: 'v1/access-token', - body: (object) $parsed, - options: $options, - convert: AccessTokenNewResponse::class, - ); - } } diff --git a/src/Services/AccessTokenService.php b/src/Services/AccessTokenService.php index fe0aade..d52acf2 100644 --- a/src/Services/AccessTokenService.php +++ b/src/Services/AccessTokenService.php @@ -4,16 +4,9 @@ namespace CasParser\Services; -use CasParser\AccessToken\AccessTokenNewResponse; use CasParser\Client; -use CasParser\Core\Exceptions\APIException; -use CasParser\Core\Util; -use CasParser\RequestOptions; use CasParser\ServiceContracts\AccessTokenContract; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class AccessTokenService implements AccessTokenContract { /** @@ -21,6 +14,7 @@ final class AccessTokenService implements AccessTokenContract */ public AccessTokenRawService $raw; + // @phpstan-ignore-next-line /** * @internal */ @@ -28,34 +22,4 @@ public function __construct(private Client $client) { $this->raw = new AccessTokenRawService($client); } - - /** - * @api - * - * Generate a short-lived access token from your API key. - * - * **Use this endpoint from your backend** to create tokens that can be safely passed to frontend/SDK. - * - * Access tokens: - * - Are prefixed with `at_` for easy identification - * - Valid for up to 60 minutes - * - Can be used in place of API keys on all v4 endpoints - * - Cannot be used to generate other access tokens - * - * @param int $expiryMinutes Token validity in minutes (max 60) - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function create( - int $expiryMinutes = 60, - RequestOptions|array|null $requestOptions = null - ): AccessTokenNewResponse { - $params = Util::removeNulls(['expiryMinutes' => $expiryMinutes]); - - // @phpstan-ignore-next-line argument.type - $response = $this->raw->create(params: $params, requestOptions: $requestOptions); - - return $response->parse(); - } } diff --git a/src/Services/CreditsRawService.php b/src/Services/CreditsRawService.php index a3432b2..c9be78c 100644 --- a/src/Services/CreditsRawService.php +++ b/src/Services/CreditsRawService.php @@ -5,15 +5,8 @@ namespace CasParser\Services; use CasParser\Client; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\Credits\CreditCheckResponse; -use CasParser\RequestOptions; use CasParser\ServiceContracts\CreditsRawContract; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class CreditsRawService implements CreditsRawContract { // @phpstan-ignore-next-line @@ -21,34 +14,4 @@ final class CreditsRawService implements CreditsRawContract * @internal */ public function __construct(private Client $client) {} - - /** - * @api - * - * Check your remaining API credits and usage for the current billing period. - * - * Returns: - * - Number of API calls used and remaining credits - * - Credit limit and reset date - * - List of enabled features for your plan - * - * Credits reset at the start of each billing period. - * - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function check( - RequestOptions|array|null $requestOptions = null - ): BaseResponse { - // @phpstan-ignore-next-line return.type - return $this->client->request( - method: 'post', - path: 'credits', - options: $requestOptions, - convert: CreditCheckResponse::class, - ); - } } diff --git a/src/Services/CreditsService.php b/src/Services/CreditsService.php index 4bde97a..21b2dc0 100644 --- a/src/Services/CreditsService.php +++ b/src/Services/CreditsService.php @@ -5,14 +5,8 @@ namespace CasParser\Services; use CasParser\Client; -use CasParser\Core\Exceptions\APIException; -use CasParser\Credits\CreditCheckResponse; -use CasParser\RequestOptions; use CasParser\ServiceContracts\CreditsContract; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class CreditsService implements CreditsContract { /** @@ -20,6 +14,7 @@ final class CreditsService implements CreditsContract */ public CreditsRawService $raw; + // @phpstan-ignore-next-line /** * @internal */ @@ -27,29 +22,4 @@ public function __construct(private Client $client) { $this->raw = new CreditsRawService($client); } - - /** - * @api - * - * Check your remaining API credits and usage for the current billing period. - * - * Returns: - * - Number of API calls used and remaining credits - * - Credit limit and reset date - * - List of enabled features for your plan - * - * Credits reset at the start of each billing period. - * - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function check( - RequestOptions|array|null $requestOptions = null - ): CreditCheckResponse { - // @phpstan-ignore-next-line argument.type - $response = $this->raw->check(requestOptions: $requestOptions); - - return $response->parse(); - } } diff --git a/src/Services/LogsRawService.php b/src/Services/LogsRawService.php index 4048e37..ef63acf 100644 --- a/src/Services/LogsRawService.php +++ b/src/Services/LogsRawService.php @@ -5,18 +5,8 @@ namespace CasParser\Services; use CasParser\Client; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\Logs\LogCreateParams; -use CasParser\Logs\LogGetSummaryParams; -use CasParser\Logs\LogGetSummaryResponse; -use CasParser\Logs\LogNewResponse; -use CasParser\RequestOptions; use CasParser\ServiceContracts\LogsRawContract; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class LogsRawService implements LogsRawContract { // @phpstan-ignore-next-line @@ -24,75 +14,4 @@ final class LogsRawService implements LogsRawContract * @internal */ public function __construct(private Client $client) {} - - /** - * @api - * - * Retrieve detailed API usage logs for your account. - * - * Returns a list of API calls with timestamps, features used, status codes, and credits consumed. - * Useful for monitoring usage patterns and debugging. - * - * @param array{ - * endTime?: \DateTimeInterface, limit?: int, startTime?: \DateTimeInterface - * }|LogCreateParams $params - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function create( - array|LogCreateParams $params, - RequestOptions|array|null $requestOptions = null, - ): BaseResponse { - [$parsed, $options] = LogCreateParams::parseRequest( - $params, - $requestOptions, - ); - - // @phpstan-ignore-next-line return.type - return $this->client->request( - method: 'post', - path: 'logs', - body: (object) $parsed, - options: $options, - convert: LogNewResponse::class, - ); - } - - /** - * @api - * - * Get aggregated usage statistics grouped by feature. - * - * Useful for understanding which API features are being used most and tracking usage trends. - * - * @param array{ - * endTime?: \DateTimeInterface, startTime?: \DateTimeInterface - * }|LogGetSummaryParams $params - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function getSummary( - array|LogGetSummaryParams $params, - RequestOptions|array|null $requestOptions = null, - ): BaseResponse { - [$parsed, $options] = LogGetSummaryParams::parseRequest( - $params, - $requestOptions, - ); - - // @phpstan-ignore-next-line return.type - return $this->client->request( - method: 'post', - path: 'logs/summary', - body: (object) $parsed, - options: $options, - convert: LogGetSummaryResponse::class, - ); - } } diff --git a/src/Services/LogsService.php b/src/Services/LogsService.php index 03336f0..4a9e6fc 100644 --- a/src/Services/LogsService.php +++ b/src/Services/LogsService.php @@ -5,16 +5,8 @@ namespace CasParser\Services; use CasParser\Client; -use CasParser\Core\Exceptions\APIException; -use CasParser\Core\Util; -use CasParser\Logs\LogGetSummaryResponse; -use CasParser\Logs\LogNewResponse; -use CasParser\RequestOptions; use CasParser\ServiceContracts\LogsContract; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class LogsService implements LogsContract { /** @@ -22,6 +14,7 @@ final class LogsService implements LogsContract */ public LogsRawService $raw; + // @phpstan-ignore-next-line /** * @internal */ @@ -29,63 +22,4 @@ public function __construct(private Client $client) { $this->raw = new LogsRawService($client); } - - /** - * @api - * - * Retrieve detailed API usage logs for your account. - * - * Returns a list of API calls with timestamps, features used, status codes, and credits consumed. - * Useful for monitoring usage patterns and debugging. - * - * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. - * @param int $limit Maximum number of logs to return - * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to 30 days ago. - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function create( - ?\DateTimeInterface $endTime = null, - int $limit = 100, - ?\DateTimeInterface $startTime = null, - RequestOptions|array|null $requestOptions = null, - ): LogNewResponse { - $params = Util::removeNulls( - ['endTime' => $endTime, 'limit' => $limit, 'startTime' => $startTime] - ); - - // @phpstan-ignore-next-line argument.type - $response = $this->raw->create(params: $params, requestOptions: $requestOptions); - - return $response->parse(); - } - - /** - * @api - * - * Get aggregated usage statistics grouped by feature. - * - * Useful for understanding which API features are being used most and tracking usage trends. - * - * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. - * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to start of current month. - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function getSummary( - ?\DateTimeInterface $endTime = null, - ?\DateTimeInterface $startTime = null, - RequestOptions|array|null $requestOptions = null, - ): LogGetSummaryResponse { - $params = Util::removeNulls( - ['endTime' => $endTime, 'startTime' => $startTime] - ); - - // @phpstan-ignore-next-line argument.type - $response = $this->raw->getSummary(params: $params, requestOptions: $requestOptions); - - return $response->parse(); - } } diff --git a/src/Services/VerifyTokenRawService.php b/src/Services/VerifyTokenRawService.php index f7504bb..fc36e5f 100644 --- a/src/Services/VerifyTokenRawService.php +++ b/src/Services/VerifyTokenRawService.php @@ -5,15 +5,8 @@ namespace CasParser\Services; use CasParser\Client; -use CasParser\Core\Contracts\BaseResponse; -use CasParser\Core\Exceptions\APIException; -use CasParser\RequestOptions; use CasParser\ServiceContracts\VerifyTokenRawContract; -use CasParser\VerifyToken\VerifyTokenVerifyResponse; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class VerifyTokenRawService implements VerifyTokenRawContract { // @phpstan-ignore-next-line @@ -21,28 +14,4 @@ final class VerifyTokenRawService implements VerifyTokenRawContract * @internal */ public function __construct(private Client $client) {} - - /** - * @api - * - * Verify an access token and check if it's still valid. - * Useful for debugging token issues. - * - * @param RequestOpts|null $requestOptions - * - * @return BaseResponse - * - * @throws APIException - */ - public function verify( - RequestOptions|array|null $requestOptions = null - ): BaseResponse { - // @phpstan-ignore-next-line return.type - return $this->client->request( - method: 'post', - path: 'v1/verify-token', - options: $requestOptions, - convert: VerifyTokenVerifyResponse::class, - ); - } } diff --git a/src/Services/VerifyTokenService.php b/src/Services/VerifyTokenService.php index 9c1094d..e09c873 100644 --- a/src/Services/VerifyTokenService.php +++ b/src/Services/VerifyTokenService.php @@ -5,14 +5,8 @@ namespace CasParser\Services; use CasParser\Client; -use CasParser\Core\Exceptions\APIException; -use CasParser\RequestOptions; use CasParser\ServiceContracts\VerifyTokenContract; -use CasParser\VerifyToken\VerifyTokenVerifyResponse; -/** - * @phpstan-import-type RequestOpts from \CasParser\RequestOptions - */ final class VerifyTokenService implements VerifyTokenContract { /** @@ -20,6 +14,7 @@ final class VerifyTokenService implements VerifyTokenContract */ public VerifyTokenRawService $raw; + // @phpstan-ignore-next-line /** * @internal */ @@ -27,23 +22,4 @@ public function __construct(private Client $client) { $this->raw = new VerifyTokenRawService($client); } - - /** - * @api - * - * Verify an access token and check if it's still valid. - * Useful for debugging token issues. - * - * @param RequestOpts|null $requestOptions - * - * @throws APIException - */ - public function verify( - RequestOptions|array|null $requestOptions = null - ): VerifyTokenVerifyResponse { - // @phpstan-ignore-next-line argument.type - $response = $this->raw->verify(requestOptions: $requestOptions); - - return $response->parse(); - } } diff --git a/src/VerifyToken/VerifyTokenVerifyResponse.php b/src/VerifyToken/VerifyTokenVerifyResponse.php deleted file mode 100644 index 70f4cb1..0000000 --- a/src/VerifyToken/VerifyTokenVerifyResponse.php +++ /dev/null @@ -1,95 +0,0 @@ - */ - use SdkModel; - - /** - * Error message (only shown if invalid). - */ - #[Optional] - public ?string $error; - - /** - * Masked API key (only shown if valid). - */ - #[Optional('masked_api_key')] - public ?string $maskedAPIKey; - - /** - * Whether the token is valid. - */ - #[Optional] - public ?bool $valid; - - public function __construct() - { - $this->initialize(); - } - - /** - * Construct an instance from the required parameters. - * - * You must use named parameters to construct any parameters with a default value. - */ - public static function with( - ?string $error = null, - ?string $maskedAPIKey = null, - ?bool $valid = null - ): self { - $self = new self; - - null !== $error && $self['error'] = $error; - null !== $maskedAPIKey && $self['maskedAPIKey'] = $maskedAPIKey; - null !== $valid && $self['valid'] = $valid; - - return $self; - } - - /** - * Error message (only shown if invalid). - */ - public function withError(string $error): self - { - $self = clone $this; - $self['error'] = $error; - - return $self; - } - - /** - * Masked API key (only shown if valid). - */ - public function withMaskedAPIKey(string $maskedAPIKey): self - { - $self = clone $this; - $self['maskedAPIKey'] = $maskedAPIKey; - - return $self; - } - - /** - * Whether the token is valid. - */ - public function withValid(bool $valid): self - { - $self = clone $this; - $self['valid'] = $valid; - - return $self; - } -} diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 0082cf4..b6359ce 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -32,7 +32,7 @@ public function testDefaultHeaders(): void requestOptions: ['transporter' => $transporter], ); - $client->credits->check(); + $client->camsKfintech->parse(); $this->assertNotFalse($requested = $transporter->getRequests()[0] ?? false); diff --git a/tests/Services/AccessTokenTest.php b/tests/Services/AccessTokenTest.php deleted file mode 100644 index bb5ae62..0000000 --- a/tests/Services/AccessTokenTest.php +++ /dev/null @@ -1,43 +0,0 @@ -client = $client; - } - - #[Test] - public function testCreate(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Mock server tests are disabled'); - } - - $result = $this->client->accessToken->create(); - - // @phpstan-ignore-next-line method.alreadyNarrowedType - $this->assertInstanceOf(AccessTokenNewResponse::class, $result); - } -} diff --git a/tests/Services/CreditsTest.php b/tests/Services/CreditsTest.php deleted file mode 100644 index 70e7b80..0000000 --- a/tests/Services/CreditsTest.php +++ /dev/null @@ -1,43 +0,0 @@ -client = $client; - } - - #[Test] - public function testCheck(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Mock server tests are disabled'); - } - - $result = $this->client->credits->check(); - - // @phpstan-ignore-next-line method.alreadyNarrowedType - $this->assertInstanceOf(CreditCheckResponse::class, $result); - } -} diff --git a/tests/Services/LogsTest.php b/tests/Services/LogsTest.php deleted file mode 100644 index 1f4c4da..0000000 --- a/tests/Services/LogsTest.php +++ /dev/null @@ -1,57 +0,0 @@ -client = $client; - } - - #[Test] - public function testCreate(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Mock server tests are disabled'); - } - - $result = $this->client->logs->create(); - - // @phpstan-ignore-next-line method.alreadyNarrowedType - $this->assertInstanceOf(LogNewResponse::class, $result); - } - - #[Test] - public function testGetSummary(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Mock server tests are disabled'); - } - - $result = $this->client->logs->getSummary(); - - // @phpstan-ignore-next-line method.alreadyNarrowedType - $this->assertInstanceOf(LogGetSummaryResponse::class, $result); - } -} diff --git a/tests/Services/VerifyTokenTest.php b/tests/Services/VerifyTokenTest.php deleted file mode 100644 index 36549b1..0000000 --- a/tests/Services/VerifyTokenTest.php +++ /dev/null @@ -1,43 +0,0 @@ -client = $client; - } - - #[Test] - public function testVerify(): void - { - if (UnsupportedMockTests::$skip) { - $this->markTestSkipped('Mock server tests are disabled'); - } - - $result = $this->client->verifyToken->verify(); - - // @phpstan-ignore-next-line method.alreadyNarrowedType - $this->assertInstanceOf(VerifyTokenVerifyResponse::class, $result); - } -} From 92b50de8ea771c015e38a2635f1ee5c011156008 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sun, 22 Feb 2026 23:18:03 +0000 Subject: [PATCH 4/8] feat(api): api update --- .stats.yml | 4 ++-- src/Inbox/InboxListCasFilesResponse/File.php | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 80a6900..1e5b8d1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-6a9d3b677dcfb856dc571865c34b3fe401e4d7f0d799edfc743acb9a55800bd0.yml -openapi_spec_hash: 037703a6c741e4310fda3f57c22fa51e +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e6762e83ef7cdff129d03d0ab8c130db2fb5d1d820142847c27d72b40a0e9f53.yml +openapi_spec_hash: f38fb40a2b28bae4b0c9c4228c1c0e0d config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/src/Inbox/InboxListCasFilesResponse/File.php b/src/Inbox/InboxListCasFilesResponse/File.php index 4228539..140d970 100644 --- a/src/Inbox/InboxListCasFilesResponse/File.php +++ b/src/Inbox/InboxListCasFilesResponse/File.php @@ -19,6 +19,7 @@ * messageDate?: string|null, * messageID?: string|null, * originalFilename?: string|null, + * senderEmail?: string|null, * size?: int|null, * url?: string|null, * } @@ -66,6 +67,12 @@ final class File implements BaseModel #[Optional('original_filename')] public ?string $originalFilename; + /** + * Email address of the CAS authority who sent this. + */ + #[Optional('sender_email')] + public ?string $senderEmail; + /** * File size in bytes. */ @@ -97,6 +104,7 @@ public static function with( ?string $messageDate = null, ?string $messageID = null, ?string $originalFilename = null, + ?string $senderEmail = null, ?int $size = null, ?string $url = null, ): self { @@ -108,6 +116,7 @@ public static function with( null !== $messageDate && $self['messageDate'] = $messageDate; null !== $messageID && $self['messageID'] = $messageID; null !== $originalFilename && $self['originalFilename'] = $originalFilename; + null !== $senderEmail && $self['senderEmail'] = $senderEmail; null !== $size && $self['size'] = $size; null !== $url && $self['url'] = $url; @@ -182,6 +191,17 @@ public function withOriginalFilename(string $originalFilename): self return $self; } + /** + * Email address of the CAS authority who sent this. + */ + public function withSenderEmail(string $senderEmail): self + { + $self = clone $this; + $self['senderEmail'] = $senderEmail; + + return $self; + } + /** * File size in bytes. */ From d8c85b904f3df1c7242527d1dd66996d0e8cd6e8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 00:17:45 +0000 Subject: [PATCH 5/8] feat(api): api update --- .stats.yml | 4 ++-- src/Inbox/InboxListCasFilesResponse/File.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 1e5b8d1..b880d0c 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 12 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-e6762e83ef7cdff129d03d0ab8c130db2fb5d1d820142847c27d72b40a0e9f53.yml -openapi_spec_hash: f38fb40a2b28bae4b0c9c4228c1c0e0d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml +openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 config_hash: 41c337f5cda03b13880617490f82bad0 diff --git a/src/Inbox/InboxListCasFilesResponse/File.php b/src/Inbox/InboxListCasFilesResponse/File.php index 140d970..99c15a9 100644 --- a/src/Inbox/InboxListCasFilesResponse/File.php +++ b/src/Inbox/InboxListCasFilesResponse/File.php @@ -68,7 +68,7 @@ final class File implements BaseModel public ?string $originalFilename; /** - * Email address of the CAS authority who sent this. + * Email address of the CAS authority (CDSL, NSDL, CAMS, or KFintech) who originally sent this statement. */ #[Optional('sender_email')] public ?string $senderEmail; @@ -192,7 +192,7 @@ public function withOriginalFilename(string $originalFilename): self } /** - * Email address of the CAS authority who sent this. + * Email address of the CAS authority (CDSL, NSDL, CAMS, or KFintech) who originally sent this statement. */ public function withSenderEmail(string $senderEmail): self { From 83a811cd2ac157f781caeabff6e8e0f4b757435e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 02:53:17 +0000 Subject: [PATCH 6/8] feat(api): manual updates --- .stats.yml | 4 +- README.md | 10 +- src/AccessToken/AccessTokenCreateParams.php | 70 ++++++ src/AccessToken/AccessTokenNewResponse.php | 95 +++++++ src/Client.php | 7 + src/Credits/CreditCheckResponse.php | 163 ++++++++++++ src/InboundEmail/InboundEmailCreateParams.php | 208 +++++++++++++++ .../AllowedSource.php | 16 ++ .../InboundEmailDeleteResponse.php | 62 +++++ src/InboundEmail/InboundEmailGetResponse.php | 237 ++++++++++++++++++ .../InboundEmailGetResponse/AllowedSource.php | 16 ++ .../InboundEmailGetResponse/Status.php | 15 ++ src/InboundEmail/InboundEmailListParams.php | 109 ++++++++ .../InboundEmailListParams/Status.php | 17 ++ src/InboundEmail/InboundEmailListResponse.php | 122 +++++++++ .../InboundEmailListResponse/InboundEmail.php | 237 ++++++++++++++++++ .../InboundEmail/AllowedSource.php | 16 ++ .../InboundEmail/Status.php | 15 ++ src/InboundEmail/InboundEmailNewResponse.php | 237 ++++++++++++++++++ .../InboundEmailNewResponse/AllowedSource.php | 16 ++ .../InboundEmailNewResponse/Status.php | 15 ++ src/Logs/LogCreateParams.php | 108 ++++++++ src/Logs/LogGetSummaryParams.php | 86 +++++++ src/Logs/LogGetSummaryResponse.php | 72 ++++++ src/Logs/LogGetSummaryResponse/Summary.php | 106 ++++++++ .../Summary/ByFeature.php | 95 +++++++ src/Logs/LogNewResponse.php | 92 +++++++ src/Logs/LogNewResponse/Log.php | 157 ++++++++++++ src/ServiceContracts/AccessTokenContract.php | 23 +- .../AccessTokenRawContract.php | 27 +- src/ServiceContracts/CreditsContract.php | 21 +- src/ServiceContracts/CreditsRawContract.php | 24 +- src/ServiceContracts/InboundEmailContract.php | 96 +++++++ .../InboundEmailRawContract.php | 81 ++++++ src/ServiceContracts/LogsContract.php | 43 +++- src/ServiceContracts/LogsRawContract.php | 44 +++- src/ServiceContracts/VerifyTokenContract.php | 21 +- .../VerifyTokenRawContract.php | 24 +- src/Services/AccessTokenRawService.php | 49 ++++ src/Services/AccessTokenService.php | 40 ++- src/Services/CreditsRawService.php | 37 +++ src/Services/CreditsService.php | 32 ++- src/Services/InboundEmailRawService.php | 168 +++++++++++++ src/Services/InboundEmailService.php | 171 +++++++++++++ src/Services/LogsRawService.php | 85 +++++++ src/Services/LogsService.php | 72 +++++- src/Services/VerifyTokenRawService.php | 31 +++ src/Services/VerifyTokenService.php | 26 +- src/VerifyToken/VerifyTokenVerifyResponse.php | 95 +++++++ tests/ClientTest.php | 2 +- tests/Services/AccessTokenTest.php | 43 ++++ tests/Services/CreditsTest.php | 43 ++++ tests/Services/InboundEmailTest.php | 106 ++++++++ tests/Services/LogsTest.php | 57 +++++ tests/Services/VerifyTokenTest.php | 43 ++++ 55 files changed, 3887 insertions(+), 20 deletions(-) create mode 100644 src/AccessToken/AccessTokenCreateParams.php create mode 100644 src/AccessToken/AccessTokenNewResponse.php create mode 100644 src/Credits/CreditCheckResponse.php create mode 100644 src/InboundEmail/InboundEmailCreateParams.php create mode 100644 src/InboundEmail/InboundEmailCreateParams/AllowedSource.php create mode 100644 src/InboundEmail/InboundEmailDeleteResponse.php create mode 100644 src/InboundEmail/InboundEmailGetResponse.php create mode 100644 src/InboundEmail/InboundEmailGetResponse/AllowedSource.php create mode 100644 src/InboundEmail/InboundEmailGetResponse/Status.php create mode 100644 src/InboundEmail/InboundEmailListParams.php create mode 100644 src/InboundEmail/InboundEmailListParams/Status.php create mode 100644 src/InboundEmail/InboundEmailListResponse.php create mode 100644 src/InboundEmail/InboundEmailListResponse/InboundEmail.php create mode 100644 src/InboundEmail/InboundEmailListResponse/InboundEmail/AllowedSource.php create mode 100644 src/InboundEmail/InboundEmailListResponse/InboundEmail/Status.php create mode 100644 src/InboundEmail/InboundEmailNewResponse.php create mode 100644 src/InboundEmail/InboundEmailNewResponse/AllowedSource.php create mode 100644 src/InboundEmail/InboundEmailNewResponse/Status.php create mode 100644 src/Logs/LogCreateParams.php create mode 100644 src/Logs/LogGetSummaryParams.php create mode 100644 src/Logs/LogGetSummaryResponse.php create mode 100644 src/Logs/LogGetSummaryResponse/Summary.php create mode 100644 src/Logs/LogGetSummaryResponse/Summary/ByFeature.php create mode 100644 src/Logs/LogNewResponse.php create mode 100644 src/Logs/LogNewResponse/Log.php create mode 100644 src/ServiceContracts/InboundEmailContract.php create mode 100644 src/ServiceContracts/InboundEmailRawContract.php create mode 100644 src/Services/InboundEmailRawService.php create mode 100644 src/Services/InboundEmailService.php create mode 100644 src/VerifyToken/VerifyTokenVerifyResponse.php create mode 100644 tests/Services/AccessTokenTest.php create mode 100644 tests/Services/CreditsTest.php create mode 100644 tests/Services/InboundEmailTest.php create mode 100644 tests/Services/LogsTest.php create mode 100644 tests/Services/VerifyTokenTest.php diff --git a/.stats.yml b/.stats.yml index b880d0c..cdf3c0a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 12 +configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 -config_hash: 41c337f5cda03b13880617490f82bad0 +config_hash: d54f39abb185904495bef7c5f8702746 diff --git a/README.md b/README.md index 17ea850..e37f9da 100644 --- a/README.md +++ b/README.md @@ -45,9 +45,9 @@ $client = new Client( environment: 'environment_1', ); -$unifiedResponse = $client->camsKfintech->parse(); +$response = $client->credits->check(); -var_dump($unifiedResponse->demat_accounts); +var_dump($response->enabled_features); ``` ### Value Objects @@ -69,7 +69,7 @@ use CasParser\Core\Exceptions\RateLimitException; use CasParser\Core\Exceptions\APIStatusException; try { - $unifiedResponse = $client->camsKfintech->parse(); + $response = $client->credits->check(); } catch (APIConnectionException $e) { echo "The server could not be reached", PHP_EOL; var_dump($e->getPrevious()); @@ -114,7 +114,7 @@ use CasParser\Client; $client = new Client(requestOptions: ['maxRetries' => 0]); // Or, configure per-request: -$result = $client->camsKfintech->parse(requestOptions: ['maxRetries' => 5]); +$result = $client->credits->check(requestOptions: ['maxRetries' => 5]); ``` ## Advanced concepts @@ -130,7 +130,7 @@ Note: the `extra*` parameters of the same name overrides the documented paramete ```php camsKfintech->parse( +$response = $client->credits->check( requestOptions: [ 'extraQueryParams' => ['my_query_parameter' => 'value'], 'extraBodyParams' => ['my_body_parameter' => 'value'], diff --git a/src/AccessToken/AccessTokenCreateParams.php b/src/AccessToken/AccessTokenCreateParams.php new file mode 100644 index 0000000..0d1e34d --- /dev/null +++ b/src/AccessToken/AccessTokenCreateParams.php @@ -0,0 +1,70 @@ + */ + use SdkModel; + use SdkParams; + + /** + * Token validity in minutes (max 60). + */ + #[Optional('expiry_minutes')] + public ?int $expiryMinutes; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with(?int $expiryMinutes = null): self + { + $self = new self; + + null !== $expiryMinutes && $self['expiryMinutes'] = $expiryMinutes; + + return $self; + } + + /** + * Token validity in minutes (max 60). + */ + public function withExpiryMinutes(int $expiryMinutes): self + { + $self = clone $this; + $self['expiryMinutes'] = $expiryMinutes; + + return $self; + } +} diff --git a/src/AccessToken/AccessTokenNewResponse.php b/src/AccessToken/AccessTokenNewResponse.php new file mode 100644 index 0000000..9dace1d --- /dev/null +++ b/src/AccessToken/AccessTokenNewResponse.php @@ -0,0 +1,95 @@ + */ + use SdkModel; + + /** + * The at_ prefixed access token. + */ + #[Optional('access_token')] + public ?string $accessToken; + + /** + * Token validity in seconds. + */ + #[Optional('expires_in')] + public ?int $expiresIn; + + /** + * Always "api_key" - token is a drop-in replacement for x-api-key header. + */ + #[Optional('token_type')] + public ?string $tokenType; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?string $accessToken = null, + ?int $expiresIn = null, + ?string $tokenType = null + ): self { + $self = new self; + + null !== $accessToken && $self['accessToken'] = $accessToken; + null !== $expiresIn && $self['expiresIn'] = $expiresIn; + null !== $tokenType && $self['tokenType'] = $tokenType; + + return $self; + } + + /** + * The at_ prefixed access token. + */ + public function withAccessToken(string $accessToken): self + { + $self = clone $this; + $self['accessToken'] = $accessToken; + + return $self; + } + + /** + * Token validity in seconds. + */ + public function withExpiresIn(int $expiresIn): self + { + $self = clone $this; + $self['expiresIn'] = $expiresIn; + + return $self; + } + + /** + * Always "api_key" - token is a drop-in replacement for x-api-key header. + */ + public function withTokenType(string $tokenType): self + { + $self = clone $this; + $self['tokenType'] = $tokenType; + + return $self; + } +} diff --git a/src/Client.php b/src/Client.php index d9c6aff..cf8252a 100644 --- a/src/Client.php +++ b/src/Client.php @@ -11,6 +11,7 @@ use CasParser\Services\CdslService; use CasParser\Services\ContractNoteService; use CasParser\Services\CreditsService; +use CasParser\Services\InboundEmailService; use CasParser\Services\InboxService; use CasParser\Services\KfintechService; use CasParser\Services\LogsService; @@ -83,6 +84,11 @@ class Client extends BaseClient */ public SmartService $smart; + /** + * @api + */ + public InboundEmailService $inboundEmail; + /** * @param RequestOpts|null $requestOptions */ @@ -134,6 +140,7 @@ public function __construct( $this->kfintech = new KfintechService($this); $this->nsdl = new NsdlService($this); $this->smart = new SmartService($this); + $this->inboundEmail = new InboundEmailService($this); } /** @return array */ diff --git a/src/Credits/CreditCheckResponse.php b/src/Credits/CreditCheckResponse.php new file mode 100644 index 0000000..c0983a6 --- /dev/null +++ b/src/Credits/CreditCheckResponse.php @@ -0,0 +1,163 @@ +|null, + * isUnlimited?: bool|null, + * limit?: int|null, + * remaining?: float|null, + * resetsAt?: \DateTimeInterface|null, + * used?: float|null, + * } + */ +final class CreditCheckResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * List of API features enabled for your plan. + * + * @var list|null $enabledFeatures + */ + #[Optional('enabled_features', list: 'string')] + public ?array $enabledFeatures; + + /** + * Whether the account has unlimited credits. + */ + #[Optional('is_unlimited')] + public ?bool $isUnlimited; + + /** + * Total credit limit for billing period. + */ + #[Optional] + public ?int $limit; + + /** + * Remaining credits (null if unlimited). + */ + #[Optional(nullable: true)] + public ?float $remaining; + + /** + * When credits reset (ISO 8601). + */ + #[Optional('resets_at', nullable: true)] + public ?\DateTimeInterface $resetsAt; + + /** + * Number of credits used this billing period. + */ + #[Optional] + public ?float $used; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list|null $enabledFeatures + */ + public static function with( + ?array $enabledFeatures = null, + ?bool $isUnlimited = null, + ?int $limit = null, + ?float $remaining = null, + ?\DateTimeInterface $resetsAt = null, + ?float $used = null, + ): self { + $self = new self; + + null !== $enabledFeatures && $self['enabledFeatures'] = $enabledFeatures; + null !== $isUnlimited && $self['isUnlimited'] = $isUnlimited; + null !== $limit && $self['limit'] = $limit; + null !== $remaining && $self['remaining'] = $remaining; + null !== $resetsAt && $self['resetsAt'] = $resetsAt; + null !== $used && $self['used'] = $used; + + return $self; + } + + /** + * List of API features enabled for your plan. + * + * @param list $enabledFeatures + */ + public function withEnabledFeatures(array $enabledFeatures): self + { + $self = clone $this; + $self['enabledFeatures'] = $enabledFeatures; + + return $self; + } + + /** + * Whether the account has unlimited credits. + */ + public function withIsUnlimited(bool $isUnlimited): self + { + $self = clone $this; + $self['isUnlimited'] = $isUnlimited; + + return $self; + } + + /** + * Total credit limit for billing period. + */ + public function withLimit(int $limit): self + { + $self = clone $this; + $self['limit'] = $limit; + + return $self; + } + + /** + * Remaining credits (null if unlimited). + */ + public function withRemaining(?float $remaining): self + { + $self = clone $this; + $self['remaining'] = $remaining; + + return $self; + } + + /** + * When credits reset (ISO 8601). + */ + public function withResetsAt(?\DateTimeInterface $resetsAt): self + { + $self = clone $this; + $self['resetsAt'] = $resetsAt; + + return $self; + } + + /** + * Number of credits used this billing period. + */ + public function withUsed(float $used): self + { + $self = clone $this; + $self['used'] = $used; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailCreateParams.php b/src/InboundEmail/InboundEmailCreateParams.php new file mode 100644 index 0000000..ee42c80 --- /dev/null +++ b/src/InboundEmail/InboundEmailCreateParams.php @@ -0,0 +1,208 @@ +>|null, + * metadata?: array|null, + * reference?: string|null, + * } + */ +final class InboundEmailCreateParams implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + use SdkParams; + + /** + * Webhook URL where we POST email notifications. + * Must be HTTPS in production (HTTP allowed for localhost during development). + */ + #[Required('callback_url')] + public string $callbackURL; + + /** + * Optional custom email prefix for user-friendly addresses. + * - Must be 3-32 characters + * - Alphanumeric + hyphens only + * - Must start and end with letter/number + * - Example: `john-portfolio@import.casparser.in` + * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in`. + */ + #[Optional] + public ?string $alias; + + /** + * Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com. + * + * @var list>|null $allowedSources + */ + #[Optional('allowed_sources', list: AllowedSource::class)] + public ?array $allowedSources; + + /** + * Optional key-value pairs (max 10) to include in webhook payload. + * Useful for passing context like plan_type, campaign_id, etc. + * + * @var array|null $metadata + */ + #[Optional(map: 'string')] + public ?array $metadata; + + /** + * Your internal identifier (e.g., user_id, account_id). + * Returned in webhook payload for correlation. + */ + #[Optional] + public ?string $reference; + + /** + * `new InboundEmailCreateParams()` is missing required properties by the API. + * + * To enforce required parameters use + * ``` + * InboundEmailCreateParams::with(callbackURL: ...) + * ``` + * + * Otherwise ensure the following setters are called + * + * ``` + * (new InboundEmailCreateParams)->withCallbackURL(...) + * ``` + */ + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list>|null $allowedSources + * @param array|null $metadata + */ + public static function with( + string $callbackURL, + ?string $alias = null, + ?array $allowedSources = null, + ?array $metadata = null, + ?string $reference = null, + ): self { + $self = new self; + + $self['callbackURL'] = $callbackURL; + + null !== $alias && $self['alias'] = $alias; + null !== $allowedSources && $self['allowedSources'] = $allowedSources; + null !== $metadata && $self['metadata'] = $metadata; + null !== $reference && $self['reference'] = $reference; + + return $self; + } + + /** + * Webhook URL where we POST email notifications. + * Must be HTTPS in production (HTTP allowed for localhost during development). + */ + public function withCallbackURL(string $callbackURL): self + { + $self = clone $this; + $self['callbackURL'] = $callbackURL; + + return $self; + } + + /** + * Optional custom email prefix for user-friendly addresses. + * - Must be 3-32 characters + * - Alphanumeric + hyphens only + * - Must start and end with letter/number + * - Example: `john-portfolio@import.casparser.in` + * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in`. + */ + public function withAlias(string $alias): self + { + $self = clone $this; + $self['alias'] = $alias; + + return $self; + } + + /** + * Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com. + * + * @param list> $allowedSources + */ + public function withAllowedSources(array $allowedSources): self + { + $self = clone $this; + $self['allowedSources'] = $allowedSources; + + return $self; + } + + /** + * Optional key-value pairs (max 10) to include in webhook payload. + * Useful for passing context like plan_type, campaign_id, etc. + * + * @param array $metadata + */ + public function withMetadata(array $metadata): self + { + $self = clone $this; + $self['metadata'] = $metadata; + + return $self; + } + + /** + * Your internal identifier (e.g., user_id, account_id). + * Returned in webhook payload for correlation. + */ + public function withReference(string $reference): self + { + $self = clone $this; + $self['reference'] = $reference; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailCreateParams/AllowedSource.php b/src/InboundEmail/InboundEmailCreateParams/AllowedSource.php new file mode 100644 index 0000000..938f1ac --- /dev/null +++ b/src/InboundEmail/InboundEmailCreateParams/AllowedSource.php @@ -0,0 +1,16 @@ + */ + use SdkModel; + + #[Optional] + public ?string $msg; + + #[Optional] + public ?string $status; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with(?string $msg = null, ?string $status = null): self + { + $self = new self; + + null !== $msg && $self['msg'] = $msg; + null !== $status && $self['status'] = $status; + + return $self; + } + + public function withMsg(string $msg): self + { + $self = clone $this; + $self['msg'] = $msg; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailGetResponse.php b/src/InboundEmail/InboundEmailGetResponse.php new file mode 100644 index 0000000..5e76c16 --- /dev/null +++ b/src/InboundEmail/InboundEmailGetResponse.php @@ -0,0 +1,237 @@ +>|null, + * callbackURL?: string|null, + * createdAt?: \DateTimeInterface|null, + * email?: string|null, + * inboundEmailID?: string|null, + * metadata?: array|null, + * reference?: string|null, + * status?: null|Status|value-of, + * updatedAt?: \DateTimeInterface|null, + * } + */ +final class InboundEmailGetResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Accepted CAS providers (empty = all). + * + * @var list>|null $allowedSources + */ + #[Optional('allowed_sources', list: AllowedSource::class)] + public ?array $allowedSources; + + /** + * Webhook URL for email notifications. + */ + #[Optional('callback_url')] + public ?string $callbackURL; + + /** + * When the mailbox was created. + */ + #[Optional('created_at')] + public ?\DateTimeInterface $createdAt; + + /** + * The inbound email address to forward CAS statements to. + */ + #[Optional] + public ?string $email; + + /** + * Unique inbound email identifier. + */ + #[Optional('inbound_email_id')] + public ?string $inboundEmailID; + + /** + * Custom key-value metadata. + * + * @var array|null $metadata + */ + #[Optional(map: 'string')] + public ?array $metadata; + + /** + * Your internal reference identifier. + */ + #[Optional(nullable: true)] + public ?string $reference; + + /** + * Current mailbox status. + * + * @var value-of|null $status + */ + #[Optional(enum: Status::class)] + public ?string $status; + + /** + * When the mailbox was last updated. + */ + #[Optional('updated_at')] + public ?\DateTimeInterface $updatedAt; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list>|null $allowedSources + * @param array|null $metadata + * @param Status|value-of|null $status + */ + public static function with( + ?array $allowedSources = null, + ?string $callbackURL = null, + ?\DateTimeInterface $createdAt = null, + ?string $email = null, + ?string $inboundEmailID = null, + ?array $metadata = null, + ?string $reference = null, + Status|string|null $status = null, + ?\DateTimeInterface $updatedAt = null, + ): self { + $self = new self; + + null !== $allowedSources && $self['allowedSources'] = $allowedSources; + null !== $callbackURL && $self['callbackURL'] = $callbackURL; + null !== $createdAt && $self['createdAt'] = $createdAt; + null !== $email && $self['email'] = $email; + null !== $inboundEmailID && $self['inboundEmailID'] = $inboundEmailID; + null !== $metadata && $self['metadata'] = $metadata; + null !== $reference && $self['reference'] = $reference; + null !== $status && $self['status'] = $status; + null !== $updatedAt && $self['updatedAt'] = $updatedAt; + + return $self; + } + + /** + * Accepted CAS providers (empty = all). + * + * @param list> $allowedSources + */ + public function withAllowedSources(array $allowedSources): self + { + $self = clone $this; + $self['allowedSources'] = $allowedSources; + + return $self; + } + + /** + * Webhook URL for email notifications. + */ + public function withCallbackURL(string $callbackURL): self + { + $self = clone $this; + $self['callbackURL'] = $callbackURL; + + return $self; + } + + /** + * When the mailbox was created. + */ + public function withCreatedAt(\DateTimeInterface $createdAt): self + { + $self = clone $this; + $self['createdAt'] = $createdAt; + + return $self; + } + + /** + * The inbound email address to forward CAS statements to. + */ + public function withEmail(string $email): self + { + $self = clone $this; + $self['email'] = $email; + + return $self; + } + + /** + * Unique inbound email identifier. + */ + public function withInboundEmailID(string $inboundEmailID): self + { + $self = clone $this; + $self['inboundEmailID'] = $inboundEmailID; + + return $self; + } + + /** + * Custom key-value metadata. + * + * @param array $metadata + */ + public function withMetadata(array $metadata): self + { + $self = clone $this; + $self['metadata'] = $metadata; + + return $self; + } + + /** + * Your internal reference identifier. + */ + public function withReference(?string $reference): self + { + $self = clone $this; + $self['reference'] = $reference; + + return $self; + } + + /** + * Current mailbox status. + * + * @param Status|value-of $status + */ + public function withStatus(Status|string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } + + /** + * When the mailbox was last updated. + */ + public function withUpdatedAt(\DateTimeInterface $updatedAt): self + { + $self = clone $this; + $self['updatedAt'] = $updatedAt; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailGetResponse/AllowedSource.php b/src/InboundEmail/InboundEmailGetResponse/AllowedSource.php new file mode 100644 index 0000000..8c6cebd --- /dev/null +++ b/src/InboundEmail/InboundEmailGetResponse/AllowedSource.php @@ -0,0 +1,16 @@ + + * } + */ +final class InboundEmailListParams implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + use SdkParams; + + /** + * Maximum number of inbound emails to return. + */ + #[Optional] + public ?int $limit; + + /** + * Pagination offset. + */ + #[Optional] + public ?int $offset; + + /** + * Filter by status. + * + * @var value-of|null $status + */ + #[Optional(enum: Status::class)] + public ?string $status; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param Status|value-of|null $status + */ + public static function with( + ?int $limit = null, + ?int $offset = null, + Status|string|null $status = null + ): self { + $self = new self; + + null !== $limit && $self['limit'] = $limit; + null !== $offset && $self['offset'] = $offset; + null !== $status && $self['status'] = $status; + + return $self; + } + + /** + * Maximum number of inbound emails to return. + */ + public function withLimit(int $limit): self + { + $self = clone $this; + $self['limit'] = $limit; + + return $self; + } + + /** + * Pagination offset. + */ + public function withOffset(int $offset): self + { + $self = clone $this; + $self['offset'] = $offset; + + return $self; + } + + /** + * Filter by status. + * + * @param Status|value-of $status + */ + public function withStatus(Status|string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailListParams/Status.php b/src/InboundEmail/InboundEmailListParams/Status.php new file mode 100644 index 0000000..9515885 --- /dev/null +++ b/src/InboundEmail/InboundEmailListParams/Status.php @@ -0,0 +1,17 @@ +|null, + * limit?: int|null, + * offset?: int|null, + * status?: string|null, + * total?: int|null, + * } + */ +final class InboundEmailListResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** @var list|null $inboundEmails */ + #[Optional('inbound_emails', list: InboundEmail::class)] + public ?array $inboundEmails; + + #[Optional] + public ?int $limit; + + #[Optional] + public ?int $offset; + + #[Optional] + public ?string $status; + + /** + * Total number of inbound emails (for pagination). + */ + #[Optional] + public ?int $total; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list|null $inboundEmails + */ + public static function with( + ?array $inboundEmails = null, + ?int $limit = null, + ?int $offset = null, + ?string $status = null, + ?int $total = null, + ): self { + $self = new self; + + null !== $inboundEmails && $self['inboundEmails'] = $inboundEmails; + null !== $limit && $self['limit'] = $limit; + null !== $offset && $self['offset'] = $offset; + null !== $status && $self['status'] = $status; + null !== $total && $self['total'] = $total; + + return $self; + } + + /** + * @param list $inboundEmails + */ + public function withInboundEmails(array $inboundEmails): self + { + $self = clone $this; + $self['inboundEmails'] = $inboundEmails; + + return $self; + } + + public function withLimit(int $limit): self + { + $self = clone $this; + $self['limit'] = $limit; + + return $self; + } + + public function withOffset(int $offset): self + { + $self = clone $this; + $self['offset'] = $offset; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } + + /** + * Total number of inbound emails (for pagination). + */ + public function withTotal(int $total): self + { + $self = clone $this; + $self['total'] = $total; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailListResponse/InboundEmail.php b/src/InboundEmail/InboundEmailListResponse/InboundEmail.php new file mode 100644 index 0000000..5328b37 --- /dev/null +++ b/src/InboundEmail/InboundEmailListResponse/InboundEmail.php @@ -0,0 +1,237 @@ +>|null, + * callbackURL?: string|null, + * createdAt?: \DateTimeInterface|null, + * email?: string|null, + * inboundEmailID?: string|null, + * metadata?: array|null, + * reference?: string|null, + * status?: null|Status|value-of, + * updatedAt?: \DateTimeInterface|null, + * } + */ +final class InboundEmail implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Accepted CAS providers (empty = all). + * + * @var list>|null $allowedSources + */ + #[Optional('allowed_sources', list: AllowedSource::class)] + public ?array $allowedSources; + + /** + * Webhook URL for email notifications. + */ + #[Optional('callback_url')] + public ?string $callbackURL; + + /** + * When the mailbox was created. + */ + #[Optional('created_at')] + public ?\DateTimeInterface $createdAt; + + /** + * The inbound email address to forward CAS statements to. + */ + #[Optional] + public ?string $email; + + /** + * Unique inbound email identifier. + */ + #[Optional('inbound_email_id')] + public ?string $inboundEmailID; + + /** + * Custom key-value metadata. + * + * @var array|null $metadata + */ + #[Optional(map: 'string')] + public ?array $metadata; + + /** + * Your internal reference identifier. + */ + #[Optional(nullable: true)] + public ?string $reference; + + /** + * Current mailbox status. + * + * @var value-of|null $status + */ + #[Optional(enum: Status::class)] + public ?string $status; + + /** + * When the mailbox was last updated. + */ + #[Optional('updated_at')] + public ?\DateTimeInterface $updatedAt; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list>|null $allowedSources + * @param array|null $metadata + * @param Status|value-of|null $status + */ + public static function with( + ?array $allowedSources = null, + ?string $callbackURL = null, + ?\DateTimeInterface $createdAt = null, + ?string $email = null, + ?string $inboundEmailID = null, + ?array $metadata = null, + ?string $reference = null, + Status|string|null $status = null, + ?\DateTimeInterface $updatedAt = null, + ): self { + $self = new self; + + null !== $allowedSources && $self['allowedSources'] = $allowedSources; + null !== $callbackURL && $self['callbackURL'] = $callbackURL; + null !== $createdAt && $self['createdAt'] = $createdAt; + null !== $email && $self['email'] = $email; + null !== $inboundEmailID && $self['inboundEmailID'] = $inboundEmailID; + null !== $metadata && $self['metadata'] = $metadata; + null !== $reference && $self['reference'] = $reference; + null !== $status && $self['status'] = $status; + null !== $updatedAt && $self['updatedAt'] = $updatedAt; + + return $self; + } + + /** + * Accepted CAS providers (empty = all). + * + * @param list> $allowedSources + */ + public function withAllowedSources(array $allowedSources): self + { + $self = clone $this; + $self['allowedSources'] = $allowedSources; + + return $self; + } + + /** + * Webhook URL for email notifications. + */ + public function withCallbackURL(string $callbackURL): self + { + $self = clone $this; + $self['callbackURL'] = $callbackURL; + + return $self; + } + + /** + * When the mailbox was created. + */ + public function withCreatedAt(\DateTimeInterface $createdAt): self + { + $self = clone $this; + $self['createdAt'] = $createdAt; + + return $self; + } + + /** + * The inbound email address to forward CAS statements to. + */ + public function withEmail(string $email): self + { + $self = clone $this; + $self['email'] = $email; + + return $self; + } + + /** + * Unique inbound email identifier. + */ + public function withInboundEmailID(string $inboundEmailID): self + { + $self = clone $this; + $self['inboundEmailID'] = $inboundEmailID; + + return $self; + } + + /** + * Custom key-value metadata. + * + * @param array $metadata + */ + public function withMetadata(array $metadata): self + { + $self = clone $this; + $self['metadata'] = $metadata; + + return $self; + } + + /** + * Your internal reference identifier. + */ + public function withReference(?string $reference): self + { + $self = clone $this; + $self['reference'] = $reference; + + return $self; + } + + /** + * Current mailbox status. + * + * @param Status|value-of $status + */ + public function withStatus(Status|string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } + + /** + * When the mailbox was last updated. + */ + public function withUpdatedAt(\DateTimeInterface $updatedAt): self + { + $self = clone $this; + $self['updatedAt'] = $updatedAt; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailListResponse/InboundEmail/AllowedSource.php b/src/InboundEmail/InboundEmailListResponse/InboundEmail/AllowedSource.php new file mode 100644 index 0000000..31a4465 --- /dev/null +++ b/src/InboundEmail/InboundEmailListResponse/InboundEmail/AllowedSource.php @@ -0,0 +1,16 @@ +>|null, + * callbackURL?: string|null, + * createdAt?: \DateTimeInterface|null, + * email?: string|null, + * inboundEmailID?: string|null, + * metadata?: array|null, + * reference?: string|null, + * status?: null|Status|value-of, + * updatedAt?: \DateTimeInterface|null, + * } + */ +final class InboundEmailNewResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Accepted CAS providers (empty = all). + * + * @var list>|null $allowedSources + */ + #[Optional('allowed_sources', list: AllowedSource::class)] + public ?array $allowedSources; + + /** + * Webhook URL for email notifications. + */ + #[Optional('callback_url')] + public ?string $callbackURL; + + /** + * When the mailbox was created. + */ + #[Optional('created_at')] + public ?\DateTimeInterface $createdAt; + + /** + * The inbound email address to forward CAS statements to. + */ + #[Optional] + public ?string $email; + + /** + * Unique inbound email identifier. + */ + #[Optional('inbound_email_id')] + public ?string $inboundEmailID; + + /** + * Custom key-value metadata. + * + * @var array|null $metadata + */ + #[Optional(map: 'string')] + public ?array $metadata; + + /** + * Your internal reference identifier. + */ + #[Optional(nullable: true)] + public ?string $reference; + + /** + * Current mailbox status. + * + * @var value-of|null $status + */ + #[Optional(enum: Status::class)] + public ?string $status; + + /** + * When the mailbox was last updated. + */ + #[Optional('updated_at')] + public ?\DateTimeInterface $updatedAt; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list>|null $allowedSources + * @param array|null $metadata + * @param Status|value-of|null $status + */ + public static function with( + ?array $allowedSources = null, + ?string $callbackURL = null, + ?\DateTimeInterface $createdAt = null, + ?string $email = null, + ?string $inboundEmailID = null, + ?array $metadata = null, + ?string $reference = null, + Status|string|null $status = null, + ?\DateTimeInterface $updatedAt = null, + ): self { + $self = new self; + + null !== $allowedSources && $self['allowedSources'] = $allowedSources; + null !== $callbackURL && $self['callbackURL'] = $callbackURL; + null !== $createdAt && $self['createdAt'] = $createdAt; + null !== $email && $self['email'] = $email; + null !== $inboundEmailID && $self['inboundEmailID'] = $inboundEmailID; + null !== $metadata && $self['metadata'] = $metadata; + null !== $reference && $self['reference'] = $reference; + null !== $status && $self['status'] = $status; + null !== $updatedAt && $self['updatedAt'] = $updatedAt; + + return $self; + } + + /** + * Accepted CAS providers (empty = all). + * + * @param list> $allowedSources + */ + public function withAllowedSources(array $allowedSources): self + { + $self = clone $this; + $self['allowedSources'] = $allowedSources; + + return $self; + } + + /** + * Webhook URL for email notifications. + */ + public function withCallbackURL(string $callbackURL): self + { + $self = clone $this; + $self['callbackURL'] = $callbackURL; + + return $self; + } + + /** + * When the mailbox was created. + */ + public function withCreatedAt(\DateTimeInterface $createdAt): self + { + $self = clone $this; + $self['createdAt'] = $createdAt; + + return $self; + } + + /** + * The inbound email address to forward CAS statements to. + */ + public function withEmail(string $email): self + { + $self = clone $this; + $self['email'] = $email; + + return $self; + } + + /** + * Unique inbound email identifier. + */ + public function withInboundEmailID(string $inboundEmailID): self + { + $self = clone $this; + $self['inboundEmailID'] = $inboundEmailID; + + return $self; + } + + /** + * Custom key-value metadata. + * + * @param array $metadata + */ + public function withMetadata(array $metadata): self + { + $self = clone $this; + $self['metadata'] = $metadata; + + return $self; + } + + /** + * Your internal reference identifier. + */ + public function withReference(?string $reference): self + { + $self = clone $this; + $self['reference'] = $reference; + + return $self; + } + + /** + * Current mailbox status. + * + * @param Status|value-of $status + */ + public function withStatus(Status|string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } + + /** + * When the mailbox was last updated. + */ + public function withUpdatedAt(\DateTimeInterface $updatedAt): self + { + $self = clone $this; + $self['updatedAt'] = $updatedAt; + + return $self; + } +} diff --git a/src/InboundEmail/InboundEmailNewResponse/AllowedSource.php b/src/InboundEmail/InboundEmailNewResponse/AllowedSource.php new file mode 100644 index 0000000..0b38841 --- /dev/null +++ b/src/InboundEmail/InboundEmailNewResponse/AllowedSource.php @@ -0,0 +1,16 @@ + */ + use SdkModel; + use SdkParams; + + /** + * End time filter (ISO 8601). Defaults to now. + */ + #[Optional('end_time')] + public ?\DateTimeInterface $endTime; + + /** + * Maximum number of logs to return. + */ + #[Optional] + public ?int $limit; + + /** + * Start time filter (ISO 8601). Defaults to 30 days ago. + */ + #[Optional('start_time')] + public ?\DateTimeInterface $startTime; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?\DateTimeInterface $endTime = null, + ?int $limit = null, + ?\DateTimeInterface $startTime = null, + ): self { + $self = new self; + + null !== $endTime && $self['endTime'] = $endTime; + null !== $limit && $self['limit'] = $limit; + null !== $startTime && $self['startTime'] = $startTime; + + return $self; + } + + /** + * End time filter (ISO 8601). Defaults to now. + */ + public function withEndTime(\DateTimeInterface $endTime): self + { + $self = clone $this; + $self['endTime'] = $endTime; + + return $self; + } + + /** + * Maximum number of logs to return. + */ + public function withLimit(int $limit): self + { + $self = clone $this; + $self['limit'] = $limit; + + return $self; + } + + /** + * Start time filter (ISO 8601). Defaults to 30 days ago. + */ + public function withStartTime(\DateTimeInterface $startTime): self + { + $self = clone $this; + $self['startTime'] = $startTime; + + return $self; + } +} diff --git a/src/Logs/LogGetSummaryParams.php b/src/Logs/LogGetSummaryParams.php new file mode 100644 index 0000000..605bc07 --- /dev/null +++ b/src/Logs/LogGetSummaryParams.php @@ -0,0 +1,86 @@ + */ + use SdkModel; + use SdkParams; + + /** + * End time filter (ISO 8601). Defaults to now. + */ + #[Optional('end_time')] + public ?\DateTimeInterface $endTime; + + /** + * Start time filter (ISO 8601). Defaults to start of current month. + */ + #[Optional('start_time')] + public ?\DateTimeInterface $startTime; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?\DateTimeInterface $endTime = null, + ?\DateTimeInterface $startTime = null + ): self { + $self = new self; + + null !== $endTime && $self['endTime'] = $endTime; + null !== $startTime && $self['startTime'] = $startTime; + + return $self; + } + + /** + * End time filter (ISO 8601). Defaults to now. + */ + public function withEndTime(\DateTimeInterface $endTime): self + { + $self = clone $this; + $self['endTime'] = $endTime; + + return $self; + } + + /** + * Start time filter (ISO 8601). Defaults to start of current month. + */ + public function withStartTime(\DateTimeInterface $startTime): self + { + $self = clone $this; + $self['startTime'] = $startTime; + + return $self; + } +} diff --git a/src/Logs/LogGetSummaryResponse.php b/src/Logs/LogGetSummaryResponse.php new file mode 100644 index 0000000..c322ffc --- /dev/null +++ b/src/Logs/LogGetSummaryResponse.php @@ -0,0 +1,72 @@ + */ + use SdkModel; + + #[Optional] + public ?string $status; + + #[Optional] + public ?Summary $summary; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param Summary|SummaryShape|null $summary + */ + public static function with( + ?string $status = null, + Summary|array|null $summary = null + ): self { + $self = new self; + + null !== $status && $self['status'] = $status; + null !== $summary && $self['summary'] = $summary; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } + + /** + * @param Summary|SummaryShape $summary + */ + public function withSummary(Summary|array $summary): self + { + $self = clone $this; + $self['summary'] = $summary; + + return $self; + } +} diff --git a/src/Logs/LogGetSummaryResponse/Summary.php b/src/Logs/LogGetSummaryResponse/Summary.php new file mode 100644 index 0000000..852e652 --- /dev/null +++ b/src/Logs/LogGetSummaryResponse/Summary.php @@ -0,0 +1,106 @@ +|null, + * totalCredits?: float|null, + * totalRequests?: int|null, + * } + */ +final class Summary implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Usage breakdown by feature. + * + * @var list|null $byFeature + */ + #[Optional('by_feature', list: ByFeature::class)] + public ?array $byFeature; + + /** + * Total credits consumed in the period. + */ + #[Optional('total_credits')] + public ?float $totalCredits; + + /** + * Total API requests made in the period. + */ + #[Optional('total_requests')] + public ?int $totalRequests; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list|null $byFeature + */ + public static function with( + ?array $byFeature = null, + ?float $totalCredits = null, + ?int $totalRequests = null, + ): self { + $self = new self; + + null !== $byFeature && $self['byFeature'] = $byFeature; + null !== $totalCredits && $self['totalCredits'] = $totalCredits; + null !== $totalRequests && $self['totalRequests'] = $totalRequests; + + return $self; + } + + /** + * Usage breakdown by feature. + * + * @param list $byFeature + */ + public function withByFeature(array $byFeature): self + { + $self = clone $this; + $self['byFeature'] = $byFeature; + + return $self; + } + + /** + * Total credits consumed in the period. + */ + public function withTotalCredits(float $totalCredits): self + { + $self = clone $this; + $self['totalCredits'] = $totalCredits; + + return $self; + } + + /** + * Total API requests made in the period. + */ + public function withTotalRequests(int $totalRequests): self + { + $self = clone $this; + $self['totalRequests'] = $totalRequests; + + return $self; + } +} diff --git a/src/Logs/LogGetSummaryResponse/Summary/ByFeature.php b/src/Logs/LogGetSummaryResponse/Summary/ByFeature.php new file mode 100644 index 0000000..8d15ea0 --- /dev/null +++ b/src/Logs/LogGetSummaryResponse/Summary/ByFeature.php @@ -0,0 +1,95 @@ + */ + use SdkModel; + + /** + * Credits consumed by this feature. + */ + #[Optional] + public ?float $credits; + + /** + * API feature name. + */ + #[Optional] + public ?string $feature; + + /** + * Number of requests for this feature. + */ + #[Optional] + public ?int $requests; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?float $credits = null, + ?string $feature = null, + ?int $requests = null + ): self { + $self = new self; + + null !== $credits && $self['credits'] = $credits; + null !== $feature && $self['feature'] = $feature; + null !== $requests && $self['requests'] = $requests; + + return $self; + } + + /** + * Credits consumed by this feature. + */ + public function withCredits(float $credits): self + { + $self = clone $this; + $self['credits'] = $credits; + + return $self; + } + + /** + * API feature name. + */ + public function withFeature(string $feature): self + { + $self = clone $this; + $self['feature'] = $feature; + + return $self; + } + + /** + * Number of requests for this feature. + */ + public function withRequests(int $requests): self + { + $self = clone $this; + $self['requests'] = $requests; + + return $self; + } +} diff --git a/src/Logs/LogNewResponse.php b/src/Logs/LogNewResponse.php new file mode 100644 index 0000000..45adea4 --- /dev/null +++ b/src/Logs/LogNewResponse.php @@ -0,0 +1,92 @@ +|null, status?: string|null + * } + */ +final class LogNewResponse implements BaseModel +{ + /** @use SdkModel */ + use SdkModel; + + /** + * Number of logs returned. + */ + #[Optional] + public ?int $count; + + /** @var list|null $logs */ + #[Optional(list: Log::class)] + public ?array $logs; + + #[Optional] + public ?string $status; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + * + * @param list|null $logs + */ + public static function with( + ?int $count = null, + ?array $logs = null, + ?string $status = null + ): self { + $self = new self; + + null !== $count && $self['count'] = $count; + null !== $logs && $self['logs'] = $logs; + null !== $status && $self['status'] = $status; + + return $self; + } + + /** + * Number of logs returned. + */ + public function withCount(int $count): self + { + $self = clone $this; + $self['count'] = $count; + + return $self; + } + + /** + * @param list $logs + */ + public function withLogs(array $logs): self + { + $self = clone $this; + $self['logs'] = $logs; + + return $self; + } + + public function withStatus(string $status): self + { + $self = clone $this; + $self['status'] = $status; + + return $self; + } +} diff --git a/src/Logs/LogNewResponse/Log.php b/src/Logs/LogNewResponse/Log.php new file mode 100644 index 0000000..2df24ca --- /dev/null +++ b/src/Logs/LogNewResponse/Log.php @@ -0,0 +1,157 @@ + */ + use SdkModel; + + /** + * Credits consumed for this request. + */ + #[Optional] + public ?float $credits; + + /** + * API feature used. + */ + #[Optional] + public ?string $feature; + + /** + * API endpoint path. + */ + #[Optional] + public ?string $path; + + /** + * Unique request identifier. + */ + #[Optional('request_id')] + public ?string $requestID; + + /** + * HTTP response status code. + */ + #[Optional('status_code')] + public ?int $statusCode; + + /** + * When the request was made. + */ + #[Optional] + public ?\DateTimeInterface $timestamp; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?float $credits = null, + ?string $feature = null, + ?string $path = null, + ?string $requestID = null, + ?int $statusCode = null, + ?\DateTimeInterface $timestamp = null, + ): self { + $self = new self; + + null !== $credits && $self['credits'] = $credits; + null !== $feature && $self['feature'] = $feature; + null !== $path && $self['path'] = $path; + null !== $requestID && $self['requestID'] = $requestID; + null !== $statusCode && $self['statusCode'] = $statusCode; + null !== $timestamp && $self['timestamp'] = $timestamp; + + return $self; + } + + /** + * Credits consumed for this request. + */ + public function withCredits(float $credits): self + { + $self = clone $this; + $self['credits'] = $credits; + + return $self; + } + + /** + * API feature used. + */ + public function withFeature(string $feature): self + { + $self = clone $this; + $self['feature'] = $feature; + + return $self; + } + + /** + * API endpoint path. + */ + public function withPath(string $path): self + { + $self = clone $this; + $self['path'] = $path; + + return $self; + } + + /** + * Unique request identifier. + */ + public function withRequestID(string $requestID): self + { + $self = clone $this; + $self['requestID'] = $requestID; + + return $self; + } + + /** + * HTTP response status code. + */ + public function withStatusCode(int $statusCode): self + { + $self = clone $this; + $self['statusCode'] = $statusCode; + + return $self; + } + + /** + * When the request was made. + */ + public function withTimestamp(\DateTimeInterface $timestamp): self + { + $self = clone $this; + $self['timestamp'] = $timestamp; + + return $self; + } +} diff --git a/src/ServiceContracts/AccessTokenContract.php b/src/ServiceContracts/AccessTokenContract.php index fece3c7..c5a0c9e 100644 --- a/src/ServiceContracts/AccessTokenContract.php +++ b/src/ServiceContracts/AccessTokenContract.php @@ -4,4 +4,25 @@ namespace CasParser\ServiceContracts; -interface AccessTokenContract {} +use CasParser\AccessToken\AccessTokenNewResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\RequestOptions; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface AccessTokenContract +{ + /** + * @api + * + * @param int $expiryMinutes Token validity in minutes (max 60) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + int $expiryMinutes = 60, + RequestOptions|array|null $requestOptions = null + ): AccessTokenNewResponse; +} diff --git a/src/ServiceContracts/AccessTokenRawContract.php b/src/ServiceContracts/AccessTokenRawContract.php index b52767b..326e148 100644 --- a/src/ServiceContracts/AccessTokenRawContract.php +++ b/src/ServiceContracts/AccessTokenRawContract.php @@ -4,4 +4,29 @@ namespace CasParser\ServiceContracts; -interface AccessTokenRawContract {} +use CasParser\AccessToken\AccessTokenCreateParams; +use CasParser\AccessToken\AccessTokenNewResponse; +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\RequestOptions; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface AccessTokenRawContract +{ + /** + * @api + * + * @param array|AccessTokenCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|AccessTokenCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/CreditsContract.php b/src/ServiceContracts/CreditsContract.php index 678b37f..1bb58a2 100644 --- a/src/ServiceContracts/CreditsContract.php +++ b/src/ServiceContracts/CreditsContract.php @@ -4,4 +4,23 @@ namespace CasParser\ServiceContracts; -interface CreditsContract {} +use CasParser\Core\Exceptions\APIException; +use CasParser\Credits\CreditCheckResponse; +use CasParser\RequestOptions; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface CreditsContract +{ + /** + * @api + * + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function check( + RequestOptions|array|null $requestOptions = null + ): CreditCheckResponse; +} diff --git a/src/ServiceContracts/CreditsRawContract.php b/src/ServiceContracts/CreditsRawContract.php index 436209b..396184b 100644 --- a/src/ServiceContracts/CreditsRawContract.php +++ b/src/ServiceContracts/CreditsRawContract.php @@ -4,4 +4,26 @@ namespace CasParser\ServiceContracts; -interface CreditsRawContract {} +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\Credits\CreditCheckResponse; +use CasParser\RequestOptions; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface CreditsRawContract +{ + /** + * @api + * + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function check( + RequestOptions|array|null $requestOptions = null + ): BaseResponse; +} diff --git a/src/ServiceContracts/InboundEmailContract.php b/src/ServiceContracts/InboundEmailContract.php new file mode 100644 index 0000000..836f9c4 --- /dev/null +++ b/src/ServiceContracts/InboundEmailContract.php @@ -0,0 +1,96 @@ +> $allowedSources Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * @param array $metadata Optional key-value pairs (max 10) to include in webhook payload. + * Useful for passing context like plan_type, campaign_id, etc. + * @param string $reference Your internal identifier (e.g., user_id, account_id). + * Returned in webhook payload for correlation. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + string $callbackURL, + ?string $alias = null, + ?array $allowedSources = null, + ?array $metadata = null, + ?string $reference = null, + RequestOptions|array|null $requestOptions = null, + ): InboundEmailNewResponse; + + /** + * @api + * + * @param string $inboundEmailID Inbound Email ID (e.g., ie_a1b2c3d4e5f6) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function retrieve( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): InboundEmailGetResponse; + + /** + * @api + * + * @param int $limit Maximum number of inbound emails to return + * @param int $offset Pagination offset + * @param Status|value-of $status Filter by status + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function list( + int $limit = 50, + int $offset = 0, + Status|string $status = 'all', + RequestOptions|array|null $requestOptions = null, + ): InboundEmailListResponse; + + /** + * @api + * + * @param string $inboundEmailID Inbound Email ID to delete + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function delete( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): InboundEmailDeleteResponse; +} diff --git a/src/ServiceContracts/InboundEmailRawContract.php b/src/ServiceContracts/InboundEmailRawContract.php new file mode 100644 index 0000000..80f74dd --- /dev/null +++ b/src/ServiceContracts/InboundEmailRawContract.php @@ -0,0 +1,81 @@ +|InboundEmailCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|InboundEmailCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; + + /** + * @api + * + * @param string $inboundEmailID Inbound Email ID (e.g., ie_a1b2c3d4e5f6) + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function retrieve( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): BaseResponse; + + /** + * @api + * + * @param array|InboundEmailListParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function list( + array|InboundEmailListParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; + + /** + * @api + * + * @param string $inboundEmailID Inbound Email ID to delete + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function delete( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): BaseResponse; +} diff --git a/src/ServiceContracts/LogsContract.php b/src/ServiceContracts/LogsContract.php index 4c7175c..d7b2de0 100644 --- a/src/ServiceContracts/LogsContract.php +++ b/src/ServiceContracts/LogsContract.php @@ -4,4 +4,45 @@ namespace CasParser\ServiceContracts; -interface LogsContract {} +use CasParser\Core\Exceptions\APIException; +use CasParser\Logs\LogGetSummaryResponse; +use CasParser\Logs\LogNewResponse; +use CasParser\RequestOptions; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface LogsContract +{ + /** + * @api + * + * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. + * @param int $limit Maximum number of logs to return + * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to 30 days ago. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + ?\DateTimeInterface $endTime = null, + int $limit = 100, + ?\DateTimeInterface $startTime = null, + RequestOptions|array|null $requestOptions = null, + ): LogNewResponse; + + /** + * @api + * + * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. + * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to start of current month. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function getSummary( + ?\DateTimeInterface $endTime = null, + ?\DateTimeInterface $startTime = null, + RequestOptions|array|null $requestOptions = null, + ): LogGetSummaryResponse; +} diff --git a/src/ServiceContracts/LogsRawContract.php b/src/ServiceContracts/LogsRawContract.php index 43678fd..5a6a6da 100644 --- a/src/ServiceContracts/LogsRawContract.php +++ b/src/ServiceContracts/LogsRawContract.php @@ -4,4 +4,46 @@ namespace CasParser\ServiceContracts; -interface LogsRawContract {} +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\Logs\LogCreateParams; +use CasParser\Logs\LogGetSummaryParams; +use CasParser\Logs\LogGetSummaryResponse; +use CasParser\Logs\LogNewResponse; +use CasParser\RequestOptions; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface LogsRawContract +{ + /** + * @api + * + * @param array|LogCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|LogCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; + + /** + * @api + * + * @param array|LogGetSummaryParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function getSummary( + array|LogGetSummaryParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse; +} diff --git a/src/ServiceContracts/VerifyTokenContract.php b/src/ServiceContracts/VerifyTokenContract.php index 77ed08e..d9073a8 100644 --- a/src/ServiceContracts/VerifyTokenContract.php +++ b/src/ServiceContracts/VerifyTokenContract.php @@ -4,4 +4,23 @@ namespace CasParser\ServiceContracts; -interface VerifyTokenContract {} +use CasParser\Core\Exceptions\APIException; +use CasParser\RequestOptions; +use CasParser\VerifyToken\VerifyTokenVerifyResponse; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface VerifyTokenContract +{ + /** + * @api + * + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function verify( + RequestOptions|array|null $requestOptions = null + ): VerifyTokenVerifyResponse; +} diff --git a/src/ServiceContracts/VerifyTokenRawContract.php b/src/ServiceContracts/VerifyTokenRawContract.php index aed9c6c..69d807d 100644 --- a/src/ServiceContracts/VerifyTokenRawContract.php +++ b/src/ServiceContracts/VerifyTokenRawContract.php @@ -4,4 +4,26 @@ namespace CasParser\ServiceContracts; -interface VerifyTokenRawContract {} +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\RequestOptions; +use CasParser\VerifyToken\VerifyTokenVerifyResponse; + +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ +interface VerifyTokenRawContract +{ + /** + * @api + * + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function verify( + RequestOptions|array|null $requestOptions = null + ): BaseResponse; +} diff --git a/src/Services/AccessTokenRawService.php b/src/Services/AccessTokenRawService.php index f595a6e..ca67b74 100644 --- a/src/Services/AccessTokenRawService.php +++ b/src/Services/AccessTokenRawService.php @@ -4,9 +4,17 @@ namespace CasParser\Services; +use CasParser\AccessToken\AccessTokenCreateParams; +use CasParser\AccessToken\AccessTokenNewResponse; use CasParser\Client; +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\RequestOptions; use CasParser\ServiceContracts\AccessTokenRawContract; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class AccessTokenRawService implements AccessTokenRawContract { // @phpstan-ignore-next-line @@ -14,4 +22,45 @@ final class AccessTokenRawService implements AccessTokenRawContract * @internal */ public function __construct(private Client $client) {} + + /** + * @api + * + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to frontend/SDK. + * + * **Legacy path:** `/v1/access-token` (still supported) + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + * + * @param array{expiryMinutes?: int}|AccessTokenCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|AccessTokenCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = AccessTokenCreateParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v1/token', + body: (object) $parsed, + options: $options, + convert: AccessTokenNewResponse::class, + ); + } } diff --git a/src/Services/AccessTokenService.php b/src/Services/AccessTokenService.php index d52acf2..489fe26 100644 --- a/src/Services/AccessTokenService.php +++ b/src/Services/AccessTokenService.php @@ -4,9 +4,16 @@ namespace CasParser\Services; +use CasParser\AccessToken\AccessTokenNewResponse; use CasParser\Client; +use CasParser\Core\Exceptions\APIException; +use CasParser\Core\Util; +use CasParser\RequestOptions; use CasParser\ServiceContracts\AccessTokenContract; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class AccessTokenService implements AccessTokenContract { /** @@ -14,7 +21,6 @@ final class AccessTokenService implements AccessTokenContract */ public AccessTokenRawService $raw; - // @phpstan-ignore-next-line /** * @internal */ @@ -22,4 +28,36 @@ public function __construct(private Client $client) { $this->raw = new AccessTokenRawService($client); } + + /** + * @api + * + * Generate a short-lived access token from your API key. + * + * **Use this endpoint from your backend** to create tokens that can be safely passed to frontend/SDK. + * + * **Legacy path:** `/v1/access-token` (still supported) + * + * Access tokens: + * - Are prefixed with `at_` for easy identification + * - Valid for up to 60 minutes + * - Can be used in place of API keys on all v4 endpoints + * - Cannot be used to generate other access tokens + * + * @param int $expiryMinutes Token validity in minutes (max 60) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + int $expiryMinutes = 60, + RequestOptions|array|null $requestOptions = null + ): AccessTokenNewResponse { + $params = Util::removeNulls(['expiryMinutes' => $expiryMinutes]); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->create(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } } diff --git a/src/Services/CreditsRawService.php b/src/Services/CreditsRawService.php index c9be78c..60412fe 100644 --- a/src/Services/CreditsRawService.php +++ b/src/Services/CreditsRawService.php @@ -5,8 +5,15 @@ namespace CasParser\Services; use CasParser\Client; +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\Credits\CreditCheckResponse; +use CasParser\RequestOptions; use CasParser\ServiceContracts\CreditsRawContract; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class CreditsRawService implements CreditsRawContract { // @phpstan-ignore-next-line @@ -14,4 +21,34 @@ final class CreditsRawService implements CreditsRawContract * @internal */ public function __construct(private Client $client) {} + + /** + * @api + * + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + * + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function check( + RequestOptions|array|null $requestOptions = null + ): BaseResponse { + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v1/credits', + options: $requestOptions, + convert: CreditCheckResponse::class, + ); + } } diff --git a/src/Services/CreditsService.php b/src/Services/CreditsService.php index 21b2dc0..4bde97a 100644 --- a/src/Services/CreditsService.php +++ b/src/Services/CreditsService.php @@ -5,8 +5,14 @@ namespace CasParser\Services; use CasParser\Client; +use CasParser\Core\Exceptions\APIException; +use CasParser\Credits\CreditCheckResponse; +use CasParser\RequestOptions; use CasParser\ServiceContracts\CreditsContract; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class CreditsService implements CreditsContract { /** @@ -14,7 +20,6 @@ final class CreditsService implements CreditsContract */ public CreditsRawService $raw; - // @phpstan-ignore-next-line /** * @internal */ @@ -22,4 +27,29 @@ public function __construct(private Client $client) { $this->raw = new CreditsRawService($client); } + + /** + * @api + * + * Check your remaining API credits and usage for the current billing period. + * + * Returns: + * - Number of API calls used and remaining credits + * - Credit limit and reset date + * - List of enabled features for your plan + * + * Credits reset at the start of each billing period. + * + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function check( + RequestOptions|array|null $requestOptions = null + ): CreditCheckResponse { + // @phpstan-ignore-next-line argument.type + $response = $this->raw->check(requestOptions: $requestOptions); + + return $response->parse(); + } } diff --git a/src/Services/InboundEmailRawService.php b/src/Services/InboundEmailRawService.php new file mode 100644 index 0000000..5bc07ba --- /dev/null +++ b/src/Services/InboundEmailRawService.php @@ -0,0 +1,168 @@ +>, + * metadata?: array, + * reference?: string, + * }|InboundEmailCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|InboundEmailCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = InboundEmailCreateParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v4/inbound-email', + body: (object) $parsed, + options: $options, + convert: InboundEmailNewResponse::class, + ); + } + + /** + * @api + * + * Retrieve details of a specific mailbox including statistics. + * + * @param string $inboundEmailID Inbound Email ID (e.g., ie_a1b2c3d4e5f6) + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function retrieve( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): BaseResponse { + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'get', + path: ['v4/inbound-email/%1$s', $inboundEmailID], + options: $requestOptions, + convert: InboundEmailGetResponse::class, + ); + } + + /** + * @api + * + * List all mailboxes associated with your API key. + * Returns active and inactive mailboxes (deleted mailboxes are excluded). + * + * @param array{ + * limit?: int, offset?: int, status?: Status|value-of + * }|InboundEmailListParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function list( + array|InboundEmailListParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = InboundEmailListParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'get', + path: 'v4/inbound-email', + query: $parsed, + options: $options, + convert: InboundEmailListResponse::class, + ); + } + + /** + * @api + * + * Permanently delete an inbound email address. It will stop accepting emails. + * + * **Note:** Deletion is immediate and cannot be undone. Any emails received after + * deletion will be rejected. + * + * @param string $inboundEmailID Inbound Email ID to delete + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function delete( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): BaseResponse { + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'delete', + path: ['v4/inbound-email/%1$s', $inboundEmailID], + options: $requestOptions, + convert: InboundEmailDeleteResponse::class, + ); + } +} diff --git a/src/Services/InboundEmailService.php b/src/Services/InboundEmailService.php new file mode 100644 index 0000000..5acee11 --- /dev/null +++ b/src/Services/InboundEmailService.php @@ -0,0 +1,171 @@ +raw = new InboundEmailRawService($client); + } + + /** + * @api + * + * Create a dedicated inbound email address for collecting CAS statements via email forwarding. + * + * **How it works:** + * 1. Create an inbound email with your webhook URL + * 2. Display the email address to your user (e.g., "Forward your CAS to ie_xxx@import.casparser.in") + * 3. When an investor forwards a CAS email, we verify the sender and deliver to your webhook + * + * **Webhook Delivery:** + * - We POST to your `callback_url` with JSON body containing files (matching EmailCASFile schema) + * - Failed deliveries are retried automatically with exponential backoff + * + * **Inactivity:** + * - Inbound emails with no activity in 30 days are marked inactive + * - Active inbound emails remain operational indefinitely + * + * @param string $callbackURL Webhook URL where we POST email notifications. + * Must be HTTPS in production (HTTP allowed for localhost during development). + * @param string $alias Optional custom email prefix for user-friendly addresses. + * - Must be 3-32 characters + * - Alphanumeric + hyphens only + * - Must start and end with letter/number + * - Example: `john-portfolio@import.casparser.in` + * - If omitted, generates random ID like `ie_abc123xyz@import.casparser.in` + * @param list> $allowedSources Filter emails by CAS provider. If omitted, accepts all providers. + * - `cdsl` → eCAS@cdslstatement.com + * - `nsdl` → NSDL-CAS@nsdl.co.in + * - `cams` → donotreply@camsonline.com + * - `kfintech` → samfS@kfintech.com + * @param array $metadata Optional key-value pairs (max 10) to include in webhook payload. + * Useful for passing context like plan_type, campaign_id, etc. + * @param string $reference Your internal identifier (e.g., user_id, account_id). + * Returned in webhook payload for correlation. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + string $callbackURL, + ?string $alias = null, + ?array $allowedSources = null, + ?array $metadata = null, + ?string $reference = null, + RequestOptions|array|null $requestOptions = null, + ): InboundEmailNewResponse { + $params = Util::removeNulls( + [ + 'callbackURL' => $callbackURL, + 'alias' => $alias, + 'allowedSources' => $allowedSources, + 'metadata' => $metadata, + 'reference' => $reference, + ], + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->create(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * Retrieve details of a specific mailbox including statistics. + * + * @param string $inboundEmailID Inbound Email ID (e.g., ie_a1b2c3d4e5f6) + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function retrieve( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): InboundEmailGetResponse { + // @phpstan-ignore-next-line argument.type + $response = $this->raw->retrieve($inboundEmailID, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * List all mailboxes associated with your API key. + * Returns active and inactive mailboxes (deleted mailboxes are excluded). + * + * @param int $limit Maximum number of inbound emails to return + * @param int $offset Pagination offset + * @param Status|value-of $status Filter by status + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function list( + int $limit = 50, + int $offset = 0, + Status|string $status = 'all', + RequestOptions|array|null $requestOptions = null, + ): InboundEmailListResponse { + $params = Util::removeNulls( + ['limit' => $limit, 'offset' => $offset, 'status' => $status] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->list(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * Permanently delete an inbound email address. It will stop accepting emails. + * + * **Note:** Deletion is immediate and cannot be undone. Any emails received after + * deletion will be rejected. + * + * @param string $inboundEmailID Inbound Email ID to delete + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function delete( + string $inboundEmailID, + RequestOptions|array|null $requestOptions = null + ): InboundEmailDeleteResponse { + // @phpstan-ignore-next-line argument.type + $response = $this->raw->delete($inboundEmailID, requestOptions: $requestOptions); + + return $response->parse(); + } +} diff --git a/src/Services/LogsRawService.php b/src/Services/LogsRawService.php index ef63acf..a32f4e9 100644 --- a/src/Services/LogsRawService.php +++ b/src/Services/LogsRawService.php @@ -5,8 +5,18 @@ namespace CasParser\Services; use CasParser\Client; +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\Logs\LogCreateParams; +use CasParser\Logs\LogGetSummaryParams; +use CasParser\Logs\LogGetSummaryResponse; +use CasParser\Logs\LogNewResponse; +use CasParser\RequestOptions; use CasParser\ServiceContracts\LogsRawContract; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class LogsRawService implements LogsRawContract { // @phpstan-ignore-next-line @@ -14,4 +24,79 @@ final class LogsRawService implements LogsRawContract * @internal */ public function __construct(private Client $client) {} + + /** + * @api + * + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits consumed. + * Useful for monitoring usage patterns and debugging. + * + * **Legacy path:** `/logs` (still supported) + * + * @param array{ + * endTime?: \DateTimeInterface, limit?: int, startTime?: \DateTimeInterface + * }|LogCreateParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function create( + array|LogCreateParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = LogCreateParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v1/usage', + body: (object) $parsed, + options: $options, + convert: LogNewResponse::class, + ); + } + + /** + * @api + * + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + * + * **Legacy path:** `/logs/summary` (still supported) + * + * @param array{ + * endTime?: \DateTimeInterface, startTime?: \DateTimeInterface + * }|LogGetSummaryParams $params + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function getSummary( + array|LogGetSummaryParams $params, + RequestOptions|array|null $requestOptions = null, + ): BaseResponse { + [$parsed, $options] = LogGetSummaryParams::parseRequest( + $params, + $requestOptions, + ); + + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v1/usage/summary', + body: (object) $parsed, + options: $options, + convert: LogGetSummaryResponse::class, + ); + } } diff --git a/src/Services/LogsService.php b/src/Services/LogsService.php index 4a9e6fc..ce04094 100644 --- a/src/Services/LogsService.php +++ b/src/Services/LogsService.php @@ -5,8 +5,16 @@ namespace CasParser\Services; use CasParser\Client; +use CasParser\Core\Exceptions\APIException; +use CasParser\Core\Util; +use CasParser\Logs\LogGetSummaryResponse; +use CasParser\Logs\LogNewResponse; +use CasParser\RequestOptions; use CasParser\ServiceContracts\LogsContract; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class LogsService implements LogsContract { /** @@ -14,7 +22,6 @@ final class LogsService implements LogsContract */ public LogsRawService $raw; - // @phpstan-ignore-next-line /** * @internal */ @@ -22,4 +29,67 @@ public function __construct(private Client $client) { $this->raw = new LogsRawService($client); } + + /** + * @api + * + * Retrieve detailed API usage logs for your account. + * + * Returns a list of API calls with timestamps, features used, status codes, and credits consumed. + * Useful for monitoring usage patterns and debugging. + * + * **Legacy path:** `/logs` (still supported) + * + * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. + * @param int $limit Maximum number of logs to return + * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to 30 days ago. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function create( + ?\DateTimeInterface $endTime = null, + int $limit = 100, + ?\DateTimeInterface $startTime = null, + RequestOptions|array|null $requestOptions = null, + ): LogNewResponse { + $params = Util::removeNulls( + ['endTime' => $endTime, 'limit' => $limit, 'startTime' => $startTime] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->create(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } + + /** + * @api + * + * Get aggregated usage statistics grouped by feature. + * + * Useful for understanding which API features are being used most and tracking usage trends. + * + * **Legacy path:** `/logs/summary` (still supported) + * + * @param \DateTimeInterface $endTime End time filter (ISO 8601). Defaults to now. + * @param \DateTimeInterface $startTime Start time filter (ISO 8601). Defaults to start of current month. + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function getSummary( + ?\DateTimeInterface $endTime = null, + ?\DateTimeInterface $startTime = null, + RequestOptions|array|null $requestOptions = null, + ): LogGetSummaryResponse { + $params = Util::removeNulls( + ['endTime' => $endTime, 'startTime' => $startTime] + ); + + // @phpstan-ignore-next-line argument.type + $response = $this->raw->getSummary(params: $params, requestOptions: $requestOptions); + + return $response->parse(); + } } diff --git a/src/Services/VerifyTokenRawService.php b/src/Services/VerifyTokenRawService.php index fc36e5f..fb94a32 100644 --- a/src/Services/VerifyTokenRawService.php +++ b/src/Services/VerifyTokenRawService.php @@ -5,8 +5,15 @@ namespace CasParser\Services; use CasParser\Client; +use CasParser\Core\Contracts\BaseResponse; +use CasParser\Core\Exceptions\APIException; +use CasParser\RequestOptions; use CasParser\ServiceContracts\VerifyTokenRawContract; +use CasParser\VerifyToken\VerifyTokenVerifyResponse; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class VerifyTokenRawService implements VerifyTokenRawContract { // @phpstan-ignore-next-line @@ -14,4 +21,28 @@ final class VerifyTokenRawService implements VerifyTokenRawContract * @internal */ public function __construct(private Client $client) {} + + /** + * @api + * + * Verify an access token and check if it's still valid. + * Useful for debugging token issues. + * + * @param RequestOpts|null $requestOptions + * + * @return BaseResponse + * + * @throws APIException + */ + public function verify( + RequestOptions|array|null $requestOptions = null + ): BaseResponse { + // @phpstan-ignore-next-line return.type + return $this->client->request( + method: 'post', + path: 'v1/token/verify', + options: $requestOptions, + convert: VerifyTokenVerifyResponse::class, + ); + } } diff --git a/src/Services/VerifyTokenService.php b/src/Services/VerifyTokenService.php index e09c873..9c1094d 100644 --- a/src/Services/VerifyTokenService.php +++ b/src/Services/VerifyTokenService.php @@ -5,8 +5,14 @@ namespace CasParser\Services; use CasParser\Client; +use CasParser\Core\Exceptions\APIException; +use CasParser\RequestOptions; use CasParser\ServiceContracts\VerifyTokenContract; +use CasParser\VerifyToken\VerifyTokenVerifyResponse; +/** + * @phpstan-import-type RequestOpts from \CasParser\RequestOptions + */ final class VerifyTokenService implements VerifyTokenContract { /** @@ -14,7 +20,6 @@ final class VerifyTokenService implements VerifyTokenContract */ public VerifyTokenRawService $raw; - // @phpstan-ignore-next-line /** * @internal */ @@ -22,4 +27,23 @@ public function __construct(private Client $client) { $this->raw = new VerifyTokenRawService($client); } + + /** + * @api + * + * Verify an access token and check if it's still valid. + * Useful for debugging token issues. + * + * @param RequestOpts|null $requestOptions + * + * @throws APIException + */ + public function verify( + RequestOptions|array|null $requestOptions = null + ): VerifyTokenVerifyResponse { + // @phpstan-ignore-next-line argument.type + $response = $this->raw->verify(requestOptions: $requestOptions); + + return $response->parse(); + } } diff --git a/src/VerifyToken/VerifyTokenVerifyResponse.php b/src/VerifyToken/VerifyTokenVerifyResponse.php new file mode 100644 index 0000000..70f4cb1 --- /dev/null +++ b/src/VerifyToken/VerifyTokenVerifyResponse.php @@ -0,0 +1,95 @@ + */ + use SdkModel; + + /** + * Error message (only shown if invalid). + */ + #[Optional] + public ?string $error; + + /** + * Masked API key (only shown if valid). + */ + #[Optional('masked_api_key')] + public ?string $maskedAPIKey; + + /** + * Whether the token is valid. + */ + #[Optional] + public ?bool $valid; + + public function __construct() + { + $this->initialize(); + } + + /** + * Construct an instance from the required parameters. + * + * You must use named parameters to construct any parameters with a default value. + */ + public static function with( + ?string $error = null, + ?string $maskedAPIKey = null, + ?bool $valid = null + ): self { + $self = new self; + + null !== $error && $self['error'] = $error; + null !== $maskedAPIKey && $self['maskedAPIKey'] = $maskedAPIKey; + null !== $valid && $self['valid'] = $valid; + + return $self; + } + + /** + * Error message (only shown if invalid). + */ + public function withError(string $error): self + { + $self = clone $this; + $self['error'] = $error; + + return $self; + } + + /** + * Masked API key (only shown if valid). + */ + public function withMaskedAPIKey(string $maskedAPIKey): self + { + $self = clone $this; + $self['maskedAPIKey'] = $maskedAPIKey; + + return $self; + } + + /** + * Whether the token is valid. + */ + public function withValid(bool $valid): self + { + $self = clone $this; + $self['valid'] = $valid; + + return $self; + } +} diff --git a/tests/ClientTest.php b/tests/ClientTest.php index b6359ce..0082cf4 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -32,7 +32,7 @@ public function testDefaultHeaders(): void requestOptions: ['transporter' => $transporter], ); - $client->camsKfintech->parse(); + $client->credits->check(); $this->assertNotFalse($requested = $transporter->getRequests()[0] ?? false); diff --git a/tests/Services/AccessTokenTest.php b/tests/Services/AccessTokenTest.php new file mode 100644 index 0000000..bb5ae62 --- /dev/null +++ b/tests/Services/AccessTokenTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testCreate(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->accessToken->create(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(AccessTokenNewResponse::class, $result); + } +} diff --git a/tests/Services/CreditsTest.php b/tests/Services/CreditsTest.php new file mode 100644 index 0000000..70e7b80 --- /dev/null +++ b/tests/Services/CreditsTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testCheck(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->credits->check(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(CreditCheckResponse::class, $result); + } +} diff --git a/tests/Services/InboundEmailTest.php b/tests/Services/InboundEmailTest.php new file mode 100644 index 0000000..bd12df6 --- /dev/null +++ b/tests/Services/InboundEmailTest.php @@ -0,0 +1,106 @@ +client = $client; + } + + #[Test] + public function testCreate(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->inboundEmail->create( + callbackURL: 'https://api.yourapp.com/webhooks/cas-email' + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboundEmailNewResponse::class, $result); + } + + #[Test] + public function testCreateWithOptionalParams(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->inboundEmail->create( + callbackURL: 'https://api.yourapp.com/webhooks/cas-email', + alias: 'john-portfolio', + allowedSources: ['cdsl', 'nsdl'], + metadata: ['plan' => 'premium', 'source' => 'onboarding'], + reference: 'user_12345', + ); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboundEmailNewResponse::class, $result); + } + + #[Test] + public function testRetrieve(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->inboundEmail->retrieve('ie_a1b2c3d4e5f6'); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboundEmailGetResponse::class, $result); + } + + #[Test] + public function testList(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->inboundEmail->list(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboundEmailListResponse::class, $result); + } + + #[Test] + public function testDelete(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->inboundEmail->delete('inbound_email_id'); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(InboundEmailDeleteResponse::class, $result); + } +} diff --git a/tests/Services/LogsTest.php b/tests/Services/LogsTest.php new file mode 100644 index 0000000..1f4c4da --- /dev/null +++ b/tests/Services/LogsTest.php @@ -0,0 +1,57 @@ +client = $client; + } + + #[Test] + public function testCreate(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->logs->create(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(LogNewResponse::class, $result); + } + + #[Test] + public function testGetSummary(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->logs->getSummary(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(LogGetSummaryResponse::class, $result); + } +} diff --git a/tests/Services/VerifyTokenTest.php b/tests/Services/VerifyTokenTest.php new file mode 100644 index 0000000..36549b1 --- /dev/null +++ b/tests/Services/VerifyTokenTest.php @@ -0,0 +1,43 @@ +client = $client; + } + + #[Test] + public function testVerify(): void + { + if (UnsupportedMockTests::$skip) { + $this->markTestSkipped('Mock server tests are disabled'); + } + + $result = $this->client->verifyToken->verify(); + + // @phpstan-ignore-next-line method.alreadyNarrowedType + $this->assertInstanceOf(VerifyTokenVerifyResponse::class, $result); + } +} From 035fb2cebd2b7fde3d8b41d8e1621257a9c855cc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:00:49 +0000 Subject: [PATCH 7/8] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index cdf3c0a..49508b3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 21 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cas-parser%2Fcas-parser-d9763d006969b49a1473851069fdfa429eb13133b64103a62963bb70ddb22305.yml openapi_spec_hash: 6aee689b7a759b12c85c088c15e29bc0 -config_hash: d54f39abb185904495bef7c5f8702746 +config_hash: 4ab3e1ee76a463e0ed214541260ee12e From 8c1b394d61ccdf310e71dc3a99a645cca75f5415 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 03:01:04 +0000 Subject: [PATCH 8/8] release: 0.5.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 17 +++++++++++++++++ src/Version.php | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index da59f99..2aca35a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.4.0" + ".": "0.5.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 63556f4..41daf9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 0.5.0 (2026-02-23) + +Full Changelog: [v0.4.0...v0.5.0](https://github.com/CASParser/cas-parser-php/compare/v0.4.0...v0.5.0) + +### Features + +* **api:** api update ([d8c85b9](https://github.com/CASParser/cas-parser-php/commit/d8c85b904f3df1c7242527d1dd66996d0e8cd6e8)) +* **api:** api update ([92b50de](https://github.com/CASParser/cas-parser-php/commit/92b50de8ea771c015e38a2635f1ee5c011156008)) +* **api:** api update ([c0fc7b8](https://github.com/CASParser/cas-parser-php/commit/c0fc7b8b4284930ca1d6eec4c58e88b026cf2da5)) +* **api:** manual updates ([83a811c](https://github.com/CASParser/cas-parser-php/commit/83a811cd2ac157f781caeabff6e8e0f4b757435e)) + + +### Chores + +* **internal:** remove mock server code ([e868489](https://github.com/CASParser/cas-parser-php/commit/e8684893f2f7c4ab6d75c2be56fc9f2d7c6a5323)) +* update mock server docs ([8a17bde](https://github.com/CASParser/cas-parser-php/commit/8a17bdee09cb200c74522cdf7ed35f8934ba4ecd)) + ## 0.4.0 (2026-02-14) Full Changelog: [v0.3.0...v0.4.0](https://github.com/CASParser/cas-parser-php/compare/v0.3.0...v0.4.0) diff --git a/src/Version.php b/src/Version.php index cb6f277..6568f49 100644 --- a/src/Version.php +++ b/src/Version.php @@ -5,5 +5,5 @@ namespace CasParser; // x-release-please-start-version -const VERSION = '0.4.0'; +const VERSION = '0.5.0'; // x-release-please-end